2014-10-06 104 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