【ExcelVBA】今日が何曜日か確認する【小ネタ】
どうも、じゃらしです。
最近本業でもテレワークが導入されて、毎日引きこもり生活をしている訳ですが、曜日感覚が分からなくなるんですよね。
そんな人は、VBEのイミディエイトウィンドウに下のコードを打ち込んでEnterを押すと、今日が何曜日か確認できます。
?WeekdayName(Weekday(Now))
オチはありません。
以上、それではまた。
【ExcelVBA】N-gramを実装してみた【言語処理】
どうも、じゃらしです。
今回はExcelVBAのネタです。
ExcelVBAで「言語処理100本ノック」に挑戦してみようと思い、N-gramというテキスト分割方法について実装してみました。
※「言語処理100本ノック」について気になる人はググってみて下さいませ
①文字単位のN-gramを行うクラスとして「CharNgram.cls」
②単語単位のN-gramを行うクラスとして「WordNgram.cls」
を作成します。
連想配列としてDictionary型を使用するので、事前に参照設定から
「Microsoft Scripting Runtime」にチェックを付けておきましょう。
早速本題です。
'CharNgram.cls Private N_ As Long Public Property Let N(ByVal hoge As Long) N_ = hoge End Property Public Property Get N() As Long N = N_ End Property Public Function ToNgram(ByRef hoge As String) As Dictionary Dim letters As String letters = Replace(hoge, " ", "") Dim length As Long length = Len(letters) Dim dic As New Dictionary Dim char As String Dim i As Long For i = 1 To length - N + 1 char = Mid(letters, i, N) If Not dic.Exists(char) Then dic.Add char, char End If Next i Set ToNgram = dic End Function
↑は、文字単位にN-gramを行う「CharNgram.cls」です。
使い方ですが、あらかじめNに数値を設定しておきます。
そして、N-gramしたい文章を引数としてToNgramを実行すると、N文字で分割された連想配列を返します。
'WordNgram.cls Private N_ As Long Public Property Let N(ByVal hoge As Long) N_ = hoge End Property Public Property Get N() As Long N = N_ End Property Public Function ToNgram(ByRef hoge As String) As Dictionary Dim arrHoge() As String arrHoge = Split(hoge) Dim dic As New Dictionary Dim word As String Dim i As Long For i = LBound(arrHoge) To UBound(arrHoge) - N + 1 word = ConcatWords(arrHoge, i) If Not dic.Exists(word) Then dic.Add word, word End If Next i Set ToNgram = dic End Function Private Function ConcatWords(ByRef arrHoge As Variant, ByVal index As Long) As String Dim arr() As String Dim i As Long For i = 1 To N ReDim Preserve arr(1 To i) As String arr(i) = arrHoge(index + i - 1) Next i ConcatWords = Join(arr) End Function
↑は、単語単位にN-gramを行う「CharNgram.cls」です。
使い方は先ほどと同様、N-gramしたい文章を引数としてToNgramを実行すると、N単語で分割された連想配列を返します。
<実行例1>
'Module1.bas Sub test() Dim sentence As String sentence = "I am an NLPer" With New CharNgram Dim i As Long For i = 1 To 3 .N = i Debug.Print Join(.ToNgram(sentence).Items, ",") Next i End With With New WordNgram For i = 1 To 3 .N = i Debug.Print Join(.ToNgram(sentence).Items, ",") Next i End With End Sub
"I am an NLPer"という文章を文字・単語単位で分割して出力します。
Nが1~3の場合でそれぞれ分割しています。
<実行例2>
'Module2.bas Sub test() Dim x As String, y As String x = "paraparaparadise" y = "paragraph" With New CharNgram .N = 2 Debug.Print Join(.ToNgram(x).Items, ",") Debug.Print Join(.ToNgram(y).Items, ",") End With End Sub
分割した要素は重複しないよ、という例です。
ExcelVBAでテキスト分析するかどうかはさておき、実装を考えるのは楽しかったです。(粉みかん)
以上、それではまた。
【ExcelVBA】複数選択しているシートのみを処理する
どうも、じゃらしです。
今回もExcelVBAの小ネタです。
シートタブをctrl+クリックで複数選択して、それらのシートだけに対して処理を行いたい時、たまにあるじゃないですか。
↓のコードで出来ます。
'Module1.bas Sub test() Dim ws As Worksheet For Each ws In ActiveWindow.SelectedSheets ‘ シート毎に行いたい処理を記述する ws.Range(“A1”) = “ちくわ” Next End Sub
以上、それではまた。
【ExcelVBA】クラスモジュールの使い方その1
どうも、じゃらしです。
今回もExcelVBAネタです。
VBAのクラスモジュールに関する記事です。
突然ですが、このコードを見たことがありますか?
Application.ScreenUpdating = False
ScreenUpdatingは、Excelの画面更新に関するApplicationのプロパティで、Falseにすると見かけ上画面描写されなくなります。
セルの値を操作するときは、これをFalseにしておくと次にTrueになる時まで見かけ上の画面描写を止めておくことができて、処理がまあまあ早くなります。
こんな感じで、マクロ実行時に必ず行わせたい処理があったりしますよね。
各プロシージャにScreenUpdating...をコーディングしていっても良いのですが、クラスモジュール化しておくと後々別のマクロでもインポートして使用したりできて便利なので紹介します。
実際のコード
今回は、パフォーマンス向上用クラスとして「PerformanceUp.cls」を作成します。
'PerformanceUp.cls Private saved_ScreenUpdating As Long Private saved_EnableEvents As Long Private Sub Class_Initialize() With Application saved_ScreenUpdating = .ScreenUpdating saved_EnableEvents = .EnableEvents .ScreenUpdating = False .EnableEvents = False End With End Sub Private Sub Class_Terminate() With Application .ScreenUpdating = saved_ScreenUpdating .EnableEvents = saved_EnableEvents End With End Sub
そして、PerformanceUpを標準モジュール上でインスタンス化します。
'Module1.bas Sub test() Dim pu As PerformanceUp Set pu = New PerformanceUp '以下処理を記述 Debug.Print "ちくわ" End Sub
こんな感じに記述すると、testプロシージャ実行時にPerformanceUpのClass_Initializeが呼び出されます。
そして、End Sub時にPerformanceUpのClass_Terminateが呼び出されます。
Application.ScreenUpdatingは画面更新
Application.EnableEventsはシート削除時などのダイアログ有無
ここら辺は切っちゃうことが多いので、WithでApplicationを括って記述しています。
特別なプロシージャ
Class_Initialize:コンストラクタ
Class_Terminate:デストラクタ
これらのプロシージャは特別で、コンストラクタはそのクラスがNewされる時(インスタンス生成時)に自動的に呼び出されます。
また、デストラクタはNewされたインスタンスがどこからも参照されなくなった時に自動的に呼び出されます。
注意1
Dim pu As New PerformanceUp
上記のようにpu宣言時にインスタンスを生成する書き方もありますが、この場合Class_Initializeは「次にpuが参照されるタイミング」で呼び出されます。つまり、Class_Initializeが呼び出されるか分からなくなってしまいます。
このクラスはプロシージャ開始時にいろいろ設定したりするのが目的ですので、この書き方は避けるべきです。
【ExcelVBA】FileDialogを活用してファイル操作をもっと便利に
どうも、じゃらしです。
今回もExcelVBAネタです。
以前取り上げた「FileSystemObject」に関連する内容です。
twitpokej.hatenablog.com
twitpokej.hatenablog.com
ファイルのパスを指定する際、変数にパスを直接コーディングしていました。
ですが、ファイルダイアログで指定できたらいいのに、と思う場面ありませんか。(こんなの↓)
そんな時は、ExcelVBAの「FileDialog」を使うことで実現できます。
以下サンプルコード
Sub test() Dim fso As New FileSystemObject 'ファイルダイアログを表示する With Application.FileDialog(msoFileDialogFilePicker) If .Show Then Dim hoge As Variant '選択したファイル1つ1つに対して処理を行う For Each hoge In .SelectedItems Debug.Print fso.GetFile(hoge).Name Next End If End With End Sub
ファイル選択中
実行結果
選択したファイル名を表示してくれます。
ちなみに、ファイルダイアログ上で複数選択した場合にも対応しています。
「FileDialog」で選択したアイテムのパスが配列「SelectedItems」に格納されているので、For Each文を使えば1つ1つに対して処理を行うこともできます。
複数ファイル選択中
実行結果
以上、それではまた。
ヴィクトリー・ドラゴンに攻撃されたら肘鉄で山札を崩せ
効果モンスター(禁止カード) 星8/闇属性/ドラゴン族/攻2400/守3000 このカードは特殊召喚できない。 自分フィールド上のドラゴン族モンスター3体を 生け贄にして生け贄召喚しなければならない。 このカードの直接攻撃によって相手ライフを0にした場合、 このカードのコントローラーはマッチに勝利する。
あなたは罰則規定によりデュエルには敗北しますが、マッチキルから逃げられます。
こんにちは、じゃらしです。
今回は、対戦ゲームの愚痴を書きました。
遊戯王には、ヴィクトリー・ドラゴン以外にもマインドクラッシュの件やら、ありますよね。
ルール上ありなので、まあ狙えるなら狙っちゃうよね、という感じです。
でも、もやもやーっとしますよね。しません?
以上、それではまた。