Поиск значения в Excel (VB)

#excel #vba

#excel #vba

Вопрос:

я изо всех сил пытаюсь заставить мой скрипт vb работать.

Мне нужно найти значение a (строка) и b (дата) в массиве.

Пример:

 [string1][date1] where in arr[[st1][dat1],[st2][dat2],[string1][date1]]
 

Последнее значение будет соответствовать true, первое и второе будут false

Значения:

Лист 1: Лист 1

Лист 2: Лист 2мой код:

 Function IsInArray(stringToBeFound1 As String, ByVal dateToBefound As Date, arr As Variant) As Boolean
   Dim Found1 As Boolean
   Dim Found2 As Boolean
   Dim x As Integer
   
   Found1 = False
   Found2 = False
   x = 0
   
    For x = 0 To UBound(arr, 1) // this does not seem to work
        If stringToBeFound1 = arr(x, 0) Then
            Found1 = True
        End If
        If dateToBefound = arr(x, 1) Then
            Found2 = True
        End If
        If Found1 = 1 And Found2 = 1 Then IsInArray = True
    Next

End Function
 

использование: =IsInArray(C6,D6,'Sheet2'!C:D)

Ответ №1:

Ключевая ошибка вашего кода заключается в том, что параметр, который вы предоставляете функции, не является массивом. Это диапазон. Пожалуйста, прочитайте больше комментариев в коде ниже.

 Function IsInArray(stringToBeFound As String, _
                   ByVal dateToBefound As Date, _
                   Rng As Range) As Boolean
    ' =IsInArray(C6,D6,'Sheet2'!C:D)        ' C:D is a range, not an array

    Dim MyRng   As Range
    Dim Arr     As Variant
    Dim R       As Long             ' loop counter: rows
   ' since there are more than a million rows in a sheet
   ' and an integer can only count up to abt 32000
   ' you can't use an Integer to loop through all rows
   
'   Found1 = False          ' }
'   Found2 = False          ' } These values are given by the Dim statements above
'   x = 0                   ' }

    ' all the column is too big a range.
    ' it will take ages to find nothing.
    ' Exclude blank cells at the bottom:-
    With Rng
        Set MyRng = Range(.Cells(1), Cells(Rows.Count, .Column).End(xlUp)) _
                    .Resize(, .Columns.Count)
'        ' you may prefer this one, actually:
'        Set MyRng = Range(.Cells(2, 1), Cells(Rows.Count, .Column).End(xlUp)) _
'                    .Resize(, .Columns.Count)
        Debug.Print MyRng.Address       ' for testing MyRng
    End With
    Arr = MyRng.Value       ' creates a 1-based 2-D array
    For R = 1 To UBound(Arr, 1)
        ' always compare the code-generated variable with the given constant
        If Arr(R, 1) = stringToBeFound Then
'        ' you may prefer a case-insensitive comparison:-
'        If StrComp(Arr(R, 1), stringToBeFound, vbTextCompare) = 0 Then
            If dateToBefound = Arr(R, 2) Then
                IsInArray = True
                Exit For
            End If
        End If
    Next
End Function
 

Я протестировал функцию как в формате UDF с нужным вам синтаксисом, так и в VBA, используя приведенный ниже код. При использовании его в качестве UDF я настоятельно рекомендую вам ссылаться на целевой диапазон с абсолютным адресом, например Sheet2'!$C:$D . Не делать этого — все равно что напрашиваться на неприятности.

 Private Sub Test()
    ' =IsInArray(C6,D6,'Sheet2'!C:D)
    Debug.Print IsInArray("B", Date   1, Sheet2.Columns("C:D"))
End Sub
 

Комментарии:

1. Большое вам спасибо, я родом из Java и мало что знаю о vb