ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 随机数据生成工具

[复制链接]

TA的精华主题

TA的得分主题

发表于 2022-11-9 20:08 | 显示全部楼层 |阅读模式
【需求】

    人员min已有多个数据总值,现在需要根据已有的值将其随机拆分至不同的产品/部门/品牌等维度,数据值类型可能包含小数点/文本/负数/整数。
【分析】
    1.如果直接用随机区间去截取数据会产生一个问题,即随机的数据产生会集中在前面的几列,而后续的列的值基本全部变为0,有自己写过的人有亲身体会。所以为了解决这个问题,需要根据拆分的组数对每个随机数的上限进行二次约束。
    2.负数进行随机拆解的问题,如果用randbettwen方法需要注意传入的参数始终保持左小又大;
    3.小数点的问题,可以先对它进行放大后再操作
    4.解决分组数量动态变化的问题,起一个参数表,读取后作为分组数量即可
【代码】
    1.主程序
Sub genRandomNum()
    t_1 = Timer
    arr = Sheets("随机分配").[a1].CurrentRegion
    ars = Sheets("参数设置").[a1].CurrentRegion
    If UBound(arr, 2) > 1 Then
        Sheets("随机分配").Range(Sheets("随机分配").Cells(1, 2), Sheets("随机分配").Cells(UBound(arr), UBound(arr, 2))).ClearContents
    End If
    '解决生成的随机数主要集中在前面的几个维度的问题
    If UBound(ars) <= 3 Then
        k = 1
    Else
        If UBound(ars) <= 6 Then
            k = 0.4
        Else
            k = 2 / (UBound(ars) - 2)
        End If
    End If
    Dim rData
    ReDim rData(1 To UBound(arr), 1 To UBound(ars) - 1)
    For j = 2 To UBound(ars)
        rData(1, j - 1) = ars(j, 1)
    Next j
    For i = 2 To UBound(arr)
        If IsNumeric(arr(i, 1)) = True Then
            If arr(i, 1) = 0 Then
                For j = 2 To UBound(ars)
                    rData(i, j - 1) = 0
                Next j
            Else
                If arr(i, 1) > 0 Then
                    syn = 1
                Else
                    arr(i, 1) = -arr(i, 1)
                    syn = -1
                End If
                rateVal = 10 ^ handleDigitalNum(arr(i, 1))
                arr(i, 1) = arr(i, 1) * rateVal
                t = arr(i, 1)
                m = 0
                For j = 2 To UBound(ars) - 1
                    rData(i, j - 1) = arr(i, 1)
                    While rData(i, j - 1) / arr(i, 1) > k
                        rData(i, j - 1) = WorksheetFunction.RandBetween(0, arr(i, 1) - m)
                    Wend
                    m = m + rData(i, j - 1)
                    t = t - m
                Next j
                rData(i, UBound(ars) - 1) = (arr(i, 1) - m)
                For j = 2 To UBound(ars)
                    rData(i, j - 1) = rData(i, j - 1) * syn / rateVal
                Next j
            End If
        On Error Resume Next
        End If
    Next i
    Sheets("随机分配").Cells(1, 2).Resize(UBound(arr), UBound(ars) - 1) = rData
    t_2 = Timer
    MsgBox "运行成功!RunTime:" & Round(t_2 - t_1, 2) & "s." & vbCrLf & "Program Designed By Apollo_Chen On 2022/10/29." & vbCrLf & "For MinMinMin Only!", vbOKOnly, "Lovely.Min"
End Sub

    2.处理小数点的函数

Function handleDigitalNum(num)  '解决小数点的问题
    If InStr(1, Str(num), ".") > 0 Then
        arrNum = Split(Str(num), ".")
        n = Len(arrNum(1))
    Else
    n = 0
    End If
    handleDigitalNum = n
End Function


【运行结果示例】

示例

示例

随机数据分配.zip

60.41 KB, 下载次数: 36

应用程序

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2022-11-9 21:23 | 显示全部楼层
不错。这种可以用规划求解来做的。相对来说简单,录制个宏就行。

TA的精华主题

TA的得分主题

发表于 2022-11-9 23:00 | 显示全部楼层
看了眼花缭乱的,功能是把一个数字拆为10个随机数字,使得和值为源数字吧?为什么直接随机会集中在前面,那是什么写法。   最容易理解的逻辑不是直接随机10个数然后插值法换算一下吗

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-11-10 01:20 | 显示全部楼层
micch 发表于 2022-11-9 23:00
看了眼花缭乱的,功能是把一个数字拆为10个随机数字,使得和值为源数字吧?为什么直接随机会集中在前面,那 ...

整数型数据要求分解为整数,线性插值解决的了?

TA的精华主题

TA的得分主题

发表于 2022-11-10 10:44 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-11-10 13:25 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
既是隨機,
以55分配10個, 有無可能第一個就是46, 剩下的都只能分配1


TA的精华主题

TA的得分主题

 楼主| 发表于 2022-11-10 14:00 | 显示全部楼层
准提部林 发表于 2022-11-10 13:25
既是隨機,
以55分配10個, 有無可能第一個就是46, 剩下的都只能分配1

也可以9和8个0哈

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-11-10 14:01 | 显示全部楼层

我知道公式可以解决,我这个程序是设计给别人用的,不是每次都分成10组,所以要综合考虑批量和动态的问题

TA的精华主题

TA的得分主题

发表于 2022-11-10 15:32 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
阿光IsGodLike 发表于 2022-11-10 14:01
我知道公式可以解决,我这个程序是设计给别人用的,不是每次都分成10组,所以要综合考虑批量和动态的问题 ...

公式演示是对3楼、4楼的回复

TA的精华主题

TA的得分主题

发表于 2022-11-10 16:11 | 显示全部楼层
這兩個參數, 可用一行即可
小數點位數 V=LEN(SPLIT(數字 & ".", ".")(1))
正負值 P=1+(數字<0)*2....或用IIF

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

本版积分规则

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

GMT+8, 2024-5-1 23:48 , Processed in 0.044242 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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