Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.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
需要比每个循环vba更高的效率_Vba_Excel_Macros - Fatal编程技术网

需要比每个循环vba更高的效率

需要比每个循环vba更高的效率,vba,excel,macros,Vba,Excel,Macros,我是vba/excel宏的新手,需要一种更有效的方法来运行下面的代码。我使用for-each循环根据列的值(同一行)从一行返回一个值。代码可以工作,但需要太多的处理能力和时间才能通过循环(通常会冻结计算机或程序)。如果有任何建议,我将不胜感激 '下面将搜索范围内的每个单元格,以确定单元格是否为空。如果单元格不为空,宏将复制单元格的值并将其粘贴到另一个工作表(同一行)中 '下面搜索范围内的每个单元格,以确定单元格是否包含“T”。如果单元格包含“T”,宏将复制另一列(同一行)的值,并将其粘贴到另一个

我是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