首页 > 解决方案 > 合并来自不同工作表的几位数据

问题描述

我正在尝试合并来自不同工作表的几位数据。经过几个问题和尝试(在数组中,感谢 Stackoverflow 之前的帮助),我认为字典可能是最好的。最终结果是一个填充表,其中包含每个条目的所有数据。(取决于条目,原始数据中的列中的数据可能位于不同的位置)

数据可以包括一个人的多个条目。但是每个条目的数据根据​​条目的阶段而有所不同。例如,如果条件是阶段 1,则第 3 列中的数据将位于最终表的第 5 列,但是如果条件是阶段 2,则第 3 列中的相同数据可能是最终表的第 10 列。

https://www.youtube.com/watch?v=o8fSY_4p93s

按照这个视频教程 ondictionaires,我想我可以通过 dtaa 找到每个单独的条目,然后为案例添加相应的变量。例如,查找 Steve Smith 的数据,如果 steve smith 存在则如果 stage 1,则将数据添加到变量 stagedate1,如果 stage2 将数据添加到 stage2date 等等。如果没有找到添加条目并找到舞台。

与视频类似,他在其中找到每个客户的相应数据,并添加销售额和销量,如果之前使用 if 函数来确定哪个数据阶段,然后将值放入正确的变量中,我也可以这样做。

我知道会有一百万种方法可以做到这一点,但这似乎简单而有效。

Sub Dictionary()

Dim dict As Dictionary

Set dict = ReadData()

Call WriteDict(dict)

End Sub

Function ReadData()

Dim dict As New Dictionary

Dim DataWs As Worksheet: Set DataWs = ThisWorkbook.Sheets("DATA")
Dim PoolOfWeekWs As Worksheet: Set PoolOfWeekWs = ThisWorkbook.Sheets("Pool of the week")

Dim LastrowData As Long: LastrowData = DataWs.range("A" & Rows.Count).End(xlUp).Row
Dim LastColData As Long: LastColData = DataWs.Cells(1 & DataWs.Columns.Count).End(xlToLeft).Column


Dim LastColDataString As String: LastColDataString = Split(Cells(1, LastColData).Address, "$")(1)

Dim DataRange As range: Set DataRange = DataWs.range("A1:" & LastColDataString & LastrowData)
Dim DataArr As Variant: DataArr = DataWs.range("A1:AO" & LastrowData)

Dim range As range: Set range = DataWs.range("A1").CurrentRegion

Dim i As Long
Dim CandidateProcessID As String, CandidateName As String, FirstName As String, ProcessStatus As String, PQLDate As Date, oCandidate As ClsCandidate

For i = 2 To range.Rows.Count
    CandidateProcessID = range.Cells(i, 10).Value
    CandidateName = range.Cells(i, 16).Value
    FirstName = range.Cells(i, 17).Value
    ProcessStatus = range.Cells(i, 9).Value
    
    If dict.Exists(CandidateProcessID) = True Then
        Set oCandidate = dict(CandidateProcessID)   'CODE ERRORS HERE AFTER A FEW ROWS (Comes across a 
    Else                                             an entry that is already in the dictionary)
        Set oCandidate = New ClsCandidate
        dict.Add CandidateProcessID, oCustomer
    End If
    
    oCandidate.CandidateName = oCandidate.CandidateName
    oCandidate.FirstName = oCandidate.FirstName
    oCandidate.ProcessStatus = oCandidate.ProcessStatus
    oCandidate.PQLDate = oCandidate.PQLDate
Next i

Set ReadData = dict


End Function

Sub WriteDict(dict As Dictionary)

    Dim key As Variant, oCandidate As ClsCandidate
    
    For Each key In dict
        Set oCandidate = dict(key)
        Debug.Print key, oCandidate.CandidateName, oCandidate.FirstName, oCandidate.ProcessStatus, oCandidate.PQLDate
    Next key

End Sub

标签: arraysexcelvbadictionary

解决方案


我相信错误是对象错误。它停止并调试。

那将是“需要对象”,它与一个非常常见的陷阱绝对一致:在每个模块Option Explicit的顶部添加,现在 VBA 不会让您运行代码,直到它知道是什么。oCustomer

Option Explicit丢失允许代码在oCustomer未声明的情况下运行:简单地说,为该本地标识符(“oCustomer”)现场创建一个新Variant/Empty指针,这样每次“工作”的迭代都只是为制作那些做准备不,炸毁:

    If dict.Exists(CandidateProcessID) = True Then
        Set oCandidate = dict(CandidateProcessID) '<~ Variant/Empty is retrieved here: "object required"
    Else
        Set oCandidate = New ClsCandidate
        dict.Add CandidateProcessID, oCustomer '<~ Variant/Empty is added here
    End If

Variant/Empty成功从字典中检索到:问题是该运算符Set oCandidate左侧的指令=说该操作的右侧必须是对象引用。Variant/Empty未能满足此要求,并引发“需要对象”运行时错误。

错误不在于检索:它与存储有关!

您可以使用静态代码分析工具轻松找到此类错误,例如Rubberduck(披露:这是我的网站)。


推荐阅读