循环遍历公式时的低效计算

时间:2015-04-14 07:29:11

标签: excel-vba vba excel

当我试图加速我在这个问题上遇到的工作簿时:

我有几行和列来填充公式,所以我试图通过在按插槽计算公式后复制和粘贴值来更快地完成所有操作。虽然这在excel上很容易使用(手动完成),但当我使用VBA时,它的行为类似于重新计算所有公式,即使它们只是值,并且计算时间也会逐步增加。

有没有办法避免这种奇怪的行为?

PS:我已经尝试将计算设置为手动但没有任何改变,因为VBA似乎并不关心它。

我知道这不应该是必要的,但这里是代码:

Dim rw As Long, k As Long, i As Long, h As Long, l As Long
'
Application.ScreenUpdating = False
'
Sheets("Report 1").Activate
    rw = Range(Cells(5, 3), Cells(5, 3).End(xlDown)).Count
        Sheets("match").Activate
k = rw / 5000
    h = 4
For l = 2 To 12
    For i = 1 To k
        Range(Cells(h, l), Cells(3 + rw - ((k - i) * 5000), l)).FormulaR1C1 = "=MATCH('BOM Str Parents'!RC,'Report 1'!c1,0)"
            Range(Cells(h, l), Cells(3 + rw - ((k - i) * 5000), l)).Value = Range(Cells(h, l), Cells(3 + rw - ((k - i) * 5000), l)).Value
        h = rw - ((k - i) * 5000) + 1
    Next i
Next l

1 个答案:

答案 0 :(得分:0)

目前还不清楚先例和家属与您要插入的值有什么关系。名为报告1 的工作表会显示从统计公式和小计公式到嵌入图表和事件宏(如 Worksheet_Change )的所有内容。您的代码将受益于减少范围的计算以接收公式/值三次到一次以及关闭“大3”应用程序模式(例如 .ScreenUpdating,.EnableEvents 和< EM> .Calculation )。阻止工作表进入使用...结束部分可以避免经常模糊的ActiveSheet父引用。 报告1 上的单元格的外部引用应暂时中断。

    Dim rw As Long, k As Long, i As Long, h As Long, l As Long, rng As Range

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.Calculation = xlCalculationManual

    With Sheets("Report 1")
        rw = .Range(.Cells(5, 3), .Cells(5, 3).End(xlDown)).Count
    End With

    With Sheets("match")
        k = rw / 5000
        h = 4
        For l = 2 To 12
            For i = 1 To k
                Set rng = .Range(.Cells(h, l), .Cells(3 + rw - ((k - i) * 5000), l))
                rng.FormulaR1C1 = "=MATCH('BOM Str Parents'!RC, 'Report 1'!C1, 0)"
                rng = rng.Value2
                Set rng = Nothing
                h = rw - ((k - i) * 5000) + 1
            Next i
        Next l
    End With

    'Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    Application.ScreenUpdating = True

这些简单的步骤可以显着加快您的计算时间。可以使用.Value2,因为我们知道匹配只会返回一个长整数或错误。我不知道你开始使用什么计算模式,所以我将回复留给了xlCalculationAutomatic评论。

实际结果将在很大程度上取决于报告1 上与细胞相关的其他内容。

<强>附录:

我不确定我的行/列计算或范围大小是否完全正确但是数组大小和方向应该很好并且运行速度要快一些。

    Debug.Print Timer
    Dim h As Long, l As Long, v As Long
    Dim rws As Long, vRPT1a As Variant, vBOMstr As Variant

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.Calculation = xlCalculationManual

    With Sheets("Report 1")
        vRPT1a = .Range(.Cells(5, 1), .Cells(5, 3).End(xlDown).Offset(0, -1)).Value
        rws = UBound(vRPT1a)
    End With

    With Sheets("match")
        h = 4
        For l = 2 To 12
            vBOMstr = Sheets("BOM Str Parents").Cells(h, l).Resize(rws, 1).Value2
            For v = LBound(vBOMstr, 1) To rws
                vBOMstr(v, 1) = Application.Match(vBOMstr(v, 1), Application.Index(vRPT1a, 0, 1), 0)
            Next v
            .Cells(4, l).Resize(rws, 1) = Application.Index(vBOMstr, 0, 1)
        Next l
    End With

    'Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    Debug.Print Timer