Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 1771|回复: 8

[已解决]求助用VBA组合相同数

[复制链接]
发表于 2013-1-27 09:55 | 显示全部楼层 |阅读模式
相同数.rar (6.96 KB, 下载次数: 27)
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
发表于 2013-1-27 11:02 | 显示全部楼层
  1. Option Explicit

  2. Sub 组合数()
  3.     Dim arr
  4.     Dim arr2()
  5.     Dim arr3(1 To 3)
  6.     Dim dic As Object
  7.     Dim i&, j&, k&, x, y, z
  8.     Dim check As Boolean
  9.    
  10.     arr = Range("c1").CurrentRegion
  11.     Set dic = CreateObject("scripting.dictionary")
  12.     For i = LBound(arr) + 1 To UBound(arr) Step 2
  13.         For j = LBound(arr, 2) To UBound(arr, 2)
  14.             Call splitnumber(arr(i, j), dic)
  15.             Call splitnumber(arr(i + 1, j), dic)
  16.             Call Anydic(dic)
  17.             If dic.Count = 0 Then check = False: dic.RemoveAll: Exit For
  18.             arr3(j) = dic.keys
  19.             check = True
  20.             dic.RemoveAll
  21.         Next
  22.         If check Then
  23.             For Each x In arr3(1)
  24.                 For Each y In arr3(2)
  25.                     For Each z In arr3(3)
  26.                         k = k + 1
  27.                         ReDim Preserve arr2(1 To k)
  28.                         arr2(k) = x * 100 + y * 10 + z
  29.                     Next
  30.                 Next
  31.             Next
  32.         End If
  33.     Next
  34.     Columns("m").Clear
  35.     Range("m1").Resize(k) = WorksheetFunction.Transpose(arr2)
  36.     Set dic = Nothing
  37.     MsgBox "提取完成"
  38. End Sub

  39. Sub splitnumber(ByVal number, ByRef dic As Object)
  40.     Dim i, s$
  41.     For i = 1 To Len(number)
  42.         s = Mid(number, i, 1)
  43.         dic(s) = dic(s) + 1
  44.     Next
  45. End Sub

  46. Sub Anydic(ByRef dic As Object)
  47.     Dim key
  48.     For Each key In dic.keys
  49.         If dic(key) = 1 Then dic.Remove key
  50.     Next
  51. End Sub
复制代码
回复

使用道具 举报

发表于 2013-1-27 11:09 | 显示全部楼层
  1. Option Explicit

  2. Sub 组合数()
  3. '---------------------------------------------------------------------------------------
  4. ' Procedure : 组合数
  5. ' Author    : hwc2ycy
  6. ' Date      : 2013/1/27
  7. ' Purpose   :
  8. '---------------------------------------------------------------------------------------
  9. '
  10.     Dim arr
  11.     Dim arr2()
  12.     Dim arr3(1 To 3)
  13.     Dim dic As Object
  14.     Dim i&, j&, k&, x, y, z
  15.     Dim Check As Boolean

  16.     '读数据到字典,因为用的是区域法,所以要确保在数字区域
  17.     '无其他内容
  18.     arr = Range("c1").CurrentRegion
  19.     '字典
  20.     Set dic = CreateObject("scripting.dictionary")
  21.     '遍历数组,2行一次
  22.     For i = LBound(arr) + 1 To UBound(arr) Step 2
  23.         For j = LBound(arr, 2) To UBound(arr, 2)
  24.             Call splitnumber(arr(i, j), dic)
  25.             Call splitnumber(arr(i + 1, j), dic)
  26.             Call AnyDic(dic)
  27.             '如果没有共同数据,则结束本轮循环,字典清空
  28.             If dic.Count = 0 Then Check = False: dic.RemoveAll: Exit For
  29.             arr3(j) = dic.keys
  30.             '能否进行组合的前提条件
  31.             Check = True
  32.             dic.RemoveAll
  33.         Next
  34.         If Check Then
  35.             '遍历,生成组合,x,y,z分别代表百,拾,个位
  36.             For Each x In arr3(1)
  37.                 For Each y In arr3(2)
  38.                     For Each z In arr3(3)
  39.                         '动态数组
  40.                         k = k + 1
  41.                         ReDim Preserve arr2(1 To k)
  42.                         arr2(k) = x * 100 + y * 10 + z
  43.                     Next
  44.                 Next
  45.             Next
  46.         End If
  47.     Next
  48.     Columns("m").Clear
  49.     '一维变二维,写回M列
  50.     Range("m1").Resize(k) = WorksheetFunction.Transpose(arr2)
  51.     Set dic = Nothing
  52.     MsgBox "提取完成"
  53. End Sub

  54. Sub splitnumber(ByVal number, ByRef dic As Object)
  55. '---------------------------------------------------------------------------------------
  56. ' Procedure : splitnumber
  57. ' Author    : hwc2ycy
  58. ' Date      : 2013/1/27
  59. ' Purpose   :把数字拆分装进字典
  60. '---------------------------------------------------------------------------------------
  61. '
  62.     Dim i, s$
  63.     For i = 1 To Len(number)
  64.         s = Mid(number, i, 1)
  65.         dic(s) = dic(s) + 1
  66.     Next
  67. End Sub

  68. Sub AnyDic(ByRef dic As Object)
  69. '---------------------------------------------------------------------------------------
  70. ' Procedure : AnyDic
  71. ' Author    : hwc2ycy
  72. ' Date      : 2013/1/27
  73. ' Purpose   :分析字典,去掉没有重复数的
  74. '---------------------------------------------------------------------------------------
  75. '
  76.     Dim key
  77.     For Each key In dic.keys
  78.         If dic(key) = 1 Then dic.Remove key
  79.     Next
  80. End Sub
