2014-10-06 107 views
-1

任何人都可以給我一些見解,爲什麼這需要這麼長時間才能運行?我在Parallels上運行WinXP,使用16GB MacBook Pro(分配給VM的4Gig)。電子表格本身(由我的客戶創建)是一個絕對的噩夢 - 38張完整的可笑複雜的公式,以及多步驟過於複雜的算法,這些都會讓Rube Goldberg非常嫉妒。但是,這個簡單的例程需要30分鐘才能運行。真的很慢循環

Sub oneList() 
'Application.ScreenUpdating = False 

ncols = Range("scores").Columns.Count 
nrows = Range("sc_id").Rows.Count 

'MsgBox nrows, ncols 
ReDim Preserve scores(1 To nrows, 1 To ncols) 

For i = 2 To nrows 
    For j = 1 To ncols 
     scores(i, j) = Application.Index(Range("scores"), i, j) 
'  Debug.Print i, j 
'  Debug.Print scores(i, j) 
'  Sheet36.Range("A1:D197").Cells(i - 1, j).Value = scores(i, j) 
    Next j 
Next i 
Sheet36.Range("A1:D197").Clear 

For a = 1 To nrows 
    For b = 1 To ncols 
     Sheet36.Range("A1:D197").Cells(a, b).Value = scores(a, b) 
    Next b 
Next a 

End Sub 

在此先感謝您的任何見解。

回答

3

您有兩個for循環,並且在這些for循環中可以更改工作表上的值。每次你改變一個值時,公式都會在前端進行計算。考慮

application.Calculation = xlCalculationManual 

,然後在腳本的末尾停止公式自動計算再將其打開

application.Calculation = xlCalculationAutomatic 

雖然他們離你可以強制與

application.Calculate 
計算運行

更新:

看起來大部分這是不必要的。您正在遍歷一個範圍,將每個單元格分配給一個二維數組,然後遍歷該數組並將這些值分散到另一個範圍中。

爲什麼不乾脆:

Sub oneList()  

    Sheet36.Range("A1:D197").value2 = Range("scores").value2  

End Sub 
+0

感謝您的支持!我在第一個循環之前進行了手動計算,在最後一個循環之後進行了自動計算。它加快了一點,但並不多。我不清楚我是否需​​要強制計算循環內的某處;我完全拋棄了這一點。 – SteveS 2014-10-06 21:10:00

+0

Application.index()在做什麼?它看起來像遍歷行和列,將它們分配給一個二維數組,然後再粘貼該數組。爲什麼不跳過迭代並使一個範圍與另一個範圍相等? – JNevill 2014-10-06 21:19:35

+0

好的。但實際上,我只是將這個例程作爲一個自學教程,在對數組做更復雜的工作的方式上。合理? 我知道,因爲我已經把這個子程序分成了兩個進行測試,前半部分(填充數組)很快。第二部分(將陣列粘貼到新的範圍內)大約需要15分鐘。十五分鐘!!! – SteveS 2014-10-06 23:28:36

1

您可以通過填充目標範圍在一個操作中提高性能:

Sub oneList() 

    Dim ncols As Long, nrows As Long 
    ncols = Range("scores").Columns.Count 
    nrows = Range("sc_id").Rows.Count 

    ReDim Preserve scores(1 To nrows, 1 To ncols) 

    For i = 2 To nrows 
     For j = 1 To ncols 
      scores(i, j) = Application.Index(Range("scores"), i, j) 
     Next j 
    Next i 

    With Sheet36.Range("A1:D197") 
     .Clear 
     .Cells(1).Resize(numrows, numcols).Value = scores 
    End With 

End Sub 

其中scores陣列是目前還不清楚,但很可能你也可以重新編寫代碼,以便從scores範圍內一次性填充該代碼。

+0

我要試一試。謝謝。我的最終目標實際上是用if-then填充多維數組,然後檢查原始範圍中的單元格是否符合特定條件,然後將結果數組吐出到工作簿中的新位置。(然後,排序,除去其中的不符合標準的空白) 我粘貼在這裏的代碼實際上只是對我來說,教我這些東西,一路上是如何工作的方式。我有點VBA autodidact。正因爲如此,有很多基礎知識我最終不得不在途中傳授自己完成這項工作的目標。 :) – SteveS 2014-10-06 23:32:01

+0

祝你好運 - 這始終是一個很好的地方來,如果你遇到的問題... – 2014-10-07 00:17:13

+0

是的,我喜歡這個網站。通常我只是找到了答案,而不必問,這一次卻有點過於具體。 – SteveS 2014-10-07 02:25:40