【发布时间】:2018-08-19 05:22:09
【问题描述】:
我正在尝试获取独特的国家名称以及该特定国家的任何独特水果(类似于下表)。我尝试使用二维数组,但它变得复杂了。
End result with plan to put Country in one combobox that populates 2nd combobox with Fruit when selected.
我看到有人在字典中推荐字典,但我很难理解这个概念。我尝试了多种方法来设置文本字典,但我不断收到 Argument Not Optional 或 Object Required 错误。我只是语法错误还是我正在尝试做的事情存在根本问题?
编辑
万一有人尝试这样做,我意识到将文本连接在一起然后在需要时将它们拆分成一个数组要容易得多。见下文:
Dim Arr As Variant
Dim rng1 As Range
Dim rng2 As Range
Dim newRng As Range
Dim name As String
Dim text As String
Dim j As Long
Dim i As Long
Dim dcName As Scripting.Dictionary
Set dcName = New Scripting.Dictionary
Set rng1 = tbl.ListColumns("Name1").DataBodyRange
Set rng2 = tbl.ListColumns("Name5 Text").DataBodyRange
Set newRng = Range(rng1, rng2)
Arr = newRng
For i = 1 To 10 Step 2
For j = LBound(Arr) To UBound(Arr)
name = Arr(j, i)
text = Arr(j, i + 1)
If name <> vbNullString Then
dcName(name) = dcName(name) & "|" & text
End If
Next j
Next i
ReDim arrSort(0 To dcName.Count - 1, 0 To 1)
For Key = 0 To dcName.Count - 1
arrSort(Key, 0) = dcName.Keys(Key)
arrSort(Key, 1) = dcName.Items(Key)
Next Key
For i = LBound(arrSort) To UBound(arrSort) - 1
For j = i + 1 To UBound(arrSort)
If UCase(arrSort(i, 0)) > UCase(arrSort(j, 0)) Then
tempName = arrSort(j, 0)
tempText = arrSort(j, 1)
arrSort(j, 0) = arrSort(i, 0)
arrSort(j, 1) = arrSort(i, 1)
arrSort(i, 0) = tempName
arrSort(i, 1) = tempText
End If
Next j
Next i
Me.cbName.List = arrSort
然后您可以将文本值拆分为一个数组并用它填充一个组合框。比我想象的要容易得多。
Private Sub cbName1_Change()
Dim i As Integer
Dim selName As String
Dim arrText As Variant
Me.cbName1Text.Clear
selIndex = Me.cbName1.ListIndex
text = arrSort(selIndex, 1)
arrText = Split(text, "|")
For i = LBound(arrText) To UBound(arrText)
If arrText(i) <> vbNullString Then
Me.cbName1Text.AddItem arrText(i)
End If
Next i
End Sub
以前的工作尝试在字典中使用字典
按 cmets 编辑
Sub GetAbilities()
Dim Arr As Variant
Dim rng1 As Range
Dim rng2 As Range
Dim newRng As Range
Dim name As Variant
Dim text As Variant
Dim dcName As Scripting.Dictionary
Dim dcText As Scripting.Dictionary
Set dcName = New Scripting.Dictionary
Set dcText = New Scripting.Dictionary
Set rng1 = tbl.ListColumns("Name1").DataBodyRange
Set rng2 = tbl.ListColumns("Text3").DataBodyRange
Set newRng = Range(rng1, rng2)
Arr = newRng
counter = 0
For j = 1 To 10 Step 2
For i = LBound(Arr) To UBound(Arr)
name = Arr(i, j)
text = Arr(i, j + 1)
If dcName.Exists(name) Then
If Not dcText.Exists(text) Then
dcText.Add text, counter
End If
Else
Set dcText = CreateObject("Scripting.Dictionary")
dcName.Add name, dcText
If text <> vbNullString Then
dcText.Add text, counter
End If
End If
counter = counter + 1
Next i
Next j
For Each n In dcName.Keys
For Each t In dcName.item(n).Keys
Debug.Print n, t
Next t
Next n
End Sub
【问题讨论】:
-
您需要指定一个键和值,以便 dcText.Add 文本(沿右行)仅添加一个键而没有值,因此该参数不是可选警告。并且根据您正在谈论的第一个键实例的想法,该键的第一个实例将具有一个关联值,该值将是一个 CreateObject 来创建您想要作为内部字典的字典。
-
谢谢,我认为将目录设置在顶部就足够了。
-
如果我知道 dcName 键,我将如何访问子字典 (dcText)?我可以将 dcName 键放入组合框中,并在选择它时获取该键。但是如何获取项目(即 dcText)以便获取它的密钥?
-
取决于您添加项目的方式。如果子字典已经存在,那么您可以将它们作为值添加到主字典中。
-
查看@displayname 对我所描述内容的回答(使用早期绑定)
标签: arrays vba excel dictionary