复制代码
回复

使用道具 举报

发表于 2013-1-27 11:16 | 显示全部楼层
增加对非数字字符的判断,以免出错。
  1. Option Explicit

  2. Sub 组合数()
  3. '---------------------------------------------------------------------------------------
  4. ' Procedure : 组合数
  5. ' Author    : hwc2ycy
  6. ' Date      : 2013/1/27
  7. ' Purpose   :字典与数组的应用
  8. '---------------------------------------------------------------------------------------
  9. '
  10.     Dim arr
  11.     Dim arr2()
  12.     Dim arr3(1 To 3)
  13.     Dim dic As Object
  14.     Dim i&, j&, k&, x, y, z
  15.     Dim Check As Boolean

  16.     '读数据到字典,因为用的是区域法,所以要确保在数字区域
  17.     '无其他内容
  18.     arr = Range("c1").CurrentRegion
  19.     '字典
  20.     Set dic = CreateObject("scripting.dictionary")
  21.     '遍历数组,2行一次
  22.     For i = LBound(arr) + 1 To UBound(arr) Step 2
  23.         For j = LBound(arr, 2) To UBound(arr, 2)
  24.             '如果数据为非数字(或者为0)的情况下,则跳出本轮循环
  25.             If Not (Val(arr(i, j)) > 0 And Val(arr(i + 1, j)) > 0) Then GoTo quit
  26.             Call splitnumber(arr(i, j), dic)
  27.             Call splitnumber(arr(i + 1, j), dic)
  28.             Call AnyDic(dic)

  29.             '如果没有共同数据,则结束本轮循环,字典清空
  30.             If dic.Count = 0 Then
  31. quit:
  32.                 Check = False
  33.                 dic.RemoveAll
  34.                 Exit For
  35.             End If

  36.             arr3(j) = dic.keys
  37.             '能否进行组合的前提条件
  38.             Check = True
  39.             dic.RemoveAll
  40.         Next
  41.         If Check Then
  42.             '遍历,生成组合,x,y,z分别代表百,拾,个位
  43.             For Each x In arr3(1)
  44.                 For Each y In arr3(2)
  45.                     For Each z In arr3(3)
  46.                         '动态数组
  47.                         k = k + 1
  48.                         ReDim Preserve arr2(1 To k)
  49.                         arr2(k) = x * 100 + y * 10 + z
  50.                     Next
  51.                 Next
  52.             Next
  53.         End If
  54.     Next
  55.     Columns("m").Clear
  56.     '一维变二维,写回M列
  57.     Range("m1").Resize(k) = WorksheetFunction.Transpose(arr2)
  58.     Set dic = Nothing
  59.     MsgBox "提取完成"
  60. End Sub

  61. Sub splitnumber(ByVal number, ByRef dic As Object)
  62. '---------------------------------------------------------------------------------------
  63. ' Procedure : splitnumber
  64. ' Author    : hwc2ycy
  65. ' Date      : 2013/1/27
  66. ' Purpose   :把数字拆分装进字典
  67. '---------------------------------------------------------------------------------------
  68. '
  69.     Dim i, s$
  70.     For i = 1 To Len(number)
  71.         s = Mid(number, i, 1)
  72.         dic(s) = dic(s) + 1
  73.     Next
  74. End Sub

  75. Sub AnyDic(ByRef dic As Object)
  76. '---------------------------------------------------------------------------------------
  77. ' Procedure : AnyDic
  78. ' Author    : hwc2ycy
  79. ' Date      : 2013/1/27
  80. ' Purpose   :分析字典,去掉没有重复数的
  81. '---------------------------------------------------------------------------------------
  82. '
  83.     Dim key
  84.     For Each key In dic.keys
  85.         If dic(key) = 1 Then dic.Remove key
  86.     Next
  87. End Sub
