ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[讨论] 复杂的多表汇总(难度有点大,做出来有分加哦)

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-1-20 22:53 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:多表合并和汇总
加注释加分,大家都注上吧

TA的精华主题

TA的得分主题

发表于 2010-1-21 08:00 | 显示全部楼层
原帖由 彭希仁 于 2010-1-20 22:53 发表
加注释加分,大家都注上吧


若我的代码加注释 能否加分 不然白加了

TA的精华主题

TA的得分主题

发表于 2010-1-21 08:12 | 显示全部楼层
原帖由 彭希仁 于 2010-1-20 22:53 发表
加注释加分,大家都注上吧

版主决定是正确的!我们来学习的,支持加注释,高手跟上吧!

TA的精华主题

TA的得分主题

发表于 2010-1-21 08:16 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
先向各位大师学习,我个人觉得通用性不够,现汇总表的A,B列与表头是先预置好的,通用的应是汇总表原为空白表,所有行列数据都是根据分表自动得出。对各位高手的挑战性也更大些。

[ 本帖最后由 wenwen000424 于 2010-1-21 08:18 编辑 ]

TA的精华主题

TA的得分主题

发表于 2010-1-21 08:20 | 显示全部楼层
原帖由 wenwen000424 于 2010-1-21 08:16 发表
先向各位大师学习,我个人觉得通用性不够,现汇总表的A,B列与表头是先预置好的,通用的应是汇总表原为空白表,所有行列数据都是根据分表自动得出。对各位高手的挑战性也更大些。


言之有理 支持

TA的精华主题

TA的得分主题

发表于 2010-1-21 08:28 | 显示全部楼层

回复 35楼 泓() 的帖子

老师,也帮我做一下这个表的数据提取可以吗?

元月1号至15号.rar

193.46 KB, 下载次数: 52

TA的精华主题

TA的得分主题

发表于 2010-1-21 08:30 | 显示全部楼层
各位老师,也帮我写一个提取数据的代码可以吗?
提取数据的行列在附件里有说明了。

元月1号至15号.rar

193.46 KB, 下载次数: 44

TA的精华主题

TA的得分主题

