循环遍历行、列和交集 VBA

Posted

技术标签:

【中文标题】循环遍历行、列和交集 VBA【英文标题】:Looping through Rows, Cloumns, and Intersection VBA 【发布时间】:2019-06-29 19:52:54 【问题描述】:

所以我想遍历一个电子表格并在这两者相交的单元格中收集表头、行表头和值。然后构建这些值的数组。

这是一个例子

   V1 V2 V3 V4 
C1  1     1  2
C2     3     
C3  2        4
C4  1     1

数组的最终输出类似于

V1, C1, 1
V2, C1, 0
V3, C1, 1
V4, C1, 4
V1, C2, 0
V2, C2, 3
etc

然后,我将对这个数组进行排序并消除任何具有“0”值的条目。

问题:我在实践中并不是最好的,并且在尝试定义变量或数组条目时不断收到错误。我觉得这个想法是合理的,但在语法方面,我无法克服具体的错误。

我想我不希望有人完全解决它,因为这违背了学习目的

我最初的解决方案是构建一个数组或 Header、一个 Row 标题数组和一个数据数组。

基本上是一个由 V 值、另一个 C 值和一个整数值组成的数组。

我写了下面的代码(再次请原谅我的无知)。

据我所知,它应该循环通过第一个范围抓取值 V1(或我的代码中的 C2)循环通过第二个范围抓取值 C1(或我的代码中的 A2)然后 1 的值(我会称它为 Z1)。然后增加整数为抓取V2,然后是C1,然后是Z2,以此类推。

Dim myarrayX() As Variant
Dim myarrayY() As Variant
Dim myarrayZ() As Variant
Dim myarrayHeader() As Variant
Dim myarrayRowHeader() As Variant
Dim myarrayIntersection() As Variant
Dim Result() As Variant
Dim i As Variant
Dim j As Variant
Dim k As Variant
Dim l As Variant
Dim m As Variant
Dim n As Variant


l = 0
m = 0
n = 0



myarrayHeader = Range("C2:H2").Value
myarrayRowHeader = Range("A2:A6").Value
myarrayIntersection = Range("C2:H6").Value



For Each i In myarrrayHeader.Cells
    myarrayX(l) = Cell.Value
        For Each j In myarrayRowHeader.Cells
            myarrayY(m) = Cell.Value
                For Each k In myarrayIntersection.Cells
                    myarrayZ(n) = Cell.Value

                    k = k + 1
                    i = i + 1
                    n = n + 1
                 Next k
             m = m + 1
       Next j
       l = l + 1
       j = j + 1
Next i

我无法得到任何输出,因为它显示“myarrayRowHeader.Cells”的“限定符无效”,我不知道为什么会这样。

【问题讨论】:

myarrayRowHeader = Range("A2:A6").Value中删除.Value @AAA - 你的建议不会单独起作用 - 考虑一下 _default 属性是什么! @AJD,OP 的最后一个问题是关于他们获得的无效限定符。 .Value 属性不一定返回范围。我没有发布这个问题的完整答案,因为 OP 说他们想自己解决这个问题。我只是帮助弄清楚他们问的一个问题。答案可能比您在下面给出的要简单得多。 @AAA 但仅删除 .Value 不会改变您建议中的结果,因为范围的默认属性,它仍将返回一个值数组!不仅Set关键字必须改变,声明也必须改变。 关键是,代码无论如何都不起作用,这就是我的答案更复杂的原因。 【参考方案1】:

我无法得到任何输出,因为它说“无效的限定符” “myarrayRowHeader.Cells”,我不知道为什么会这样。

这里有两个问题。第一个也是明显的一个错字。始终在模块顶部使用Option Explicit总是

您已将以下内容声明为变体,目的是用值填充它们 - 使它们成为值数组:

Dim myarrayHeader() As Variant '<-- Actually, this is an array of Variants, also not what you want!
Dim myarrayRowHeader() As Variant
Dim myarrayIntersection() As Variant

