动态嵌套循环

时间:2011-08-25 17:30:15

标签: excel vba loops dynamic recursion

首先,我为开始一个新线程而道歉,但原文令人困惑,因为我无法清楚表达我的问题(链接到原始帖子:Dynamic Nested Loops for Autofilter in Excel VBA)。但是现在我实际上已经按照我喜欢的方式编写了程序,除了使用switch语句而不是更动态地使用嵌套循环。

修改
RSum用于存储范围和布尔值。用户选择列的标题单元格,并选择在汇总时是否要获得该列的总和或唯一计数。这允许这些对象的集合以允许汇总多个列。这种输入并不是那么糟糕的动态。下一个以rtemp开头并以array1结尾的输入再次是用户选择列的标题单元格,但是它会获取该列中的值并将唯一列表保存到array1。使用此列表,for循环使用其值作为自动过滤器的条件循环遍历数组。对于自动过滤器后循环中的每个步骤,使用SumThisA计算摘要,将RSum对象集合作为输入。数据按行列出,每行都是唯一的记录。

所以问题是,对于下面的代码,我希望用户能够选择要汇总的类别数,有一个弹出窗口来填充这些范围(可以计算出来),然后运行一个过滤器就这样:

for i = 0 to UBound(array1)
    Autofilter criteria1:=array1(i)
    for j = 0 to UBound(array2)
        Autofilter criteria1:=array2(j)
        ......
            for x = 0 to UBound(arrayx)
                Autofilter criteria1:=arrayx(x)
                aSum(i,j,....x) = somefunction

现在我明白我需要使用递归函数,但之前从未使用过一个函数,而且这个程序有点复杂,这是我的理解。有人能帮助解释如何在这种情况下使用它吗?此外,由于该程序的普及,它可能是许多人的有用工具。

'---------Initialize Arrays---------------'
t = sMax - 1
Dim aSum()
ReDim aSum(UBound(arr1), t)  

'---------------------Perform Summary----------------'
For i = LBound(arr1) To UBound(arr1)
If i = 0 Then
    Data.AutoFilter field:=afield, Criteria1:=arr1, Operator:=xlFilterValues
Else
    Data.AutoFilter field:=afield, Criteria1:=arr1(i)
End If
temp = SumThisA(SumValues, sMax)
    For j = LBound(temp) To UBound(temp)
        aSum(i, j) = temp(j)
    Next j
Next i  

美元总和:
 1. arrayA(1)------- 100
     - arrayB(1)------ 30
     - arrayB(2)------ 70
 2. arrayA(2)------- 200
     - arrayB(1)----- 120
     - arrayB(2)------ 80
 3.总计----------- 300

2 个答案:

答案 0 :(得分:1)

这是一个非常复杂的递归示例,表示您想要做的事情。我伪造了一些标准,所以不要挂断我是如何测试的,重要的是函数Filter函数如何递归。如果我能更精确地确定你想要的东西,我可以更精确地制作它,并且硬编码更少。

测试工具:

Public Sub Test()

Dim FilteredArray As Variant, cArray As Variant, working Array As Variant
Dim criteria As Integer

criteria = 1
ReDim criteriaArray(1 To 2)
cArray(1) = Range("C1").Value
cArray(2) = Range("C2").Value
Set workingArray = Range("A1:A7")
FilteredArray = Filter(workingArray, 7, cArray, criteria)    
Range("D1") = FilteredArray    

End Sub

递归过滤器功能:

Public Function Filter(workingArray As Variant, index As Integer, _
                       criteriaArray As Variant, criteria) As Variant

Dim tempArray As Variant, i As Integer

ReDim tempArray(1 To 1)
For i = 1 To index
  If Mid(workingArray(i), criteria, 1) = criteriaArray(criteria) Then
    ReDim Preserve tempArray(1 To UBound(tempArray) + 1)
    tempArray(UBound(tempArray) - 1) = workingArray(i)
  End If
Next i
ReDim Preserve tempArray(1 To UBound(tempArray) - 1)

If criteria < 2 Then
  Filter = Filter(tempArray, UBound(tempArray), criteriaArray, criteria + 1)
Else
  Filter = tempArray
End If

End Function

答案 1 :(得分:0)

您是否考虑过使用数据透视表?您的要求似乎非常接近该功能......