ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享]浅谈DICTIONARY(字典)对象

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2007-9-10 20:52 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:数组集合和字典
狼兄辛苦了![em23][em23]

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-9-10 23:06 | 显示全部楼层

应用实例13  动态数据有效性

省份市名县区名邮编
天津市  120000
    
江西省江西省新余市 360500
    
    
    
    
河北省河北省保定市河北省保定市郊区130605
    

'模块代码

Public d As New Dictionary '定义字典对象

Sub createvaldition()
On Error Resume Next '忽略错误
Dim arr, i As Long
arr = Sheets("代码表").[a1].CurrentRegion
d.Add "all", "" '省市
For i = 1 To UBound(arr) '遍历
d.Add arr(i, 1), arr(i, 2) '地名查邮编
d.Add arr(i, 2), arr(i, 1) '邮编查地名
If arr(i, 2) Like "##0000" Then d("all") = d("all") & "," & arr(i, 1) '省级
If Mid(arr(i, 2), 3) > "0000" Then '省级以下
If Right(arr(i, 2), 2) = "00" Then '地市级
Mid(arr(i, 2), 3, 4) = "0000"
d(d(arr(i, 2))) = d(d(arr(i, 2))) & "," & arr(i, 1) '嵌套字典对象,反查
Else
Mid(arr(i, 2), 5, 2) = "00" '县区级
d(d(arr(i, 2))) = d(d(arr(i, 2))) & "," & arr(i, 1)
End If
End If
Next
    With [a2:a40].Validation '设置数据有效性
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Mid(d("all"), 2) '省份名称
        .IgnoreBlank = True
        .InCellDropdown = True
        .IMEMode = xlIMEModeNoControl
        .ShowInput = True
        .ShowError = True
    End With
End Sub

'工作表代码


Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next '忽略错误
If Target.Column < 4 Then '前三列
If Len(Target.Text) > 0 Then
Cells(Target.Row, 4) = Left(d(Target.Value), 6) '不为空使用字典取其邮编置于第四列
Else
Target.Offset(, 1).Resize(1, 3) = "" '为空则删除右面单元格的内容
Cells(Target.Row, 4) = Left(d(Target.Offset(, -1).Value), 6) '取相邻左面单元格地名的邮编
End If
    With Target.Offset(, 1).Validation '设置右面单元格的数据有效性
        .Delete
       .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Mid(d(Target.Value), 8)
        .IgnoreBlank = True
        .InCellDropdown = True
        .IMEMode = xlIMEModeNoControl
        .ShowInput = True
        .ShowError = True
    End With
End If
End Sub


33dSFbcl.rar (105.43 KB, 下载次数: 2165)
[此贴子已经被作者于2007-9-10 23:09:20编辑过]

TA的精华主题

TA的得分主题

发表于 2007-9-11 11:57 | 显示全部楼层

为什么这么好的地方总让斑竹们先占了呢?

呵呵,我也搬个板凳过来:)

TA的精华主题

TA的得分主题

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

版主辛苦,好贴!谢谢分亨

TA的精华主题

TA的得分主题

发表于 2007-9-12 18:50 | 显示全部楼层

向狼兄请教一个问题:

字典的key\item只有一个,所有我看到的例子,情况一样,key是应该只有一个,而item最好能有多个的,实际中,表格内有多项内容是很普遍的,没办法,我是先join,后split,但感觉不爽,是否还有好的办法?

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-9-12 22:19 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
QUOTE:
以下是引用smhf_6在2007-9-12 18:50:36的发言:

向狼兄请教一个问题:

字典的key\item只有一个,所有我看到的例子,情况一样,key是应该只有一个,而item最好能有多个的,实际中,表格内有多项内容是很普遍的,没办法,我是先join,后split,但感觉不爽,是否还有好的办法?

不是很明白你的问题.这个意思?

Sub macro1()
Dim i As Byte
With CreateObject("scripting.dictionary")
For i = 1 To 10
.Add 3 & "^" & i & "=" & 3 ^ i, i
.Add 4 & "^" & i & "=" & 4 ^ i, i
Next
MsgBox Join(.keys, vbCrLf)
MsgBox Join(.items, vbCrLf)
End With
End Sub

你传个附件看看

TA的精华主题

TA的得分主题

 楼主| 发表于 2007-9-12 23:31 | 显示全部楼层

应用实例14 数据的快速查找

说明:这是字典的经典用法

Private Sub CommandButton1_Click() '随机排序
Application.ScreenUpdating = False
    Dim n As Long
    n = [a65536].End(xlUp).Row
    [a:a].Copy [d1]
    [e1].Resize(n, 1).Formula = "=rand()" '设随机数辅助列用于排序
    [d:e].Sort Key1:=Range("e1"), Order1:=xlAscending, Header:=xlNo '排序
    [e:e] = "" '清空辅助列
Application.ScreenUpdating = True
End Sub


Private Sub CommandButton2_Click() '数据快速查找

Application.ScreenUpdating = False
Dim n  As Long, i As Long, arr, t As Single
t = Timer
n = [a65536].End(xlUp).Row
arr = [a1].Resize(n, 2)
With CreateObject("scripting.dictionary") '建立字典
For i = 1 To n
.Add arr(i, 1), arr(i, 2) '顺序建立字典内容
Next
arr = [d1].Resize(n, 1)
For i = 1 To UBound(arr)
arr(i, 1) = .Item(arr(i, 1)) '在字典中按key取item
Next
End With
[e1].Resize(UBound(arr), 1) = arr
Application.ScreenUpdating = True
MsgBox "查找完成,用时" & Timer - t & "秒!" '速度还可以
End Sub

 

Private Sub CommandButton3_Click() '生成原始数据
   [a:b].ClearContents
    [a1] = "X1"
    [b1] = 1
    [b2] = 2
    [a1].AutoFill Destination:=Range("a1:a20000")
    [b1:b2].AutoFill Destination:=Range("b1:b20000")
 
End Sub

Private Sub CommandButton4_Click()
[a:e] = ""
End Sub

AMXXTsrY.rar (14.13 KB, 下载次数: 1264)

TA的精华主题

TA的得分主题

发表于 2007-9-13 13:29 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2007-9-13 15:41 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
好贴,辛苦了。支持!

TA的精华主题

TA的得分主题

发表于 2007-9-13 22:23 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

谢谢版主分享。马上试做了一个,基本是安全照搬版主的代码,对代码的理解还是有点模糊。

显示1-100里含“3”的数字:

Sub dd()
Dim d As Object
Dim i As Long
Set d = CreateObject("scripting.dictionary")
For i = 1 To 100
If i Like "*" & 3 & "*" Then
d.Add i, ""
End If
Next
MsgBox Join(d.keys, vbCrLf)
Set d = Nothing
End Sub

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-23 10:54 , Processed in 0.039306 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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