ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 常见字典用法集锦及代码详解

    [复制链接]

TA的精华主题

TA的得分主题

发表于 2021-12-18 20:12 | 显示全部楼层
本帖已被收录到知识树中,索引项:数组集合和字典
蓝桥玄霜 发表于 2010-10-18 12:53
实例7  字典法排序
一、问题的提出:
A列B列是按顺序排列的全部股票代码和股票名称,C列D列和E列F列是另 ...

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Count > 1 Then Exit Sub
    If Target.Column <> 4 And Target.Column <> 3 Then Exit Sub
    Dim arr, i%, mc$
    Dim d As Object
    Set d = CreateObject("scripting.dictionary")
    arr = [a1].CurrentRegion
    For i = 2 To UBound(arr)
        mc = IIf(Len(Trim(arr(i, 1))), arr(i, 1), arr(i - 1, 1))
        arr(i, 1) = mc
        d(mc) = d(mc) & arr(i, 2) & ","
    Next
    If Target.Column = 3 Then
        With Target.Validation
            .Delete
            .Add Type:=3, Formula1:=Join(d.keys, ",")
        End With
        Target.Offset(, 1) = ""
    ElseIf Target.Column = 4 And Target.Offset(, -1) <> "" Then
        With Target.Validation
            .Delete
            .Add Type:=3, Formula1:=d(Target.Offset(, -1).Value)
        End With
    End If
End Sub

TA的精华主题

TA的得分主题

发表于 2021-12-18 20:43 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
蓝桥玄霜 发表于 2010-10-18 12:54
实例9  字典取行数,数组重新赋值
一、问题的提出:
要求编写一段代码,求得B列不重复的名字,其相应的A ...

这段代码设计有问题,如有64和98 排第1,与63和99排第1,按代码会全部提取

TA的精华主题

TA的得分主题

发表于 2022-1-7 09:10 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-1-15 21:53 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-1-19 07:41 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-1-19 09:36 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-2-9 16:10 | 显示全部楼层
本帖最后由 excel002009 于 2022-2-9 20:21 编辑
蓝桥玄霜 发表于 2010-10-18 12:53
实例7  字典法排序
一、问题的提出:
A列B列是按顺序排列的全部股票代码和股票名称,C列D列和E列F列是另 ...

n年没碰字典,再复习一下蓝版字典教程。实例8已经是比较靠后的一个字典例子,对字典的应用不彻底,原代码用数组替代也行,有点不合理。
改进下:
  1. Dim d
  2. Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  3. If Target.Count > 1 Then Exit Sub
  4. If Target.Column <> 4 And Target.Column <> 3 Then Exit Sub
  5. Dim i&, Myr&, Arr, cp$, tempStr$: tempStr = ""
  6. Myr = Sheet1.[b65536].End(xlUp).Row
  7. Arr = Sheet1.Range("a2:b" & Myr)
  8. On Error GoTo 100
  9. If Target.Column = 3 Then
  10.     Set d = CreateObject("Scripting.Dictionary")
  11.     For i = 1 To UBound(Arr)
  12.         If Arr(i, 1) <> "" Then
  13.             If tempStr <> "" Then
  14.                 d(tempStr) = Left(cp, Len(cp) - 1)
  15.             End If
  16.             tempStr = Arr(i, 1)
  17.             cp = ""
  18.         End If
  19.         cp = cp & Arr(i, 2) & ","
  20.     Next
  21.     d(tempStr) = Left(cp, Len(cp) - 1)
  22.     With Target.Validation
  23.         .Delete
  24.         .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
  25.         Operator:=xlBetween, Formula1:=Join(d.keys, ",")
  26.     End With
  27.     Target.Offset(0, 1) = ""
  28. ElseIf Target.Column = 4 And Target.Offset(0, -1) <> "" Then
  29.     If d.exists(Target.Offset(0, -1).Value) Then
  30.         With Target.Validation
  31.             .Delete
  32.             .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
  33.             Operator:=xlBetween, Formula1:=d(Target.Offset(0, -1).Value)
  34.         End With
  35.     End If
  36.     Target = Split(d(Target.Offset(0, -1).Value), ",")(0)
  37. End If
  38. Exit Sub
  39. 100:
  40.     MsgBox "请先选择一级下拉选"
  41. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2022-2-12 17:11 | 显示全部楼层
蓝桥玄霜 发表于 2010-10-18 12:54
实例9  字典取行数,数组重新赋值
一、问题的提出:
要求编写一段代码,求得B列不重复的名字,其相应的A ...

