简体   繁体   English

VBA-Excel字典

[英]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 . 关键字NewScripting.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. keyk变量被设置为VariantObject ,因此它没有将其值正确地作为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM