ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E问E答 > Excel VBA > 如何用vba代码依各项分类生成结果报告表?

如何用vba代码依各项分类生成结果报告表?

作者:绿色风 分类: 时间:2022-08-17 浏览:72
楼主
kevinchengcw
Q: 如何用vba代码依各项分类生成结果报告表?
要实现结果见下图:

 
A: 代码如下:
  1. Sub test()
  2. Dim Dic As Object, Dic2 As Object, Arr, Arr2, N&, I&, T&, Str$, Str2$, Str3$, Result, Rng As Range
  3. Set Dic = CreateObject("scripting.dictionary")  '创建字典用于统计数据
  4. Set Dic2 = CreateObject("scripting.dictionary")
  5. With Worksheets("数据")  '在数据表中读取原始数据到数组中
  6.     Arr = .[a1].Resize(.Cells(.Rows.Count, 1).End(3).Row, .Cells(1, .Columns.Count).End(1).Column).Value
  7. End With
  8. With CreateObject("vbscript.regexp")  '创建正则用于比较字段
  9.     .Global = True  '全局有效
  10.     For N = LBound(Arr) + 1 To UBound(Arr)  '循环原始数据中的数据区
  11.         Str = Arr(N, 3) & vbTab & Arr(N, 4)  '组合专业名称与品牌字段(用于统计投放报社)
  12.         Str2 = Str & "|" & Arr(N, 1) & Arr(N, 5) & Arr(N, 6)  '组合专业与品牌及投放情况字段(用于统计投放数据)
  13.         If Dic.exists(Str) Then  '如果已经存在该专业名称与品牌字段
  14.             .Pattern = "(^|,)" & Arr(N, 1) & "(?=,|$)"  '将报社名设置成匹配规则用于判断是否已存在
  15.             If Not .test(Dic(Str)) Then Dic(Str) = Dic(Str) & "," & Arr(N, 1)  '如果不存在该报社则更新对应字典项目
  16.         Else
  17.             Dic(Str) = Arr(N, 1)  '不存在的话,则添加该字典项目
  18.         End If
  19.         If Dic2.exists(Str2) Then  '如果存在该投放数据,则增加统计数据
  20.             Dic2(Str2) = Dic2(Str2) + 1
  21.         Else  '如果不存在则添加
  22.             Dic2(Str2) = 1
  23.         End If
  24.     Next N
  25. End With
  26. ReDim Result(1 To Dic.Count + 1, 1 To 4)  '根据上面取得的结果重设结果数组(含标题行)
  27. Result(1, 1) = "专业名称": Result(1, 2) = "媒体名称": Result(1, 3) = "品牌": Result(1, 4) = "投放情况"  '给标题行赋值
  28. Arr = Dic.keys  '将专业名称与品牌字段输出到数组中,便于依序提取
  29. I = 2  '结果表中数据起始行
  30. For N = LBound(Arr) To UBound(Arr)  '循环结果数据各项
  31.     Arr2 = Split(Arr(N), vbTab)  '拆分开专业名称与品牌方便写入结果数组中
  32.     Result(I, 1) = Arr2(0)  '将对应各项写入结果表中
  33.     Result(I, 3) = Arr2(1)
  34.     Result(I, 2) = Dic(Arr(N))
  35.     Arr2 = Dic2.keys  '将投放情况提取出来
  36.     Str3 = ""   '投放情况字符串初始化
  37.     For T = LBound(Arr2) To UBound(Arr2)  '循环投放情况统计
  38.         If Arr2(T) Like Arr(N) & "|*" Then  '如果当前循环到的投放情况字头与当前数据结果一致,则进行数据处理
  39.             If Str3 <> "" Then Str3 = Str3 & ","  '判断并添加分隔逗号
  40.             Str3 = Str3 & "投放" & Split(Arr2(T), "|")(1) & Dic2(Arr2(T)) & "期"  '提取对应数据并串接为投放情况结果字符串
  41.             Dic2.Remove Arr2(T)  '移除以统计过的字典项目
  42.         End If
  43.     Next T
  44.     Result(I, 4) = Str3  '投放结果写入对应位置
  45.     I = I + 1  '下移一行
  46. Next N
  47. With Worksheets("结果")  '到结果表中处理结果
  48.     .Cells.Clear  '清空原有数据
  49.     With .[a1].Resize(UBound(Result), UBound(Result, 2))  '根据结果数组确定写入范围
  50.         .Value = Result  '写入结果数组
  51.         .EntireColumn.AutoFit  '列宽自适应
  52.         Dic.RemoveAll  '清空字典内容,用于处理后期同列相同内容单元格合并
  53.         For I = 1 To 2  '循环需要处理的列号
  54.             For Each Rng In Intersect(.Cells.Offset(1), .Cells, .Parent.Columns(I))  '循环结果数据中当前处理列的除标题行外的各个单元格
  55.                 If Dic.exists(Rng.Value) Then  '如果已经有这个字典项目
  56.                     Set Dic(Rng.Value) = Union(Dic(Rng.Value), Rng)  '将当前单元格合并到字典对应项的item中(单元格区域)
  57.                 Else
  58.                     Set Dic(Rng.Value) = Rng  '否则将当前单元格值对应的字典item项
  59.                 End If
  60.             Next Rng
  61.         Next I
  62.         Arr = Dic.keys  '取得字典中的各项
  63.         On Error Resume Next  '防止操作单元格时出错,进行容错处理
  64.         Application.DisplayAlerts = False  '禁止警告信息(防止合并单元格时的提示消息框)
  65.         For N = LBound(Arr) To UBound(Arr)  '循环字典各项
  66.             For Each Rng In Dic(Arr(N)).Areas  '循环当前循环项中对应的字典item对应的单元格区域的各个区域
  67.                 If Rng.Cells.Count > 1 Then Rng.Merge  '如果区域中单元格超过1个,则进行合并
  68.             Next Rng
  69.         Next N
  70.         Application.DisplayAlerts = True  '恢复显示警告信息
  71.         .Borders.LineStyle = 1  '结果数据加上边框线
  72.     End With
  73. End With
  74. Set Dic = Nothing  '清空项目
  75. Set Dic2 = Nothing
  76. End Sub
