从一个范围复制到另一个范围忽略空白(Excel)

从一个范围复制到另一个范围忽略空白(Excel),excel,vba,Excel,Vba,我试图将一个范围从一张图纸复制到另一张图纸,但忽略空行,并确保目标中没有空行 在浏览了这个网站之后,我成功地使用了下面的代码 然而,我想将其扩展到一个大的数据范围,而且似乎需要一个绝对的时间。关于更高效的代码有什么想法吗?我是个新手 谢谢 Application.Calculation = xlCalculationManual Application.ScreenUpdating = False Application.EnableEvents = False ActiveSheet.Disp

我试图将一个范围从一张图纸复制到另一张图纸,但忽略空行,并确保目标中没有空行

在浏览了这个网站之后,我成功地使用了下面的代码

然而,我想将其扩展到一个大的数据范围,而且似乎需要一个绝对的时间。关于更高效的代码有什么想法吗?我是个新手

谢谢

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

Dim Source As Worksheet
Dim Destination As Worksheet
Dim i As Integer
Dim j As Integer

Set Source = Sheet1
Set Destination = Sheet4

j = 2
For i = 9 To 10000
    If Source.Cells(i, 2).Value <> "" Then
        Destination.Cells(j, 1).Value = Source.Cells(i, 1).Value
        Destination.Cells(j, 2).Value = Source.Cells(i, 2).Value
        Destination.Cells(j, 3).Value = Source.Cells(i, 3).Value
        Destination.Cells(j, 4).Value = Source.Cells(i, 4).Value
        Destination.Cells(j, 5).Value = Source.Cells(i, 5).Value
        Destination.Cells(j, 6).Value = Source.Cells(i, 6).Value
        Destination.Cells(j, 7).Value = Source.Cells(i, 7).Value
        Destination.Cells(j, 8).Value = Source.Cells(i, 8).Value
        Destination.Cells(j, 9).Value = Source.Cells(i, 9).Value
        j = j + 1
    End If
Next i

Application.ScreenUpdating = True
Application.EnableEvents = True
ActiveSheet.DisplayPageBreaks = True
Application.Calculation = xlCalculationAutomatic

End Sub
Application.Calculation=xlCalculationManual
Application.ScreenUpdating=False
Application.EnableEvents=False
ActiveSheet.DisplayPageBreaks=False
将源设置为工作表
将目标设置为工作表
作为整数的Dim i
作为整数的Dim j
设置源=表1
设置目的地=4
j=2
对于i=9到10000
如果Source.Cells(i,2).Value为“”,则
Destination.Cells(j,1).Value=Source.Cells(i,1).Value
Destination.Cells(j,2).Value=Source.Cells(i,2).Value
Destination.Cells(j,3).Value=Source.Cells(i,3).Value
Destination.Cells(j,4).Value=Source.Cells(i,4).Value
Destination.Cells(j,5).Value=Source.Cells(i,5).Value
Destination.Cells(j,6).Value=Source.Cells(i,6).Value
Destination.Cells(j,7).Value=Source.Cells(i,7).Value
Destination.Cells(j,8).Value=Source.Cells(i,8).Value
Destination.Cells(j,9).Value=Source.Cells(i,9).Value
j=j+1
如果结束
接下来我
Application.ScreenUpdating=True
Application.EnableEvents=True
ActiveSheet.DisplayPageBreaks=True
Application.Calculation=xlCalculationAutomatic
端接头

[编辑以增加一点清晰度]

用下面的代码替换for循环

方法1:合并所有要复制的区域,并立即粘贴它们

    Dim copyRange As Range

    For i = 9 To 10000
        If Source.Cells(i, 2).Value <> "" Then
            If copyRange Is Nothing Then
                Set copyRange = Source.Range(Source.Cells(i, 1), Source.Cells(i, 9))
            Else
                Set copyRange = Union(copyRange, Source.Range(Source.Cells(i, 1), Source.Cells(i, 9)))
            End If
        End If
    Next i

    copyRange.Copy Destination.Cells(2, 1)
