更新日:、 作成日:
VBA Filter 関数:配列を絞り込む
はじめに
Excel VBA マクロの Filter 関数から配列を絞り込む方法を紹介します。
Filter 関数は、文字列の配列から指定した文字列を含む配列を返します。
部分一致で絞り込むので あいう, あいえ, かきお に対して あい でフィルタすると、あいう, あいえ の配列を返します。
完全一致で要素を絞り込むにはループします。
完全一致で存在チェックをしたり、二次元配列の存在チェックをするにはループします。
文字列の配列を絞り込み (フィルタリング) したいときに使用します。
Filter 関数の引数と戻り値
Filter(文字列型配列, フィルタ文字)
文字列型配列からフィルタ文字と一致する要素の配列を作成します。
Filter(文字列型配列, フィルタ文字, 含む, 比較モード)
フィルタ文字を含むか含まないか指定できます。比較モードで大文字と小文字を区別するか指定できます。
引数「文字列型」 | 文字列型 (String) を指定します。 |
引数「フィルタ文字」 | フィルタリングする文字列を指定します。 |
引数「含む」 | 省略できます。 True または省略: 引数「フィルタ文字」を含む配列を返します。 False: 引数「フィルタ文字」を含まない配列を返します。 |
引数「比較モード」 | 省略できます。フィルタリングに大文字と小文字を区別するか指定します。 |
戻り値の型 | 文字列型 (String) の配列 |
引数「比較モード」
単位 | 説明 |
vbBinaryCompare (既定) | 「大文字と小文字」、「半角と全角」、「ひらがなとカタカナ」を区別する。 |
vbTextCompare | 区別しない。 |
解説
戻り値を受け取る変数は、String 型の動的配列か Variant 型である必要があります。Variant 型の動的配列だと「エラー 13 型が一致しません。」が発生します。
作成される配列は動的配列で、最小インデックスは 0 からスタートします。
引数「文字列型配列」の要素の中に引数「フィルタ文字」と一致する部分がある要素で作成された配列を返します。部分一致なので あいうえお に対して あい でフィルタしても、その要素を返します。
引数「フィルタ文字」が空文字 "" なら、すべての要素と一致します。
引数「文字列型配列」に引数「フィルタ文字」が見つからなかったときは、(0 To -1) の要素数 0 の配列を返します。これが String 型の要素数 0 の配列を作成する唯一の方法です。
引数「文字列型配列」には String 型または Variant 型の配列のみ指定できます。それ以外の型の配列を指定すると「エラー 13 型が一致しません。」が発生します。Variant 型の配列に文字列以外の値が入っているときは、文字列に変換してから処理をします。
引数「文字列型配列」には一次元配列のみ指定できます。二次元配列を指定すると「エラー 13 型が一致しません。」が発生します。
完全一致
完全一致する要素だけを返すには、Filter 関数を使わないでループしてできます。
存在チェック
部分一致で存在チェックするには、結果の配列の最大インデックスが 0 以上だと存在します。-1 だと存在しません。
完全一致で存在チェックするには、Filter 関数を使わないでループしてできます。
二次元配列を完全一致で存在チェックするには、Filter 関数を使わないでループしてできます
スポンサーリンク
使用例
Filter 関数の使用例を紹介します。
配列を絞り込む
配列を絞り込みます。
Dim s(3) As String ' 元の配列
s(0) = "ABC DEF"
s(1) = "abc 123"
s(2) = "123 ABC"
s(3) = "あいう 123"
Dim f() As String
f = Filter(s, "ABC")
Debug.Print(f(0)) ' "ABC DEF"
Debug.Print(f(1)) ' "123 ABC"
f = Filter(s, "ABC", False) ' フィルタ文字を含まない
Debug.Print(f(0)) ' "abc 123"
Debug.Print(f(1)) ' "あいう 123"
f = Filter(s, "ABC", True, vbTextCompare) ' 区別しない
Debug.Print(f(0)) ' "ABC DEF"
Debug.Print(f(1)) ' "abc 123"
Debug.Print(f(2)) ' "123 ABC"
f = Filter(s, "Tips") ' 1 つも一致しない
Debug.Print(LBound(f)) ' 0、(0 ~ -1) の要素数 0 の配列
Debug.Print(UBound(f)) ' -1
Dim v As Variant
v = Filter(s, "ABC") ' Variant 型にも代入できる
Debug.Print(v(0)) ' "ABC DEF"
Debug.Print(v(1)) ' "123 ABC"
Dim va() As Variant
va = Filter(s, "ABC") ' エラー、Variant 型の動的配列には代入できない
完全一致で絞り込む
完全一致する要素だけを返すには、Filter 関数を使わないでループしてできます。関数を作成すると便利です。ついでに文字列以外にも対応するため Variant 型で比較しています。
Sub 実行()
Dim s(4) As String ' 元の配列
s(0) = "ABC DEF"
s(1) = "abc 123"
s(2) = "ABC"
s(3) = "123 ABC"
s(4) = "ABC"
Dim v As Variant
Dim a As Variant
' 部分一致
a = Filter(s, "ABC")
For Each v In a
Debug.Print(v)
' ABC DEF
' ABC
' 123 ABC
' ABC
Next
' 完全一致
a = FilterMatch(s, "ABC")
For Each v In a
Debug.Print(v)
' ABC
' ABC
Next
End Sub
' Filter 関数を完全一致で絞り込む
Function FilterMatch(ByVal list As Variant, ByVal value As Variant) As Variant
Dim s As Variant
s = Array() ' 見つからないとき用に (0 ~ -1) の要素数 0 の配列
Dim count As Integer
count = -1
Dim i As Integer
For i = LBound(list) To UBound(list)
If list(i) = value Then ' 完全一致で比較
count = count + 1
ReDim Preserve s(count)
s(count) = list(i) ' 一致した要素を追加
End If
Next
FilterMatch = s
End Function
存在チェックする
部分一致で存在チェックするには「UBound 関数」を使用して、結果の配列の最大インデックスが 0 以上だと存在します。-1 だと存在しません。
Dim s(3) As String
s(0) = "ABC DEF"
s(1) = "abc 123"
s(2) = "123 ABC"
s(3) = "あいう 123"
Dim f() As String
f = Filter(s, "ABC")
If UBound(f) >= 0 Then ' 部分一致で存在チェック
Debug.Print ("存在している") ' 存在している
Else
Debug.Print ("見つからない")
End If
f = Filter(s, "Tips")
If UBound(f) >= 0 Then ' 部分一致で存在チェック
Debug.Print ("存在している")
Else
Debug.Print ("見つからない") ' 見つからない
End If
完全一致で存在チェックするには、Filter 関数を使わないでループしてできます。関数を作成すると便利です。ついでに文字列以外にも対応するため Variant 型で比較しています。
Sub 実行()
Dim s(3) As String ' 元の配列
s(0) = "ABC DEF"
s(1) = "abc 123"
s(2) = "123 ABC"
s(3) = "ABC"
' 完全一致
Dim b As Boolean
b = ExistsArray(s, "ABC")
Debug.Print(b) ' True
b = ExistsArray(s, "abc")
Debug.Print(b) ' False
End Sub
' 配列に完全一致する要素が存在するかどうか
Function ExistsArray(ByVal list As Variant, ByVal item As Variant) As Boolean
Dim i As Integer
For i = LBound(list) To UBound(list)
If list(i) = item Then ' 完全一致で比較
ExistsArray = True
Exit Function
End If
Next
ExistsArray = False
End Function
二次元配列を完全一致で存在チェックするには、Filter 関数を使わないでループしてできます。関数を作成すると便利です。ついでに文字列以外にも対応するため Variant 型で比較しています。
Sub 実行()
Dim s(1, 2) As String ' 元の配列
s(0, 0) = "ABC DEF"
s(0, 1) = "abc 123"
s(0, 2) = "ABC"
s(1, 0) = "ABC DEF"
s(1, 1) = "abc 123"
s(1, 2) = "ABC"
' 完全一致
Dim b As Boolean
b = ExistsArray2(s, "ABC")
Debug.Print(b) ' True
b = ExistsArray2(s, "abc")
Debug.Print(b) ' False
End Sub
' 二次元配列に完全一致する要素が存在するかどうか
Function ExistsArray2(ByVal list As Variant, ByVal item As Variant) As Boolean
Dim i As Integer
Dim j As Integer
For i = LBound(list, 1) To UBound(list, 1)
For j = LBound(list, 2) To UBound(list, 2)
If list(i, j) = item Then ' 完全一致で比較
ExistsArray2 = True
Exit Function
End If
Next
Next
ExistsArray2 = False
End Function