实例9有误 字典存的项应该是k,数据特殊未暴露。
  1. Sub a()
  2.     Dim arr, d, k%, i%, j%
  3.     Set d = CreateObject("Scripting.Dictionary")
  4.     arr = Sheet1.UsedRange
  5.     For i = 2 To UBound(arr)
  6.         If Not d.Exists(arr(i, 2)) Then
  7.             k = k + 1
  8.             d(arr(i, 2)) = k
  9.             If i <> k Then
  10.                 For j = 1 To UBound(arr, 2)
  11.                     arr(k, j) = arr(i, j)
  12.                 Next
  13.             End If
  14.         Else
  15.             arr(d(arr(i, 2)), 1) = CStr(arr(d(arr(i, 2)), 1)) + " " + CStr(arr(i, 1))
  16.             arr(d(arr(i, 2)), 4) = CStr(arr(d(arr(i, 2)), 4)) + " " + CStr(arr(i, 4))
  17.             arr(d(arr(i, 2)), 5) = Val(arr(d(arr(i, 2)), 5)) + Val(arr(i, 5))
  18.             arr(d(arr(i, 2)), 6) = Val(arr(d(arr(i, 2)), 6)) + Val(arr(i, 6))
  19.         End If
  20.     Next
  21.     With Sheet2
  22.        .Cells.ClearContents
  23.        .[a1:f1].Resize(d.Count) = arr
  24.     End With
  25. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2022-2-12 19:47 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
蓝桥玄霜 发表于 2010-10-18 12:54
实例9  字典取行数,数组重新赋值
一、问题的提出:
要求编写一段代码,求得B列不重复的名字,其相应的A ...

1
  1. Sub pmcEx1()
  2.     Dim d, arr
  3.     Set d = CreateObject("scripting.dictionary")
  4.     arr = Range("a2:c" & Range("a" & Rows.Count).End(xlUp).Row)
  5.     For i = 1 To UBound(arr)
  6.         If Not d.exists(arr(i, 1) & "|" & arr(i, 3)) Then
  7.             d(arr(i, 1) & "|" & arr(i, 3)) = arr(i, 2)
  8.         Else
  9.             d(arr(i, 1) & "|" & arr(i, 3)) = Application.Max(Val(d(arr(i, 1) & "|" & arr(i, 3))), Val(arr(i, 2)))
  10.         End If
  11.     Next
  12.     [j:l].ClearContents
  13.     k = 0
  14.     For Each tempKey In d.keys
  15.         k = k + 1
  16.         [j1].Offset(k, 0) = Split(tempKey, "|")(0)
  17.         [j1].Offset(k, 2) = Split(tempKey, "|")(1)
  18.         [j1].Offset(k, 1) = d(tempKey)
  19.     Next
  20. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2022-2-13 11:21 | 显示全部楼层
蓝桥玄霜 发表于 2010-10-18 12:56
实例11  关键字赋给两列后用Replace方法
一、问题的提出:
有如图实例11-1所示的工资表,要求编写一段代 ...

实例11:
  1. Sub realGame()
  2.     Dim d, arr(), i%, j%, k%, originArr
  3.     ReDim arr(1 To 5, 1 To 1)
  4.     k = 0
  5.     Set d = CreateObject("Scripting.Dictionary")
  6.     originArr = Range("a1").CurrentRegion
  7.     arr(1, 1) = "性别"
  8.     arr(2, 1) = "姓名"
  9.     For j = 1 To UBound(originArr, 2) Step 3
  10.         '每月工资标题
  11.         arr(Int(j / 3) + 3, 1) = originArr(1, j + 2)
  12.         For i = 2 To UBound(originArr)
  13.            If originArr(i, j) = "" Then Exit For
  14.            If Not d.exists(originArr(i, j) & "|" & originArr(i, j + 1)) Then
  15.               k = k + 1  '不重复员工计数
  16.               If k + 1 > UBound(arr, 2) Then 'arr当前容量不支持k行数据+1标题行
  17.                 ReDim Preserve arr(1 To 5, 1 To UBound(arr, 2) + 10)
  18.               End If
  19.               d(originArr(i, j) & "|" & originArr(i, j + 1)) = k + 1 '每个不重复姓名映射自己所占用的列标
  20.               '在该员工自己占用列的一二行输入自己的性别、姓名
  21.               arr(1, k + 1) = originArr(i, j)
  22.               arr(2, k + 1) = originArr(i, j + 1)
  23.            End If
  24.            arr(Int(j / 3) + 3, d(originArr(i, j) & "|" & originArr(i, j + 1))) = originArr(i, j + 2)
  25.         Next
  26.     Next
  27.     [j:z].ClearContents
  28.     [j12].Resize(k + 1, 5) = Application.Transpose(arr)
  29. End Sub
复制代码
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-30 16:48 , Processed in 0.029962 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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