Dim copyRange作为范围
对于i=9到10000
如果Source.Cells(i,2).Value为“”,则
如果copyRange为空,则
设置copyRange=Source.Range(Source.Cells(i,1),Source.Cells(i,9))
其他的
Set copyRange=Union(copyRange,Source.Range(Source.Cells(i,1),Source.Cells(i,9)))
如果结束
如果结束
接下来我
copyRange.Copy Destination.Cells(2,1)
方法2(推荐):使用自动过滤器过滤数据

    Dim sourceRng As Range
    Set sourceRng = Source.Range(Source.Cells(9, 1), Source.Cells(10000, 9))

    sourceRng.AutoFilter Field:=2, Criteria1:="<>"
    sourceRng.Copy Destination.Cells(2, 1)
    Source.AutoFilterMode = False
Dim sourceRng As范围
设置sourceRng=Source.Range(Source.Cells(9,1),Source.Cells(10000,9))
sourceRng.AutoFilter字段:=2,标准1:=“”
sourceRng.Copy Destination.Cells(2,1)
Source.AutoFilterMode=False

用下面的代码替换for循环

方法1:合并所有要复制的区域,并立即粘贴它们

    Dim copyRange As Range

    For i = 9 To 10000
        If Source.Cells(i, 2).Value <> "" Then
            If copyRange Is Nothing Then
                Set copyRange = Source.Range(Source.Cells(i, 1), Source.Cells(i, 9))
            Else
                Set copyRange = Union(copyRange, Source.Range(Source.Cells(i, 1), Source.Cells(i, 9)))
            End If
        End If
    Next i

    copyRange.Copy Destination.Cells(2, 1)
Dim copyRange作为范围
对于i=9到10000
如果Source.Cells(i,2).Value为“”,则
如果copyRange为空,则
设置copyRange=Source.Range(Source.Cells(i,1),Source.Cells(i,9))
其他的
Set copyRange=Union(copyRange,Source.Range(Source.Cells(i,1),Source.Cells(i,9)))
如果结束
如果结束
接下来我
copyRange.Copy Destination.Cells(2,1)
方法2(推荐):使用自动过滤器过滤数据

    Dim sourceRng As Range
    Set sourceRng = Source.Range(Source.Cells(9, 1), Source.Cells(10000, 9))

    sourceRng.AutoFilter Field:=2, Criteria1:="<>"
    sourceRng.Copy Destination.Cells(2, 1)
    Source.AutoFilterMode = False
Dim sourceRng As范围
设置sourceRng=Source.Range(Source.Cells(9,1),Source.Cells(10000,9))
sourceRng.AutoFilter字段:=2,标准1:=“”
sourceRng.Copy Destination.Cells(2,1)
Source.AutoFilterMode=False

在工作表行中循环几乎是处理数据块最慢的方法。唯一慢一点的是在行和列之间循环

我不确定您有多少条记录,但它在约0.14秒内处理了1500行虚拟数据

Option Explicit

Sub Macro4()

    Dim wsSource As Worksheet, wsDestination As Worksheet
    Dim i As Long, j As Long, k As Long, arr As Variant

    On Error GoTo safe_exit
    appTGGL bTGGL:=False

    Set wsSource = Sheet1
    Set wsDestination = Sheet4

    'collect values from Sheet1 into array
    With wsSource
        arr = .Range(.Cells(9, "A"), .Cells(.Rows.Count, "B").End(xlUp).Offset(0, 7)).Value
    End With

    'find first blank in column B
    For j = LBound(arr, 1) To UBound(arr, 1)
        If arr(j, 2) = vbNullString Then Exit For
    Next j

    'collect A:I where B not blank
    For i = j To UBound(arr, 1)
        If arr(i, 2) <> vbNullString Then
            For k = 1 To 9: arr(j, k) = arr(i, k): Next k
            j = j + 1
        End If
    Next i

    'clear remaining rows
    For i = j To UBound(arr, 1)
        For k = 1 To 9: arr(i, k) = vbNullString: Next k
    Next i

    'put values sans blanks into Sheet4
    With wsDestination
        .Cells(2, "A").Resize(UBound(arr, 1), UBound(arr, 2)) = arr
    End With

safe_exit:
    appTGGL

End Sub

Sub appTGGL(Optional bTGGL As Boolean = True)
    With Application
        .EnableEvents = bTGGL
        .ScreenUpdating = bTGGL
        .DisplayAlerts = bTGGL
        .Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
    End With
    Debug.Print IIf(bTGGL, "end: ", "start: ") & Timer
End Sub
选项显式
亚宏观经济4()
将wsSource设置为工作表,将wsDestination设置为工作表
尺寸i为长,j为长,k为长,arr为变体
错误转到安全出口
appTGGL bTGGL:=假
设置wsSource=Sheet1
设置wsDestination=Sheet4
'将值从Sheet1收集到数组中
使用wsSource
arr=.Range(.Cells(9,“A”),.Cells(.Rows.Count,“B”).End(xlUp).Offset(0,7)).Value
以
'在B列中找到第一个空白
对于j=LBound(arr,1)到UBound(arr,1)
如果arr(j,2)=vbNullString,则退出
下一个j
'收集A:I,其中B不是空白
对于i=j至UBound(arr,1)
如果arr(i,2)vbNullString那么
对于k=1到9:arr(j,k)=arr(i,k):下一个k
j=j+1
如果结束
接下来我
'清除其余行
对于i=j至UBound(arr,1)
对于k=1到9:arr(i,k)=vbNullString:Next k
接下来我
'将无空格的值放入表4中
带wsDestination
.Cells(2,“A”).Resize(UBound(arr,1),UBound(arr,2))=arr
以
安全出口:
appTGGL
端接头
子appTGGL(可选bTGGL为布尔值=真)
应用
.EnableEvents=bTGGL
.ScreenUpdating=bTGGL
.DisplayAlerts=bTGGL
.Calculation=IIf(bTGGL,XLCalculation自动,XLCalculation手动)
以
调试。打印IIf(bTGGL,“结束:”、“开始:”)和计时器
端接头

在工作表行中循环几乎是处理数据块最慢的方法。唯一慢一点的是在行和列之间循环

我不确定您有多少条记录,但它在约0.14秒内处理了1500行虚拟数据

Option Explicit

Sub Macro4()

    Dim wsSource As Worksheet, wsDestination As Worksheet
    Dim i As Long, j As Long, k As Long, arr As Variant

    On Error GoTo safe_exit
    appTGGL bTGGL:=False

    Set wsSource = Sheet1
    Set wsDestination = Sheet4

    'collect values from Sheet1 into array
    With wsSource
        arr = .Range(.Cells(9, "A"), .Cells(.Rows.Count, "B").End(xlUp).Offset(0, 7)).Value
    End With

    'find first blank in column B
    For j = LBound(arr, 1) To UBound(arr, 1)
        If arr(j, 2) = vbNullString Then Exit For
    Next j

    'collect A:I where B not blank
    For i = j To UBound(arr, 1)
        If arr(i, 2) <> vbNullString Then
            For k = 1 To 9: arr(j, k) = arr(i, k): Next k
            j = j + 1
        End If
    Next i

    'clear remaining rows
    For i = j To UBound(arr, 1)
        For k = 1 To 9: arr(i, k) = vbNullString: Next k
    Next i

    'put values sans blanks into Sheet4
    With wsDestination
        .Cells(2, "A").Resize(UBound(arr, 1), UBound(arr, 2)) = arr
    End With

safe_exit:
    appTGGL

End Sub

Sub appTGGL(Optional bTGGL As Boolean = True)
    With Application
        .EnableEvents = bTGGL
        .ScreenUpdating = bTGGL
        .DisplayAlerts = bTGGL
        .Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
    End With
    Debug.Print IIf(bTGGL, "end: ", "start: ") & Timer
End Sub
选项显式
亚宏观经济4()
将wsSource设置为工作表,将wsDestination设置为工作表
尺寸i为长,j为长,k为长,arr为变体
错误转到安全出口
appTGGL bTGGL:=假
设置wsSource=Sheet1
设置wsDestination=Sheet4
'将值从Sheet1收集到数组中
使用wsSource
arr=.Range(.Cells(9,“A”),.Cells(.Rows.Count,“B”).End(xlUp).Offset(0,7)).Value
以
'在B列中找到第一个空白
对于j=LBound(arr,1)到UBound(arr,1)
如果arr(j,2)=vbNullString,则退出
下一个j
'收集A:I,其中B不是空白
对于i=j至UBound(arr,1)
如果arr(i,2)vbNullStri