复制代码
回复

使用道具 举报

发表于 2013-1-27 11:20 | 显示全部楼层
再改进,避免没有生成组合数的情况下写入报错。
  1. Option Explicit

  2. Sub 组合数()
  3. '---------------------------------------------------------------------------------------
  4. ' Procedure : 组合数
  5. ' Author    : hwc2ycy
  6. ' Date      : 2013/1/27
  7. ' Purpose   :字典与数组的应用
  8. '---------------------------------------------------------------------------------------
  9. '
  10.     Dim arr
  11.     Dim arr2()
  12.     Dim arr3(1 To 3)
  13.     Dim dic As Object
  14.     Dim i&, j&, k&, x, y, z
  15.     Dim Check As Boolean

  16.     '读数据到字典,因为用的是区域法,所以要确保在数字区域
  17.     '无其他内容
  18.     arr = Range("c1").CurrentRegion
  19.     '字典
  20.     Set dic = CreateObject("scripting.dictionary")
  21.     '遍历数组,2行一次
  22.     For i = LBound(arr) + 1 To UBound(arr) Step 2
  23.         For j = LBound(arr, 2) To UBound(arr, 2)
  24.             '如果数据为非数字(或者为0)的情况下,则跳出本轮循环
  25.             If Not (Val(arr(i, j)) > 0 And Val(arr(i + 1, j)) > 0) Then GoTo quit
  26.             Call splitnumber(arr(i, j), dic)
  27.             Call splitnumber(arr(i + 1, j), dic)
  28.             Call AnyDic(dic)

  29.             '如果没有共同数据,则结束本轮循环,字典清空
  30.             If dic.Count = 0 Then
  31. quit:
  32.                 Check = False
  33.                 dic.RemoveAll
  34.                 Exit For
  35.             End If

  36.             arr3(j) = dic.keys
  37.             '能否进行组合的前提条件
  38.             Check = True
  39.             dic.RemoveAll
  40.         Next
  41.         If Check Then
  42.             '遍历,生成组合,x,y,z分别代表百,拾,个位
  43.             For Each x In arr3(1)
  44.                 For Each y In arr3(2)
  45.                     For Each z In arr3(3)
  46.                         '动态数组
  47.                         k = k + 1
  48.                         ReDim Preserve arr2(1 To k)
  49.                         arr2(k) = x * 100 + y * 10 + z
  50.                     Next
  51.                 Next
  52.             Next
  53.         End If
  54.     Next
  55.     If k > 0 Then
  56.         Columns("m").Clear
  57.         '一维变二维,写回M列
  58.         Range("m1").Resize(k) = WorksheetFunction.Transpose(arr2)
  59.         MsgBox "提取完成"
  60.     Else
  61.         MsgBox "数据中无相同数据,组合结果为0"
  62.     End If
  63.     Set dic = Nothing

  64. End Sub

  65. Sub splitnumber(ByVal number, ByRef dic As Object)
  66. '---------------------------------------------------------------------------------------
  67. ' Procedure : splitnumber
  68. ' Author    : hwc2ycy
  69. ' Date      : 2013/1/27
  70. ' Purpose   :把数字拆分装进字典
  71. '---------------------------------------------------------------------------------------
  72. '
  73.     Dim i, s$
  74.     For i = 1 To Len(number)
  75.         s = Mid(number, i, 1)
  76.         dic(s) = dic(s) + 1
  77.     Next
  78. End Sub

  79. Sub AnyDic(ByRef dic As Object)
  80. '---------------------------------------------------------------------------------------
  81. ' Procedure : AnyDic
  82. ' Author    : hwc2ycy
  83. ' Date      : 2013/1/27
  84. ' Purpose   :分析字典,去掉没有重复数的
  85. '---------------------------------------------------------------------------------------
  86. '
  87.     Dim key
  88.     For Each key In dic.keys
  89.         If dic(key) = 1 Then dic.Remove key
  90.     Next
  91. End Sub