确实 - 您确实在代码开头使用值填充这些数组。

myarrayHeader = Range("C2:H2").Value ' One row, multiple columns
myarrayRowHeader = Range("A2:A6").Value ' Multiple rows, one column
myarrayIntersection = Range("C2:H6").Value ' Multiple rows, multiple columns

此时,它们是数组,而不是对象,因此没有任何内在方法或属性。换句话说,myarrayRowHeader 没有 .Cells 方法或属性,因此 VBA 编译器会抱怨。

代码的正确语法是简单地遍历数组:

For i = LBound(myarrrayHeader, 2) to UBound(myarrrayHeader, 2) ' <--- typo here 
    myarrayX(l) = myarrayHeader(I,1)
        For j = LBound(myarrayRowHeader, 1) to UBound(myarrayRowHeader, 1)
            myarrayY(m) = myarrayRowHeader(j,1)
'etc.

请注意,将 Excel 范围转换为数组时,它始终是二维数组,即使只选择了一列。

但是因为您在多个列和数组中工作,所以您的简单循环将不起作用。您必须了解空间中的相对关系,如下所示。

Dim myarrayHeader As Variant 
Dim myarrayRowHeader As Variant
Dim myarrayIntersection As Variant
dim myarray(,) as Variant
myarrayHeader = Range("C2:H2").Value ' One row, multiple columns
myarrayRowHeader = Range("A2:A6").Value ' Multiple rows, one column
myarrayIntersection = Range("C2:H6").Value ' Multiple rows, multiple columns

Dim rowNum as Long
rowNum = 1

ReDim myarray(UBound(myarrayRowHeader,1) * UBound(myarrayHeader, 2),3) ' <--- double check this for right numbers

For i = LBound(myarrayHeader, 2) to UBound(myarrayHeader, 2) 
    For j = LBound(myarrayRowHeader, 1) to UBound(myarrayRowHeader, 1)
        myarray(rowNum, 1) = myarrayHeader(1,i)
        myarray(rowNum, 2) = myarrayRowHeader(j,1)
        myarray(rowNum, 3) = myarrayIntersection(I,j)
        rowNum = rowNum+1
    Next j
Next I

编辑:

我的原始代码只是考虑基于单个维度调整最终数组的大小,但最终数组当然是基于两个维度的。当 OP 试图遍历所有数据时,这会导致原始代码出现越界错误。

另一个选项,将事物保持在 UBound(x,1) 模式是使用.Transpose

myarrayHeader = Range("C2:H2").Transpose.Value ' Now multiple rows, one column

【讨论】:

只是为了我自己的理解。 redim 语句正在重新定义“myarray”,其界限是“myarrayRowHeader”列扩展多长时间和 3 个条目以允许在第二个嵌套 for 语句中获得三个值?我收到一个超出范围的下标,除非我将“for i”语句的值从“LBound(myarrayHeader, 2) to UBound(myarrayHeader, 2)”更改为“LBound(myarrayHeader, 1) to UBound(myarrayHeader, 1 )" 是的,ReDim最后设置了你想要的数组。当您重新定义 UBound 时,它是否按照您想要的方式工作? 是的,经过小幅调整后数值正确,非常感谢。 @Danny,修复了导致您超出范围错误的编码错误。将其更改为 UBound(myarrayHeader, 1) 似乎有效的原因是第一个维度大小为“1”,因此与另一个维度匹配。但是,您不会获得所有数据 (For I = 1 To 1)。查看 cpearson.com/excel/ArraysAndRanges.aspx 了解有关此内容的一些好读物。

以上是关于循环遍历行、列和交集 VBA的主要内容,如果未能解决你的问题,请参考以下文章

VBA:循环遍历行和自动填充的宏

在VBA(excel)中循环遍历行的最有效/最快的方法是啥?

VBA循环遍历2个不同大小的范围

如何使用 Excel VBA 宏循环行?

VBA 列循环

使用 VBA 循环遍历 XML