VBA递归过程快速组合数据

56 篇文章 2 订阅
55 篇文章 4 订阅

实例需求:数据表包含的列数不固定,有的列(数量和位置不固定)包含组合数据,例如C2单元格为D,P,说明Unit Config有两种分别为D和P,如下图所示。

在这里插入图片描述

现在需要将所有的组合罗列出来,如下所示。

在这里插入图片描述

示例代码如下。

Sub Demo()
    Dim i As Long, j As Long, c As Variant
    Dim arrData, arrRes, iR As Long, aRow() As Variant
    Dim LastRow As Long, ColCnt As Long
    Dim oSht1 As Worksheet, aTxt
    Dim oColl As New Collection
    Set oSht1 = Sheets("Sheet1") 
    arrData = oSht1.Range("A1").CurrentRegion.Value
    ColCnt = UBound(arrData, 2)
    ReDim aRow(ColCnt - 1)
    For i = LBound(arrData) + 1 To UBound(arrData)
        For j = LBound(arrData, 2) To UBound(arrData, 2)
            aRow(j - 1) = Split(arrData(i, j), ",")
        Next j
        GenerateCombinations oColl, aRow
    Next i
    ReDim arrRes(1 To oColl.Count, ColCnt - 1)
    iR = 0
    For Each c In oColl
        aTxt = Split(c, "|")
        iR = iR + 1
        For j = 0 To UBound(aTxt)
            arrRes(iR, j) = aTxt(j)
        Next
    Next
    Sheets.Add
    Range("A1").Resize(, ColCnt).Value = oSht1.Range("A1").Resize(, ColCnt).Value
    Range("A2").Resize(iR, ColCnt).Value = arrRes
End Sub

【代码解析】
第8行代码将数据表加载到数组中。
第9行代码获取数据表的列数。
第10行代码为数组aRow分配存储空间。
第11~16行代码循环遍历每行数据。
第12~14行代码循环处理一行中的每个单元格数据,将其按逗号拆分,并保存在嵌套数组aRow中。
第15行代码调用递归过程创建数据组合。
第17行代码为结果数组arrRes分配存储空间。
第19~25行代码循环遍历Collection对象中的元素。
第20行代码将字符串拆分为数组。
第22~24行代码将数组保存在结果数组。
第26行代码添加新工作表。
第27行代码将工作表标题由源工作表拷贝到结果工作表。
第28行代码结果保存到新建工作表中。

Sub GenerateCombinations(ByRef oColl As Object, aVals() As Variant, Optional curStr As String = "", Optional colIdx As Long = 0)
    Dim i As Long
    If colIdx = UBound(aVals) + 1 Then
        oColl.Add Mid(curStr, 2)
        Exit Sub
    End If
    For i = LBound(aVals(colIdx)) To UBound(aVals(colIdx))
        GenerateCombinations oColl, aVals, curStr & "|" & aVals(colIdx)(i), colIdx + 1
    Next i
End Sub

【代码解析】
递归过程有3个参数:

  • oColl为Collection对象,用于保存结果数据
  • aVals为包含拆分内容的数组
  • curStr为当前已经组合的字符串
  • colIdx为当前处理的层级(也可以理解为数据表的列)

第3行代码根据colIdx判断是否已经到达最后一个层级,如果满足条件,第4行代码将字符串(组合)添加到Collection对象中。
第5行代码结束当前调用过程的执行。
第7~9行代码循环处理数组aVals中的每个元素。
第8行代码调用递归过程,其中层级colIdx加一。

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值