ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 字典嵌套小白入门笔记

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2019-10-8 15:42 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
老师好,我来交作业了 http://club.excelhome.net/thread-1501690-1-1.html

如果搁到今天,这个贴子我不会写,连想法都不会有。因为实在太简单了,太浅显,简单浅显到没有东西可以写。
在那个帖子中我之所以表现出一种忘乎所以的兴奋纯粹只是缘于长久以来的一种渴望,偶然在一篇帖子中知道了还有字典嵌套这么个用法,看了香川老师的一个字典中级用法的帖子理解的朦朦胧胧,我太希望看到一个贴近生活的实例,让我真真切切的感受一下到底字典嵌套应该用到什么地方怎么用,但当时的我一个模型都想不出来。所以,当一个你觊觎已久的女人突然某一天在毫无征兆的情况下含羞带笑赤果果的躺到你面前的时候再怎么表现的手舞足蹈语无伦次都是可以理解的了。

废话有点多,敲键盘的时候有两句话总是在脑际盘旋萦绕挥之不去,“谨防怒里性,慢发喜中言”,看到这里,绝大多数人可以悬崖勒马回头是岸了,老祖宗的这两句总结已是这篇帖子90%的价值所在。

在那篇水贴中,我说,这是一个极其经典的,案例,是的,余下9.9%的价值应该留给这个题目本身。至少我觉得她很经典,经典到即便以我的水平只看到题目的一个图片便仿佛刹那间的心领神会。
题目如下(原题是根据每个地区建立文件夹,稍做了更改)

微信截图_20191008135305.png
题目要求:根据不同的地区建立工作簿,将学生信息按照学校区分录入到不同的工作表里。
字典嵌套案例.rar (17.3 KB, 下载次数: 173)



还有人在往下看吗?那有些事情就不得不先白活白活了。
首先,这显然不是一个教学帖,只是一个小白理解字典嵌套的心路笔记;
其次,这类题目用字典嵌套并非是一个很好的解法,它只是足够简单又贴近生活而且恰恰可以帮助理解字典套字典;
第三,这个帖子并不适合小白,我是说,比我还白的同学,比我黑的老师应该也看不到这一句。
我不会说的很细,所以,必须是已经会熟练使用字典基本用法的人;知道字典嵌套,暂时还不会用或者说暂时还没用过,不知道或者没见过在实际题目中应用;觉得创建字典key很简单,输出也很简单,但是唯独在字典嵌套过程中找出嵌套的各个Item有点吃力。是的,这就是十一以前的我,也是这个帖子的唯一受众。
并不是不敢往细了写,我这人没啥优点就是胆儿大,什么活儿都敢接,你们能看到这个帖子就是最好的佐证。
但是,我所学的VBA都是东拼西凑来的,我甚至都不确定很多基本的定义我理解/记忆的是否准确,从来我都是由着心来顺着嘴叫,所以,在我滔滔不绝胡说八道的时候,你要有基本的洞悉力和辨别力,这也是小白勿看的原因。
最后再强调一次,下面所说的这些,都只是我自己片面的理解,可能与你的所学相悖,甚至可能不对(但是放心结果没错),一切皆以你的所学为准,另外,我只会点一下我自己学习字典嵌套时的难点,简单的会一笔带过,因为,难点,我也会一笔带过。。。

让一个基础不牢的学生来讲这些是一件很残忍的事情,好在这种残忍会是双向的,所以,既然还是有人好奇,我都掉井里了我充满期待并很乐意看到再掉进来几个。


啪!话说三国时期刘备刘玄德,汉室之后皇族宗亲,单枪匹马意图匡复,奈何势单力薄。偶遇屠户张飞,头脑简单却家底殷实,红脸关羽,貌似忠厚却身具神力,花言巧语骗至麾下。乃哄翼德散尽资财招募乡勇,云长出力,捉拿走卒…… 所谓上梁不正下梁歪,手下人纷纷效仿,一骗二,二哄四……最终借此据鼎一足。据史书考证,此乃传销咳咳字典之起源。
字典有两部分构成:key(关键字)和其对应的 item(条目),这两大要素是字典最本源的结构。
刘备是key,他的Item是张飞和关羽,——这就是最常用的字典。
刘备是key,他没有上线,吸引他的是皇权,字典就是皇权。所以刘备是一级key,他的item是张飞和关羽;但是张飞买了乡勇,发展了下线,他现在也成了key,是二级key,张飞的item是他拿钱买来的乡勇;关羽是和张飞并列的二级key,关羽的item是他出力擒来的走卒,比如黄忠。。。。乡勇们再去哄骗他们的亲戚成为他们的Item,黄忠带来他原来的部下成为他的item。。。。这样本身既是上线的item,又是下线的key,这就是传销金字塔咳咳字典嵌套。

