ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 根据行列数据出现个数组合数据

[复制链接]

TA的精华主题

TA的得分主题

发表于 2021-3-8 22:07 | 显示全部楼层 |阅读模式
本帖最后由 三票 于 2021-3-9 16:01 编辑

根据行列数据出现个数组合数据

上示例中,交叉出的结果。在组合中行、列出几个数在组合结果中就出现几个,在同一组合结果中只要有数据出现的行列中的数据按出现个数同时组合出现
QQ图片20210309155258.png

根据行列数据出现个数组合数据(3).zip

10.57 KB, 下载次数: 33

TA的精华主题

TA的得分主题

发表于 2021-3-9 23:57 | 显示全部楼层
本帖最后由 DevilW 于 2021-3-10 11:51 编辑
  1. Sub test()
  2.     Dim br(1 To 10000, 1 To 6), ar
  3.     Set d = CreateObject("Scripting.Dictionary")
  4.     r = Join(Application.Transpose([d3:d8]), "") '行规则
  5.     c = Join(Application.Transpose(Application.Transpose([e2:j2])), "") '列规则
  6.     ReDim ar(Application.Count([e3:j8]))
  7.     For Each a In [e3:j8] '取有效数据
  8.         If a <> "" Then n = n + 1: ar(n) = a
  9.     Next
  10.     For s1 = 1 To n - 5
  11.         For s2 = s1 + 1 To n - 4
  12.             For s3 = s2 + 1 To n - 3
  13.                 For s4 = s3 + 1 To n - 2
  14.                     For s5 = s4 + 1 To n - 1
  15.                         For s6 = s5 + 1 To n
  16.                             s = Array(0, ar(s1), ar(s2), ar(s3), ar(s4), ar(s5), ar(s6)) '取得组合
  17.                             For i = 1 To 6
  18.                                 rx = s(i) / 6: cx = s(i) Mod 6
  19.                                 If rx = Int(rx) Then ry = rx Else ry = Int(rx) + 1 '取每数行信息
  20.                                 If cx Mod 6 Then cy = cx Mod 6 Else cy = 6 '取每数列信息
  21.                                 d(ry) = d(ry) + 1: d(cy + 6) = d(cy + 6) + 1 '字典记录行列信息
  22.                             Next
  23.                             For i = 1 To 6
  24.                                 rs = rs & Val(d(i)): cs = cs & Val(d(i + 6)) '行列信息排列
  25.                             Next
  26.                             d.RemoveAll
  27.                             If r = rs And c = cs Then '行列规则与行列信息相比较
  28.                                 x = x + 1
  29.                                 For i = 1 To 6
  30.                                     br(x, i) = s(i)
  31.                                 Next
  32.                             End If
  33.                             rs = "": cs = ""
  34.     Next s6, s5, s4, s3, s2, s1
  35.     [l17].Resize(x, 6) = br
  36. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2021-3-10 00:01 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-3-10 08:35 | 显示全部楼层
本帖最后由 三票 于 2021-3-10 08:57 编辑
DevilW 发表于 2021-3-10 00:01
代码审核,先放图

非常感谢您的帮助!!期待您上传附件

TA的精华主题

TA的得分主题

发表于 2021-3-16 13:55 | 显示全部楼层
有难度,如果数字位数也变的话,更加麻烦

TA的精华主题

TA的得分主题

发表于 2021-3-17 14:32 | 显示全部楼层
'6个数共有240个组合,[e2:j2]和数为6,按条件只能组合为6个数,,,

Option Explicit

Sub test()
  Dim arr, brr, i, j, k, m, n, cnt, s
  arr = [d2:j8].Value
  ReDim brr(1 To UBound(arr, 1), 1 To UBound(arr, 2)), pos(1 To 3, 1 To UBound(arr, 2))
  For j = 2 To UBound(arr, 2)
    If arr(1, j) > 0 Then
      m = 0: n = n + 1
      For i = 2 To UBound(arr, 1)
        If arr(i, 1) > 0 And Len(arr(i, j)) > 0 Then
          m = m + 1
          brr(m, n) = arr(i, j)
        End If
      Next
      pos(1, n) = arr(1, j): pos(2, n) = m
    End If
  Next
  ReDim arr(1 To 10 ^ 3, 1 To n)
  cnt = 1
  For i = 1 To n
    m = 0
    Call comb(brr, arr, i, pos(1, i), pos(2, i), m)
    pos(1, i) = m: pos(2, i) = 1: cnt = cnt * m
  Next
  ReDim brr(1 To cnt, 1 To 1) As String
  For i = 1 To UBound(brr, 1)
    For j = 1 To n
      s = s & arr(pos(2, j), j)
    Next
    brr(i, 1) = Mid(s, 2): s = vbNullString
    If pos(2, n) < pos(1, n) Then
      pos(2, n) = pos(2, n) + 1
    Else
      For j = n - 1 To 1 Step -1
        If pos(2, j) < pos(1, j) Then
          pos(2, j) = pos(2, j) + 1
          For k = j + 1 To n
            pos(2, k) = 1
          Next
          Exit For
        End If
      Next
    End If
  Next
  [s3].Resize(UBound(brr, 1)) = brr
