需要比每个循环vba更高的效率
我是vba/excel宏的新手,需要一种更有效的方法来运行下面的代码。我使用for-each循环根据列的值(同一行)从一行返回一个值。代码可以工作,但需要太多的处理能力和时间才能通过循环(通常会冻结计算机或程序)。如果有任何建议,我将不胜感激 '下面将搜索范围内的每个单元格,以确定单元格是否为空。如果单元格不为空,宏将复制单元格的值并将其粘贴到另一个工作表(同一行)中 '下面搜索范围内的每个单元格,以确定单元格是否包含“T”。如果单元格包含“T”,宏将复制另一列(同一行)的值,并将其粘贴到另一个工作表(同一行)中需要比每个循环vba更高的效率,vba,excel,macros,Vba,Excel,Macros,我是vba/excel宏的新手,需要一种更有效的方法来运行下面的代码。我使用for-each循环根据列的值(同一行)从一行返回一个值。代码可以工作,但需要太多的处理能力和时间才能通过循环(通常会冻结计算机或程序)。如果有任何建议,我将不胜感激 '下面将搜索范围内的每个单元格,以确定单元格是否为空。如果单元格不为空,宏将复制单元格的值并将其粘贴到另一个工作表(同一行)中 '下面搜索范围内的每个单元格,以确定单元格是否包含“T”。如果单元格包含“T”,宏将复制另一列(同一行)的值,并将其粘贴到另一个
公式数组应该是您最好的希望。这假设不匹配的单元格将导致目标范围中的空值:
chk = "Demographic!AU2:AU" & lastRow
src = "Demographic!AU2:AU" & lastRow
With Sheets("Employee import").Range("F2:F" & lastRow)
.FormulaArray = "=IF(" & chk & "<> """"," & src & ", """")"
.Value = .Value '<-- if you want to remove the formulas and keep only the copied values
End With
chk = "Demographic!AM2:AM" & lastRow
src = "Demographic!AO2:AO" & lastRow
With Sheets("Employee import").Range("G2:G" & lastRow)
.FormulaArray = "=IF(" & chk & "= ""T""," & src & ", """")"
.Value = .Value '<-- if you want to remove the formulas and keep only the copied values
End With
chk=“人口统计!AU2:AU”&lastRow
src=“人口统计!AU2:AU”&lastRow
带工作表(“员工导入”)。范围(“F2:F”和lastRow)
.FormulaArray=“=IF(“&chk&”“,”&src&“,”)”
.Value=.Value'公式数组应该是您最好的希望。这假设不匹配的单元格将导致目标范围中的空值:
chk = "Demographic!AU2:AU" & lastRow
src = "Demographic!AU2:AU" & lastRow
With Sheets("Employee import").Range("F2:F" & lastRow)
.FormulaArray = "=IF(" & chk & "<> """"," & src & ", """")"
.Value = .Value '<-- if you want to remove the formulas and keep only the copied values
End With
chk = "Demographic!AM2:AM" & lastRow
src = "Demographic!AO2:AO" & lastRow
With Sheets("Employee import").Range("G2:G" & lastRow)
.FormulaArray = "=IF(" & chk & "= ""T""," & src & ", """")"
.Value = .Value '<-- if you want to remove the formulas and keep only the copied values
End With
chk=“人口统计!AU2:AU”&lastRow
src=“人口统计!AU2:AU”&lastRow
带工作表(“员工导入”)。范围(“F2:F”和lastRow)
.FormulaArray=“=IF(“&chk&”“,”&src&“,”)”
value = 如果你只想要一个直的数据传输(即没有公式或格式),并且你的数据集很大,那么你可以考虑通过一个数组以一个批次写数据。
不过,您自己的代码不应该太慢,所以它表明您正在运行一些计算,或者您正在处理工作表更改事件。如果这是可能的,那么您可能希望在数据传输期间禁用这些选项:
With Application
.EnableEvents = False
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
只需记住在例行程序结束时重置它们:
With Application
.EnableEvents = True
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
如果您选择数组路径,则骨架代码如下所示:
Dim inData As Variant
Dim outData() As Variant
Dim r As Long
'Read the demographic data
With Worksheets("Demographic")
inData = .Range(.Cells(2, "AU"), .Cells(.Rows.Count, "AU").End(xlUp)).Value2
End With
'Use this if your column F is to be entirely overwritten
ReDim outData(1 To UBound(inData, 1), 1 To UBound(inData, 2))
'Use this if you have exisiting data in column F
'With Worksheets("Employee import")
' outData = .Cells(2, "F").Resize(UBound(inData, 1)).Value2
'End With
'Pass the values across
For r = 1 To UBound(inData, 1)
If Not IsEmpty(inData(r, 1)) Then
outData(r, 1) = inData(r, 1)
End If
Next
'Write the new values
Worksheets("Employee import").Cells(2, "F").Resize(UBound(outData, 1)).Value = outData
如果你只想要一个直接的数据传输(即没有公式或格式),并且你的数据集很大,那么你可以考虑用数组的形式将数据写入一个批。
不过,您自己的代码不应该太慢,所以它表明您正在运行一些计算,或者您正在处理工作表更改事件。如果这是可能的,那么您可能希望在数据传输期间禁用这些选项:
With Application
.EnableEvents = False
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
只需记住在例行程序结束时重置它们:
With Application
.EnableEvents = True
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
如果您选择数组路径,则骨架代码如下所示:
Dim inData As Variant
Dim outData() As Variant
Dim r As Long
'Read the demographic data
With Worksheets("Demographic")
inData = .Range(.Cells(2, "AU"), .Cells(.Rows.Count, "AU").End(xlUp)).Value2
End With
'Use this if your column F is to be entirely overwritten
ReDim outData(1 To UBound(inData, 1), 1 To UBound(inData, 2))
'Use this if you have exisiting data in column F
'With Worksheets("Employee import")
' outData = .Cells(2, "F").Resize(UBound(inData, 1)).Value2
'End With
'Pass the values across
For r = 1 To UBound(inData, 1)
If Not IsEmpty(inData(r, 1)) Then
outData(r, 1) = inData(r, 1)
End If
Next
'Write the new values
Worksheets("Employee import").Cells(2, "F").Resize(UBound(outData, 1)).Value = outData
对于第一次复制/粘贴值,实际上不需要任何检查,因为空白值将被粘贴为空白值
所以你可以去:
With Worksheets("Demographic")
With .Range("AU2", .Cells(.Rows.count, "AU").End(xlUp))
Worksheets("Employee import").Range("F2").Resize(.Rows.count).Value = .Value
End With
End With
对于第二次复制/粘贴值,您可以粘贴所有值,然后过滤不需要的值并在目标工作表中清除它们
具体如下:
With Worksheets("Demographic")
With .Range("AM2", .Cells(.Rows.count, "AM").End(xlUp))
Worksheets("Employee import").Range("G2").Resize(.Rows.count).Value = .Offset(, 2).Value
End With
End With
With Worksheets("Employee import")
With .Range("G1", .Cells(.Rows.count, "G").End(xlUp))
.AutoFilter field:=1, Criteria1:="<>T"
.Resize(.Rows.count).Offset(1).SpecialCells(xlCellTypeVisible).ClearContents
End With
.AutoFilterMode = False
End With
与工作表(“人口统计”)
带.Range(“AM2”,.Cells(.Rows.count,“AM”).End(xlUp))
工作表(“员工导入”).Range(“G2”).Resize(.Rows.count).Value=.Offset(,2).Value
以
以
带工作表(“员工导入”)
带.Range(“G1”,.Cells(.Rows.count,“G”).End(xlUp))
.自动筛选字段:=1,标准1:=“T”
.Resize(.Rows.count).偏移量(1).特殊单元格(xlCellTypeVisible).ClearContent
以
.AutoFilterMode=False
以
也就是说,如果工作簿中有许多公式和/或事件处理程序,那么在运行代码并重新启用它们之前,禁用它们(Application.EnableEvents=False
,Application.Calculation=xlCalculationManual
)也会使您受益匪浅(Application.EnableEvents=True
,Application.Calculation=xlCalculationAutomatic
)编码完成后对于第一次复制/粘贴值,实际上不需要任何检查,因为空白值将作为空白值粘贴
所以你可以去:
With Worksheets("Demographic")
With .Range("AU2", .Cells(.Rows.count, "AU").End(xlUp))
Worksheets("Employee import").Range("F2").Resize(.Rows.count).Value = .Value
End With
End With
对于第二次复制/粘贴值,您可以粘贴所有值,然后过滤不需要的值并在目标工作表中清除它们
具体如下:
With Worksheets("Demographic")
With .Range("AM2", .Cells(.Rows.count, "AM").End(xlUp))
Worksheets("Employee import").Range("G2").Resize(.Rows.count).Value = .Offset(, 2).Value
End With
End With
With Worksheets("Employee import")
With .Range("G1", .Cells(.Rows.count, "G").End(xlUp))
.AutoFilter field:=1, Criteria1:="<>T"
.Resize(.Rows.count).Offset(1).SpecialCells(xlCellTypeVisible).ClearContents
End With
.AutoFilterMode = False
End With
与工作表(“人口统计”)
带.Range(“AM2”,.Cells(.Rows.count,“AM”).End(xlUp))
工作表(“员工导入”).Range(“G2”).Resize(.Rows.count).Value=.Offset(,2).Value
以
以
带工作表(“员工导入”)
带.Range(“G1”,.Cells(.Rows.count,“G”).End(xlUp))
.自动筛选字段:=1,标准1:=“T”
.Resize(.Rows.count).偏移量(1).特殊单元格(xlCellTypeVisible).ClearContent
以
.AutoFilterMode=False
以
也就是说,如果工作簿中有许多公式和/或事件处理程序,那么在运行代码并重新启用它们之前,禁用它们(Application.EnableEvents=False
,Application.Calculation=xlCalculationManual
)也会使您受益匪浅(Application.EnableEvents=True
,Application.Calculation=xlCalculationAutomatic
)在编码完成后,不需要复制和粘贴值,只需像这样直接设置新值。Sheets(“Employee import”).Range(“G”和i)。Value=Sheets(“人口统计”).Range(“AO”和i)
。这可能会大大加快代码的速度。直接赋值应该比复制/粘贴更快。尝试一下,让我们看看效果如何:Sheets(“Employee import”).Range(“F”&i)。Value=Sheets(“人口统计”).Range(“AU”&i).Value
谢谢!我是个白痴,我知道你在处理多少行数据?请忽略我之前的评论,我没有注意到I
在循环中每次都在递增-我以为只有复制数据时才会递增。在屏幕更新过程中,你可以停止自动计算同样,这可能会有帮助:Application.Calculation=xlCalculationManual您的代码在这里…Application