Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA-如何使For循环更快_Excel_Vba - Fatal编程技术网

Excel VBA-如何使For循环更快

Excel VBA-如何使For循环更快,excel,vba,Excel,Vba,对于15个工作表(每个工作表少于100行),此循环大约需要2分钟。有没有更快的方法 For Each ws In Worksheets For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row ws.Cells(i, "H").Value = ws.Cells(i, "C").Value & ws.Cells(i, "A").Value

对于15个工作表(每个工作表少于100行),此循环大约需要2分钟。有没有更快的方法

For Each ws In Worksheets
    For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
        ws.Cells(i, "H").Value = ws.Cells(i, "C").Value & ws.Cells(i, "A").Value
    Next i
Next
试试这个(未测试)

工作表中每个ws的

使用ws.Range(“H2”).Resize(ws.Cells(Rows.Count,“A”).End(xlUp).Row-1,1)
.公式=“=C2和A2”
.Value=.Value
以
下一个

也考虑添加

Application.ScreenUpdating = False
Application.EnableEvents = False

返回到代码的开头,并在结尾将它们重置为
True
,以防在事件回调中触发代码。

另一种方法可以是将数据复制到数组中,然后将数组写回,但我不确定这是否真的比使用公式并用值替换公式快

Sub TestIt()
Dim i As Long
Dim ws As Worksheet
Dim aDat As Variant, cdat As Variant, hDat As Variant, lastRow As Long

    TurnOff
    For Each ws In Worksheets
        With ws
            lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
            aDat = .Range("A2:A" & lastRow).Value2
            cdat = .Range("C2:C" & lastRow).Value2
            ReDim hDat(1 To lastRow, 1 To 1)
            For i = LBound(aDat) To UBound(aDat)
                hDat(i, 1) = aDat(i, 1) & cdat(i, 1)
            Next i
            .Range("H2:H" & lastRow).Value2 = hDat
    
        End With
    Next
    TurnOn
End Sub

Sub TurnOff()
    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    Application.DisplayStatusBar = False
    Application.EnableEvents = False
End Sub
Sub TurnOn()
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.DisplayStatusBar = True
    Application.EnableEvents = True
End Sub

我希望这可以帮助您更快地执行宏

Sub Macro1()

Dim ws As Worksheet, rCount As Integer, rng As Range

For Each ws In Worksheets
    rCount = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
    ws.Range("H2").Formula = "=CONCATENATE(" & ws.Range("C2").Address(RowAbsolute:=False) & "," & ws.Range("A2").Address(RowAbsolute:=False) & ")"
    Set rng = ws.Range("H2:H" & rCount)
    ws.Range("H2").Copy
    rng.Select
    ws.Paste
    rng.Copy
    rng.PasteSpecial (xlPasteValues)
    Application.CutCopyMode = False
Next

End Sub

谢谢,Ramana

请注意,您没有限定
单元格(Rows.Count,“A”).End(xlUp).Row
。这可能会导致代码中难以精确定位的逻辑错误。始终记得限定您的范围
ws.Cells(Rows.Count,“A”).End(xlUp)。Row
也许这样做就足够了。我注意到,对于新工作簿,在15个工作表中的每个工作表中设置100行数据,您的代码在旧计算机上运行不到1秒。按照@Storax的建议禁用东西应该会有很大帮助。我的经验是,通过禁用屏幕更新(在某些情况下,我甚至将应用程序可见性设置为false)和自动计算,执行速度最快。另外,除非您不确定代码是否正常运行,否则请避免调试输出。缺点是,对于运行数分钟的宏,您没有任何迹象表明是否有任何进展,或者宏是否陷入无限循环。我认为在这种情况下,数组apporach不会获得任何速度。。。如果只有几百行。。。旁注:您只需编写一个函数
MemorySave(isOn为布尔值)
,然后进行计算:
Application.calculation=IIf(isOn,xlCalculationManual,xlCalculationAutomatic)
Application.ScreenUpdate=Not(isOn)
SaveMemory True
将关闭所有功能,而
SaveMemory False
将重置所有功能。是的,您可能是对的,对于数百行甚至数千行,使用数组方法,OP不会获得任何速度。我只是想把它作为另一种选择展示给OP。关于您的旁注:通常情况下,您会保存以前的
计算、重新更新等状态,然后将其重置为保存状态。但在我看来,这并不是必需的。也许自动重新计算是OP代码的速度杀手。通常运行的数组方法在速度上至少可以提高10倍。但在这种情况下,绝对差异(在禁用计算、事件等之后)应该不会太大。