发表于 2010-1-21 08:34 | 显示全部楼层
我的代码其实很好理解,就是一般思路,一行行、一列列比对。
希望我的注释不会让大家糊涂了。
  1. Const r = 4
  2. '定义常量r=4,因为所有的行列都从4开始,这是为了程序的可读性,否则一直加3、加4不好理解
  3. Sub cc()
  4. Dim i&, j&, k&, m&, n&, x&, rng, Arr, brr, Sh As Worksheet, d As Object
  5. Application.ScreenUpdating = False
  6. '停止屏幕更新
  7. Range(Cells(2, 2), Cells(2, 100)).Replace "Z", "V"
  8. '将表格中第一行里的"Z"换成"V"
  9. rng = [b1].CurrentRegion
  10. '将总表中单元格区域传递给数组rng
  11. For i = r To UBound(rng) - 1
  12. If rng(i, 1) = "" Then rng(i, 1) = rng(i - 1, 1)
  13. Next
  14. '因为是合并单元格(例如广东,"A4:A14",只有A4不为空),所以把省份为空值的变为与前一数值相同
  15. For i = r To UBound(rng, 2) - 1
  16. If rng(2, i) = "" Then rng(2, i) = rng(2, i - 1)
  17. Next
  18. '同上一段代码用途,这里是把手机机型为空的变为与前一数值相同
  19. For Each Sh In ThisWorkbook.Sheets
  20. '在各个表中循环
  21. If Sh.Name <> "总表" Then
  22. t = 0
  23. '设置变量t为0
  24. Set d = CreateObject("scripting.dictionary")
  25. '建立字典,这是的字典用途和那几位老师的不同,只是为了方便剔除总表中有而分表中没有的机型,加快速度
  26. Arr = Sh.[b1].CurrentRegion
  27. '将分表中单元格区域传递给数组arr
  28. For i = r To UBound(Arr) - 1
  29. If Arr(i, 1) = "" Then Arr(i, 1) = Arr(i - 1, 1)
  30. Next
  31. '与总表中一样,把省份为空的变为与前一数值相同
  32. For i = r To UBound(Arr, 2)
  33. If Arr(2, i - 1) = "" Then Arr(2, i - 1) = Arr(2, i - 2)
  34. d(Arr(2, i - 1) & Arr(3, i - 1)) = ""
  35. Next
  36. '与总表中一样,把机型为空的变为与前一数值相同,并把分表中的机型放入字典
  37. '当总表中的机型分表中没有,则跳过,节省时间
  38. n = 0
  39. For k = r To UBound(rng, 2) - 1
  40. m = 0
  41. x = 0
  42. y = 0
  43. '设置变量m,x,y为0
  44. 'm是用来在数组rng中的纵列递增的
  45. 'x,y是用来在数组arr中的纵列递增的
  46. '以上用法用来减少循环层数
  47. Do While t < UBound(rng, 2) - 2
  48. '它的意思不用说了,主要说明它的用途,因为我的代码就是让两个数组纵向比对之后,再横向比对
  49. 't就用来控制在数组rng的横向比对中不要出界,所以t的最大值是UBound(rng, 2) - 3
  50. j = j + 1
  51. 'j是用来控制在数组rng的纵向比对中不要出界的,所以j的最大值是UBound(rng) - 3
  52. Stop
  53. If d.exists(rng(2, t + 2) & rng(3, t + 2)) Then
  54. '当数组arr(分表)中包含rng(总表)中的机型与颜色(机型与颜色同时比对)时,继续运行下行代码
  55. If j = UBound(rng) - 3 Then m = 0: n = n + 1: GoTo 0
  56. 'j达到最大值UBound(rng) - 3时,m清零,因为一个纵列中所有行已经比对完成了,下一列从头开始
  57. 'n的作用与t相同,将数组arr一列一列提取比对,接着运行标识“0”后面的代码
  58. m = m + 1
  59. If rng(r + m - 1, 1) & rng(r + m - 1, 2) = Arr(r + x, 1) & Arr(r + x, 2) Then
  60. '当数组arr(分表)中与含rng(总表)中的省份与销售网点相同(省份与销售网点同时比对)时,继续运行下行代码
  61. y = y + 1
  62. If rng(2, t + 2) & rng(3, t + 2) = Arr(2, r + n - 1) & Arr(3, r + n - 1) Then
  63. '当数组arr(分表)中与含rng(总表)中的机型与颜色相同时,继续运行下行代码
  64. rng(m + 3, t + 2) = rng(m + 3, t + 2) + Arr(3 + y, r + n - 1)
  65. '将数组arr中的销售数量与rng中省份与销售网点相同、机型与颜色相同的数量相加
  66. 'Cells(m + 3, t + 3) = Cells(m + 3, t + 3) + Arr(3 + y, r + n - 1)
  67. '上面这行是当时测试代码时,在单元格中填充数值验证对错用的
  68. x = x + 1
  69. 'x递增,继续比对arr中的某列中的下一行
  70. End If
  71. End If
  72. Else
  73. 0
  74. t = t + 1
  75. x = 0
  76. j = 0
  77. y = 0
  78. '列递数增加1,行递增数清零
  79. End If
  80. Loop
  81. n = n + 1
  82. If n = UBound(Arr, 2) Then n = 0
  83. '当n达到最大值是,清零
  84. Next
  85. End If
  86. Set d = Nothing
  87. '清除字典中的内容,因为下一个工作表还要用
  88. Next
  89. [b1].Resize(UBound(rng) - 1, UBound(rng, 2) - 1) = rng
  90. '填充数组rng到总表,但跳过最后一行和一列,因为它们有公式。
  91. Range(Cells(2, 2), Cells(2, 100)).Replace "V", "Z"
  92. '把总表中原先替换的再换回来
  93. Application.ScreenUpdating = True
  94. '打开屏幕更新
  95. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-1-21 08:39 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
