2014-11-02 404 views
0

爲Excel編寫的這個循環取2個唯一列表的範圍,並在另一個表的表格中搜索它們。它是一個兩列搜索,來自列表的2個值必須出現在一行中以供累加器計數。它工作得很好,但當我解析大量數據時,我可以等待幾分鐘。我正在尋找一種讓這個循環更快的方法。任何幫助,將不勝感激。提前致謝。如何讓VBA循環運行更快?

Sub parseTwo(ByVal startRng As Range, ByVal findRng As Range, _ 
ByVal pasteStartRng As Range, ByVal strTitle As String, ByVal findTableColumn As String, _ 
ByVal startOffset As Integer, ByVal handledOffset As Integer, _ 
ByVal handledBool As Boolean) 
'========================================================================== 
'========================================================================== 
'Turn off some Excel functionality so code runs faster 
Application.ScreenUpdating = False 
Application.DisplayStatusBar = False 
Application.Calculation = xlCalculationManual 
Application.EnableEvents = False 
'========================================================================== 
'========================================================================== 
Dim x As Long   'Declare accumulator. 
x = 0     'Give x default value. 
'========================================================================== 
'========================================================================== 
Dim firstLoop As Boolean 'Declare boolean value. 
firstLoop = True   'Declare initial value of boolean as true. 
'========================================================================== 
'========================================================================== 
Dim pasteFindRng As Range 'Set the paste range for "find" items. 
Set pasteFindRng = pasteStartRng.Offset(1, -1 
Dim pasteAccum As Range 'Set the paste range for the "accumulator". 
Set pasteAccum = pasteStartRng.Offset(1, 0) 
'========================================================================== 
'========================================================================== 
Dim initialFindRng As Range 'Keep track of the initial "find" range to reference it later. 
Set initialFindRng = findRng 
'========================================================================== 
'========================================================================== 
Do While startRng.Text <> vbNullString    'Do while there is data in the "start" range. 
    Do While findRng.Text <> vbNullString   'Do while there is data in the "find" range. 
     With Worksheets("Formatting").Range("FormattingTable[" & findTableColumn & "]") 
      Set c = .Find(findRng.Text, LookIn:=xlValues, LookAt:=xlWhole) 
        firstAddress = c.Address 
        Do 
         If handledBool = True Then 
          If c.Offset(0, handledOffset).Text <> vbNullString Then 
           If c.Offset(0, startOffset).Text = startRng.Text Then 
            x = x + 1 
           End If 
          End If 
         Else 
          If c.Offset(0, startOffset).Text = startRng.Text Then 
           x = x + 1 
          End If 
         End If 
        Set c = .FindNext(c) 
        Loop While Not c Is Nothing And c.Address <> firstAddress 
     End With 
'========================================================================== 
'========================================================================== 
     If firstLoop = True Then 'If this is the first time through loop then paste find items 
      pasteFindRng.Value = findRng.Text 
      Set pasteFindRng = pasteFindRng.Offset(1, 0) 'Set pastefind range down 1 
     End If 
'========================================================================== 
     pasteAccum.Value = x     'Set x to paste. 
     Set pasteAccum = pasteAccum.Offset(1, 0) 'Set accumulator paste range down 1. 
     x = 0          'Reset x 
'========================================================================== 
     Set findRng = findRng.Offset(1, 0)   'Set find range down 1. 
'========================================================================== 
    Loop 
    If firstLoop = True Then 'If this is the first time through loop then paste the title. 
     pasteStartRng.Offset(0, -1) = strTitle 
    End I 
'========================================================================== 
    pasteStartRng.Value = startRng.Text    'Paste the value of the start range. 
'========================================================================== 
    Set pasteStartRng = pasteStartRng.Offset(0, 1) 'Set paste start range over to the right 1. 
'========================================================================== 
    Set pasteAccum = pasteStartRng.Offset(1, 0)  'Reset "accumulator" paste range. 
'========================================================================== 
    Set startRng = startRng.Offset(1, 0)   'Move "start" range down 1. 
    Set findRng = initialFindRng     'Reset "find" range. 
'========================================================================== 
    firstLoop = False 
Loop 
'======================================================================================== 
Application.ScreenUpdating = True 
Application.DisplayStatusBar = True 
Application.Calculation = xlCalculationAutomatic 
Application.EnableEvents = True 

End Sub 
+0

任何原因你不會只使用SUMIFS或DSUM或任何其他內置機制的這種事情? – siride 2014-11-02 18:13:02

+0

https://www.youtube.com/watch?v=H4YRPdRXKFs – 2014-11-02 18:15:43

+0

謝謝。我會檢查這些功能。我之前已經對此進行了一些研究,但沒有發現任何內置的功能,可以計算同一行中多列中不同字符串的出現,但我可能是錯的! SumIF看起來可能是一個競爭者。謝謝。 – ArkhangelsK 2014-11-02 18:23:07

回答

0

其尖端,嘗試創建一個變量

Range("FormattingTable[" & findTableColumn & "]") 

值和避免這樣做在一個循環內。或者更好地替換:

Worksheets("Formatting").Range("FormattingTable[" & findTableColumn & "]") 

由循環內的範圍值。