【问题标题】:How to get index of Element in two dimensional array?如何获取二维数组中元素的索引?
【发布时间】:2020-06-30 18:04:40
【问题描述】:

我有一个二维数组。 我还有一个 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

【问题讨论】:

  • 什么是Table1Table2... 更多代码会有所帮助,这样我们就有了minimal reproducible example
  • 我目前没有访问代码的权限,所以我会写下这些是我用工作表中的 Ranges 填写的 2 个表。就像 Table1 = Range("A1:B40") 假设和 Table2 = Range("A1:A40") 来自另一个工作表。
  • @Yanger - 发布了一个广泛的答案,如何获取二维数组元素的索引。如果有帮助,请随时勾选绿色复选标记来接受。 - 进一步提示:声明所有变量(使用Option Explicit)并完全限定范围引用以避免不必要地显示默认活动工作表,最好使用工作表的代码(名称)或通过ThisWorkbook.WorkSheets("Sheet1").Range(...)

标签: arrays excel vba indexing dimensions


【解决方案1】:

在您讨论的案例中没有索引... vElementvElement2 变量属于 Variant 类型。它们不是对象,具有Index 属性。

当您使用For Each vElement In Table1 循环时,VBA 从数组的第一个元素开始,向下到最后一行,然后对下一列执行相同操作。

当您需要知道将数组“索引”命名为什么时,您必须使用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

您可以计算数组元素的行和列。并且代码证明使用它们,返回的数组值正是找到的那个......

数组'indexes'是否更清楚...?

【讨论】:

  • 发布后我不知道你的答案,但我发现你的精彩解释中几乎相同的想法对许多初级程序员很有帮助;赞成 :+)
【解决方案2】:

在二维数组中显示元素的索引 - 复杂的方式

如果我理解正确,您正在通过 ►For Each 构造循环遍历数据字段数组,并希望获取同一数组的当前行/列索引对。

为了回答你的问题

"如何获取二维数组中元素的索引",

搁置一旁,如果您通过首先循环遍历数组行并最终在此循环中通过更改逻辑来更改逻辑,您会以一种更明显和通常的方式自动获得这些数组列 - 请参阅 附录 *)

允许重建例如下面示例调用中的第 6 个数组元素引用当前索引对(元素 i=6 ~> table1(3,2) ~> row:=3/column:=2)这是必要的

  • 添加元素计数器i,每次获取下一个元素时将其值增加+1,并且
  • 将此计数器作为参数(除了对数据字段的引用)传递给帮助函数getIndex()

以另一个数组的形式返回结果,即一个只包含两个值的数组:(1)当前数组行,(2)当前数组列:

调用示例

注意: 为了更好的可读性并为了将答案压缩到所需的最小值(参见MCVE),以下示例调用仅在@987654331 上执行一个For Each 循环@数据字段数组;您可以根据自己的需要更改此设置或提出其他问题。

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

*) 附录 - “简单的方法”

正如上面提到的,使用行和列变量rc 正好相反;允许通过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


【讨论】:

  • 也投了赞成票。更费力的答案,需要更多时间...... :)
【解决方案3】:
Dim Table1() As Variant
Dim Table2() As Variant
Table1 = Range(Cells(2, 3), Cells(lastRow, vMaxCol))
Table2 = Range(Cells(2, 1), Cells(lastRow, 1))

Table1 是 Variant(1 到 33、1 到 9) Table2 是 Variant(1 to 33, 1 to 1)

这 33 和 9 是动态的。

【讨论】:

    最近更新 更多