2017-01-20 101 views
0

下面的代碼非常慢,我的電腦需要一些時間才能完成操作。我試圖從author_metadata使用更少的線路,但是甚至40000線路太多。 用excel VBA有更快的選擇嗎?Excel vba在大數據工作表中執行緩慢

author_metadata = ThisWorkbook.Worksheets("author_metadata").Range("A1:P542995").Value 

allprofs = ThisWorkbook.Worksheets("allprofs").Range("A1:H4005").Value 
Top200 = ThisWorkbook.Worksheets("Top200").Range("A1:B200").Value 


m = 1 

For j = 1 To 200 
    For k = 1 To 4005 
     If allprofs(k, 4) = Top200(j, 1) Then 

     For i = 2 To UBound(author_metadata) 

       If author_metadata(i, 10) = Top200(j, 1) Then 

        If allprofs(k, 2) = author_metadata(i, 12) Then 
        'do some data assigning between arrays like the next line 
        Top200Full(m, 1) = author_metadata(i, 1) 

        m = m + 1 

        End If 

       End If 

     Next i 
     End If 
    Next k 
Next j 

ThisWorkbook.Worksheets("Top200full").Range("A2:Q75601").Value = Top200Full 


End Sub 
+0

它掛在哪裏?最後一行?嘗試在基於數組粘貼的末尾定義範圍,也許 –

+4

[代碼評論](http://codereview.stackexchange.com/)將能夠提供幫助。 –

+0

你可以做的是添加一些進度指標,看看瓶頸在哪裏。我會先把它放在For循環的開頭,像'Debug.Print「j:」&j&「 - k:」&k'。然後看看這個更新有多快或多慢。 考慮修復:我看不到這麼快;看起來你在這裏有不可避免的複雜性。除了爲此編寫基於XLL或C++的COM加載項外) –

回答

1

使用AutoFilter()方法和Dictionary對象

如果我正確把握你的邏輯,一個可能的代碼可能是以下

Option Explicit 

Sub main() 
    Dim Top200 As Variant, allproofFiltered As Variant 
    Dim m As Long 
    Dim cell As Range 
    Dim allproofFilteredDict As Scripting.Dictionary 
    Top200 = Application.Transpose(ThisWorkbook.Worksheets("Top200").Range("A1:A200").Value) 

    With ThisWorkbook.Worksheets("allprofs") 
     With .Range("D1", .Cells(.Rows.count, "D").End(xlUp)) 
      .AutoFilter Field:=1, Criteria1:=Top200, Operator:=xlFilterValues '<--| filter referenced range on its 3rd column (i.e. "State") with 1 
      If Application.WorksheetFunction.Subtotal(103, .Cells) > 1 Then '<--| if any filterd cells other than header 
       Set allproofFilteredDict = New Scripting.Dictionary 
       For Each cell In .Resize(.Rows.count - 1).Offset(1, -2).SpecialCells(xlCellTypeVisible) 
        allproofFilteredDict(cell.Value) = cell.Value 
       Next 
       allproofFiltered = allproofFilteredDict.keys 
      Else 
       Exit Sub 
      End If 
     End With 
     .AutoFilterMode = False 
    End With 

    With ThisWorkbook.Worksheets("author_metadata") 
     With .Range("J1:L" & .UsedRange.Rows(.UsedRange.Rows.count).Row) 
      .AutoFilter Field:=1, Criteria1:=Top200, Operator:=xlFilterValues '<--| filter referenced range on its 3rd column (i.e. "State") with 1 
      .AutoFilter Field:=3, Criteria1:=allproofFiltered, Operator:=xlFilterValues '<--| filter referenced range on its 3rd column (i.e. "State") with 1 
      If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then '<--| if any filterd cells other than header      
       .Resize(.Rows.count - 1, 1).Offset(1, -9).SpecialCells(xlCellTypeVisible).Copy 
       ThisWorkbook.Worksheets("Top200full").Range("A2").PasteSpecial xlPasteValues 
      End If 
     End With 
     .AutoFilterMode = False 
    End With 
End Sub 

使用Dictionary對象必須將它的庫引用添加到您的項目:

  • 點擊工具 - >引用

  • 向下滾動列表框中的「Microsoft腳本字典」項,並勾選其對號

  • 單擊確定

0

有時,這有助於加快我的代碼;

Application.Calculation = xlCalculationManual 
Application.EnableEvents = False