复制代码
回复

使用道具 举报

发表于 2013-1-27 11:22 | 显示全部楼层    本楼为最佳答案   
本帖最后由 hwc2ycy 于 2013-1-27 11:23 编辑

对于百位为0,没有显示出来。
如果要显示出来在百位为0的情况,代码就用这个。
  1. Option Explicit

  2. Sub 组合数()
  3. '---------------------------------------------------------------------------------------
  4. ' Procedure : 组合数
  5. ' Author    : hwc2ycy
  6. ' Date      : 2013/1/27
  7. ' Purpose   :字典与数组的应用
  8. '---------------------------------------------------------------------------------------
  9. '
  10.     Dim arr
  11.     Dim arr2()
  12.     Dim arr3(1 To 3)
  13.     Dim dic As Object
  14.     Dim i&, j&, k&, x, y, z
  15.     Dim Check As Boolean

  16.     '读数据到字典,因为用的是区域法,所以要确保在数字区域
  17.     '无其他内容
  18.     arr = Range("c1").CurrentRegion
  19.     '字典
  20.     Set dic = CreateObject("scripting.dictionary")
  21.     '遍历数组,2行一次
  22.     For i = LBound(arr) + 1 To UBound(arr) Step 2
  23.         For j = LBound(arr, 2) To UBound(arr, 2)
  24.             '如果数据为非数字(或者为0)的情况下,则跳出本轮循环
  25.             If Not (Val(arr(i, j)) > 0 And Val(arr(i + 1, j)) > 0) Then GoTo quit
  26.             Call splitnumber(arr(i, j), dic)
  27.             Call splitnumber(arr(i + 1, j), dic)
  28.             Call AnyDic(dic)

  29.             '如果没有共同数据,则结束本轮循环,字典清空
  30.             If dic.Count = 0 Then
  31. quit:
  32.                 Check = False
  33.                 dic.RemoveAll
  34.                 Exit For
  35.             End If

  36.             arr3(j) = dic.keys
  37.             '能否进行组合的前提条件
  38.             Check = True
  39.             dic.RemoveAll
  40.         Next
  41.         If Check Then
  42.             '遍历,生成组合,x,y,z分别代表百,拾,个位
  43.             For Each x In arr3(1)
  44.                 For Each y In arr3(2)
  45.                     For Each z In arr3(3)
  46.                         '动态数组
  47.                         k = k + 1
  48.                         ReDim Preserve arr2(1 To k)
  49.                         arr2(k) = "'" & Format(x * 100 + y * 10 + z, "000")
  50.                     Next
  51.                 Next
  52.             Next
  53.         End If
  54.     Next
  55.     Columns("m").Clear
  56.     If k > 0 Then

  57.         '一维变二维,写回M列
  58.         Range("m1").Resize(k) = WorksheetFunction.Transpose(arr2)
  59.         MsgBox "提取完成"
  60.     Else
  61.         MsgBox "数据中无相同数据,组合结果为0"
  62.     End If
  63.     Set dic = Nothing

  64. End Sub

  65. Sub splitnumber(ByVal number, ByRef dic As Object)
  66. '---------------------------------------------------------------------------------------
  67. ' Procedure : splitnumber
  68. ' Author    : hwc2ycy
  69. ' Date      : 2013/1/27
  70. ' Purpose   :把数字拆分装进字典
  71. '---------------------------------------------------------------------------------------
  72. '
  73.     Dim i, s$
  74.     For i = 1 To Len(number)
  75.         s = Mid(number, i, 1)
  76.         dic(s) = dic(s) + 1
  77.     Next
  78. End Sub

  79. Sub AnyDic(ByRef dic As Object)
  80. '---------------------------------------------------------------------------------------
  81. ' Procedure : AnyDic
  82. ' Author    : hwc2ycy
  83. ' Date      : 2013/1/27
  84. ' Purpose   :分析字典,去掉没有重复数的
  85. '---------------------------------------------------------------------------------------
  86. '
  87.     Dim key
  88.     For Each key In dic.keys
  89.         If dic(key) = 1 Then dic.Remove key
  90.     Next
  91. End Sub
复制代码
回复

使用道具 举报

 楼主| 发表于 2013-1-27 12:08 | 显示全部楼层
hwc2ycy 发表于 2013-1-27 11:22
对于百位为0,没有显示出来。
如果要显示出来在百位为0的情况,代码就用这个。

