Excel VBA – 循环检查整个列范围而不是每个单元格

我写了一个脚本,它检查列范围4(D列)中的非空值的单元格范围,如果它find非空值,则复制该值并将其粘贴到列范围6(列F )。 该脚本运行,但速度非常慢,脚本需要5分钟来处理并完成其运行。 有没有什么办法来改进这个脚本,以便它可以在复制和粘贴值之前预先检查范围? 看来,复制/粘贴function正在放慢速度。

下面的代码

Sub ArrayCopyPaste() Dim J as Integer Application.Calculation = xlCalculationManual For J = 2 To 500 If Cells(J, 4).Value <> "" Then Cells(J, 4).Copy Cells(J, 6).PasteSpecial Paste:=xlPasteValues End If Next J Application.Calculation = xlCalculationAutomatic End Sub 

这里有一个方法:

 Sub test() Dim r1, r2, n As Long With Sheets("Sheet1") '~~> change to suit Dim lrow As Long lrow = .Range("D" & .Rows.Count).End(xlUp).Row r1 = Application.Transpose(.Range("D2:D" & lrow)) r2 = Application.Transpose(.Range("F2:F" & lrow)) For n = LBound(r1) To UBound(r1) If r1(n) <> "" Then r2(n) = r1(n) Next .Range("F2:F" & lrow) = Application.Transpose(r2) End With End Sub 

将范围数据传送到数组,然后将数组传送到数组。
然后将数组返回到范围。 HTH。

重要: Application.Transpose有限制。 我只能处理几千个数据。

跟进:尝试删除

 Dim rngToDelete As Range, k As Long With Sheets("Sheet1") '~~> change to suit For k = 2 To 500 If .Cells(k, 6).Value = "" Then If rngToDelete Is Nothing Then Set rngToDelete = .Cells(k, 6) Else Set rngToDelete = Union(rngToDelete, .Cells(k, 6)) End If End If Next rngToDelete.Delete xlUp 'rngToDelete.EntireRow.Delete xlUp ~~> use this if you want to delete entire row. End With 

确定所有的目标范围,然后一次删除。 HTH。

先试试这个,看看它是否有所作为:

 Dim currentCalculation As Variant currentCalculation = Application.Calculation Application.Calculation = xlCalculationManual Application.ScreenUpdating = False For J = 2 To 500 If Cells(J, 4).Value <> "" Then Cells(J, 4).Copy Cells(J, 6).PasteSpecial Paste:=xlPasteValues End If Next J Application.ScreenUpdating = True Application.Calculation = currentCalculation 

另一个想法。 你有没有试过这样做?

 For J = 2 To 500 If Cells(J, 4).Value <> "" Then Cells(J, 6).Value = Cells(J, 4).Value End If Next J 

如果空白被复制,那么对你的目标栏不会产生任何影响,所以不要麻烦检查它们。 不要循环 – 只需复制整个列。

 Sub CopyColumn() ' copying this way does not use your clipboard Columns("D").Copy Columns("F") End Sub 

如果您只需要列的一部分,请指定要复制的范围而不是整个列:

 Sub CopyPartOfColumn() ' copying this way does not use your clipboard Range("D2:D500").Copy Range("F2:F500") End Sub 

您在您的问题下面的评论中提到,您希望生成的列是没有空白的值的综合列表。 您可以通过删除列或范围中的空白,再次不循环来快速做到这一点。 在您复制所需的值后运行。

 Sub RemoveBlanks() Range("F2:F500").SpecialCells(xlCellTypeBlanks).Delete Shift:=xlUp End Sub