ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 求一个可以用来随机抽取人名的VBA

[复制链接]

TA的精华主题

TA的得分主题

发表于 2008-12-2 10:06 | 显示全部楼层
很好用啊

TA的精华主题

TA的得分主题

发表于 2010-2-4 21:56 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-3-5 18:11 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
看看,我也需要一个啊

TA的精华主题

TA的得分主题

发表于 2014-3-5 19:25 | 显示全部楼层
ericfei 发表于 2008-11-26 15:35
Have a try

出错。溢出的?

Test.rar

278.32 KB, 下载次数: 24

TA的精华主题

TA的得分主题

发表于 2014-3-6 12:35 | 显示全部楼层
本帖最后由 香川群子 于 2014-3-6 12:37 编辑
ericfei 发表于 2008-11-26 15:35
Have a try


4楼楼主写的代码很不好。请认真学习,彻底放弃这个思路。

代码在随机取值过程中【非常不必要地】使用了【递归方法】,
且递归方法在数据量大时容易产生重复的随机值(每次随机取值范围都是整个范围,没有排除重复值)
因此,重复时递归【只有进、没有来得及出】,当重复次数过多时必然导致【堆栈溢出】的错误。


…………
请看我的附件:


简单几句代码就足够了!

Sub GetRnd()
    Dim arr, i&, m&, n&, r&, t
    [b2:b65536] = ""
    m = [a1].End(4).Row - 1: arr = [a2].Resize(m)
    n = Int(Val(InputBox("How many ?", "Get Rand", 238)))
    If n < 1 Or n > m Then MsgBox "HeadCounts is not correct.": Exit Sub
   
    Randomize
    For i = 1 To n
        r = Int((m - i + 1) * Rnd) + i
        t = arr(r, 1): arr(r, 1) = arr(i, 1): arr(i, 1) = t
    Next
   
    [b2].Resize(n) = arr
End Sub

核心代码就蓝色几句……【经典数组洗牌算法】即可得到随机不重复乱序结果。

RandTest.rar (61.47 KB, 下载次数: 195)





TA的精华主题

TA的得分主题

发表于 2014-3-6 12:41 | 显示全部楼层
ericfei 发表于 2008-11-26 16:30
现在有重复的???程序里已经考虑到不重复这个问题了

随机不重复部分使用【经典数组洗牌算法】非常简洁:

  For i = 1 To n
        r = Int((m - i + 1) * Rnd) + i
        t = arr(r, 1): arr(r, 1) = arr(i, 1): arr(i, 1) = t
    Next

   代码算法解释:

  For i = 1 To n  '循环遍历抽取n个不重复值

        r = Int((m - i + 1) * Rnd) + i  '从剩余m-i+1个数中获取随机数。
                                                     '由于此范围是变动的,可保证不重复。

        t = arr(r, 1)               '随机抽到的r位置值存入临时变量t
        arr(r, 1) = arr(i, 1)     '当前第 i 个值写入r位置(本次随机值)
                                         ' →  这个过程不仅避免遗漏、和重复,还能顺便打乱顺序,效率非常之高。
        arr(i, 1) = t                '临时变量t中存放的r位置随机值,写入当前 i位置 完成交换。

    Next


详细解释抽取过程中剩余数和位置区间关系:
  
标题:   i 值   剩余个数  随机抽取范围  已排除区间
计算:     i          m-i+1        [i ,   m]             [0, i-1]
             1           m             [1,  m]              [0, 0]
             2          m - 1         [2,  m]              [0, 1]
             3          m - 2         [3,  m]              [0, 2]
             4          m - 3         [4,  m]              [0, 3]
            …………
            m-2        3           [m-2, m]              [0, m-3]
            m-1        2           [m-1, m]              [0, m-2]
             m          1            [ m , m]              [0,  m-1]


这样就明白了吧!

新增附件改为对矩形区域中数据进行随机抽取:
RandTest2.rar (11.53 KB, 下载次数: 284)


规则如下:
① 从A1开始的多列区域为源数据,第1行为列标题,允许各列数据个数(行数)不等 (即部分含有空白单元格)
② 需要抽取个数n 由对话框输入数值后(自动Int取整),但不得大于元素总个数m,也不能<1
③ 输出结果仍按同样列数……但行数会根据n大小自动决定
④ 输出结果为源数据区域间隔1列开始,第1行留空


评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-3-6 12:46 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-10-10 16:02 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
很好用,谢谢

TA的精华主题

TA的得分主题

发表于 2015-3-15 18:52 | 显示全部楼层
ericfei 发表于 2008-11-26 15:35
Have a try

正是我想要的谢谢

TA的精华主题

TA的得分主题

发表于 2015-9-17 09:51 | 显示全部楼层
香川群子

思路很清晰,赞一个
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

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

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

GMT+8, 2024-4-26 12:26 , Processed in 0.048497 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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