结果里少了C3:E4里面的216,516两组数
回复

使用道具 举报

发表于 2013-1-27 13:04 | 显示全部楼层
本帖最后由 hwc2ycy 于 2013-1-27 13:06 编辑

哦。我直接跳过一行了。
改一下就成了。把
  1.     For i = LBound(arr) + 1 To UBound(arr) Step 2
复制代码
改成
  1.     For i = LBound(arr) + 1 To UBound(arr)-1
复制代码
回复

使用道具 举报

发表于 2013-1-27 13:06 | 显示全部楼层
  1. Sub 组合数()
  2. '---------------------------------------------------------------------------------------
  3. ' Procedure : 组合数
  4. ' Author    : hwc2ycy
  5. ' Date      : 2013/1/27
  6. ' Purpose   :字典与数组的应用
  7. '---------------------------------------------------------------------------------------
  8. '
  9.     Dim arr
  10.     Dim arr2()
  11.     Dim arr3(1 To 3)
  12.     Dim dic As Object
  13.     Dim i&, j&, k&, x, y, z
  14.     Dim Check As Boolean

  15.     '读数据到字典,因为用的是区域法,所以要确保在数字区域
  16.     '无其他内容
  17.     arr = Range("c1").CurrentRegion
  18.     '字典
  19.     Set dic = CreateObject("scripting.dictionary")
  20.     '遍历数组,2行一次
  21.     For i = LBound(arr) + 1 To UBound(arr) - 1
  22.         For j = LBound(arr, 2) To UBound(arr, 2)
  23.             '如果数据为非数字(或者为0)的情况下,则跳出本轮循环
  24.             If Not (Val(arr(i, j)) > 0 And Val(arr(i + 1, j)) > 0) Then GoTo quit
  25.             Call splitnumber(arr(i, j), dic)
  26.             Call splitnumber(arr(i + 1, j), dic)
  27.             Call AnyDic(dic)

  28.             '如果没有共同数据,则结束本轮循环,字典清空
  29.             If dic.Count = 0 Then
  30. quit:
  31.                 Check = False
  32.                 dic.RemoveAll
  33.                 Exit For
  34.             End If

  35.             arr3(j) = dic.keys
  36.             '能否进行组合的前提条件
  37.             Check = True
  38.             dic.RemoveAll
  39.         Next
  40.         If Check Then
  41.             '遍历,生成组合,x,y,z分别代表百,拾,个位
  42.             For Each x In arr3(1)
  43.                 For Each y In arr3(2)
  44.                     For Each z In arr3(3)
  45.                         '动态数组
  46.                         k = k + 1
  47.                         ReDim Preserve arr2(1 To k)
  48.                         arr2(k) = "'" & Format(x * 100 + y * 10 + z, "000")
  49.                     Next
  50.                 Next
  51.             Next
  52.         End If
  53.     Next
  54.     Columns("m").Clear
  55.     If k > 0 Then

  56.         '一维变二维,写回M列
  57.         Range("m1").Resize(k) = WorksheetFunction.Transpose(arr2)
  58.         MsgBox "提取完成"
  59.     Else
  60.         MsgBox "数据中无相同数据,组合结果为0"
  61.     End If
  62.     Set dic = Nothing

  63. End Sub

  64. Sub splitnumber(ByVal number, ByRef dic As Object)
  65. '---------------------------------------------------------------------------------------
  66. ' Procedure : splitnumber
  67. ' Author    : hwc2ycy
  68. ' Date      : 2013/1/27
  69. ' Purpose   :把数字拆分装进字典
  70. '---------------------------------------------------------------------------------------
  71. '
  72.     Dim i, s$
  73.     For i = 1 To Len(number)
  74.         s = Mid(number, i, 1)
  75.         dic(s) = dic(s) + 1
  76.     Next
  77. End Sub

  78. Sub AnyDic(ByRef dic As Object)
  79. '---------------------------------------------------------------------------------------
  80. ' Procedure : AnyDic
  81. ' Author    : hwc2ycy
  82. ' Date      : 2013/1/27
  83. ' Purpose   :分析字典,去掉没有重复数的
  84. '---------------------------------------------------------------------------------------
  85. '
  86.     Dim key
  87.     For Each key In dic.keys
  88.         If dic(key) = 1 Then dic.Remove key
  89.     Next
  90. End Sub
复制代码
回复

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-26 21:40 , Processed in 1.026861 second(s), 10 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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