VBA 配列内の値を検索する
In this Article
このチュートリアルでは、VBAで配列内の値を検索(Find)する方法を説明します。 配列の中の文字列を検索する方法は、配列が1次元か多次元かによっても異なります。
一次元配列の検索
一次元配列の中の値を検索するには、フィルタ関数を使用します。
Dim z As Variant
'元の配列にフィルタをかける
z = Filter(Array, String, True, vbCompareBinary)
Filterオプションの構文は以下の通りです。
Filter(Source Array, Match as String, [Include as Boolean], [Compare as vbCompareMethod])
Source Array と Match as String は必須ですが、Include as BooleanとCompare as vbCompareMethodはオプションです。 これらが省略された場合、それぞれTrueと vbCompareBinaryに設定されます。
Filterにマッチする値を検索する
Sub FindBob()
'配列の作成
Dim strName() As Variant
strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams")
'フィルタデータを格納するためバリアント型を宣言する
Dim strSubNames As Variant
'元の配列にフィルタをかける
strSubNames = Filter(strName, "Bob")
'UBound値が-1より大きい場合、値が見つかったことになる
If UBound(strSubNames ) > -1 Then MsgBox ("I Found Bob")
End Sub
2つ目の配列は、フィルタによって見つかった値を保持します。 UBoundの値が-1でなければ、あなたは探していた値を見つけたということです。 また、そのテキストが元の配列に何回現れたかを計算することもできます。
Sub CountNames()
'配列の作成
Dim strName() As Variant
strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams")
'フィルタデータを格納するためバリアント型を宣言する
Dim strSubNames As Variant
'元の配列にフィルタをかける
strSubNames = Filter(strName, "Bob")
'UBoundの値に1を足すと、テキストの出現回数が得られる
Msgbox UBound(strSubNames) + 1 & " names found."
End Sub
フィルタに一致しない値を検索する
[Include as Boolean]オプションを使用すると、配列の中でフィルタに一致しない値がいくつあるか調べることができます。
Sub CountExtraNames()
'配列を作成する
Dim strName() As Variant
strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams")
'フィルタデータを格納するための配列を宣言する
Dim strSubNames As Variant
'元の配列にフィルタをかける
strSubNames = Filter(strName, "Bob", False)
'UBoundの値に1を足すと、テキストの出現回数が得られる
Msgbox UBound(strSubNames) + 1 & " names found."
End Sub
というわけで、この行を修正します。
strSubNames = Filter(strName, "Bob")
を、以下の行に置き換えてください。
strSubNames = Filter(strName, "Bob", False)
こうすると、”Bob “にマッチしない名前がすべて返されます。
大文字・小文字を区別するフィルタ
このフィルターは、デフォルトで大文字と小文字が区別されます。実はこれは、すべてのVBA関数に当てはまります。 もし、大文字と小文字を区別しないテキストを検索したい場合は、コードを少し修正する必要があります。
z = Filter(strName, "bob",, vbTextCompare)
このようにフィルターのオプションにvbTextCompareを追加すると、”bob” または “Bob” を見つけることができるようになります。 これを省略すると、VBAはデフォルトでvbBinaryCompareを使用し、完全に一致するデータのみを探します。 上の例では、 [Include as Boolean]引数が省略されているので、Trueが仮定されていることに注意してください。
オプション比較テキスト
また、モジュールの先頭にOption Compare Textというテキストを追加することで、そのモジュールに記述するすべての関数を大文字小文字を区別せずに記述することができます。
ループを使った配列の検索
ループの使い方は、Filter関数の使い方より少し複雑です。 配列内のすべての値をループする関数を作成します。
Sub LoopThroughArray()
'配列を作成する
Dim strName() As Variant
strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams")
Dim strFind as string
strFind = "Bob"
Dim i As Long
'配列の中をループする
For i = LBound(strName, 1) To UBound(strName, 1)
If InStr(strName(i), strFind) > 0 Then
MsgBox "Bob has been found!"
Exit For
End If
Next i
End Sub
「Bob Smith」や「Bob Williams」ではなく、「Bob」という文字列の一部を見つけるには、If文の中でInstr関数を使う必要がありました。 これは、ループが返す文字列の中に「Bob」があるかどうかを配列から調べ、文字列の中にある場合はメッセージボックスを返してループを終了させるものです。
多次元配列の検索
また、ループを使って多次元配列を検索することもできます。 この場合、配列内のすべての値をループする関数を作成する必要があります。下記の例では、2つの次元をループさせる必要があります。
Function LoopThroughArray()
Dim varArray() As Variant
Dim strFind As String
strFind = "Doctor"
'配列のサイズを宣言する
ReDim varArray(1, 2)
'配列を初期化する
varArray(0, 0) = "Mel Smith"
varArray(0, 1) = "Fred Buckle"
varArray(0, 2) = "Jane Eyre"
varArray(1, 0) = "Accountant"
varArray(1, 1) = "Secretary"
varArray(1, 2) = "Doctor"
'ループ用の変数を宣言する
Dim i As Long, j As Long
'1次元目のループ
For i = LBound(varArray, 1) To UBound(varArray, 1)
'2次元目のループ
For j = LBound(varArray, 2) To UBound(varArray, 2)
'値が見つかったら msgbox を表示して関数の実行を終了する
If varArray(i, j) = strFind Then
MsgBox "Doctor has been found!"
End Function
End If
Next j
Next i
End Function