|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
本帖最后由 microyip 于 2019-10-21 17:42 编辑
最近,看到了“月关”坛友对字典嵌套的热衷,今天又刚好有个坛友问及字典嵌套的应用,突然想弄个字典嵌套与递归的混合应用教程范例出来的冲动。
先看看本帖二楼的常规字典嵌套的应用,代码也不是很复杂,也易于理解,但存在一个缺陷,对字典嵌套层数必须用手工一层层写进代码里。
利用递归方式写字典嵌套,就可以相对简单解决层数问题了,就代码相对复杂了点。
其中,代码中关于建设字典过程基本是没问题的,但递归应用字典代码中,我已知有一定的Bug,但具体这个Bug在实际应用会不会产生呢?暂时不知道,所以我也没有预先设置代码去处理了。如果有朋友专门指出或者其他我未知的Bug,欢迎提出指正。
- Sub 递归建立字典嵌套示例()
- Dim oDic As Object, vKey As Variant, vMsg As Variant, sMsg As String
- Dim vData As Variant, nRow As Long, nCol As Long
-
- vData = [{"广东省","深圳市","罗湖区";"广东省","深圳市","宝安区";"广东省","广州市","海珠区";"广东省","广州市","白云区"}]
- '需要设置字典的数据
- For nRow = 1 To UBound(vData)
- vKey = Application.WorksheetFunction.Index(vData, nRow) '获取字典设置需要的关键字数组
- Set oDic = SetDic(oDic, vKey, nRow) '对vKey指定关键字进行字典层级设置
- Next
-
- vData = [{"广东省","深圳市","罗湖区";"广东省","广州市","东山区";"广东省","珠海市","香山区";"浙江省","杭州市","西湖区"}]
- '需要检索字典的结果
- For nRow = 1 To UBound(vData)
- vKey = Application.WorksheetFunction.Index(vData, nRow) '检索字典的关键字数组
- vMsg = GetDicMsg(oDic, vKey) '获取指定关键字在检索字典过程中的信息
- If vMsg(3) = "" Then
- sMsg = "【" & vMsg(2) & "】的数据排序是:" & vMsg(1)
- Else '存在出错关键字
- If Not vMsg(4) Then '当存在最后关键字得到是字典
- sMsg = "数据内存在【"
- If vMsg(2) <> "" Then sMsg = sMsg & vMsg(2) & ","
- sMsg = sMsg & vMsg(3) & "】,但不是一个最终值"
- Else
- sMsg = "数据内不存在【"
- If vMsg(2) <> "" Then sMsg = sMsg & vMsg(2) & "】的【"
- sMsg = sMsg & vMsg(3) & "】"
- End If
- End If
- If sMsg <> "" Then MsgBox sMsg
- Next
- End Sub
- Private Function SetDic(ByVal oDic As Variant, ByVal vKey As Variant, Optional ByVal vItem As Variant, Optional ByVal nIndex As Long) As Object
- 'oDic,设定的字典初始状态
- 'vKey,字典的关键字或者关键字数组
- 'vItem,字典最终设置的Item值
- 'nIndex,需要设置的字典层数
- If IsMissing(vItem) Then '当函数接收的vItem参数没有被传过来参数值时
- vItem = Empty '预设一个参数值
- End If
- If TypeName(oDic) <> "Dictionary" Then '参数oDic的类型不是字典类型时
- Set oDic = CreateObject("Scripting.Dictionary") '设置oDic为一个新字典
- End If
- If IsArray(vKey) Then 'vKey是数组时
- If nIndex = 0 Then '当函数接收的nIndex参数没有被传过来参数值时
- nIndex = LBound(vKey) '获取第一层关键字数组的序号
- End If
- If nIndex = UBound(vKey) Then '需要设置的字典层数为最大关键字数组序号时
- oDic(vKey(nIndex)) = vItem '建立字典
- Else
- Set oDic(vKey(nIndex)) = SetDic(oDic(vKey(nIndex)), vKey, vItem, nIndex + 1) '建立下一层字典
- End If
- Else 'vKey不是数组时
- oDic(vKey) = vItem '建立字典
- End If
- Set SetDic = oDic '返回已建立的字典
- End Function
- Private Function GetDicMsg(ByVal oDic As Object, ByVal vKey As Variant, Optional ByVal vMsg As Variant, Optional ByVal nIndex As Long) As Variant
- 'oDic,匹配数据的字典
- 'vKey,字典的关键字或者关键字数组
- 'vMsg,返回用的信息
- 'nIndex,需要设置的字典层数
- Dim nI As Long, vKey_Now As Variant
-
- If IsMissing(vMsg) Then '当函数接收的vMsg参数没有被传过来参数值时
- ReDim vMsg(1 To 4) '重置数组,1、最终的Item结果;2、能获取的关键字;3、不能获取的关键字或获取的关键字得到的是一个字典;4、最终Item结果不是字典
- vMsg(4) = True
- End If
- If IsArray(vKey) Then 'vKey是数组时
- If nIndex = 0 Then '当函数接收的nIndex参数没有被传过来参数值时
- nIndex = LBound(vKey) '获取第一层关键字数组的序号
- End If
- vKey_Now = vKey(nIndex) '当前的关键字值
- If oDic.Exists(vKey_Now) Then '存在对应层字典的关键字
- If nIndex = UBound(vKey) Then '需要读取的字典层数为最大关键字数组序号时
- vMsg(4) = TypeName(oDic(vKey_Now)) <> "Dictionary" '当前关键字得到的是否字典类型
- If vMsg(4) Then '当前关键字的不是字典类型
- vMsg(1) = oDic(vKey_Now) '记录最终的Item结果
- If vMsg(2) <> "" Then vMsg(2) = vMsg(2) & ","
- vMsg(2) = vMsg(2) & vKey_Now '记录获取的关键字
- Else
- vMsg(3) = vKey_Now '记录获取的关键字得到的是一个字典
- End If
- Else
- If vMsg(2) <> "" Then vMsg(2) = vMsg(2) & ","
- vMsg(2) = vMsg(2) & vKey_Now '记录获取的关键字
- vMsg = GetDicMsg(oDic(vKey_Now), vKey, vMsg, nIndex + 1) '对下一层级的字典检索
- End If
- Else
- vMsg(3) = vKey_Now '记录不能获取的关键字
- End If
- Else 'vKey不是数组时
- If oDic.Exists(vKey) Then
- vMsg(4) = TypeName(oDic(vKey)) <> "Dictionary" '当前关键字得到的是否字典类型
- If vMsg(4) Then '当前关键字的不是字典类型
- vMsg(1) = oDic(vKey) '记录最终的Item结果
- vMsg(2) = vKey '记录获取的关键字
- Else
- vMsg(3) = vKey '记录获取的关键字得到的是一个字典
- End If
- Else
- vMsg(3) = vKey '记录不能获取的关键字
- End If
- End If
- GetDicMsg = vMsg '返回信息
- End Function
复制代码
附上附件以供参考
递归建立字典嵌套示例(by.micro).rar
(22.92 KB, 下载次数: 126)
|
评分
-
4
查看全部评分
-
|