ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 【已完美解决】根据多种条件,生成随机不重复数

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-4-14 11:19 | 显示全部楼层 |阅读模式
本帖最后由 LMY123 于 2013-4-14 13:22 编辑

捕获.PNG

根据A2到D2的条件,在A3到c62这个区域生成50-100范围内的不重复随机数,保留两位小数.rar (8.24 KB, 下载次数: 188)

TA的精华主题

TA的得分主题

发表于 2013-4-14 12:00 | 显示全部楼层
  1. Sub text()
  2.     Dim arr() As Single                          '定义数组
  3.     Dim min As Integer                            '定义随机数的最小值
  4.     Dim max As Integer                            '定义随机数的最大值
  5.     Dim flag As Boolean                           '定义标志变量,用来判断是否有重复值
  6.     Dim rng As Range
  7.     Dim n As Integer
  8.     n = Val(Range("c2"))
  9.     max = Val(Range("b2"))                     '将b2单元格的数值赋值给最大值
  10.     min = Val(Range("a2"))                      '将a2单元格的数值赋值给最小值
  11.     ReDim arr(n)                  '更改数组大小
  12.     For I = 0 To n                '循环生成随机数
  13.         Do
  14.             arr(I) = Rnd() * (max - min) + min    '生成随机数
  15.             flag = False
  16.             For j = 0 To (I - 1)                  '循环判断当前的随机数是否和前面生成的随机数相同,如果相同就重新生成
  17.                 If (arr(I) = arr(j)) Then
  18.                     flag = True
  19.                 End If
  20.             Next
  21.         Loop While flag
  22.     Next
  23.     t = 0
  24.     For Each rng In [a3:c42]
  25.         rng = Format(arr(t), "0.00")
  26.         t = t + 1
  27.     Next
  28. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2013-4-14 12:01 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-4-14 12:24 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
lzyamo3057 发表于 2013-4-14 12:01
大概这个意思吧,修改修改下。。

多谢大师指导,我仔细研究一下

TA的精华主题

TA的得分主题

发表于 2013-4-14 12:54 | 显示全部楼层
本帖最后由 香川群子 于 2013-4-14 13:05 编辑

功能比楼主要求更复杂的随机取数代码:

功能介绍:
1、2. 指定数值区间 a to b
备注:
     a或b 也可以是负数 (直接写成负数即可)
     a或b 也可以是小数 (当指定小数数位d时)
      
3. 指定取数个数m

4. 指定小数位数 d=2

   或者 指定d=0时,返回整数
   或者 指定d=负数时,可向上取整数(和=Round()函数一样的用法)
   比如 d=-2时,返回 100/400/2300/10300……类似这样的数据。

5. 增加了指定最小间隔的参数h
这个参数的作用是这样的:
h=1时,可以保证抽取的结果不会重复。
h=0时,可以让抽取结果产生随机重复。
h>0时,可以保证抽取结果之间的最小间隔>=h
  → 这个功能很强大!

6. 自动计算取值区间内的不重复数据个数
(这个用工作表函数就能计算得到结果。注意初值需要+1处理)

7. 输出结果可以指定列数l

如果列数l=1,则可纵向按行输出到1列
如果列数=m (取值个数),则可横向输出为一行。


8. 输出顺序参数r
默认r=0时,使用经典数组洗牌法乱序后输出结果。
如果r=1(或其它值)时,将按从小到大顺序输出结果。


随机取数.rar (8.95 KB, 下载次数: 423)


评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-4-14 13:00 | 显示全部楼层
香川群子 发表于 2013-4-14 12:54
功能比楼主要求更复杂的随机取数代码:

功能介绍:

多谢大师指导,确实太强大了

TA的精华主题

TA的得分主题

发表于 2013-4-14 13:03 | 显示全部楼层
补充:如果设定【取值个数】超过数据区间【不重复个数】时:
1. 如果设定了最小间隔=0,那么将会抽取到重复值直至满足取值个数。
2. 如果设定最小间隔>0 (包括h=1时),则会抽取所有不重复值以后,再以0值代替空余的输出位置。最后乱序输出结果。


附代码:
  1. Sub kagawa() '指定区间内 均匀随机取不重复值 按指定列数输出
  2.     Randomize
  3.     d = [d2]: a = [a2] * 10 ^ d: b = [b2] * 10 ^ d
  4.     m = [c2]: h = [e2]: l = [g2]: r = [h2]
  5.    
  6.     ReDim c(m - 1)
  7.     If b - a < m * h Then c(0) = a Else c(0) = Int(((b - a + 1) / m - h) * Rnd()) + a
  8.     n = 0
  9.     Do
  10.         If b - c(n) < (m - n) * h Then
  11.             If c(n) + h <= b Then
  12.                 c(n + 1) = c(n) + h
  13.             Else
  14.                 GoTo Ext
  15.             End If
  16.         Else
  17.             c(n + 1) = c(n) + Int(((b - c(n) + 1) / (m - n) - h) * Rnd() * 2) + h
  18.         End If
  19.         n = n + 1
  20.     Loop Until n = m - 2
  21.     c(m - 1) = c(n) + Int((b - c(n) + 1 - h) * Rnd()) + h
  22. Ext:
  23.     ReDim f(m \ l, l - 1)
  24.     If r = 0 Then
  25.         For i = 0 To m - 1
  26.             r = Int((m - i) * Rnd()) + i
  27.             t = c(r): c(r) = c(i): c(i) = c(r)
  28.             f(i \ l, i Mod l) = t / 10 ^ d
  29.         Next
  30.     Else
  31.         For i = 0 To m - 1
  32.             f(i \ l, i Mod l) = c(i) / 10 ^ d
  33.         Next
  34.     End If
  35.     [a4].CurrentRegion.Offset(1) = ""
  36.     [a5].Resize(m \ l + 1, l) = f
  37.    
  38. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2013-4-14 13:08 | 显示全部楼层
LMY123 发表于 2013-4-14 13:00
多谢大师指导,确实太强大了

呵呵,我不谦虚地说,这个是目前论坛里最好的随机取值实际应用代码。


算法我就不介绍了。

有兴趣的话自己好好研究一下。





TA的精华主题

TA的得分主题

发表于 2013-4-14 13:10 | 显示全部楼层
LMY123 发表于 2013-4-14 12:24
多谢大师指导,我仔细研究一下

他这个代码很容易理解……应该也够你用了。

不过反复进行检查来排除重复,从算法效率上来看是不及格的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-4-14 13:11 | 显示全部楼层
香川群子 发表于 2013-4-14 13:03
补充:如果设定【取值个数】超过数据区间【不重复个数】时:
1. 如果设定了最小间隔=0,那么将会抽取到重复 ...

多谢大师再次指导,慢慢消化学习中
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-18 11:19 , Processed in 0.058894 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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