ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > 我的酷贴 > Excel VBA > 一个稍复杂点的数据表统计及结果输出示例

一个稍复杂点的数据表统计及结果输出示例

作者:绿色风 分类: 时间:2022-08-18 浏览:95
楼主
kevinchengcw
 

对于如上图一样的一份数据表,如何统计出各个工地领用的各个物料、单位及数量并生成各工地的统计清单会让人觉得有些麻烦,借用本例,此处演示一种利用VBA结合字典处理类似数据统计输出的一种方法,代码如下:
  1. Sub test()
  2. Dim Dic, Dic2, Arr, Tmp
  3. Dim M, N, I As Long
  4. Dim Str As String
  5. Set Dic = CreateObject("scripting.dictionary")  '创建两个字典项目,用于记录及分类数据
  6. Set Dic2 = CreateObject("scripting.dictionary")
  7. '→→→→-
  8. '统计数据程序段
  9. '→→→→-
  10. With Worksheets("各工地汇总")  '首先处理各工地汇总页面中的数据
  11.     For M = 2 To .Cells(.Rows.Count, 1).End(3).Row  '循环页面中的各行
  12.         For N = 3 To .Cells(M, .Columns.Count).End(1).Column - 2  '根据数据特点,循环数据中需统计的各列
  13.             If .Cells(M, N) <> "" Then  '如果循环到的单元格不为空,则
  14.                 Str = .Cells(2, N).Value & vbTab & .Cells(M, 1).Value & vbTab & .Cells(M, 2).Value  '将标题行及该行A,B列单元格依特定字符串接赋值给字符串(当作字典的key使用)
  15.                 If Not Dic.exists(Str) Then   '先判断是否有该key存在,如果没有,则
  16.                     Dic.Add Str, .Cells(M, N).Value   '添加该字典项,item项用于存储当前单元格的值
  17.                 Else  '如果存在该字典项,则
  18.                     Dic(Str) = Dic(Str) + .Cells(M, N).Value  '将现有item项与当前单元格值进行累加后作为新的item项赋值给字典对应项
  19.                 End If
  20.             End If
  21.         Next N  '循环到下一列
  22.     Next M   '循环到下一行
  23. End With
  24. '→→→→→→→→→→--
  25. '将原始数据拆分成各自工地的程序段
  26. '→→→→→→→→→→--
  27. Arr = Dic.keys  '将字典的所有key值赋值给数组Arr
  28. For N = LBound(Arr) To UBound(Arr)   '循环数组中各项(用于提取字典对应各项)
  29.     If Not Dic2.exists(Split(Arr(N), vbTab)(0)) Then Dic2.Add Split(Arr(N), vbTab)(0), ""   '提取字典中的各个工地名(即字典key值依特定字符拆分后的每一段)并存储至字典2中
  30.     '注:此处的工地名其实也可从表中直接读取
  31. Next N
  32. For N = LBound(Arr) To UBound(Arr)   '再次循环数组各值,此次用来将各工地的物料及单件、数量等统计资料拆分后串接并存储为对应工地字典项的item项
  33.     If Dic2(Split(Arr(N), vbTab)(0)) <> "" Then  '如果对应的工地名的字典item项在字典2中不是空值,则将item项及新数据用“|”分隔串接后作为item项储存
  34.         Dic2(Split(Arr(N), vbTab)(0)) = Dic2(Split(Arr(N), vbTab)(0)) & "|" & Split(Arr(N), vbTab)(1) & vbTab & Split(Arr(N), vbTab)(2) & vbTab & Dic(Arr(N))
  35.     Else   '如果不存在,则创建该工地的字典项,并将当前资料项依特定字符分隔串接后存为字典的item项
  36.         Dic2(Split(Arr(N), vbTab)(0)) = Split(Arr(N), vbTab)(1) & vbTab & Split(Arr(N), vbTab)(2) & vbTab & Dic(Arr(N))
  37.         '注意:上面这句等同于Dic2.Add Split(Arr(N), vbTab)(0), Split(Arr(N), vbTab)(1) & vbTab & Split(Arr(N), vbTab)(2) & vbTab & Dic(Arr(N))
  38.     End If
  39. Next N
  40. '→→→→→→--
  41. '数据输出处理的程序段
  42. '→→→→→→--
  43. Arr = Dic2.keys  '将字典2的key值全部赋值给数组Arr,便于循环取出各项值
  44. With Worksheets("sheet2")   '将结果输出至sheet2工作表
  45.     For N = LBound(Arr) To UBound(Arr)  '循环数组各项
  46.         If N = LBound(Arr) Then  '如果是数组的第一个值(因第一次执行时如果用判断最后一行的方式会出现偏差,故单独执行首次)
  47.             Tmp = Split(Dic2(Arr(N)), "|")  '将当前数组项对应的字典2的item项依字符“|”分割后赋值给Tmp数组
  48.             For M = LBound(Tmp) To UBound(Tmp)  '分割后的数组项是由物料名,单位及数量组成,故要进一步分割放入对应单元格里
  49.                 .Cells(M + 1, 1) = Split(Tmp(M), vbTab)(0)   '在这里单元格的递增可以与数组的递增同步(注意,数组在默认情况下下标从0开始)
  50.                 .Cells(M + 1, 2) = Split(Tmp(M), vbTab)(1)
  51.                 .Cells(M + 1, 3) = Split(Tmp(M), vbTab)(2)
  52.             Next M
  53.         Else  '如果不是数组的第一个值,则
  54.             I = .Cells(.Rows.Count, 1).End(3).Row    '取得当前A列的最后一行的行标
  55.             Tmp = Split(Dic2(Arr(N)), "|")  '将当前数组项对应的字典2的item项依字符“|”分割后赋值给Tmp数组
  56.             For M = LBound(Tmp) To UBound(Tmp)  '从当前A列最后一行的下面隔一行起输出对应的项到对应的单元格
  57.                 .Cells(M + I + 2, 1) = Split(Tmp(M), vbTab)(0)
  58.                 .Cells(M + I + 2, 2) = Split(Tmp(M), vbTab)(1)
  59.                 .Cells(M + I + 2, 3) = Split(Tmp(M), vbTab)(2)
  60.             Next M
  61.         End If
  62.     Next N
  63.     .Cells.SpecialCells(xlCellTypeConstants, 23).Borders.LineStyle = 1   '执行完数据后输出后,将有数据的单元格的设置边框
  64. End With
  65. Set Dic = Nothing  '清空字典项
  66. Set Dic2 = Nothing
  67.             
  68. End Sub

以上代码对于物料名重复或工地名重复等情况处理效果良好。
附示例文件。(数据表:各工地汇总,结果输出表:Sheet2)
复杂数据VBA统计方法示例.rar
2楼
kensam
学习了 有点接近我想统计的数据了
3楼
本人号被盗,
师傅真棒,太厉害了

免责声明

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

评论列表
sitemap