【问题标题】:How to use FindFirst Function to compare 2 in-memory record-set?如何使用 FindFirst 函数比较 2 个内存记录集?
【发布时间】:2019-02-01 17:13:51
【问题描述】:

我想遍历 A 列并检查 B 列中是否存在任何值。我目前正在使用 .Find 函数,但是当我开始处理大量行 (>60 000) 时,它开始占用运行代码的时间很长。

我认为我可以在每列的内存记录集中创建 2 个并使用 .FindFirst 比较它们,但我无法使其工作。我认为这是因为我没有使用任何“ADO/DAO”连接,因为我的数据在工作簿本身中。

有没有办法在 B 列中为 A 列的每个值快速找到匹配项?

我尝试将代码更改为 .FindFirst 并使用记录集,但它一直说“对象不支持属性等...”。

For Each cel In rngRD.Cells

    With ThisWorkbook.Sheets("RawData").Range("A1:A" & Last_Row_DB)
        .Cells(1, 1).Activate
        Set CRef = .Find(What:=cel, _
                    After:=ActiveCell, _
                    LookIn:=xlValues, _
                    LookAt:=xlWhole, _
                    SearchOrder:=xlByRows, _
                    SearchDirection:=xlNext, _
                    MatchCase:=False, _
                    SearchFormat:=False)
        'If cannot be found then
        If CRef Is Nothing Then
            'Do Something
        Else
            Set CRef = .FindNext(CRef)
        End If

    End With

Next cel

【问题讨论】:

  • Excel Range 不是 RecordSet - 它是 Range(Excel 也不是“数据库”,但这既不是这里也不是那里......)。我建议在Dictionary 中建立一个查找,然后使用它。这里有很多关于如何做到这一点的例子。
  • @Comintern - 感谢您的快速回复。例如,如果我想用值 B 引用值 A,我认为会使用 Dictionary。这里 A 列和 B 列会有相似的数据,我只想知道它们之间是否可以找到重复项,字典会这样做吗?
  • 如果Dictionary 包含来自B 列的值,而Dictionary 中的A 列值.Exists,则它是重复的。 Here's an example over on Code Review.
  • @Comintern - 谢谢,我正在尝试这个并将发布结果!

标签: excel vba recordset findfirst


【解决方案1】:

我无法让它与字典一起使用,但找到了另一种方法来做我需要的事情,并且对于 >60 000 的行数,计算时间非常快。我现在能做的最好了!

Sub compareData()

Dim ListA As Range
Dim ListB As Range
Dim c As Range

'Create recordset to hold values to copy
Set rs = New Recordset
    With rs
        .Fields.Append "ID", adVarChar, 1000, adFldIsNullable
        .Fields.Append "Sector", adVarChar, 1000, adFldIsNullable
        .Fields.Append "Category", adVarChar, 1000, adFldIsNullable
        .Fields.Append "Description", adVarChar, 1000, adFldIsNullable
        .Fields.Append "DayNum", adVarChar, 1000, adFldIsNullable
        .Fields.Append "Site", adVarChar, 1000, adFldIsNullable
        .Fields.Append "Prod", adVarChar, 1000, adFldIsNullable
        .Fields.Append "SU", adInteger, , adFldMayBeNull
        .Fields.Append "BaseUnit", adInteger, , adFldMayBeNull
        .Open
    End With

'Define 2 lists to compare (ID's)
ListARange = Sheets("DATA").Cells(Rows.Count, "A").End(xlUp).Row 'Find the last row with data on column A
ListBRange = Sheets("RAW DATA").Cells(Rows.Count, "A").End(xlUp).Row 'Find the last row with data on column B

Set ListA = Sheets("DATA").Range("A2:A" & ListARange) 'Set your range only until the last row with data
Set ListB = Sheets("RAW DATA").Range("A2:A" & ListBRange)

'Check if ID already exists in the list, if not, add to recordSet
For Each c In ListB
    If Application.CountIf(ListA, c) = 0 Then
        rs.AddNew
        rs!ID = c
        rs!Sector = c.Offset(0, 1)
        rs!Category = c.Offset(0, 2)
        rs!Description = c.Offset(0, 3)
        rs!DayNum = c.Offset(0, 4)
        rs!Site = c.Offset(0, 5)
        rs!Prod = c.Offset(0, 6)
        rs!SU = c.Offset(0, 7)
        rs!BaseUnit = c.Offset(0, 8)
        rs.Update
    End If
Next c

【讨论】:

    猜你喜欢
    • 2018-07-12
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多