详见附件及素材源帖。
依各项分类生成结果报告表.rar
2楼
大元帅的双刃剑
[code]Sub Macro1()
    Dim d As Object,  k, t, arr, brr(), i&, j%, m&, s$
    Set d = CreateObject("scripting.dictionary")
    arr = Sheets("数据").[a1].CurrentRegion
    ReDim brr(1 To UBound(arr), 1 To 4)
    For i = 2 To UBound(arr)
        s = arr(i, 3) & arr(i, 4)
        If Not d.Exists(s) Then
            m = m + 1
            d(s) = m
            brr(m, 1) = arr(i, 3)
            brr(m, 2) = arr(i, 1)
            brr(m, 3) = arr(i, 4)
            brr(m, 4) = arr(i, 1) & arr(i, 6) & arr(i, 5)
        Else
            brr(d(s), 2) = brr(d(s), 2) & "," & arr(i, 1)
            brr(d(s), 4) = brr(d(s), 4) & "," & arr(i, 1) & arr(i, 6) & arr(i, 5)
        End If
    Next
    For i = 1 To m
        d.RemoveAll
        a = Split(brr(i, 4), ",")
        For j = 0 To UBound(a)
            d(a(j)) = d(a(j)) + 1
        Next
        k = d.keys
        t = d.items
        s = ""
        For j = 0 To d.Count - 1
            s = s & ",投放" & k(j) & t(j) & "期"
        Next
        brr(i, 4) = Mid(s, 2)
    Next
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    ActiveSheet.UsedRange.Offset(1).Clear
    With [a2].Resize(m, 4)
        .Value = brr
        .Sort Key1:=[a2].Resize(m), Order1:=xlAscending ' 以防Sheets("数据")中的“专业名称”相同字段不在一起
        .Borders.LineStyle = 1
        arr = .Value
    End With
    For i = m - 1 To 1 Step -1
        If arr(i, 1) = arr(i + 1, 1) Then Cells(i + 1, 1).Resize(2).Merge
    Next
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
End Sub

高难度VBA语言请求2a.rar
3楼
打滚的蛋饼
收藏下
4楼
gysegz
kevinchengcw版主你真牛!支持,顶起**

免责声明

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

评论列表
sitemap