所以,其实,已经说完了。。。 。。。
上面这些都是废话,我学字典嵌套的时候唯一困扰我的,就是最后取item,所以, 不如直接去题上。



先来介绍一下五虎上将:
area = 地区
school = 高校
id = 学生编号
person = 学生姓名
age = 学生年龄
很显然,前3位爷都是key,是层层包含的关系,最后一位爷id已经是最末级key了,它没下线发展了,所以它后面两位是它的item。

Sub 字典套字典基础入门案例()
Dim d As Object, area, school, id, person, age
arr = [a1].CurrentRegion
Set d = CreateObject("scripting.dictionary")
For i = 2 To UBound(arr)
'一定一定一定,要给每个key起个个性鲜明的变量名,——如果需要赋给变量的话,除非你已经特别特别熟练。这对最后取"item"的时候有好处,你会很清楚的知道你已经到了哪一级
area = arr(i, 5): school = arr(i, 4): id = arr(i, 1): person = arr(i, 2): age = arr(i, 3)

If Not d.exists(area) Then   '如果'地区(key)'不存在
        Set d(area) = CreateObject("scripting.dictionary")   '创建'地区key'
        Set d(area)(school) = CreateObject("scripting.dictionary") '一级key都不存在了,不用废话,二级key,三级key...直接创建就行
        d(area)(school)(id) = Array(person, age) '创建'学生编号(key)',这已经是末级key,将学生基本信息作为Item赋值给id
    End If

'如果'地区(key)'已经创建过了,那么   
    If Not d(area).exists(school) Then '如果'高校(key)'不存在
        Set d(area)(school) = CreateObject("scripting.dictionary")  ‘则创建'高校(key)'
        d(area)(school)(id) = Array(person, age) '此条同上
    End If
'这条不注释了   
    If Not d(area)(school).exists(id) Then
        d(area)(school)(id) = Array(person, age)
    End If

下面,就来到了我当时学习字典嵌套时最容易困惑的地方,"(取出)item"。
每次创建了key,我就开始试图去想,去理清,它的item,——这一级的item是什么?我非要想出来,弄明白,再嵌套一级的item是什么?再再嵌套一级的item又是什么…… 越嵌套下去脑袋越大。
这是真真实实的我看了香川群子老师的那个字典中级用法贴后的状态和想法。
那个贴单看就是这么晦涩,——至少我看的时候是这样,满脑子想的都是Item,晦涩到我迫不及待地想借助一个现实中的题目来消化一下。
天可怜见让我遇到了这个题目,让我知道了原来我上面的想的都多余了。
还记得倚天屠龙记中,武当山上张三丰教张无忌学太极剑的法门么?忘却!
忘却什么?忘却item!
所以我的法门就是,在字典嵌套过程中,没有Item!没有Item!没有Item!
基本字典的构成是什么? key - item,两个元素,
嵌套字典的构成是什么? key|子key|子子key ... - item ,还是两个元素(中间没有item)。
(上面其实我更习惯叫一级key,二级key,三级key...)
如果把这个结构纳入到脑子里,后面“取出item”的时候就太简单了,因为根本不用取!没有还取什么?
那剩下的只有取key了,取key就太简单了
For Each area In d.keys '取出 '地区(key)'
      For Each school In d(area) '取出 '高校(key)'
            For Each id In d(area)(school) '取出 '学生编号(key)'
... ...
好了,为了不干扰大家的思路,这个题的主干部分已经解完了。
就是这么简单,只需要这么简单。
我自己总结归纳主要有两点:
①清醒的知道哪一级是(被创建的)key,我把它们赋给了恰如其分的变量;
②取出的过程中不要考虑item,只管取key就行。实际上取key的过程就是取出item的过程,所谓见山不是山,见水不是水。等几次熟练之后,你看嵌套过程中的key自然而然的就会看成item,行云流水毫不做作,这就到了见山是山见水是水的境界。
好了,就这些。

