|
本帖最后由 香川群子 于 2014-7-23 11:35 编辑
中山郎 发表于 2014-7-23 10:13
可能是我描述的不清楚,1楼描述中,只是示例,比较不贴切,现在上传真实情况的数据,就不是ABC123什么的,而 ...
附件也只是2列……会有更多列么?
下面这个是通用的【香川多列组合】的递归算法代码:- Dim sj, jg(), m&, n&, k&
- Sub MultiColumnCombin() 'by kagawa 香川多列组合
- Dim i&, j&, t&, tms#
- tms = Timer
-
- sj = [a1].CurrentRegion '以A1所在单元格区域为多列组合对象 数据读入数组sj
- m = UBound(sj): n = UBound(sj, 2) '获取最大行数m 和最大列数n
- k = 1 '组合总数k 初始值=1
- For j = 1 To n '遍历各列
- t = 0 '本列元素个数t 初始化
- For i = 1 To m '遍历本列各行
- If sj(i, j) <> "" Then t = t + 1
- Next
- k = k * t '计算组合总数
- Next
- ReDim jg(k, 1 To n) '根据计算组合总数定义结果数组jg
-
- k = 0: Call dgMN(1) '调用递归计算过程 注意计数值k要初始化=0
-
- With [a1].Offset(, n + 2) '选择比原始数据隔开2列的单元格作为输出结果的起始位置
- .CurrentRegion = "" '清空输出区域
- .Resize(k, n) = jg '输出结果
- End With
-
- MsgBox Format(Timer - tms, "0.000s ") & k '耗时以及组合结果总数k
- End Sub
- Sub dgMN(j&) '递归计算过程 (参数j为递归进入的列位置)
- Dim i&, j1&, t
- For i = 1 To m '遍历各行
- t = sj(i, j) '读取该行该列位置的内容
- If t = "" Then
- Exit For '如果该位置为空白单元格即可提前退出。(如需强行计算则注销本句)
- Else
- jg(k, j) = t '在结果数组jg中对应列位置记录本次递归计算得到的组合结果
- If j = n Then '如果已到最后一列n列 则可确定本次组合结果
- For j1 = 1 To n '把当前组合结果传递到下一组合
- If jg(k, j1) <> "" Then Exit For Else jg(k, j1) = jg(k - 1, j1)
- Next
- k = k + 1 '结果数组jg的计数k序号参数+1 更新记录位置进入下一行。
- Else
- Call dgMN(j + 1) '如果还没到最后1列n列 则继续递归进入到下一列。
- End If
- End If
- Next
- End Sub
复制代码 |
|