【问题标题】:How Loop more efficiently?如何更有效地循环?
【发布时间】:2019-01-03 12:00:58
【问题描述】:

我遇到了与循环有关的情况。

问题是我想检查一个范围中的 EmployeeID 是否在另一个范围副本中不存在并将其粘贴到第二个范围中。

请看我的代码。实际上代码运行成功,但是出了点问题。另外我想问一下,我怎样才能让这段代码更有效地高速运行循环。其实我试过用数组,但不知道够不够用?

提前致谢!

Option Explicit

Sub UniqueWorkerCodeLoop()

Dim i As Integer
Dim j  As Integer
Dim DB As Worksheet:            Set DB = Worksheets("DB")
Dim Report As Worksheet:        Set Report = Worksheets("Report")
Dim Lrow1 As Long:              Lrow1 = DB.Range("A" & Rows.Count).End(xlUp).Row
Dim Lrow2 As Long:              Lrow2 = Report.Range("A" & Rows.Count).End(xlUp).Row
Dim DBTbl As ListObject:        Set DBTbl = DB.ListObjects("Table1")
Dim ReportTbl3 As ListObject:   Set ReportTbl3 = Report.ListObjects("Table3")
Dim DBArray As Variant:         DBArray = DB.ListObjects("Table1").DataBodyRange.Value
Dim ReportArray As Variant:     ReportArray = Report.ListObjects("Table3").DataBodyRange.Value

For i = 1 To UBound(DBArray, 1)
    For j = 1 To UBound(ReportArray, 1)
        If DBArray(i, 1) <> ReportArray(j, 1) Then
            DB.Range("A" & i + 3).Copy
            Report.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial (xlPasteValues)
        End If
    Next j
Next i
End Sub

【问题讨论】:

  • 如果您尝试仅比较来自 DBArray 的 1 列与 1 列 ReportArray 您可以使用 1 个循环和 Application.Match 而不是 2 个 For 循环

标签: arrays excel vba loops


【解决方案1】:

尝试类似:

for i = 1 to ubound(DBArray)
    if application.iferror(application.match(DBArray(i,1),ReportArray,0),0)=0 then Report.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).value = DBArray(i,1)
next i

您已经在数组中找到了值,因此只需将其附加到报告表中,而不是复制/粘贴(我使用了您的行并删除了 pastespecial;我没有测试代码)


编辑1:

尝试分解信息以确保我们提取到适当的信息:

Dim i as long, lrs as long, lrd as long, sarr as variant, darr as variant
with sheets("DB")
    lrs = .cells(.rows.count,1).end(xlup).row 'last row source
    sarr = .range(.cells(1,1),.cells(lrs,1)).value 'source array
end with
with sheets("Report")
    lrd = .cells(.rows.count,1).end(xlup).row 'last row destination
    darr = .range(.cells(1,1),.cells(lrd,1)).value 'destination array
    for i = lbound(sarr) to ubound(sarr)
        if application.isna(application.match(sarr(i,1),darr,0)) then
            lrd = .cells(.rows.count,1).end(xlup).row 'last row destination
            .cells(lrd+1,1).value = sarr(i,1)
        end if
    next i
end with

请注意,此代码使用工作表 DB 和报表中的行/列。

另请注意,示例代码中的最后一行表示没有完全限定的范围(例如,sheets("report").Rows.Count),这可能是您的问题的一部分。如果活动表(显示的内容)没有行,则您的 rows.count 将其显示为基本范围。

【讨论】:

  • 。 @ShaiRado 并不是要偷你的风头!有同样的想法(一维匹配,多维vlookup),并在我添加.value而不是复制/粘贴时发布
  • 感谢您的代码。但目前同样的问题还在继续。在 DBArray 我有 EmployeeID 和这个数组是动态的。 ReportArray EmployeeID 列是空的。当我第一次运行代码时,唯一的 EmployeeID 被传输到 ReportArray。但如果我再次运行相同的代码,代码会将相同的 EployeeID 带入 ReportArray。我无法解决它。
  • @Khazar 你的数据是不是显示在标准的excel电子表格中,支持列引用等?您使用的是“表格”引用,而不是诸如 Range(Cells(1,1),Cells(lastrow,1)) 之类的范围,所以这可能是问题的一部分吗?我不知道你的桌子是什么组成的。本质上,提供的概念应该符合要求:使用 match() 函数来确定一个值是否在一个范围内;当发生错误(也就是找不到值)时,您将该值附加到搜索范围的末尾。搜索范围可以是任意行数/列数。
  • @Khazar 更新了帖子,还注意到您的数据中有一些资格问题。
  • 非常感谢您的支持。您编辑的代码可以正常工作。我很感激你。
猜你喜欢
  • 2022-01-19
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
相关资源
最近更新 更多