ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 求助:怎么利用VBA实现排列组合,进行分组排序?谢谢!

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2012-7-19 16:19 | 显示全部楼层
本帖最后由 zhaogang1960 于 2012-7-19 16:44 编辑
小花鹿 发表于 2012-7-19 14:38
不断重复运行程序,有时候会处于没有响应状态,不知什么原因?

字典+do循环就有这个问题,可以考虑使用数组解决,现在除了再使用字典+do循环,我还找不到每个宿舍中学校不能重复的方法

TA的精华主题

TA的得分主题

发表于 2012-7-19 16:22 | 显示全部楼层
数组法:
  1. Sub Macro1()
  2.     Dim arr(1 To 2), brr(), i&, j&, m&, n&, r&, l&, v&, ds As Object
  3.     Set ds = CreateObject("scripting.dictionary")
  4.     m = [d:d].Find("女", , , xlWhole).Row
  5.     arr(1) = Range("a2:d" & m - 1)
  6.     arr(2) = Range("a" & m & ":d" & [a65536].End(3).Row)
  7.     Columns("G:J").ClearContents
  8.     [g1:j1] = Array("宿舍号", "姓名", "学校", "性别")
  9.     For l = 1 To 2
  10.         For i = 1 To UBound(arr(l))
  11.             ds(i) = ""
  12.         Next
  13.         ReDim brr(1 To UBound(arr(l)), 1 To 4)
  14.         r = 0
  15.         For i = 1 To WorksheetFunction.RoundUp(UBound(arr(l)) / 6, 0) - 1
  16.             k = ds.keys
  17.             lr = UBound(k)
  18.             For v = 0 To 5
  19.               n = Int(Rnd * (lr - v))
  20.               ds.Remove k(n)
  21.               r = r + 1
  22.               brr(r, 1) = i
  23.               For j = 2 To 4
  24.                 brr(r, j) = arr(l)(k(n), j)
  25.               Next
  26.               k(n) = k(lr - v)
  27.             Next
  28.         Next
  29.         k = ds.keys
  30.         m = i
  31.         For i = 0 To ds.Count - 1
  32.             r = r + 1
  33.             brr(r, 1) = m
  34.             For j = 2 To 4
  35.                 brr(r, j) = arr(l)(k(i), j)
  36.             Next
  37.         Next
  38.         [g65536].End(3).Offset(1).Resize(r, 4) = brr
  39.         ds.RemoveAll
  40.     Next
  41. End Sub

复制代码

TA的精华主题

TA的得分主题

发表于 2012-7-19 17:45 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
为了避免使用Do语句造成死循环,采用乱序排序模拟随机取值,请参考:
  1. Sub Macro1()
  2.     Dim arr(1 To 2), brr(), i&, j&, m&, n&, r&, l&, lr&, ii&, v&, d As Object, ds As Object
  3.     Application.ScreenUpdating = False
  4.     Set d = CreateObject("scripting.dictionary")
  5.     Set ds = CreateObject("scripting.dictionary")
  6.     lr = Range("A65536").End(xlUp).Row - 1
  7.     ReDim brr(1 To lr, 1 To 1)
  8.     For i = 1 To lr
  9.         brr(i, 1) = Int((Rnd * lr) + 1)
  10.     Next
  11.     [e2].Resize(lr) = brr
  12.     m = [d:d].Find("女", , , xlWhole).Row
  13.     With Range("a2:e" & m - 1)
  14.         .Sort Key1:=[e2]
  15.         arr(1) = .Value
  16.     End With
  17.     With Range("a" & m & ":e" & [a65536].End(3).Row)
  18.         .Sort Key1:=.Cells(1, 5)
  19.         arr(2) = .Value
  20.     End With
  21.     Columns("e:j").ClearContents
  22.     [g1:j1] = Array("宿舍号", "姓名", "学校", "性别")
  23.     For l = 1 To 2
  24.         For i = 1 To UBound(arr(l))
  25.             d(i) = ""
  26.         Next
  27.         ReDim brr(1 To UBound(arr(l)), 1 To 4)
  28.         r = 0
  29.         For i = 1 To WorksheetFunction.RoundUp(UBound(arr(l)) / 6, 0) - 1
  30.             For v = 1 To 6
  31.                 For ii = 1 To UBound(arr(l))
  32.                     If Len(arr(l)(ii, 3)) Then
  33.                         If Not ds.Exists(arr(l)(ii, 3)) Then
  34.                             r = r + 1
  35.                             ds(arr(l)(ii, 3)) = ""
  36.                             d.Remove ii
  37.                             brr(r, 1) = i
  38.                             For j = 2 To 4
  39.                                 brr(r, j) = arr(l)(ii, j)
  40.                             Next
  41.                             arr(l)(ii, 3) = ""
  42.                             Exit For
  43.                         End If
  44.                     End If
  45.                 Next
  46.             Next
  47.             ds.RemoveAll
  48.         Next
  49.         k = d.keys
  50.         m = i
  51.         For i = 0 To d.Count - 1
  52.             r = r + 1
  53.             brr(r, 1) = m
  54.             For j = 2 To 4
  55.                 brr(r, j) = arr(l)(k(i), j)
  56.             Next
  57.         Next
  58.         [g65536].End(3).Offset(1).Resize(r, 4) = brr
  59.         d.RemoveAll
  60.     Next
  61.     [a1].CurrentRegion.Sort Key1:=[a2], Header:=xlYes
  62.     Application.ScreenUpdating = True
  63. End Sub



