如何使用设定的范围

我正在寻找一种方法来改善一个更好的方式来写一段代码,看看是否有客户从“第二列表”中的“第一列表”,并将数据复制到名为“find”的工作表。

它是这样的:

Dim row As Long, row2 As Long, found as Long Dim ID As String, prtGtId as String, GtId2 as String Application.ScreenUpdating = False prtGtId = "B" GtId2 = "D" row = 2 row2 = 2 found = 0 Do While row <= Cells(Rows.Count, prtGtId).End(xlUp).row ID = Cells(row, prtGtId) Sheets("Second List").Select Do While row2 <= Cells(Rows.Count, GtId2).End(xlUp).row If (ID = Cells(row2, GtId2)) Then Rows(row2).Select Selection.Copy Sheets("Found").Select Rows(2).Select Selection.Insert Shift:=xlDown Sheets("First List").Select Rows(row).Select Selection.Copy Sheets("Found").Select Rows(2).Select Selection.Insert Shift:=xlDown Sheets("Second List").Select found = found + 1 End If row2 = row2 + 1 Loop Sheets("First List").Select row = row + 1 row2 = 2 Loop Sheets("Blank").Select Cells(2, 3) = found Application.ScreenUpdating = True 

这是我的实际代码的简化版本(这是更大,包含很多提前退出循环以及按字母顺序),但现在我主要担心使用“.select”函数是消耗我的大部分处理时间。

我知道我已经看到有另一种方式使用

 Set rng = Range(Cells(2, prtGtId),Cells(Cells(Rows.Count, GtId2).End(xlUp).row, prtGtId)) For Each Cell in rng Code Next Cell 

或者沿着这些方向,但我似乎无法find比“这样快得多”的详细教程。

考虑到我需要将行拷贝到“find”时保留行中的格式,有没有办法改变这种方式使其更快?

激活并select模拟用户键击,即使您将Application.ScreenUpdating设置为false,也不需要真正select对象。 你通常应该避免这些方法(这里看到一个有趣的文章关于为什么和什么时候select: http : //dailydoseofexcel.com/archives/2004/04/27/beginning-vba-select-and-activate/ )。 声明variables(设置rng …)或直接处理对象。

 Sub test() Dim row As Long, row2 As Long, found As Long Dim ID As String, prtGtId As String, GtId2 As String Application.ScreenUpdating = False prtGtId = "B" GtId2 = "D" row = 2 row2 = 2 found = 0 Do While row <= Sheets("First List").Cells(Rows.Count, prtGtId).End(xlUp).row ID = Sheets("First List").Cells(row, prtGtId) ' Sheets("Second List").Select With Sheets("Second List") Do While row2 <= .Cells(Rows.Count, GtId2).End(xlUp).row If (ID = .Cells(row2, GtId2)) Then .Rows(row2).Copy Sheets("Found").Rows(2).Insert Shift:=xlDown Sheets("First List").Rows(row).Copy Sheets("Found").Rows(2).Insert Shift:=xlDown found = found + 1 End If row2 = row2 + 1 Loop End With ' Sheets("First List").Select row = row + 1 row2 = 2 Loop Sheets("Blank").Cells(2, 3) = found Application.ScreenUpdating = True End Sub 

你看到less了几行,没有更多的select。 另请参阅如何使用“with”语句(在此用作示例),这可能非常有用。 (我假设你启动你的macros,并激活工作表“First List”,这就是为什么我添加Sheets(“First List”))编程这种方式也避免了这种错误(所以你可以启动你的macros而不用担心激活工作表)

让我举个简单的例子说明你可以在你提供的代码中做什么。 而不是行(row2)。select你也可以编写Set CurrentRow = Rows(row2)当然,你必须事先声明CurrentRow作为范围(Dim CurrentRow as Range)。当你释放CurrentRowvariables也是明智的通过使用Set CurrentRow = Nothing来完成。你需要知道的唯一事情就是你在Set语句中的等号后面应该产生一个范围对象。 大多数使用.Select的代码的时间线可以被重写为不select该项目,但是,例如,将其放入一个variables中。 这通常会加快代码的速度,而且在代码完成之后,您不必重置select。 我希望这有帮助

也许你可以用第一个列表中的所有ID创build一个数组,然后检查是否在第二个列表中find了相同的ID,然后用双ID的行号创build一个数组。

使用最后一个数组,您可以对所需的所有行进行一个大的select,并将其全部复制一次。

我不知道这是否加快了很多,但也许你可以尝试。

我会完全删除Select语句。 试试这个,不需要范围。

 If (ID = Cells(row2, GtId2)) Then Sheets("Second List").Rows(row2).Copy Sheets("Found").Rows(2).Insert Shift:=xlDown Sheets("First List").Rows(rw).Copy Sheets("Found").Rows(2).Insert Shift:=xlDown found = found + 1 End If