这个题我只所以认为它经典,就是它包含了字典嵌套的各个要素,贴近生活,易懂且不晦涩。
它另一个经典就是沉默,只需要看着题目本身自己思考理解就行,不要别人解释,说一句都是废话,都是对经典的亵渎。

该说的不该说的都已经说了,在最后,我会给出这个题的完整代码,尽管已经不需要。
最最后,总结一下,祝贺吧,祝贺贵坛又多了一个会使用字典套字典的人,由衷的感到高兴,(左拱手),(右拱手),溜!


Sub 字典套字典基础入门案例()
Dim d As Object, area, school, id, person, age, s, n&
arr = [a1].CurrentRegion
Set d = CreateObject("scripting.dictionary")
For i = 2 To UBound(arr)
area = arr(i, 5): school = arr(i, 4): id = arr(i, 1): person = arr(i, 2): age = arr(i, 3)

    If Not d.exists(area) Then
        Set d(area) = CreateObject("scripting.dictionary")
        Set d(area)(school) = CreateObject("scripting.dictionary")
        d(area)(school)(id) = Array(person, age)
    End If

    If Not d(area).exists(school) Then
        Set d(area)(school) = CreateObject("scripting.dictionary")
        d(area)(school)(id) = Array(person, age)
    End If

    If Not d(area)(school).exists(id) Then
        d(area)(school)(id) = Array(person, age)
    End If
Next

s = Array("地区", "高校", "学号", "姓名", "年龄")
Application.ScreenUpdating = False
For Each area In d.keys
    Workbooks.Add
    With ActiveWorkbook
        For Each school In d(area)
            .Worksheets.Add.Name = school
            n = 0
            For Each id In d(area)(school)
                n = n + 1
                Cells(1, 1).Resize(, 5) = s
                Cells(n + 1, 1) = area
                Cells(n + 1, 2) = school
                Cells(n + 1, 3) = id
                Cells(n + 1, 4).Resize(, 2) = d(area)(school)(id)
            Next
        Next
    .SaveAs ThisWorkbook.Path & "\" & area & ".xlsx"
    .Close True
    End With
Next
Application.ScreenUpdating = True
End Sub

评分

10

查看全部评分

TA的精华主题

TA的得分主题

发表于 2019-10-8 16:15 | 显示全部楼层
首先,评分纯粹是你写了一大堆,具体优否,不予以评论。
其次,我就看到你说来说去,还是说事业线的事,就无细看下去了,哈哈

TA的精华主题

TA的得分主题

发表于 2019-10-8 16:19 | 显示全部楼层
情绪与文彩一色,代码与示例齐飞

TA的精华主题

TA的得分主题

发表于 2019-10-8 16:23 | 显示全部楼层
本帖最后由 killq 于 2019-10-8 16:25 编辑

                                    1

图片.png

TA的精华主题

TA的得分主题

发表于 2019-10-8 16:25 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-10-8 16:27 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
microyip 发表于 2019-10-8 16:25
人家只是文字上随便说说,你还当真,无语

我不管我不管,你诈骗了我,就要负责

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-10-8 16:50 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
microyip 发表于 2019-10-8 16:15
首先,评分纯粹是你写了一大堆,具体优否,不予以评论。
其次,我就看到你说来说去,还是说事业线的事,就 ...

作为一个满腹经纶文采斐然的五笔高手,老师这分给的有点冤了,基本功基本功。。。我就当老师是给原来的题目评分好了。讲真,要不是那个帖子被删了而论坛又不给我权限,我这点分打打包就全送出去了

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-10-8 16:54 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

老师要少看电脑了,1楼天堑般的沟啊。。。。

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-10-8 17:03 | 显示全部楼层
aman1516 发表于 2019-10-8 16:19
情绪与文彩一色,代码与示例齐飞

老师慧眼如炬定非常人也!

大家眼前没有垃圾桶的话还是克制一点吧。
我是打算直接把原题目扔上来的,上个帖子中说的有点过这样敷衍的痕迹太明显了点,不得已那就讲两句,文思泉涌的人啊,哎,不说了

TA的精华主题

TA的得分主题

发表于 2019-10-8 17:45 | 显示全部楼层
解决问题关键是思路,一招解决不了那就两三招,没必要追求一刀切
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-4-26 21:03 , Processed in 0.048146 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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