Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 1845|回复: 6

[已解决]用VBA随机部姓名问题

[复制链接]
发表于 2017-4-29 18:02 | 显示全部楼层 |阅读模式
本帖最后由 laoau138 于 2017-4-29 22:37 编辑


用VBA随机部姓名问题


最佳答案
2017-4-29 21:43
随机值排序比较麻烦,以下代码为未排序的。
必需的话在代码最后加入一句工作表排序就行了。
  1. Sub aaa()
  2. Dim arr, brr, crr, i&, j&, d As Object, c, n&, r&
  3. Set d = CreateObject("scripting.dictionary")
  4. arr = Range("a2:d" & [a65536].End(3).Row)
  5. For i = 1 To UBound(arr)
  6.   d(arr(i, 2) & "," & arr(i, 4)) = d(arr(i, 2) & "," & arr(i, 4)) & "," & i
  7. Next i
  8. ReDim crr(1 To d.Count, 1 To 4)
  9. Randomize
  10. For Each c In d.keys
  11.   brr = Split(d(c), ",")
  12.   r = r + 1
  13.   n = Int(UBound(brr) * Rnd + 1)
  14.   For j = 1 To 4
  15.     crr(r, j) = arr(brr(n), j)
  16.   Next j
  17. Next c
  18. [f2].Resize(r, 4) = crr
  19. End Sub
复制代码


用VBA随机部姓名问题.rar

15.93 KB, 下载次数: 9

excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
发表于 2017-4-29 21:43 | 显示全部楼层    本楼为最佳答案   
随机值排序比较麻烦,以下代码为未排序的。
必需的话在代码最后加入一句工作表排序就行了。
  1. Sub aaa()
  2. Dim arr, brr, crr, i&, j&, d As Object, c, n&, r&
  3. Set d = CreateObject("scripting.dictionary")
  4. arr = Range("a2:d" & [a65536].End(3).Row)
  5. For i = 1 To UBound(arr)
  6.   d(arr(i, 2) & "," & arr(i, 4)) = d(arr(i, 2) & "," & arr(i, 4)) & "," & i
  7. Next i
  8. ReDim crr(1 To d.Count, 1 To 4)
  9. Randomize
  10. For Each c In d.keys
  11.   brr = Split(d(c), ",")
  12.   r = r + 1
  13.   n = Int(UBound(brr) * Rnd + 1)
  14.   For j = 1 To 4
  15.     crr(r, j) = arr(brr(n), j)
  16.   Next j
  17. Next c
  18. [f2].Resize(r, 4) = crr
  19. End Sub
复制代码


评分

参与人数 1 +9 收起 理由
laoau138 + 9 来学习

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2017-4-29 22:36 | 显示全部楼层
大灰狼1976 发表于 2017-4-29 21:43
随机值排序比较麻烦,以下代码为未排序的。
必需的话在代码最后加入一句工作表排序就行了。


Sub suij()
    Dim d As Object, arr, brr, i&, j&, k&
    Set d = CreateObject("scripting.dictionary")
    arr = [a1].CurrentRegion
    ReDim brr(1 To 10, 1 To 4)
    Do While k < 10
        temp = Application.RandBetween(2, UBound(arr))
        bmxb = arr(temp, 2) & arr(temp, 4)
        If Not d.exists(temp) Then
            If Not d.exists(bmxb) Then
                d(bmxb) = ""
                d(temp) = ""
                k = k + 1
                For j = 1 To 4
                    brr(k, j) = arr(temp, j)
                Next
            End If
        End If
    Loop
    [f2].Resize(10, 4) = brr
    Set d = Nothing
    MsgBox "ok"
End Sub


回复

使用道具 举报

发表于 2017-4-29 23:11 | 显示全部楼层
我的思路跟你贴的代码是完全不一样的。
我是先将同部门同性别的行号都记录进字典,
再遍历字典的KEY,在每个ITEM里面取一个随机值就可以了,不会存在重复,
所以可以用FOR循环来做,也可以在初期就确定结果数组的最大下标。
你贴的代码是先在数组中选随机行号,再来判断取到的数据是否跟已有数据冲突,
如果没有就新增,如有就跳过,由于有这种不确定性,所以必须用DO LOOP循环来做。

当然,结果跟我的一样是没有排序的,这本来就不是什么问题。

评分

参与人数 1 +9 收起 理由
laoau138 + 9 来学习

查看全部评分

回复

使用道具 举报

发表于 2017-4-29 23:15 | 显示全部楼层
你贴的代码还有一个问题,它是在知道K=10,也就是说已知有10条结果记录的前提下,用WHILE K<10做为跳出DO LOOP循环的条件,如果事先不知道的话,它是无法得出正确结果的(甚至陷入死循环),不信你可以通过增减你的原始数据来验证。

评分

参与人数 1 +9 收起 理由
laoau138 + 9 来学习

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2017-4-30 14:18 | 显示全部楼层
大灰狼1976 发表于 2017-4-29 23:15
你贴的代码还有一个问题,它是在知道K=10,也就是说已知有10条结果记录的前提下,用WHILE K

这个对不对

5.rar

19.34 KB, 下载次数: 3

回复

使用道具 举报

发表于 2017-5-1 18:16 | 显示全部楼层
K,X变量都给定值了,还有什么好看的。
你随便弄些数据验证下就明白了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-19 19:19 , Processed in 0.419611 second(s), 17 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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