web-dev-qa-db-ja.com

配列内の文字列を検索する方法

VBAの配列内の文字列を簡単に(1行で)検索できますか?または、各要素をループしてターゲット文字列と比較する必要がありますか?

編集:1次元配列です。知っておく必要があるのは、IF文字列が配列のどこかにあることです。

IE:

names(JOHN, BOB, JAMES, PHLLIP)

「JOHN」が配列内にあるかどうかを確認するにはどうすればよいでしょうか。5000回前後繰り返されるため、最小限に抑える必要があります。また、関数が全体のプロセスを遅くしたくないのです。

37
aSystemOverload

文字列が配列内で見つかったかどうかを知りたい場合は、次の関数を試してください。

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
  IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)
End Function

Sean Cheshire が指摘しているように、これは1次元配列でなければなりません。

例:

Sub Test()
  Dim arr As Variant
  arr = Split("abc,def,ghi,jkl", ",")
  Debug.Print IsInArray("ghi", arr)
End Sub

HansUp からのコメントに基づいて更新されたコードの下)

配列内の一致する要素のインデックスが必要な場合は、これを試してください:

Function IsInArray(stringToBeFound As String, arr As Variant) As Long
  Dim i As Long
  ' default return value if value not found in array
  IsInArray = -1

  For i = LBound(arr) To UBound(arr)
    If StrComp(stringToBeFound, arr(i), vbTextCompare) = 0 Then
      IsInArray = i
      Exit For
    End If
  Next i
End Function

これも1次元配列を想定しています。 LBoundとUBoundはゼロベースであるため、インデックス2は2番目ではなく3番目の要素を意味することに注意してください。

例:

Sub Test()
  Dim arr As Variant
  arr = Split("abc,def,ghi,jkl", ",")
  Debug.Print (IsInArray("ghi", arr) > -1)
End Sub

特定の例を念頭に置いている場合は、それを使用して質問を更新してください。それ以外の場合は、サンプルコードが状況に当てはまらない場合があります。

62
JimmyPena

別のオプションは、配列の代わりに辞書を使用することです。

Dim oNames As Object
Set oNames = CreateObject("Scripting.Dictionary")
'You could if need be create this automatically from an existing Array
'The 1 is just a dummy value, we just want the names as keys
oNames.Add "JOHN", 1
oNames.Add "BOB", 1
oNames.Add "JAMES", 1
oNames.Add "PHILIP", 1

これにより、1行の

oNames.Exists("JOHN")

辞書が提供する利点は、Filterからの部分一致に対する完全一致です。配列に元の名前のリストがあるが、最初に4人に加えて2人の新しい人である「JO」または「PHIL」を探していたとします。この場合、Filter(oNAMES, "JO")は「JOHN」に一致しますが、これはmayは望ましくありません。辞書があれば、それはできません。

23
atomicules

完全一致(つまり、部分一致なし)を強制する別のオプションは次のとおりです。

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
  IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))
End Function

Matchメソッドとその引数の詳細については、 http://msdn.Microsoft.com/en-us/library/office/ff835873(v = office.15).aspx をご覧ください。

13
Brian Hinchey

見つかったすべての文字列のarrayを返す関数があります。

Filter(sourcearray, match[, include[, compare]])
sourcearrayは1次元でなければなりません
この関数は、match文字列を含む配列内のすべての文字列を返します

6
SeanC

Apple ISでも機能するより単純な関数も:

Function isInArray(ByVal stringToBeFound As String, ByVal arr As Variant) As Boolean
For Each element In arr
    If element = stringToBeFound Then
        isInArray = True
        Exit Function
    End If
Next element
End Function
5

別の答えがあります。高速で確実に動作し(atomiculesの回答を参照)、コンパクトな呼び出しコードがあります。

' Returns true if item is in the array; false otherwise.
Function IsInArray(ar, item$) As Boolean
    Dim delimiter$, list$

    ' Chr(7) is the ASCII 'Bell' Character.
    ' It was chosen for being unlikely to be found in a normal array.
    delimiter = Chr(7)

    ' Create a list string containing all the items in the array separated by the delimiter.
    list = delimiter & Join(ar, delimiter) & delimiter

    IsInArray = InStr(list, delimiter & item & delimiter) > 0
End Function

使用例:

Sub test()
    Debug.Print "Is 'A' in the list?", IsInArray(Split("A,B", ","), "A")
End Sub
4
ChaimG

Caseステートメントは、一部のアプリケーションにより簡単に適合する場合があります。

select case var
case "a string", "another string", sVar
  'do something
case else
  'do something else
end select
1
technicaltitch

定数のリストの場合、次のように選択ケースを使用できます。

Dim Item$: Item = "A"

Select Case Item
  Case "A", "B", "C"
    ' If 'Item' is in the list then do something.
  Case Else
    ' Otherwise do something else.
End Select
1
ChaimG