End Sub

Function comb(arr, brr, p, a, b, m)
  Dim i, j, n
  ReDim crr(1 To UBound(brr, 1), 1 To 2)
  crr(2, 1) = "," & arr(1, p)
  crr(2, 2) = 1: n = 2
  If crr(2, 2) = a Then m = m + 1: brr(m, p) = "," & arr(1, p)
  For i = 2 To b
    For j = n + 1 To 2 * n
      crr(j, 1) = crr(j - n, 1) & "," & arr(i, p)
      crr(j, 2) = crr(j - n, 2) + 1
      If crr(j, 2) = a Then
        m = m + 1: brr(m, p) = crr(j, 1)
      End If
    Next
    n = n * 2
  Next
End Function

TA的精华主题

TA的得分主题

发表于 2021-3-17 15:40 | 显示全部楼层
'你这还有行限定,加了个字典处理了一下,输出结果确实为12个,,,

Option Explicit

Sub test()
  Dim arr, brr, i, j, k, m, n, cnt, s, t, dic, key, flag As Boolean
  Set dic = CreateObject("scripting.dictionary")
  arr = [d2:j8].Value
  ReDim brr(1 To UBound(arr, 1), 1 To UBound(arr, 2)), pos(1 To 3, 1 To UBound(arr, 2))
  For j = 2 To UBound(arr, 2)
    If arr(1, j) > 0 Then
      m = 0: n = n + 1
      For i = 2 To UBound(arr, 1)
        If arr(i, 1) > 0 And Len(arr(i, j)) > 0 Then
          m = m + 1
          brr(m, n) = arr(i, j)
        End If
      Next
      pos(1, n) = arr(1, j): pos(2, n) = m
    End If
  Next
  For i = 2 To UBound(arr, 1)
    If arr(i, 1) > 0 Then
      For j = 2 To UBound(arr, 2)
        If arr(1, j) > 0 Then
          s = s & "," & arr(i, j)
        End If
      Next
      dic(s) = arr(i, 1): s = vbNullString
    End If
  Next
  ReDim arr(1 To 10 ^ 3, 1 To n)
  cnt = 1
  For i = 1 To n
    m = 0
    Call comb(brr, arr, i, pos(1, i), pos(2, i), m)
    pos(1, i) = m: pos(2, i) = 1: cnt = cnt * m
  Next
  ReDim brr(1 To cnt, 1 To 1) As String
  cnt = 0
  For i = 1 To UBound(brr, 1)
    For j = 1 To n
      s = s & arr(pos(2, j), j)
    Next
    s = s & ",": flag = True
    For Each key In dic.keys
      t = Split(key, ","): m = 0
      For j = 1 To UBound(t)
        If InStr(s, "," & t(j) & ",") Then m = m + 1
        If m > dic(key) Then Exit For
      Next
      If m <> dic(key) Then flag = False: Exit For
    Next
    If flag Then
      cnt = cnt + 1
      brr(cnt, 1) = Mid(s, 2)
    End If
    s = vbNullString
    If pos(2, n) < pos(1, n) Then
      pos(2, n) = pos(2, n) + 1
    Else
      For j = n - 1 To 1 Step -1
        If pos(2, j) < pos(1, j) Then
          pos(2, j) = pos(2, j) + 1
          For k = j + 1 To n
            pos(2, k) = 1
          Next
          Exit For
        End If
      Next
    End If
  Next
  With [s3]
    .Resize(UBound(brr, 1)).ClearContents
    If cnt > 0 Then .Resize(cnt) = brr
  End With
End Sub

Function comb(arr, brr, p, a, b, m)
  Dim i, j, n
  ReDim crr(1 To UBound(brr, 1), 1 To 2)
  crr(2, 1) = "," & arr(1, p)
  crr(2, 2) = 1: n = 2
  If crr(2, 2) = a Then m = m + 1: brr(m, p) = "," & arr(1, p)
  For i = 2 To b
    For j = n + 1 To 2 * n
      crr(j, 1) = crr(j - n, 1) & "," & arr(i, p)
      crr(j, 2) = crr(j - n, 2) + 1
      If crr(j, 2) = a Then
        m = m + 1: brr(m, p) = crr(j, 1)
      End If
    Next
    n = n * 2
  Next
End Function

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-4-22 12:38 | 显示全部楼层
一把小刀闯天下 发表于 2021-3-17 15:40
'你这还有行限定,加了个字典处理了一下,输出结果确实为12个,,,

Option Explicit

老师您好,您看一下这个问题能解决吗?

根据行列数据出现个数组合数据(3).zip

28.56 KB, 下载次数: 3

TA的精华主题

TA的得分主题

发表于 2021-4-22 13:04 | 显示全部楼层
三票 发表于 2021-4-22 12:38
老师您好,您看一下这个问题能解决吗?

天书系列,看看有没有神仙飘过的,,,
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

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

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

GMT+8, 2024-4-24 05:38 , Processed in 0.036393 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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