Создать динамически изменяемый массив для хранения счетчика строк - PullRequest
0 голосов
/ 06 ноября 2018

Функция ниже находит первый результат.

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

Как бы я создал размер массива на основе количества результатов, найденных в цикле for?

Я предполагаю, что счетчик цикла for будет играть какую-то роль в этом. Допустим, цикл for нашел 2 совпадения в строках с номерами 56 и 98, соответствующих моим операторам if:

array_example (counter, 0) = 56
array_example (counter, 0) = 98

Сохраненные значения будут:

array_example (1, 0) = 56
array_example (2, 0) = 98

Private Sub Complex_Search(col1, cval1, col2, cval2)

'MsgBox (col1 & " " & col2)
'MsgBox (cval1 & " " & cval2)

Dim i
Dim lRow
Dim Counter

    lRow = Cells(Rows.Count, 1).End(xlUp).row

    Counter = 0

    With Sheets("Office Spaces")

        For i = 2 To lRow

            If LCase(.Cells(i, col1).Value) = LCase(cval1) And LCase(.Cells(i, col2).Value) = LCase(cval2) Then

                row = i

                Counter = Counter + 1

            End If

        Next i

    End With

    If row = "" Then

        MsgBox ("Search complete. 0 results found")

    Else
        GetRowData (row)

        UserForm1.resmax.Value = 1
    End If

End Sub

1 Ответ

0 голосов
/ 06 ноября 2018

Стоит отметить, что вы даже не инициализировали строку и просто разрешили vba неявно объявить ее как вариантный тип для вас. Чтобы избежать распространенных проблем, возникающих из-за опечаток, включите Option Explicit вверху вашего кода и Dim каждую переменную с типом рядом с ним. Например: Dim i as long. Dim i будет работать, но объявит его типом варианта

Для инициализации массива в VBA вы используете Dim row() as variant. Оттуда вы можете изменить его размер, используя Redim row(LboundX to UboundX), но это сбросит все сохраненные значения до нуля. Чтобы обойти это, используйте Redim Preserve row(LBoundX to UBound X).

Если вы хотите использовать 2D-массив, добавьте запятую, а затем установите границы для следующего измерения Redim Preserve row(LBoundX to UBound X, LboundY to UBoundY)

В верхней части вашего кода я бы включил

 Dim row() as Variant
 Redim Preserve row(1 to 1)

Тогда внутри цикла я бы изменил row = i на

row(Ubound(row)) = i 
Redim Preserve row(1 to Ubound(row) +1)

Теперь, когда у вас есть массив, проверка, которую вы выполните ниже, больше не будет работать и, скорее всего, выдаст ошибку, потому что у вас нет указанного индекса. Вместо этого я предлагаю изменить его с If row = "" Then на If Counter = 0 Then.

Я не уверен, каково намерение с GetRowData(row), но вы можете просто получить доступ к каждому номеру строки через row(i). Стоит, однако, отметить, что массив строк будет иметь счетчик +1 количество элементов, но последний будет пустым. Вы можете обойти это, добавив оператор if в уже существующий оператор, который будет выглядеть примерно так:

If Counter = 0 Then
    row(1) = i
Else
    ReDim Preserve row(1 To UBound(row) + 1)
    row(UBound(row)) = i
End If

Counter = Counter + 1

Реализуя это изменение, строка должна иметь ровно Counter количество элементов, которые имеют непустое значение

На самом деле я не предлагаю создавать массив столбцов, потому что изменение размера массива становится более громоздким. Redim preserve или не только позволяет изменять последнее измерение в массиве, поэтому для изменения количества строк вам нужно будет установить массив равным транспонированию самого себя, выполните redim и затем установите его в перенести себя снова. Это просто излишне грязно. Если вы вставляете его на лист и хотите, чтобы он был в столбце, вместо этого вы можете просто перенести его в конец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...