原帖由 泓() 于 2010-1-21 08:00 发表


若我的代码加注释 能否加分 不然白加了

  

能啊,加吧,求你了,哈哈

TA的精华主题

TA的得分主题

发表于 2010-1-21 09:01 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
代码注释:

  1. Sub DataSums()
  2.     Dim Arr, Ary, k%, icol%
  3.     Dim Sh As Worksheet, Str$
  4.     Dim Dic As Object

  5.     Set Dic = CreateObject("Scripting.Dictionary")
  6.     Arr = Range("B2", [D65536].End(3).End(2).Offset(-1, -1))    '将本表有效范围的数据写入数组Arr
  7.     For k = 3 To UBound(Arr)    '遍历数组中的数据行,将合并单元格造成的空值填上
  8.         If Arr(k, 1) = "" Then Arr(k, 1) = Arr(k - 1, 1)
  9.     Next

  10.     For icol = 3 To UBound(Application.Transpose(Arr))    '遍历数组中的数据列(维),将合并单元格造成的空值填上
  11.         If Arr(1, icol) = "" Then Arr(1, icol) = Arr(1, icol - 1)
  12.         If Left(Arr(1, icol), 1) Like "[A-Z]" Then Arr(1, icol) = Right(Arr(1, icol), Len(Arr(1, icol)) - 1)    '去掉字母,以保障型号吻合
  13.     Next

  14.     For Each Sh In Sheets    '遍历工作表
  15.         If Sh.Name <> ActiveSheet.Name Then    '判定为非当前工作表时
  16.             Ary = Sh.Range("B2", Sh.[D65536].End(3).End(2).Offset(-1, -1))  '将本表有效范围的数据写入数组Ary
  17.             For k = 3 To UBound(Ary)    '遍历数组中的数据行,将合并单元格造成的空值填上
  18.                 If Ary(k, 1) = "" Then Ary(k, 1) = Ary(k - 1, 1)
  19.             Next

  20.             For icol = 3 To UBound(Application.Transpose(Ary)) 遍历数组中的数据列(维),将合并单元格造成的空值填上
  21.                 If Ary(1, icol) = "" Then Ary(1, icol) = Ary(1, icol - 1)
  22.                 If Left(Ary(1, icol), 1) Like "[A-Z]" Then Ary(1, icol) = Right(Ary(1, icol), Len(Ary(1, icol)) - 1)    '去掉字母,以保障型号吻合
  23.             Next
  24.             For k = 3 To UBound(Ary)    '用两个循环将当前工作表中的求和区域的数值按区域、商家、型号、颜色的唯一性写入字典
  25.                 For icol = 3 To UBound(Application.Transpose(Ary))
  26.                     Str = Ary(k, 1) & Ary(k, 2) & " " & Ary(1, icol) & Ary(2, icol)
  27.                     Dic(Str) = Dic(Str) + Ary(k, icol)
  28.                 Next
  29.             Next
  30.             Erase Ary    '清除数组
  31.         End If
  32.     Next

  33.     Ary = Range("D4", [D65536].End(3).End(2).Offset(-1, -1))    'Ary的范围即当前工作表的求和范围
  34.     For k = 1 To UBound(Ary)
  35.         For icol = 1 To UBound(Application.Transpose(Ary))
  36.             Ary(k, icol) = Dic(Arr(k + 2, 1) & Arr(k + 2, 2) & " " & Arr(1, icol + 2) & Arr(2, icol + 2))    '用查字典的方法将Ary中的每一个值查找出来
  37.         Next
  38.     Next
  39.     Dic.RemoveAll    '清除字典

  40.     [D4].Resize(k - 1, UBound(Application.Transpose(Ary))) = Ary    '将Ary数组写入求和区域
  41. End Sub
复制代码
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-23 23:50 , Processed in 0.047928 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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