【问题标题】:How to make multiple "for" statements run efficiently in VBA如何使多个“for”语句在 VBA 中高效运行
【发布时间】:2019-08-30 02:37:39
【问题描述】:

在我的代码中有一个搜索顺序,如下所示:

它获取 ws.sheet range A 中的每个值(大约 2000 个范围)并在另一个名为 wp.sheet range A 的工作表中查找它(大约 90 个范围)。如果 ws.sheet 范围中的特定值 x,例如 A3 在 wp.sheet 范围 A 中未找到,则工作表 ws.sheet 中的下一个搜索顺序是要搜索的下一个范围 B3(与值 x 相同的行)中的值 y表 wp.sheet 在整个范围 B 中,依此类推。

这就是我的“for”循环所做的事情,我的代码的问题在于,它将 ws.sheet 范围 A1-2000 中的每个值与 wp.sheet 范围 A1-90 中的值进行比较需要很长时间。有没有更快或更有效的替代方法?

Dim wb As Workbook, wq As Object
Dim ws, wi As Worksheet, datDatum
Dim w As Long, I As Long, t As Long
Dim DefaultMsgBox()
Dim r, i As Integer    



For r = 2 To 2000

Check = True:

For i = 1 To 90
    If ws.Range("A" & r).Value = wp.Sheets("ABC").Range("A" & i).Value Then
       wp.Sheets("ABC").Rows(i).Columns("E:AB").Copy
       ws.Range("G" & r).PasteSpecial
       GoTo NextR
    End If
Next i

For i = 1 To 90
     If ws.Range("B" & r).Value = wp.Sheets("ABC").Range("B" & i).Value Then
        wp.Sheets("ABC").Rows(i).Columns("E:AB").Copy
        ws.Range("G" & r).PasteSpecial
        GoTo NextR
     End If
Next i

For i = 1 To 90
     If ws.Range("C" & r).Value = wp.Sheets("ABC").Range("C" & i).Value And ws.Range("D" & r).Value = wp.Sheets("ABC").Range("D" & i).Value Then
        wp.Sheets("ABC").Rows(i).Columns("E:AB").Copy
        ws.Range("G" & r).PasteSpecial
        GoTo NextR
     End If
 Next i

NextR:
    If Not Check = ws.Range("A" & r).Value = wp.Sheets("ABC").Range("A" & i).Value Or Not Check = ws.Range("B" & r).Value = wp.Sheets("ABC").Range("A" & i).Value Or Not Check = ws.Range("C" & r).Value = wp.Sheets("ABC").Range("C" & i).Value And ws.Range("D" & r).Value = wp.Sheets("ABC").Range("D" & i).Value Then
    MsgBox "......"
    End If
Next r
End sub

【问题讨论】:

  • 是否需要在 A 列中 B 列之前搜索该值?列 C 和 D 应该一起检查,还是通过组合条件进行试验? .Copy 是否应该做任何事情,还是与以后的粘贴一起使用?
  • 非常感谢您的评论。我也添加了粘贴命令。我已经排除了它,因为它没有必要。搜索的顺序是固定的,是有目的的
  • 为什么是“下一个 ru”?应该是“下一个我”
  • 没错,我已经更正了

标签: vba for-loop row next


【解决方案1】:

我建议关闭 ScreenUpdating 并改用 Find 功能:

Dim cell, foundValue, lookupRange As Range

Set wp = ThisWorkbook.Sheets("ABC")
Set ws = ThisWorkbook.Sheets("WS")

r = 2
number_r = 2000
ru = 1
number_ru = 90

Application.ScreenUpdating = False

'Loop through each cell in WS, offsetting through columns A to C
For Each cell In ws.Range("A" & r & ":A" & number_r)
    For i = 0 To 2

        'Define range to look up in ABC
        Set lookupRange = wp.Range(wp.Cells(ru, i + 1), wp.Cells(number_ru, i + 1))

        'Look for current WS cell on corresponding column in ABC
        Set foundValue = lookupRange.Find(cell.Offset(0, i).Value)

        'If cell is found in ABC...
        If Not foundValue Is Nothing Then
            Select Case i
            Case 2 'If found cell is in column C

                Do 'Lookup loop start

                'If same values on columns D...
                If foundValue.Offset(0, 1).Value = cell.Offset(0, 3).Value Then

                    'Copy data to WS and switch to the next cell
                    wp.Rows(foundValue.Row).Columns("E:AB").Copy
                    ws.Range("G" & cell.Row).PasteSpecial
                    GoTo nextCell

                'If not same values on columns D...
                Else

                    'Try to find next match, if any
                    Set foundValue = lookupRange.FindNext(foundValue)
                    If foundValue Is Nothing Then GoTo noMatchFound

                End If

                Loop 'Repeat until WS values in column C and D match ABC values in columns C and D

            Case Else 'If found cell is in column A or B

                'Copy data to WS and switch to the next cell
                wp.Rows(foundValue.Row).Columns("E:AB").Copy
                ws.Range("G" & cell.Row).PasteSpecial
                GoTo nextCell

            End Select

        End If
    Next i
noMatchFound:
    MsgBox "......" 'Message appears only when no match was found in column A, column B and column C + D
nextCell:
Next cell

Application.ScreenUpdating = True

【讨论】:

  • 您好查韦斯,感谢您的支持。我马上试试
  • 嗨查韦斯,代码不是我要找的。在您的代码中,当在工作表 ABC range(A i) 中找到范围 (A r) 中的值时,它会跳转到下一个列 B 并继续搜索。但我的意图是:在工作表“ws”的范围(A2)中取值,并在工作表 ABC 范围(A)中查找。如果在工作表 ABC 范围 A 中找到 A2,则一切正常。如果未找到,则跳转到工作表“ws”中的 B2 并在工作表 ABC 范围 B 中查找该值,依此类推。这就是我的“for”循环状态。但是,它需要很长时间才能通过所有范围。我将进一步编辑我的文字以使其更清晰
  • 嗨 Yavuz,我根据您的说明修改了代码。我还关闭了 ScreenUpdating 以尝试使代码运行得更快。让我知道这是否符合您最初的预期。
  • 嗨查韦斯非常感谢您的努力。我已经用一些示例尝试了代码,它似乎工作得很好。尽管还有一件事,是否也可以在“查找”部分中包含一个附加代码,在查看和比较两张表中的 A 和 B 列的值之后,它不仅需要 C 列,还需要 C 列中的值和 D 一起并将其与另一张表中的 C 和 D 列进行比较。并且条件是两个值在两张表中都必须相同。我正在考虑“Application.Match”功能。那适合吗?
  • 你好亚武兹。这么晚才回复很抱歉。我忘记了 C + D 列的条件。我现在添加了它。请让我知道这是否按您的预期工作,如果您有任何问题。
【解决方案2】:

我希望你不介意我这么说,但是你的代码很难理解,包括你选择的变量名。我可以建议,如果您不使用 .copy 语句,请将它们注释掉,您的代码会运行得更快。

【讨论】:

  • 您好,杰伊,谢谢您的评论。我试图稍微简化变量的选择。我希望它现在更清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
相关资源
最近更新 更多