ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 字典嵌套汇总

[复制链接]

TA的精华主题

TA的得分主题

发表于 2023-4-4 00:59 | 显示全部楼层 |阅读模式
本帖最后由 tpb123 于 2023-4-4 01:00 编辑

老师们,这个字典嵌套是哪里出错了,怎么没办法累加。麻烦帮忙看看,谢谢
Sub 测试汇总()
    Set d = CreateObject("scripting.dictionary")
    Set dic = CreateObject("scripting.dictionary") '必要的
    arr = Range("a1").CurrentRegion
    For i = 2 To UBound(arr)
        d(arr(i, 1)) = ""    '店名
         x = arr(i, 2) '日期
        Set dic(x) = CreateObject("scripting.dictionary") '日期字典
        If Not dic(x).exists(arr(i, 1)) Then '判断是否存在嵌套的字典中
        dic(x)(arr(i, 1)) = Val(arr(i, 3)) '不存在写入嵌套的字典中,将店名作为键值写入日期的字典中作为键,值为对应的金额
        Else
        dic(x)(arr(i, 1)) = dic(x)(arr(i, 1)) + Val(arr(i, 3))  '存在写入嵌套的字典中,将值进行累加
        End If
    Next i
[a18].CurrentRegion.ClearContents
[a18] = "日期"
[a19].Resize(dic.Count, 1) = Application.Transpose(dic.keys) '日期去重复
[b18].Resize(1, d.Count) = Application.Transpose(Application.Transpose(d.keys)) '店名去重复
brr = [a18].CurrentRegion
    For i = 2 To UBound(brr)
        For j = 2 To UBound(brr, 2)
        brr(i, j) = dic(brr(i, 1))(brr(1, j))
        Next
    Next
[a18].CurrentRegion = brr
End Sub

图片.png

字典嵌套汇总测试.rar

17.98 KB, 下载次数: 47

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-4 02:01 | 显示全部楼层
本帖最后由 tpb123 于 2023-4-4 08:26 编辑

可以了,写错位置,创建字典的时候。不好意思
这边判断一下就可以了
If Not dic.exists(x) Then Set dic(x) = CreateObject("scripting.dictionary") '日期字典

TA的精华主题

TA的得分主题

发表于 2023-4-4 10:18 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-4 20:04 来自手机 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
grf1973 发表于 2023-4-4 10:18
标准的交叉表。

大神,用sql

TA的精华主题

TA的得分主题

发表于 2023-4-9 14:48 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
brr = [a18].CurrentRegion 这一语句会把31/03/2023这类格式为Date的数据改为String;我认为需要利用CDate函数对brr(i, 1)数据类型从String改为Date。即:
brr = [a18].CurrentRegion
    For i = 2 To UBound(brr)
        For j = 2 To UBound(brr, 2)
              brr(i, j) = dic(CDate(brr(i, 1)))(brr(1, j))
        Next
    Next
[a18].CurrentRegion = brr


TA的精华主题

TA的得分主题

发表于 2023-4-9 15:42 | 显示全部楼层
在您的代码中,当判断店名不存在于日期字典时,您是将该店名及金额作为一个新的键值对写入日期字典中。然而,这样一来,您的日期字典中存放的就不再是单纯的日期键值对,而变成了键值对嵌套,即日期键对应的值是另一个店名和金额的字典。

在后续的处理中,您尝试通过日期键获取对应的嵌套字典,并从嵌套字典中取出店铺对应的金额值。但由于日期键对应的值已经不再是普通的金额了,而是另一个字典,因此会导致无法正常累加金额。

解决这个问题的方法是,将日期键对应的值设为另一个字典,用来存放店名及其对应的金额。修改代码如下:

Sub 测试汇总()
    Set d = CreateObject("scripting.dictionary")
    Set dic = CreateObject("scripting.dictionary") '必要的
    arr = Range("a1").CurrentRegion
    For i = 2 To UBound(arr)
        If Not dic.exists(arr(i, 2)) Then
            Set dic(arr(i, 2)) = CreateObject("scripting.dictionary") '日期字典
        End If
        If Not dic(arr(i, 2)).exists(arr(i, 1)) Then '判断是否存在嵌套的字典中
            dic(arr(i, 2))(arr(i, 1)) = Val(arr(i, 3)) '如果不存在,将店名作为键值写入日期的字典中作为键,值为对应的金额
        Else
            dic(arr(i, 2))(arr(i, 1)) = dic(arr(i, 2))(arr(i, 1)) + Val(arr(i, 3))  '如果存在,将值进行累加
        End If
        d(arr(i, 1)) = ""    '店名
    Next i
    [a18].CurrentRegion.ClearContents
    [a18] = "日期"
    [a19].Resize(dic.Count, 1) = Application.Transpose(dic.keys) '日期去重复
    [b18].Resize(1, d.Count) = Application.Transpose(Application.Transpose(d.keys)) '店名去重复
    brr = [a18].CurrentRegion
    For i = 2 To UBound(brr)
        For j = 2 To UBound(brr, 2)
            brr(i, j) = dic(brr(i, 1))(brr(1, j))
        Next
    Next
    [a18].CurrentRegion = brr
End Sub
在这个修改后的代码中,我们首先检查日期字典中是否已存在日期键,如果不存在就向字典中添加该键,并将其对应的值设为另一个字典。然后再判断店名是否存在于日期字典内的子字典中。如不存在,则创建新的店名及其金额键值对,否则直接从嵌套字典中取出店名对应的金额值进行累加。这样一来,嵌套字典就只会出现在日期字典内,而不会再出现在店名字典中了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-12 09:28 来自手机 | 显示全部楼层
selen 发表于 2023-4-9 15:42
在您的代码中,当判断店名不存在于日期字典时,您是将该店名及金额作为一个新的键值对写入日期字典中。然而 ...

是的,要加个判断,不然每次都是新字典,对应的值,自然就不存在了

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-12 09:29 来自手机 | 显示全部楼层
peter199083 发表于 2023-4-9 14:48
brr = [a18].CurrentRegion 这一语句会把31/03/2023这类格式为Date的数据改为String;我认为需要利用CDate ...

老师,高解,细心,学到了

TA的精华主题

TA的得分主题

发表于 2023-4-12 16:47 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
tpb123 发表于 2023-4-4 02:01
可以了,写错位置,创建字典的时候。不好意思
这边判断一下就可以了
If Not dic.exists(x) Then Set dic( ...

完整的代码是哪个
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-9-27 21:22 , Processed in 0.037297 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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