复制代码

TA的精华主题

TA的得分主题

发表于 2012-7-19 17:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
请看附件
宿舍分配222.rar (19.6 KB, 下载次数: 65)

TA的精华主题

TA的得分主题

发表于 2012-7-20 11:39 | 显示全部楼层
本帖最后由 小花鹿 于 2012-7-20 11:44 编辑

现把附件改一下:
1、把学校和性别改成了乱序排列
2、增加了一个随机抽取的条件
宿舍分配.rar (12.03 KB, 下载次数: 15)

继续征求既高效又易懂的代码。
表2是模拟结果,由于人名是随机抽取的,所以这个模拟结果只是一个样子。
最好是只用数组和字典,不用SORT或工作表函数等。

TA的精华主题

TA的得分主题

发表于 2012-7-20 13:15 | 显示全部楼层
小花鹿 发表于 2012-7-20 11:39
现把附件改一下:
1、把学校和性别改成了乱序排列
2、增加了一个随机抽取的条件

不应排斥工作表排序方法,好像还没有超过Sort方法的VBA排序法
提供一个思路:
1、求出男女人数后,使用数组生成不重复随机数放到一个一维数组中,按照这个数组的顺序分别存放男女数据,这样就完成了随机数
2、再用12楼方法后半部分思路

TA的精华主题

TA的得分主题

发表于 2012-7-20 13:34 | 显示全部楼层
zhaogang1960 发表于 2012-7-20 13:15
不应排斥工作表排序方法,好像还没有超过Sort方法的VBA排序法
提供一个思路:
1、求出男女人数后,使用 ...

好的,我试试。
一定要好好研究一下这个题目,很有实际意义。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-20 16:13 | 显示全部楼层
谢谢各位老师的帮助,也希望这个问题能够得到更多人的关注,得到更加漂亮的程序!

TA的精华主题

TA的得分主题

发表于 2012-7-20 21:24 | 显示全部楼层
小花鹿 发表于 2012-7-20 11:39
现把附件改一下:
1、把学校和性别改成了乱序排列
2、增加了一个随机抽取的条件

学校乱序有道理,性别就最好分开……反正不同的性别肯定不能同宿舍。

完全可以男生女生分开放置在不同的区域,用同样的代码处理就可以了。

TA的精华主题

TA的得分主题

发表于 2012-7-20 21:32 | 显示全部楼层
香川群子 发表于 2012-7-20 21:24
学校乱序有道理,性别就最好分开……反正不同的性别肯定不能同宿舍。

完全可以男生女生分开放置在不同 ...

学校和性别乱序都是有可能的,比如这个表是按学生报名时的顺序填写的,而分宿舍时又不想打乱这个顺序。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-6-24 20:27 , Processed in 0.038373 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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