[英]VBA-excel dictionary
Im copying cells from one sheet to another, finding and matching column header names and pasting to the correct cell. 我将单元格从一张纸复制到另一张纸,查找并匹配列标题名称,然后粘贴到正确的单元格。 These column header names differ slightly per sheet, altough they contain the same data.
这些列标题名称每张纸略有不同,尽管它们包含相同的数据。 My working code has a lot of repetition:
我的工作代码有很多重复之处:
' sub that finds head in a specified worksheet and sets rngCol variable
Sub rngByHead(Sheet As Worksheet, head As String)
' sub for copying data
With Source1
' find and set producer, note name difference)
Call rngByHead(Source1, "bedrijfsnaam")
Dim producent As String
producent = .Cells(docSource1.Row, rngCol).Value
' find and set Fase
Call rngByHead(Source1, "Fase")
Dim fase As String
fase = .Cells(docSource1.Row, rngCol).Value
' find and set Status
Call rngByHead(Source1, "Status")
Dim status As String
status = .Cells(docSource1.Row, rngCol).Value
' find and set versionnumber, note name difference
Call rngByHead(Source1, "Wijziging")
Dim versienummer As String
versienummer = .Cells(docSource1.Row, rngCol).Value
End With
With Target
' find and write all variables to uploadlijst
Call rngByHead(Target, "bestandsnaam")
.Cells(cell.Row, rngCol).Value = bestand
Call rngByHead(Target, "producent")
.Cells(cell.Row, rngCol).Value = producent
Call rngByHead(Target, "fase")
.Cells(cell.Row, rngCol).Value = LCase(fase)
Call rngByHead(Target, "status")
.Cells(cell.Row, rngCol).Value = LCase(status)
Call rngByHead(Target, "versienummer")
.Cells(cell.Row, rngCol).Value = versienummer
End With
I was trying a more cleaner option with a dictionary for matching the different header names in target and data sheets. 我正在尝试使用字典更干净的选项,以匹配目标表和数据表中的不同标题名称。 I also created a secong dictionary to store those values under the specific keys.
我还创建了一个secong字典来将这些值存储在特定键下。 I keep getting errors on this code, both 424 object missing as ByRef argument type mismatch.
我不断在此代码上出错,因为ByRef参数类型不匹配,两个424对象都丢失了。
' Create dict
Dim dict As Scripting.Dictionary
' Create dictValues
Dim dictValues As Scripting.Dictionary
Dim key As Object
' Add keys to dict
dict("producent") = "Bedrijfsnaam"
dict("fase") = "Fase"
dict("status") = "Status"
dict("versienummer") = "Wijziging"
dict("documentdatum") = "Datum"
dict("omschrijving1") = "Omschrijving 1"
dict("omschrijving2") = "Omschrijving 2"
dict("omschrijving3") = "Omschrijving 3"
dict("discipline") = "Discipline"
dict("bouwdeel") = "Bouwdeel"
dict("labels") = "Labels"
' store values of sheet Source 1
With Source1
' create second dictValues to store values for each key
Set dictValues = New Scripting.Dictionary
' loop through keys in dict, this line gives error 424
For Each key In dict.Keys
' use dict to pass right value to rngByHead sub
Call rngByHead(Target, dict(key))
' store value of cell to dictValues under same key
dictValues(key) = .Cells(cell.Row, rngCol).Value
Next key
End With
' set values to sheet Target
With Target
' loop through keys in dict
For Each key In dict.Keys
' use dict to pass value of key item to rngByHead sub
Call rngByHead(Target, key)
' set value of cell to dictValues
.Cells(cell.Row, rngCol).Value = dictValues(key)
Next key
End With
What am I doing wrong? 我究竟做错了什么? I'm new to vba dictionary and can't figure this one out.
我是vba字典的新手,无法解决这一问题。 Thanks for your help!
谢谢你的帮助!
Try like this: 尝试这样:
Dim dict As New Scripting.Dictionary
Dim dictValues As New Scripting.Dictionary
The keyword New
initializes an object from type Scripting.Dicitionary
. 关键字
New
从Scripting.Dicitionary
类型初始化一个对象。 Without it, no new object is initialized, just an object of type Scripting.Dictionary
is declared. 没有它,就不会初始化新对象,只会声明
Scripting.Dictionary
类型的对象。 This is called early binding in VBA. 这在VBA中称为早期绑定。 See a bit here - What is the difference between Early and Late Binding?
在这里看到一点- 早期绑定和后期绑定有什么区别?
I fixed it! 我修好了它! Posting the code here on Stackoverflow for future reference.
在此处将代码发布到Stackoverflow上,以备将来参考。 It turned out to be very simple, my dictionary was working fine.
事实证明这很简单,我的字典运行良好。 The
key
or k
variable was set as Variant
or Object
, so it didn't pass it's value correctly as String
to the rngByHead sub. key
或k
变量被设置为Variant
或Object
,因此它没有将其值正确地作为String
传递给rngByHead子对象。 Converting the k
to str
as String
did the trick. 将
k
转换为str
作为String
。
'sub that finds head in a specified worksheet and sets rngCol variable
Sub rngByHead(Sheet As Worksheet, head As String)
'setting up dictionary
Dim dict As New Scripting.Dictionary
Dim dictValues As New Scripting.Dictionary
Dim k As Variant
Dim str As String
'create dictionary
Set dictValues = New Scripting.Dictionary
Set dict = New Scripting.Dictionary
'add keys to dict
dict("producent") = "Bedrijfsnaam"
dict("fase") = "Fase"
dict("status") = "Status"
dict("versienummer") = "Wijziging"
dict("documentdatum") = "Datum"
dict("omschrijving1") = "Omschrijving"
dict("omschrijving2") = "Omschrijving 2"
dict("omschrijving3") = "Omschrijving 3"
dict("discipline") = "Discipline"
dict("bouwdeel") = "Bouwdeel"
dict("labels") = "Labels"
'store values of sheet Source 1
With Source1
'find and set variables using dictionary
'creating array of keys
keys = dict.keys
For Each k In keys
Call rngByHead(Source1, dict(k))
dictValues(k) = .Cells(docSource1.Row, rngCol).Value
Next
End With
With Target
'find and write variables using dictionary
For Each k In keys
'converting k as Variant to str as String
str = k
Call rngByHead(Target, str)
.Cells(cell.Row, rngCol).Value = dictValues(k)
Next
End With
Another note: you have to enable Microsoft Scripting Runtime
in microsoft visual basic code editor under Tools
> References
. 另一个注意事项:您必须在Microsoft Visual Basic代码编辑器中的“
Tools
>“ References
下启用Microsoft Scripting Runtime
。
Provided a user has enabled the option Trust Access to the VBA Project object model
in File
-> Options
-> Trust Center
-> Trust Center Setttings
-> Macro Settings
. 如果用户在
File
-> Options
-> Trust Center
-> Trust Center Setttings
-> Macro Settings
启用选项Trust Access to the VBA Project object model
。 You can run this code and enable the Microsoft Scripting Runtime
reference: 您可以运行以下代码并启用
Microsoft Scripting Runtime
参考:
Sub Test()
Dim Ref As Object, CheckRefEnabled%
CheckRefEnabled = 0
With ThisWorkbook
For Each Ref In .VBProject.References
If Ref.Name = "Scripting" Then
CheckRefEnabled = 1
Exit For
End If
Next Ref
If CheckRefEnabled = 0 Then
.VBProject.References.AddFromGUID "{420B2830-E718-11CF-893D-00A0C9054228}", 1, 0
End If
End With
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.