|
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
|
|