2015-06-26 85 views
1

我正在尋找一種方法來改善一種更好的方式來編寫一段代碼,看看是否有客戶端來自「第二列表」中的「第一列表」並將數據複製過來到名爲「找到」的工作表。如何使用設置範圍

它是這樣的:

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 

或東西沿着這些線路的另一種方式,但我似乎無法找到一個詳細的教程,還遠不止「這將大大加快這種方式」 。

考慮到我在複製到「Found」時需要保留行中的格式,有沒有辦法改變這個以使其更快?

+0

請勿將[宏]用於MS Office或VBA。 [macros tag wiki](http://stackoverflow.com/tags/macros/info) –

回答

2

激活並選擇模擬用戶鍵擊,即使將Application.ScreenUpdating設置爲false,也不需要真正選擇對象。您通常應該避免使用這些方法(請參閱此處有關有關爲什麼以及何時選擇的有趣文章:http://dailydoseofexcel.com/archives/2004/04/27/beginning-vba-select-and-activate/)。聲明變量(設置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 

你看到幾行少了,不再選擇。另請參閱如何使用「with」語句(在此用作示例),這可能非常有用。(我假設你在啓動宏的時候啓動了工作表「First List」,這就是爲什麼我添加Sheets(「First List」))這種編程方式也避免了這種錯誤(所以你可以啓動你的宏而不必擔心工作表是激活)

1

讓我舉個簡單的例子說明你可以在你提供的代碼中做什麼。而不是行(row2)。選擇你也可以編寫Set CurrentRow = Row(row2) 當然,你必須事先聲明CurrentRow爲一個範圍(Dim CurrentRow as Range) 也可以建議釋放CurrentRow變量當你完成它通過使用Set CurrentRow = Nothing 你需要知道的唯一的事情是你在Set語句中的等號後面應該產生一個範圍對象。 大多數使用.Select的代碼時間線可以被重寫爲不選擇該項目,但是,例如,將其放入一個變量中。這通常會加快代碼的速度,並且您不必在代碼完成後重置選擇。 我希望這可以幫助

1

也許你可以用第一個列表中的所有ID創建一個數組,然後檢查你是否在第二個列表中找到相同的ID,並用雙ID的行號創建一個數組。

使用最後一個數組,您可以對所需的所有行進行一個大的選擇,並一次複製所有行。

我不知道這是否加快了很多,但也許你可以嘗試。

1

我會完全刪除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