久々に書いてみたら忘れていた Excel VBA のイディオム集

久々に書いたら思い出せなくなっていた Excel VBA のイディオムをまとめておく。

目次

配列の生成と push()

JavaScript でいうところの Array.prototype.push() がやりたい。

' 配列は「変数名()」で宣言する
Dim myArr() As String
' Index 0 で初期化しておく
ReDim myArr(0)

Dim ws As Variant
For Each ws In Worksheets  ' 何かループするモノ
  ' 最終要素に値を追加する
  myArr(UBound(myArr)) = x.Name
  
  ' 配列の長さを拡張する
  ReDim Preserve myArr(UBound(myArr) + 1)
Next x

' ループを1回以上通ると、ループ内で1つ余分に要素を作ってしまうので、最終要素を削除する
If UBound(myArr) > 0 Then
  ReDim Preserve myArr(UBound(myArr) - 1)
End If

という流れ。

配列の .length を知る

JavaScript でいうところの Array.length が知りたい。

' 配列を用意。この配列にデータが入っているとして…
Dim myArr() As String

' 要素数を求める
Dim length As Integer
length = UBound(myArr) - LBound(myArr) + 1

If length = 0 Then
  MsgBox "配列の要素数が 0 個です"
End If

UBound()LBound() の差に +1 して求める。要素数が0個の時、UBound()-1 を返すので。

ある文字列が、指定の文字列を含んでいるかどうか

SQL でいう LIKE、JavaScript でいう String.prototype.includes() 相当。

' 検索対象の文字列を用意する
Dim myStr As String: myStr = "My Excel VBA String"

' 変数 myStr に、文字列 "Str" が含まれているか
If myStr Like "*Str*" Then
  ' 文字列 "Str" を含んでいる
End If

ループの書き方

Do While とか For Each In とか、VBA はループの書き方が多くていつも迷う。

Dir() は呼ぶ度にファイル名を返し、なくなったら空文字を返すので Do While で継続条件を示すのが良い。

Dim file As String: file = Dir(path)  ' 変数 path で対象のディレクトリを指定する

Do While file <> ""
  ' 1つのファイル名が取得できたので、あとはよしなに…
  MsgBox file
  
  ' ループの最後で、次のファイルを取得する
  file = Dir()
Loop

シートを順に回す時なんかは For Each In が楽。

' ループで使用する変数を用意しておく。対象のモノによっては型を Variant にしないとエラーが出るかも
Dim worksheet As Variant
' ワークシートを順に探索する
For Each worksheet In ActiveWorkbook.Worksheets
  ' あとはよしなに…
  MsgBox worksheet.name
Next

JavaScript だと worksheets.forEach(worksheet => console.log(worksheet.name)) なノリで、worksheet を仮引数で受け取れるのだが、VBA の場合は Dim でイチイチ宣言しておいてあげないといけないのがダルいところ。

デバッグ出力したい

Debug.Print "文字列" という風に書くと、「イミディエイトウィンドウ」に出力される。文字列か数値など、素のまま出力できるモノしか指定できないので、配列とかを雑に確認しようとして Debug.Print myArr とかしたくても無理な点には注意。


以上。JavaScript ばっかり書いてて VBA 忘れてきていた…。