web-dev-qa-db-ja.com

Excel VBAで値が配列にあるかどうかを確認します

私は以下のコードを持っています、それは値が配列にあるかどうかをチェックすることになっています。

Sub test()
    vars1 = Array("Examples")
    vars2 = Array("Example")
    If IsInArray(Range("A1").Value, vars1) Then
        x = 1
    End If

    If IsInArray(Range("A1").Value, vars2) Then
        x = 1
    End If
End Sub

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

セルA1には何らかの理由でExamplesという単語が含まれていますが、IsInArrayの両方が、vars1配列

IsInArray関数を完全一致にするには、何を変更する必要がありますか?

11
Ryflex

次のようにブルートフォースできます。

Public Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
    Dim i
    For i = LBound(arr) To UBound(arr)
        If arr(i) = stringToBeFound Then
            IsInArray = True
            Exit Function
        End If
    Next i
    IsInArray = False

End Function

のように使用する

IsInArray("example", Array("example", "someother text", "more things", "and another"))
20
Brad

この質問はここで尋ねられました: VBA配列-厳密な(近似ではない)一致をチェック

Sub test()
    vars1 = Array("Examples")
    vars2 = Array("Example")
    If IsInArray(Range("A1").value, vars1) Then
        x = 1
    End If

    If IsInArray(Range("A1").value, vars2) Then
        x = 1
    End If
End Sub

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

Excel VBAのMatch()関数を使用して、値が配列に存在するかどうかを確認します。

Sub test()
    Dim x As Long

    vars1 = Array("Abc", "Xyz", "Examples")
    vars2 = Array("Def", "IJK", "MNO")

    If IsNumeric(Application.Match(Range("A1").Value, vars1, 0)) Then
        x = 1
    ElseIf IsNumeric(Application.Match(Range("A1").Value, vars2, 0)) Then
        x = 1
    End If

    MsgBox x
End Sub
3
Sixthsense

これは本質的に再び@Bradの答えですが、配列に存在する場合は検索しているアイテムのインデックスを返すわずかに変更された関数を含める価値があると思いました。アイテムが配列にない場合、代わりに_-1_を返します。

この出力は、「文字列内」関数If InStr(...) > 0 Thenと同様にチェックできるため、例としてその下に小さなテスト関数を作成しました。

_Option Explicit

Public Function IsInArrayIndex(stringToFind As String, arr As Variant) As Long

    IsInArrayIndex = -1

    Dim i As Long
    For i = LBound(arr, 1) To UBound(arr, 1)
        If arr(i) = stringToFind Then
            IsInArrayIndex = i
            Exit Function
        End If
    Next i

End Function

Sub test()

    Dim fruitArray As Variant
    fruitArray = Array("orange", "Apple", "banana", "berry")

    Dim result As Long
    result = IsInArrayIndex("Apple", fruitArray)

    If result >= 0 Then
        Debug.Print chr(34) & fruitArray(result) & chr(34) & " exists in array at index " & result
    Else
        Debug.Print "does not exist in array"
    End If

End Sub
_

それから私は少し外に出て、2次元配列用に1つを肉付けしました。なぜなら 範囲に基づいて配列を生成する が一般的にこの形式だからです。

入力として使用される配列の2つのインデックス(値が見つかったと仮定)のみの2つの値を持つ単一次元バリアント配列を返します。値が見つからない場合、_(-1, -1)_の配列を返します。

_Option Explicit

Public Function IsInArray2DIndex(stringToFind As String, arr As Variant) As Variant

    IsInArray2DIndex= Array(-1, -1)

    Dim i As Long
    Dim j As Long

    For i = LBound(arr, 1) To UBound(arr, 1)
        For j = LBound(arr, 2) To UBound(arr, 2)
            If arr(i, j) = stringToFind Then
                IsInArray2DIndex= Array(i, j)
                Exit Function
            End If
        Next j
    Next i

End Function
_

テスト用に設定したデータの写真を次に示します。

test 2

_Sub test2()

    Dim fruitArray2D As Variant
    fruitArray2D = sheets("Sheet1").Range("A1:B2").value

    Dim result As Variant
    result = IsInArray2DIndex("Apple", fruitArray2D)

    If result(0) >= 0 And result(1) >= 0 Then
        Debug.Print chr(34) & fruitArray2D(result(0), result(1)) & chr(34) & " exists in array at row: " & result(0) & ", col: " & result(1)
    Else
        Debug.Print "does not exist in array"
    End If

End Sub
_
1
Marcucciboy2

以下の関数は、一致がない場合は「0」を返し、一致する場合は「正の整数」を返します。


Function IsInArray(stringToBeFound As String, arr As Variant) As Integer IsInArray = InStr(Join(arr, ""), stringToBeFound) End Function ______________________________________________________________________________

:この関数は、最初に 'Join'を使用して配列の内容全体を文字列に連結し(結合方法が内部的にループを使用するかどうかは不明)、InStrを使用してこの文字列内のmacthをチェックします。

0

パフォーマンスとパワフルの両方である別のバリ​​アントを提供したいと思います。

  • 時々遅いMatch )は使用しません
  • StringIntegerBooleanなどをサポートnot String- only
  • 検索対象アイテムのインデックスを返します
  • supportsnth-occurrence

...

'-1 if not found
'https://stackoverflow.com/a/56327647/1915920
Public Function IsInArray( _
  item As Variant, _
  arr As Variant, _
  Optional nthOccurrence As Long = 1 _
  ) As Long

    IsInArray = -1

    Dim i As Long:  For i = LBound(arr, 1) To UBound(arr, 1)
        If arr(i) = item Then
            If nthOccurrence > 1 Then
                nthOccurrence = nthOccurrence - 1
                GoTo continue
            End If
            IsInArray = i
            Exit Function
        End If
continue:
    Next i

End Function

次のように使用します。

Sub testInt()
  Debug.Print IsInArray(2, Array(1, 2, 3))  '=> 1
End Sub

Sub testString1()
  Debug.Print IsInArray("b", Array("a", "b", "c", "a"))  '=> 1
End Sub

Sub testString2()
  Debug.Print IsInArray("b", Array("a", "b", "c", "b"), 2)  '=> 3
End Sub

Sub testBool1()
  Debug.Print IsInArray(False, Array(True, False, True))  '=> 1
End Sub

Sub testBool2()
  Debug.Print IsInArray(True, Array(True, False, True), 2)  '=> 2
End Sub
0