For Each - 评估 - 值的顺序取决于是否从工作表或字符串参数溢出函数

问题描述 投票:0回答:2

我需要一个函数来从 Excel 溢出函数生成的动态范围中提取值并将它们保存到动态数组中。为此,我使用 For Each 循环。如果动态范围来自直接从字符串参数获取的 EXCEL 溢出函数或通过对工作表中溢出函数的引用,则它应该独立工作。由于某些奇怪的原因,顺序不同。

活动工作表中的单元格 A1 包含以下公式:=SEQUENCE(5,4,1,1)

Sub eval1()
Dim v As Variant
Dim s As String
For Each v In Evaluate("=A1#")
s = s & v & " "
Next
Debug.Print s
End Sub

输出: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Sub eval2()
Dim v As Variant
Dim s As String
For Each v In Evaluate("=SEQUENCE(5,4,1,1)")
s = s & v & " "
Next
Debug.Print s
End Sub

输出: 1 5 9 13 17 2 6 10 14 18 3 7 11 15 19 4 8 12 16 20

我期望两个子系统的输出:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
或者至少两者都是一样的。

excel vba range evaluate
2个回答
1
投票

这是部分答案,但由于您在这里处理 2D 数组,因此只需使用

For
循环、
LBound
UBound
:

Sub eval3()
    Dim v1 As Variant
    v1 = Evaluate("=A1#")
        
    Dim v2 As Variant
    v2 = Evaluate("=SEQUENCE(5,4,1,1)")
    
    Dim i As Long, j As Long, s As String
    For i = LBound(v1, 1) To UBound(v1, 1)
        For j = LBound(v1, 2) To UBound(v1, 2)
            s = s & v1(i, j) & " "
        Next
    Next
    
    Debug.Print s
    s = vbNullString
    
    For i = LBound(v2, 1) To UBound(v2, 1)
        For j = LBound(v2, 2) To UBound(v2, 2)
            s = s & v2(i, j) & " "
        Next
    Next
    
    Debug.Print s
End Sub

输出:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 

0
投票

区别在于行主序与列主序遍历。 MS 文档没有指定 For Each 循环使用哪个。所有结论均基于代码测试结果。

对于范围:行主顺序

Sub ForEachRange()
    Dim c As Range, sMsg As String
    For Each c In Range("A1:B2")
        sMsg = sMsg & " " & c.Address(0, 0)
    Next
    Debug.Print sMsg
End Sub

输出:

A1 B1 A2 B2

对于数组范围:列主顺序

Sub ForEachArr()
    Dim c, sMsg As String
    Dim MyArray(1 To 2, 1 To 2) As Integer ' 2x2 array
    MyArray(1, 1) = 1
    MyArray(1, 2) = 2
    MyArray(2, 1) = 3
    MyArray(2, 2) = 4
    For Each c In MyArray
        sMsg = sMsg & " " & c
    Next
    Debug.Print sMsg
End Sub

输出:

1 3 2 4

我不确定为什么会有差异。但它看起来像:

For Each v In Evaluate("=A1#")
相当于
For Each v In Range("A1:D5")

For Each v In Evaluate("=SEQUENCE(5,4,1,1)")
相当于

vArrary = Evaluate("=SEQUENCE(5,4,1,1)")
For Each v In vArrary

使用嵌套

For
循环来迭代结果更可靠。

© www.soinside.com 2019 - 2024. All rights reserved.