ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E问E答 > Excel VBA > 如何通过配码比例和总和来求得所有配码?

如何通过配码比例和总和来求得所有配码?

作者:绿色风 分类: 时间:2022-08-17 浏览:138
楼主
liuguansky
Q:如何通过配码比例和总和来求得所有配码?

效果如下图:

A:用如下代码可以实现:
  1. Sub justtest()
  2.     Dim arr, i%, arrt(), s%, k%, dic As New dictionary'定义变量,定义字典对象,需在VBE下工具-引用-mscripting.runtime
  3.     Dim dic1 As New dictionary, d, m%, n%, j As Boolean
  4.     If Application.Sum([b3:h3]) = 1 Then'判断比例和是否为1,如果为1,则进行下面的判断。
  5.         arr = [b3:h3*12]'获取初始比例与和值12的乘积,赋值给数组。
  6.         For i = 1 To 7'在数组中循环
  7.             If Int(arr(i)) = arr(i) Then
  8.                 s = arr(i) + s'如果为整,则累加
  9.                 Else: dic.Add i, Int(arr(i)): s = s + Int(arr(i))'不为整,则添加字典项目,同时累加整数部分。为后续服务
  10.             End If
  11.         Next i
  12.         k = Application.WorksheetFunction.Combin(dic.Count, 12 - s)'返回所有组合数。
  13. '组合思路:DIC.COUNT代表非整数的个数,12-S代表可以分配的个数。就是把12-S个数分配到DIC.COUNT个地方,所以个数为Combin(dic.Count, 12 - s)
  14.         Cells(8, 1) = "订货配码": Range("b8:h" & Rows.Count).Clear'清空配码返回区域,方便返回,清除干扰。
  15.         If k = 1 Then'如果只有一种配码方式,则全是整数,
  16.             Cells(8, 2).Resize(1, 7) = arr'直接返回之前赋值整数数组即可。
  17.             MsgBox "共1种方案,见区域" & Cells(8, 2).Resize(1, 7).Address(0, 0)'友好提示配码的方案数,与返回配码的对应区域。
  18.             Else:如果不只一种方案,则:
  19.             Do Until m = k'循环到,出现K种方案为止。
  20.                 str1 = ""
  21.                 For Each d In dic.keys'这里用随机数方式来生成K种方案。
  22.                     j = Rnd() >= 0.5'把随机判断赋值给一个BOOLEAN类型的变量
  23.                     If j Then arr(d) = dic(d) Else arr(d) = dic(d) + 1'如果J真,则取整,如果假,则取整+1
  24.                     str1 = str1 & arr(d)同时把相应的值进行组合,用于判断是否重复。
  25.                 Next d
  26.                 If Application.Sum(arr) = 12 Then'当和值达到12,才是满足的配码方式:
  27.                     If Not dic1.exists(str1) Then dic1.Add str1, arr: m = m + 1'如果字典项目中不存在,则说明为新的配码方式,于是添加项目,同时对ITEM赋值满足条件的数组。并且计数加1,此计数再与总配码方式K相比例,当随机循环达到K值时,即停止循环
  28.                 End If
  29.             Loop
  30.             ReDim arrt(1 To k, 1 To 7)'重定义数组,用于返回目标配码方案
  31.             For i = 1 To k
  32.                 For m = 1 To 7
  33.                     arrt(i, m) = dic1.Items(i - 1)(m)'数组对数组赋值,用循环实现 。
  34.             Next m, i
  35.             Cells(8, 2).Resize(k, 7) = arrt'对配码返回区域赋值。
  36.             MsgBox "共" & k & "种方案,见区域" & Cells(8, 2).Resize(k, 7).Address(0, 0)'友好提示方案种数,并提示配码方案返回区域。
  37.         End If
  38.         Else: MsgBox "请确认输入的销售比例是否正确!"'不为1,则友好提示重新录入销售比例。
  39.     End If
  40. End Sub
具体示例文件如下:
2楼
xmyjk
花花字典高手,学习个。
3楼
kangguowei
学习.

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap