ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 一个熟悉字典的学习建议及一个实例的字典学习

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-7-8 15:02 | 显示全部楼层 |阅读模式
山菊花老师的《正松舒,慢匀稳——太极字典少年班》深入浅出、生动幽默,对于字典学习大有裨益,不知道的E友可点击:“知识树”--编程开发参考--VBA语言基础--数组集合和字典--本帖。
最后部分的“感动中国人物评选”不便于初学者用F8按钮在“本地窗口”中逐步查看,再山菊花老师的指导下,本人悉心整理了一个便于逐步观察程序运行、适合初学者学习的“评选表”,当然,实质上与原表是一样的,只是暂时将“事件程序”取消了,并增加了一些注释。 人物评选表.zip (488.99 KB, 下载次数: 125)
  1. '原工作表感动中国人物评选“事件”程序不便于按F8按钮在本地窗口中逐步查看
  2. '以下程序将“事件”去掉,并增加了观察用语句,就便于按F8按钮在本地窗口中逐步查看了
  3. '置于最高处的变量申明有二个作用
  4. '1.作用于每一个过程
  5. '2.过程结束后,变量保持最终状态不变(除非进行“开始化”,否则此处字典d、数组Arr、条目s、下标上界k总保持最终状态不变)
  6. '注:如将置顶申明变量语句注释掉,则“开始化”时会报错。这也说明了申明变量的必要性
  7. '注:数组多设置的最后一个空列(9=8+1)是“删除姓名”过程的技术需要
  8. Dim d As Object, Arr(1 To 2, 1 To 9), s%, k%      '数组变量是变体变量,变体变量无需申明变量类型。
  9. Sub 二零二零年感动中国人物评选()
  10.     Set d = CreateObject("Scripting.Dictionary")    '后期绑定字典
  11.     Call 开始化     '调用位于最下面的“开始化”过程
  12. End Sub

  13. Sub 投票()
  14.     Dim s1%, i, j, m    'i, j, m都是变体变量
  15.     If [h26] = "" Then Exit Sub     '如果h26为空,则退出Sub代码块,否则…
  16.     s1 = d([h26].Value)     '查字典:调出字典中此关键字(姓名)的条目;如字典中无此关键字,则字典会首先自动添加此关键字(其条目为空值或0)
  17.                                        '夸张点说:d("关键字")=x或x=d("关键字")是字典学习中的全部内容!前者叫"挥之即去"(入典)、后者叫"召之即来"(显示)
  18.     i = d.Keys      '第一次观察字典;关键字(姓名)集合
  19.     j = d.Items     '第一次观察字典;条目集合
  20.     k = UBound(Arr, 2)      '空白计票列的列数(k=9)。UBound表示数组上标;2表示“第二维”(即1 To 9列)
  21.     If s1 = 0 Then      '如果是首次出现的候选人姓名,则…
  22.         If s < k - 1 Then       '如果“姓名票数”表中已有的候选人姓名所占的列数没有超过7,则…
  23.             s = s + 1       '在原有列数的基础上加一列(注:初始列数为0)
  24.             d([h26].Value) = s      '修改字典:将字典中关键字[h26].Value的条目由0改为s
  25.                                               '关键字的条目亦即“姓名票数”表中候选人姓名所在的列数
  26.             s1 = s      '将s值赋给s1
  27.                             '注意:本句为下面Arr(2, s1) = Arr(2, s1) + 1所用
  28.                             '注意:s1绝不会通过s1 = d([h26].Value)反向(自左至右)给关键字修改条目
  29.                             '也就是说,字典不会容忍类似5=d("关键字")这样的"语句"存在
  30.             i = d.Keys      '更改条目后观察字典;关键字(候选人姓名)集合
  31.             j = d.Items     '更改条目后观察字典;条目(候选人姓名所在列数)集合
  32.             Arr(1, s) = [h26].Value     '将首次出现的候选人姓名写入数组1行s列
  33.         End If
  34.     End If
  35.     If s1 Then Arr(2, s1) = Arr(2, s1) + 1      '字典中存在其数组列数(条目,且不为0)的同一姓名的票数累加
  36.     m = Arr     '观察用;数组状态(此数组将写入投票区域h28:o29)
  37.         If d([h26].Value) = 0 Then
  38.         MsgBox "候选人数不能超过" & k - 1 & "位!", 48, "提示"       '此句中=0更换为=""亦可
  39.         d.Remove ([h26].Value)      '从字典中同时清除多余的姓名和这个姓名的条目
  40.         End If
  41.     Range("k26").Value = "刚才录入的是:" & [h26].Value     '备忘录语句
  42.     i = d.Keys      '“投票“之前再观察一次字典;关键字(候选人姓名)集合
  43.     j = d.Items     '“投票“之前再观察一次字典;条目(候选人姓名所在列数)集合
  44.     Range("h26:i26").ClearContents      '清除区域中的内容
  45.     Range("h28:o29").Value = Arr        '投票,即将数组内的值赋给单元格区域
  46.     [h26].Activate      '激活“姓名”输入单元格
  47. End Sub

  48. Sub 更改姓名()
  49.     If Range("i31").Value = "" Or Range("i32").Value = "" Then Exit Sub
  50.     If d.Exists(Range("i32").Value) Then    '如果关键字存在,则…
  51.         MsgBox "已经存在姓名" & Range("i32").Value & ",不能改名!", 48, "改名"
  52.     Else    '否则…
  53.         s1 = d(Range("i31").Value)      '查字典
  54.         i = d.Keys      '观察用;关键字(候选人姓名)集合
  55.         j = d.Items     '观察用;条目(候选人姓名所在列数)集合
  56.         d.Key(Range("i31").Value) = Range("i32").Value  '更改字典中的关键字(候选人姓名)
  57.         i = d.Keys      '观察用;关键字(候选人姓名)集合
  58.         j = d.Items     '观察用;条目(候选人姓名所在列数)集合
  59.         m = Arr     '观察用;改名之前数组的状态
  60.         Arr(1, s1) = Range("i32").Value     '更改数组中的候选人姓名
  61.         m = Arr     '观察用;改名之后数组的状态
  62.         Range("i31:j32").ClearContents      '清除区域中的内容
  63.         Range("h28:o29").Value = Arr        '将改名后数组内的值赋给单元格区域
  64.     End If
  65.     [h26].Activate      '激活“姓名”输入单元格
  66. End Sub

  67. Sub 删除姓名()
  68. i = d.Keys      '观察用;关键字(姓名)集合
  69. j = d.Items     '观察用;条目(姓名所在列数)集合
  70. m = Arr     '观察用;数组状态
  71.     If Range("i31").Value = "" Then Exit Sub
  72.     s1 = d(Range("i31").Value)      '查字典
  73.     d.Remove (Range("i31").Value)       '从字典中同时清除“错误的姓名”和这个姓名的条目(列号)
  74.     i = d.Keys      '观察用;关键字(姓名)集合
  75.     j = d.Items     '观察用;条目(姓名所在列数)集合
  76.     s = s - 1    '原有候选人数(亦即原有候选人占用的列数)-1
  77.     For t = s1 To k - 1
  78.         Arr(1, t) = Arr(1, t + 1)       '在数组中,依次以右列候选人姓名覆盖左列候选人姓名
  79.         Arr(2, t) = Arr(2, t + 1)       '在数组中,依次以右列候选人姓名的得票数覆盖左列候选人姓名的得票数
  80.         m = Arr     '观察用;“覆盖”后的数组状态
  81.         If Arr(1, t + 1) <> "" Then d(Arr(1, t + 1)) = t      '在字典中,依次将右列候选人姓名的条目数(列号)减1
  82.         i = d.Keys      '观察用;关键字(姓名)集合
  83.         j = d.Items     '观察用;条目(姓名所在列数)集合
  84.     Next
  85. Range("h28:o29").Value = Arr    '将数组内的值赋给单元格区域
  86. Range("i31:j32").ClearContents      '清除区域中的内容
  87. [h26].Activate      '激活“姓名”输入单元格
  88. End Sub

  89. Sub 合并姓名()
  90.     If Range("i34").Value = "" Or Range("i35").Value = "" Then Exit Sub
  91.     If Range("i34").Value = Range("i35").Value Then
  92.     MsgBox "相同姓名不存在合并运算!", 48, "合并姓名"
  93.     Range("i34:j35").ClearContents      '清除区域中的内容
  94.     [h26].Activate      '激活“姓名”输入单元格
  95.     Exit Sub
  96.     End If
  97.     s1 = d(Range("i34").Value)      '查字典
  98.     s2 = d(Range("i35").Value)      '查字典
  99.     Arr(2, s2) = Arr(2, s2) + Arr(2, s1)
  100.     Range("i31").Value = Range("i34").Value
  101.     Call 删除姓名
  102.     Range("i34:j35").ClearContents      '清除区域中的内容
  103.     [h26].Activate      '激活“姓名”输入单元格
  104. End Sub

  105. Sub 开始化()
  106.     d.RemoveAll    '清除字典中全部信息
  107.     d.CompareMode = IIf(Range("g27").Value, 1, 0)    'CompareMode等于0时区分大小写,等于1时不区分大小写
  108.                                                      '在投票开始之前点击特定按钮,可以方便地设置g27的值为1(TRUE)或0(FALSE)
  109.     s = 0   '为设置关键字(候选人姓名)的条目(候选人姓名所在列数)作准备
  110.     Erase Arr    '清除数组元素,但保留空间结构
  111.     Range("h26:k26,h28:o29,i31:j32,i34:j35").ClearContents    '清除评选表单元格区域中显示的内容
  112.     [h26].Activate      '激活h26单元格
  113. End Sub
复制代码

(欢迎批评指正
(一直想以实际行动替代回复,发布此主题也是对没有及时回复山菊花老师的致歉。)

TA的精华主题

TA的得分主题

发表于 2020-12-14 17:03 | 显示全部楼层
现在正在学习字典用法, 跟帖关注学习
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-17 09:43 , Processed in 0.031597 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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