我刚接触VBA(2个月),我试图向脚本字典中添加三个变量以重新格式化Excel表,但我遇到了错误。
我尝试通过
添加三个变量countrydict.Add country, data, time
但是我收到一条错误消息
Run-time error '450':
Wrong number of arguments or invalid property assignment
但是如果我写
还是可以的countrydict.Add country, data 'or
countrydict.Add country, time
Dim lastrow As Long
Dim iter As Long
Dim diter As Long
Dim countrydict As Object
Dim country As String
Dim data As String
Dim time As String
Dim key As Variant
Dim i As Long
Const StartRow As Byte = 2
lastrow = Range("A" & StartRow).End(xlDown).Row
Set countrydict = CreateObject("Scripting.Dictionary")
Dim diter2 As Long, arr, arr2
With ActiveSheet
For iter = 2 To lastrow
country = Trim(.Cells(iter, 1).Value) '<<<<<
data = Trim(.Cells(iter, 2).Value) '<<<<<
time = Trim(.Cells(iter, 3).Text) '<<<<<
If countrydict.Exists(country) Then
If Not InStr(1, countrydict(country), data) > 0 Then
countrydict(country) = countrydict(country) & _
"|" & data & "/" & time
End If
Else
countrydict.Add country, data, time '<<<<<<<
End If
Next
iter = 2
For Each key In countrydict
.Cells(iter, 1).Value = key & ":"
.Cells(iter, 1).Font.Bold = True
.Cells(iter, 1).Font.ColorIndex = 30
iter = iter + 1
arr = Split(countrydict(key), "|")
For diter = 0 To UBound(arr)
arr2 = Split(arr(diter), "/")
.Cells(iter, 1).Value = arr2(0)
.Cells(iter, 2).Value = arr2(1)
Next diter
Next key
End With
End Sub
预期结果是以这种格式重新格式化表格
"A" "B" "C"
EU Sales 10:00
EU Tax 12:00
USA Sales 09:00
USA Tax 10:00
以这种格式
EU:
Sales 10:00
Tax 12:00
USA:
Sales 09:00
Tax 10:00
非常感谢您的帮助。几天来我一直在努力解决这个问题...
答案 0 :(得分:2)
VBA具有字典结构。 Dictionary is an object,并且可以通过早期绑定(例如Set countrydict = CreateObject("Scripting.Dictionary")
)或通过后期绑定来引用,指的是Microsoft脚本运行时(在VBEditor>其他>库):
后者的优点是速度更快,按 Ctrl + space 可以看到Intelli-Sense:
关于字典中具有多个变量的问题,则可能有一个包含这些变量的数组:
Sub MyDictionary()
Dim myDict As New Scripting.Dictionary
If Not myDict.Exists("Slim") Then
Debug.Print "Adding Slim"
myDict.Add "Slim", Array("Eminem", "has", "a", "daughter!")
End If
If Not myDict.Exists("Barcelona") Then
Debug.Print "Adding Barcelona"
myDict.Add "Barcelona", Array("I", "have", "been there", 2018)
End If
If Not myDict.Exists("Barcelona") Then
myDict.Add "Barcelona", Array("I", "have", "been there", 2018)
Else
Debug.Print "Barcelona already exists!"
End If
'Keys
Dim key As Variant
For Each key In myDict.Keys
Debug.Print "--------------"
Debug.Print "Key -> "; key
Dim arrItem As Variant
For Each arrItem In myDict(key)
Debug.Print arrItem
Next
Next key
End Sub
这是代码的结果:
Adding Slim
Adding Barcelona
Barcelona already exists!
--------------
Key -> Slim
Eminem
has
a
daughter!
--------------
Key -> Barcelona
I
have
been there
2018
如果字典的值不是数组,例如如果在myDict.Add "notArray", 124
处添加内容,则在尝试打印数组时会弹出错误。使用IsArray built-in function可以避免这种情况。
答案 1 :(得分:1)
另一种可能性是创建一个新类来存储您的数据。将数据存储在此类的实例中,然后将此对象传递给字典。
这样,您可以通过事件扩展类以返回其他内容,例如,将所有值组合为字符串等。使用公共属性,您甚至可以设置输入验证以及不进行输入验证,但这可能不止于此。现在需要。
我将“类”保持在绝对最小值,通常,类中的公共变量是不好的,但是由于我们仅将其用作自定义数据类型,所以这无关紧要。
编辑:我对该类进行了一些更新,以显示更多功能,但这里以旧的示例为例。
标准模块“模块1”:
Option Explicit
Sub fillDict()
Dim adict As Scripting.Dictionary
Set adict = New Dictionary
Dim info As myRegionData
Dim iter As Long
For iter = 0 To 10
Set info = New myRegionData
info.Region = "someRegion" & iter
info.data = "someData" & iter
info.Time = "someTime" & iter
adict.Add info.Region, info
Next iter
Dim returnInfo As myRegionData
Set returnInfo = adict.Item("someRegion1")
With returnInfo
Debug.Print .Region, .data, .Time 'someRegion1 someData1 someTime1
Debug.Print .fullSentence 'At someTime1 I was in someRegion1 and did someData1
End With
End Sub
类模块(简单)“ myRegionData”:
Option Explicit
Public Region As String
Public data As String
Public Time As String
类模块(扩展)“ myRegionData”:
Option Explicit
Private Type TmyRegionData
'More about this structure:
'https://rubberduckvba.wordpress.com/2018/04/25/private-this-as-tsomething/
Region As String
data As String
Time As String
End Type
Private this As TmyRegionData
Public Property Get Region() As String
Region = this.Region
End Property
Public Property Let Region(value As String)
this.Region = value
End Property
Public Property Get data() As String
data = this.data
End Property
Public Property Let data(value As String)
this.data = value
End Property
Public Property Get Time() As String
Time = this.Time
End Property
Public Property Let Time(value As String)
this.Time = value
End Property
Public Function getFullSentence() As String
getFullSentence = "At " & Time & " I was in " & Region & " and did " & data
End Function