ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 14965|回复: 46

[原创] 五一以后最强帖【多层循环组合算法代码】生成器

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-5-6 10:58 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:循环和遍历
需要列出全部组合结果时,最快的还是简单有效的多层循环。

但是有一个问题,如果每次要求组合提取数n不同,则循环层数不同,代码需要重新写……
而且如果n较大时,会很麻烦……


怎么解决这个问题呢?
一种思路,是直接编写通用算法的代码,用Do……Loop循环或递归算法,
一劳永逸地解决组合算法问题。(这个方面目前我香川群子的组合算法最好)

但是,这样的代码相对比较复杂一些,对于初学者来说不是很容易掌握。


因此,我给大家编写了【组合算法代码生成器】。
是那种最简单的多层循环组合算法。

代码如下:
  1. Sub 生成多层循环组合代码()
  2.    
  3.     n = Val(InputBox("抽取个数 n =", "多层循环组合代码", [b1]))
  4.     '输入n、或提取B1单元格中数字作为组合数n
  5.     If n = 0 Then Exit Sub Else [b1] = n
  6.     m = Val(InputBox("组合对象元素个数 m =", "多层循环组合代码", IIf([a2] = "", [a1], [a1].End(4).Row)))
  7.     '输入m、或按A列元素个数m、或提取A1单元格中的数字作为组合元素总数m
  8.     If m >= n Then k = WorksheetFunction.Combin(m, n): MsgBox "组合结果总数 = " & k
  9.    
  10.     tmN = "AutoCombin_Arr_" & n
  11.     s = s & "Sub " & tmN & "()" & Chr(10) & Chr(10)
  12.     s = s & "  Dim k&, m&, n&, tms#" & Chr(10)
  13.     s = s & "  tms = Timer" & Chr(10)
  14.     s = s & "  n = " & n & ": m = [a1].End(4).Row: If m < n Then Exit Sub" & Chr(10)
  15.     s = s & "  k = WorksheetFunction.Combin(m, n)" & Chr(10)
  16.     s = s & "  If k < Cells.Rows.Count Then ReDim jg(1 To k, 0 To n)" & Chr(10)
  17.     s = s & "  k = 0 : sj = [a1].Resize(m)" & Chr(10) & Chr(10)
  18.    
  19.     t1 = "  Dim i1&"
  20.     For i = 2 To n
  21.         t1 = t1 & ", i" & i & "&"
  22.     Next
  23.     s = s & t1 & Chr(10)
  24.    
  25.     s = s & "  For i1 = 1 To m - " & n - 1 & Chr(10)
  26.    
  27.     t2 = "    jg(k, 0) = i1"
  28.     t3 = "    jg(k, 1) = sj(i1, 1)"
  29.     t4 = "'    jg(k, 0) = sj(i1, 1)"
  30.     t5 = "'    jg(k, 1) = i1"
  31.     t6 = "  Next i" & n
  32.     For i = 2 To n
  33.         s = s & "  For i" & i & " = i" & i - 1 & " + 1 To m - " & n - i & Chr(10)
  34.         t2 = t2 & " & "","" & i" & i
  35.         t3 = t3 & " : jg(k, " & i & ") = sj(i" & i & ", 1)"
  36.         t4 = t4 & " & sj(i" & i & ", 1)"
  37.         t5 = t5 & " : jg(k, " & i & ") = i" & i
  38.         t6 = t6 & ", i" & n - i + 1
  39.     Next

  40.     s = s & "    k = k + 1" & Chr(10)
  41.     s = s & IIf(k < Cells.Rows.Count, "", "'") & t2 & Chr(10)
  42.     s = s & IIf(k < Cells.Rows.Count, "", "'") & t3 & Chr(10) & Chr(10)
  43.     s = s & t4 & Chr(10)
  44.     s = s & t5 & Chr(10)
  45.     s = s & t6 & Chr(10)
  46.    
  47.     s = s & "  If k > Cells.Rows.Count Then Msgbox Format(Timer - tms ,""0.000s "") & k : Exit Sub" & Chr(10) & Chr(10)
  48.     s = s & "  [d1].CurrentRegion ="""": [d1].Resize(k, n + 1) = jg" & Chr(10)
  49.     s = s & "  [d1].Resize(, n + 1).EntireColumn.AutoFit" & Chr(10)
  50.     s = s & "  Msgbox Format(Timer - tms ,""0.000s "") & k" & Chr(10) & Chr(10)
  51.     s = s & "End Sub"
  52.    
  53.     key = MsgBox("立即运行这个组合计算宏吗", vbDefaultButton2 + vbYesNo)
  54.     If key = vbYes Then
  55.         Set t = ThisWorkbook.VBProject.VBComponents.Add(1)
  56.         t.CodeModule.AddFromString s
  57.         Application.run "" & tmN
  58.         ThisWorkbook.VBProject.VBComponents.Remove t
  59.     Else
  60.         Set t = ActiveWorkbook.VBProject.VBComponents.Add(1)
  61.         t.CodeModule.AddFromString s
  62.         ActiveSheet.Buttons.Add(60, 30, 40, 30).Select
  63.         With Selection
  64.             .Characters.TEXT = "Combin_Arr" & Chr(10) & "n= " & n
  65.             .AutoSize = True
  66.             .Placement = xlFreeFloating
  67.             .OnAction = ActiveWorkbook.Name & "!" & tmN
  68.         End With
  69.    
  70.     '    ActiveWorkbook.VBProject.VBComponents.Remove t
  71.     End If
  72.    
  73. End Sub
复制代码
请大家试用。有问题我会答疑。

评分

3

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-5-6 11:02 | 显示全部楼层
代码运用实例:

生成m选5的多层循环组合算法代码:
http://club.excelhome.net/forum. ... p;extra=#pid7618833
  1. Sub AutoCombin_Arr_5()

  2.   Dim k&, m&, n&, tms#
  3.   tms = Timer
  4.   n = 5: m = [a1].End(4).Row: If m < n Then Exit Sub
  5.   k = WorksheetFunction.Combin(m, n)
  6.   If k < Cells.Rows.Count Then ReDim jg(1 To k, 0 To n)
  7.   k = 0: sj = [a1].Resize(m)

  8.   Dim i1&, i2&, i3&, i4&, i5&
  9.   For i1 = 1 To m - 4
  10.   For i2 = i1 + 1 To m - 3
  11.   For i3 = i2 + 1 To m - 2
  12.   For i4 = i3 + 1 To m - 1
  13.   For i5 = i4 + 1 To m - 0
  14.     k = k + 1
  15. '    jg(k, 0) = i1 & "," & i2 & "," & i3 & "," & i4 & "," & i5
  16. '    jg(k, 1) = sj(i1, 1) : jg(k, 2) = sj(i2, 1) : jg(k, 3) = sj(i3, 1) : jg(k, 4) = sj(i4, 1) : jg(k, 5) = sj(i5, 1)

  17. '    jg(k, 0) = sj(i1, 1) & sj(i2, 1) & sj(i3, 1) & sj(i4, 1) & sj(i5, 1)
  18. '    jg(k, 1) = i1 : jg(k, 2) = i2 : jg(k, 3) = i3 : jg(k, 4) = i4 : jg(k, 5) = i5
  19.   Next i5, i4, i3, i2, i1
  20.   If k > Cells.Rows.Count Then MsgBox Format(Timer - tms, "0.000s ") & k: Exit Sub

  21.   [d1].CurrentRegion = "": [d1].Resize(k, n + 1) = jg
  22.   [d1].Resize(, n + 1).EntireColumn.AutoFit
  23.   MsgBox Format(Timer - tms, "0.000s ") & k

  24. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-5-6 11:04 | 显示全部楼层
来一个m选32的多层循环组合算法代码:
  1. Sub AutoCombin_Arr_32()

  2.   Dim k&, m&, n&, tms#
  3.   tms = Timer
  4.   n = 32: m = [a1].End(4).Row: If m < n Then Exit Sub
  5.   k = WorksheetFunction.Combin(m, n)
  6.   If k < Cells.Rows.Count Then ReDim jg(1 To k, 0 To n)
  7.   k = 0: sj = [a1].Resize(m)

  8.   Dim i1&, i2&, i3&, i4&, i5&, i6&, i7&, i8&, i9&, i10&, i11&, i12&, i13&, i14&, i15&, i16&, i17&, i18&, i19&, i20&, i21&, i22&, i23&, i24&, i25&, i26&, i27&, i28&, i29&, i30&, i31&, i32&
  9.   For i1 = 1 To m - 31
  10.   For i2 = i1 + 1 To m - 30
  11.   For i3 = i2 + 1 To m - 29
  12.   For i4 = i3 + 1 To m - 28
  13.   For i5 = i4 + 1 To m - 27
  14.   For i6 = i5 + 1 To m - 26
  15.   For i7 = i6 + 1 To m - 25
  16.   For i8 = i7 + 1 To m - 24
  17.   For i9 = i8 + 1 To m - 23
  18.   For i10 = i9 + 1 To m - 22
  19.   For i11 = i10 + 1 To m - 21
  20.   For i12 = i11 + 1 To m - 20
  21.   For i13 = i12 + 1 To m - 19
  22.   For i14 = i13 + 1 To m - 18
  23.   For i15 = i14 + 1 To m - 17
  24.   For i16 = i15 + 1 To m - 16
  25.   For i17 = i16 + 1 To m - 15
  26.   For i18 = i17 + 1 To m - 14
  27.   For i19 = i18 + 1 To m - 13
  28.   For i20 = i19 + 1 To m - 12
  29.   For i21 = i20 + 1 To m - 11
  30.   For i22 = i21 + 1 To m - 10
  31.   For i23 = i22 + 1 To m - 9
  32.   For i24 = i23 + 1 To m - 8
  33.   For i25 = i24 + 1 To m - 7
  34.   For i26 = i25 + 1 To m - 6
  35.   For i27 = i26 + 1 To m - 5
  36.   For i28 = i27 + 1 To m - 4
  37.   For i29 = i28 + 1 To m - 3
  38.   For i30 = i29 + 1 To m - 2
  39.   For i31 = i30 + 1 To m - 1
  40.   For i32 = i31 + 1 To m - 0
  41.     k = k + 1
  42. '    jg(k, 0) = i1 & "," & i2 & "," & i3 & "," & i4 & "," & i5 & "," & i6 & "," & i7 & "," & i8 & "," & i9 & "," & i10 & "," & i11 & "," & i12 & "," & i13 & "," & i14 & "," & i15 & "," & i16 & "," & i17 & "," & i18 & "," & i19 & "," & i20 & "," & i21 & "," & i22 & "," & i23 & "," & i24 & "," & i25 & "," & i26 & "," & i27 & "," & i28 & "," & i29 & "," & i30 & "," & i31 & "," & i32
  43. '    jg(k, 1) = sj(i1, 1) : jg(k, 2) = sj(i2, 1) : jg(k, 3) = sj(i3, 1) : jg(k, 4) = sj(i4, 1) : jg(k, 5) = sj(i5, 1) : jg(k, 6) = sj(i6, 1) : jg(k, 7) = sj(i7, 1) : jg(k, 8) = sj(i8, 1) : jg(k, 9) = sj(i9, 1) : jg(k, 10) = sj(i10, 1) : jg(k, 11) = sj(i11, 1) : jg(k, 12) = sj(i12, 1) : jg(k, 13) = sj(i13, 1) : jg(k, 14) = sj(i14, 1) : jg(k, 15) = sj(i15, 1) : jg(k, 16) = sj(i16, 1) : jg(k, 17) = sj(i17, 1) : jg(k, 18) = sj(i18, 1) : jg(k, 19) = sj(i19, 1) : jg(k, 20) = sj(i20, 1) : jg(k, 21) = sj(i21, 1) : jg(k, 22) = sj(i22, 1) : jg(k, 23) = sj(i23, 1) : jg(k, 24) = sj(i24, 1) : jg(k, 25) = sj(i25, 1) : jg(k, 26) = sj(i26, 1) : jg(k, 27) = sj(i27, 1) : jg(k, 28) = sj(i28, 1) : jg(k, 29) = sj(i29, 1) : jg(k, 30) = sj(i30, 1) : jg(k, 31) = sj(i31, 1) : jg(k, 32) = sj(i32, 1)

  44. '    jg(k, 0) = sj(i1, 1) & sj(i2, 1) & sj(i3, 1) & sj(i4, 1) & sj(i5, 1) & sj(i6, 1) & sj(i7, 1) & sj(i8, 1) & sj(i9, 1) & sj(i10, 1) & sj(i11, 1) & sj(i12, 1) & sj(i13, 1) & sj(i14, 1) & sj(i15, 1) & sj(i16, 1) & sj(i17, 1) & sj(i18, 1) & sj(i19, 1) & sj(i20, 1) & sj(i21, 1) & sj(i22, 1) & sj(i23, 1) & sj(i24, 1) & sj(i25, 1) & sj(i26, 1) & sj(i27, 1) & sj(i28, 1) & sj(i29, 1) & sj(i30, 1) & sj(i31, 1) & sj(i32, 1)
  45. '    jg(k, 1) = i1 : jg(k, 2) = i2 : jg(k, 3) = i3 : jg(k, 4) = i4 : jg(k, 5) = i5 : jg(k, 6) = i6 : jg(k, 7) = i7 : jg(k, 8) = i8 : jg(k, 9) = i9 : jg(k, 10) = i10 : jg(k, 11) = i11 : jg(k, 12) = i12 : jg(k, 13) = i13 : jg(k, 14) = i14 : jg(k, 15) = i15 : jg(k, 16) = i16 : jg(k, 17) = i17 : jg(k, 18) = i18 : jg(k, 19) = i19 : jg(k, 20) = i20 : jg(k, 21) = i21 : jg(k, 22) = i22 : jg(k, 23) = i23 : jg(k, 24) = i24 : jg(k, 25) = i25 : jg(k, 26) = i26 : jg(k, 27) = i27 : jg(k, 28) = i28 : jg(k, 29) = i29 : jg(k, 30) = i30 : jg(k, 31) = i31 : jg(k, 32) = i32
  46.   Next i32, i31, i30, i29, i28, i27, i26, i25, i24, i23, i22, i21, i20, i19, i18, i17, i16, i15, i14, i13, i12, i11, i10, i9, i8, i7, i6, i5, i4, i3, i2, i1
  47.   If k > Cells.Rows.Count Then MsgBox Format(Timer - tms, "0.000s ") & k: Exit Sub

  48.   [d1].CurrentRegion = "": [d1].Resize(k, n + 1) = jg
  49.   [d1].Resize(, n + 1).EntireColumn.AutoFit
  50.   MsgBox Format(Timer - tms, "0.000s ") & k

  51. End Sub
复制代码
如果这些代码自己写……可能会疯掉吧。而且容易出错。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-5-6 13:29 | 显示全部楼层
m = Val(InputBox("缁勫悎瀵硅薄鍏冪礌涓?暟 m =", "澶氬眰寰?幆缁勫悎浠g爜", IIf([a2] = "", [a1], [a1].End(4).Row)))
    '杈撳叆m銆佹垨鎸堿鍒楀厓绱犱釜鏁癿銆佹垨鎻愬彇A1鍗曞厓鏍间腑鐨勬暟瀛椾綔涓虹粍鍚堝厓绱犳


请教代码粘贴后出现这种情况?

TA的精华主题

TA的得分主题

发表于 2014-5-6 14:23 | 显示全部楼层
香川老师是真正的大师,因为算法是解决问题的关键,老师一直在坚持提高算法的效率,学习

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-5-6 14:41 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
abc3d 发表于 2014-5-6 13:29
m = Val(InputBox("缁勫悎瀵硅薄鍏冪礌涓?暟 m =", "澶氬眰寰?幆缁勫悎浠g爜", IIf([a2] = "", [a1], [a ...

可能是我的字体有问题。

你自己把文字提示部分重新抄写一遍就可以了。

TA的精华主题

TA的得分主题

发表于 2014-5-6 15:39 | 显示全部楼层
香川群子 发表于 2014-5-6 14:41
可能是我的字体有问题。

你自己把文字提示部分重新抄写一遍就可以了。

谢谢!跟excel版本没关系吧,我用的是13版本的。

TA的精华主题

TA的得分主题

发表于 2014-5-6 21:45 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-5-7 13:47 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
abc3d 发表于 2014-5-6 15:39
谢谢!跟excel版本没关系吧,我用的是13版本的。

你用32位的13版试试 ?我以前用64位的时候,VBA也是乱七八糟的问题。

TA的精华主题

TA的得分主题

发表于 2014-5-11 19:52 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-25 00:26 , Processed in 0.048034 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表