Как получить индекс элемента в двумерном массиве? - PullRequest
0 голосов
/ 19 марта 2020

У меня есть массив с 2 измерениями. У меня также есть цикл For Each, который зацикливается на элементах этих массивов.

Как я могу получить индекс vElement / vElement2 в момент моего комментария здесь в коде? Я был бы очень, очень благодарен, если бы Вы могли мне помочь.

For Each vElement In Table1

    For Each vElement2 In Table2
        If ws_1.Cells(1, c) = vElement Then
            For Row = 3 To lastRow
                    amountValue = amountValue + ws_1.Cells(Row, c).value
                    ws_2.Cells(row2, colIlosc) = amountValue
'Here i would love to have index of vElement for example. In my head it would be something like... Index(vElement) or Index(Table1(vElement))

                    ws_2.Cells(row2, columncodeprod) = vElement2
                    row2 = row2 + 1
                amountValue = 0
            Next Row
        End If
    Next vElement2
Next vElement

Ответы [ 3 ]

1 голос
/ 20 марта 2020

В случае, если вы обсуждаете обсуждение, НЕТ индекса ... vElement и vElement2 переменные имеют тип Variant. Они не являются объектами, чтобы иметь свойство Index.

Когда вы используете For Each vElement In Table1 l oop, VBA начинается с первого элемента массива, спускается до последней строки и затем выполняет то же самое для следующего столбца.

Когда вам нужно узнать, что вы называете массивами 'indexes', вы должны использовать For i = 1 To Ubound(Table1, 1), а затем For j = 1 To Ubound(Table1, 2). В таком случае вы будете знать соответствующие строки и столбцы элементов массива. Мы можем считать их вашими псевдоиндексами ...

Если вы действительно хотите / настаиваете на извлечении таких индексов в итерации типа For Each vElement In Table1, вы должны их построить. Я попробую en elocvent пример кода:

Sub testElemIndex()
 Dim sh As Worksheet, Table1 As Variant, vElement As Variant
 Dim i As Long, indexRow As Long, indexCol

  Set sh = ActiveSheet

  sh.Range("C6").value = "TestIndex"
  Table1 = sh.Range("A1:E10").value
  For Each vElement In Table1
    i = i + 1:
    If vElement = "TestIndex" Then
        If i <= UBound(Table1, 1) Then
          indexRow = i: indexCol = 1
        Else
          indexCol = Int(i / UBound(Table1, 1)) + 1
          indexRow = i - Int(i / UBound(Table1, 1)) * UBound(Table1, 1)
        End If
        Debug.Print Table1(indexRow, indexCol), indexRow, indexCol: Stop
    End If
  Next
End Sub

Вы можете вычислить строки и столбцы элемента массива. И код доказывает, что, используя их, возвращаемое значение массива в точности совпадает с найденным ...

Это немного больше света о индексах массива ...?

1 голос
/ 20 марта 2020

Показать индексы элемента в 2-мерном массиве - сложный способ

Если я правильно понимаю, вы перебираете массив полей данных с помощью конструкции ► For Each и хотите получить текущую пару строк / столбцов этого же массива.

Чтобы ответить на ваш вопрос

"Как получить индексов элемента в двумерном массиве",

I оставьте в стороне , чтобы вы получили их автоматически более наглядным и обычным способом , если бы вы изменили логи c, сначала просматривая строки массива и внутри этого l oop в конце концов через столбцы массива - см. Добавление *).

Чтобы разрешить восстановление, например, 6-го элемента массива в приведенном ниже примере вызова со ссылкой на текущую пару индексов (элемент i=6 ~> table1(3,2) ~> row: = 3 / column: = 2)

  • необходимо добавить счетчик элемента i, увеличив его значение на +1 каждый раз, когда вы получаете следующий элемент, и
  • , чтобы передать этот счетчик в качестве аргумента (дополнительно к ссылке на поле данных) к справочной функции getIndex()

, возвращающей результаты в виде другого массива, то есть массива, состоящего только из двух значений: (1) текущей строки массива, (2) текущий столбец массива:

Пример вызова

Примечание: Для лучшей читаемости и для сокращения ответа до необходимого минимума ( c .f. MCVE ) в следующем примере вызова выполняется только один For Each l oop над массивом поля данных table1; Вы сможете изменить это в соответствии со своими потребностями или задать другой вопрос.

Option Explicit                         ' declaration head of your code module                     

Sub ShowIndicesOf2DimArray()
    Dim table1                          ' declare variant 1-based 2-dim datafield
    table1 = Sheet1.Range("A2:B4")      ' << change to sheets Code(Name)

    Dim vElem, i As Long
    Dim curRow As Long, curCol As Long  ' current row/column number
    For Each vElem In table1

        i = i + 1                       ' increment element counter
        curRow = getIndex(table1, i)(1) ' <~ get row index via help function 
        curCol = getIndex(table1, i)(2) ' <~ get col index via help function 

        'optional debug info in VB Editors immediate window (here: Direktbereich)
        Debug.Print i & ". " & _
                " Table1(" & curRow & "," & curCol & ") = " & vElem & vbTab;
        Debug.Print ", where curRow|curCol are " & Join(getIndex(table1, i), "|")
    Next vElem
End Sub

Функция справки getIndex(), вызываемая по вышеуказанной процедуре

Function getIndex(table1, ByVal no As Long) As Variant
'Purpose: get 1-based 1-dim array with current row+column indices
    ReDim tmp(1 To 2)
    tmp(1) = (no - 1) Mod UBound(table1) + 1
    tmp(2) = Int((no - 1) / UBound(table1) + 1)
    getIndex = tmp
End Function

enter image description here

*) Приложение - «простой путь»

Как раз наоборот, используя строку и столбец переменные r и c, как указано выше; позволяет ссылаться на элемент просто через table1(r,c):

Sub TheSimpleWay()
    Dim table1                          ' declare variant 1-based 2-dim datafield
    table1 = Sheet1.Range("A2:B4")      ' << change to sheets Code(Name)
    Dim vElem, i As Long
    Dim r As Long, c As Long            ' row and column counter
    For r = 1 To UBound(table1)         ' start by row 1 (1-based!) up to upper boundary in 1st dimension
        For c = 1 To UBound(table1, 2)  ' start by col 1 (1-based!) up to upper boundary in 2nd dimension
            i = i + 1
            Debug.Print i & ". " & _
                " Table1(" & r & "," & c & ") = " & table1(r, c) & vbTab;
            Debug.Print ", where row|col are " & r & "|" & c

        Next c
    Next r
End Sub


0 голосов
/ 20 марта 2020
Dim Table1() As Variant
Dim Table2() As Variant
Table1 = Range(Cells(2, 3), Cells(lastRow, vMaxCol))
Table2 = Range(Cells(2, 1), Cells(lastRow, 1))

Таблица 1 - вариант (от 1 до 33, от 1 до 9) Таблица 2 - вариант (от 1 до 33, от 1 до 1)

Эти 33 и 9 являются динамическими c.

...