在 vba 中优化匹配公式循环
optimizing match formula looping in vba
Lastrow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
For i = 3 To Lastrow
Sheets("sample").Range("AM1000000").End(xlUp).Offset(1, 0).Select
Selection.FormulaArray = _
"=IF(ISNUMBER(MATCH(1," & Chr(10) & " (order!R2C15:R1000000C15=RC[-24])*" & Chr(10) & " (order!R2C7:R1000000C7=RC[-32])*" & Chr(10) & " (order!R2C24:R1000000C24=RC[-15])," & Chr(10) & " 0)), ""pass"",""review"")"
Next i
Columns("AM:AM").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
我正在 for 循环中使用匹配公式,但它花费了太多时间。有什么方法可以优化这段代码使其运行得更快吗?
谢谢!
您可以进行很多改进,其中几个主要改进是:
1) 读取和写入作品sheet 上的单元格非常慢,字符串操作也是如此。而是先计算出结果,然后将其写入 sheet 而不是将公式写入单元格。更好的是,将结果存储在一个数组中,并在最后将它们全部写出(但这超出了本题的范围,您可以在线搜索数组)。您可以使用 application.worksheetfunction 重新创建 VBA 中的现有公式,或者您可以考虑创建自己的函数来执行此操作。
2) 再次避免选择单元格 - 操作非常缓慢。而是使用带有 Cells 引用的 for 循环来指定受影响的单元格:
For i = 3 To Lastrow
Sheets("sample").cells(i, 39).FormulaArray = _
"=IF(ISNUMBER(MATCH(1," & Chr(10) & " (order!R2C15:R1000000C15=RC[-24])*" & Chr(10) & " (order!R2C7:R1000000C7=RC[-32])*" & Chr(10) & " (order!R2C24:R1000000C24=RC[-15])," & Chr(10) & " 0)), ""pass"",""review"")"
Next i
单元格语法是(行,列)。这里我是行号,39是AM列。
通过减少数组公式中的引用范围,我们可以加快速度。
同时删除剪贴板也会加快速度:
lastrow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
For i = 3 To lastrow
With WorksSheets("sample").Range("AM" & i)
.FormulaArray = _
"=IF(ISNUMBER(MATCH(1," & Chr(10) & " (order!R2C15:R" & lastrow & "C15=RC[-24])*" & Chr(10) & " (order!R2C7:R" & lastrow & "C7=RC[-32])*" & Chr(10) & " (order!R2C24:R" & lastrow & "C24=RC[-15])," & Chr(10) & " 0)), ""pass"",""review"")"
.Value = .Value
End With
Lastrow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
For i = 3 To Lastrow
Sheets("sample").Range("AM1000000").End(xlUp).Offset(1, 0).Select
Selection.FormulaArray = _
"=IF(ISNUMBER(MATCH(1," & Chr(10) & " (order!R2C15:R1000000C15=RC[-24])*" & Chr(10) & " (order!R2C7:R1000000C7=RC[-32])*" & Chr(10) & " (order!R2C24:R1000000C24=RC[-15])," & Chr(10) & " 0)), ""pass"",""review"")"
Next i
Columns("AM:AM").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
我正在 for 循环中使用匹配公式,但它花费了太多时间。有什么方法可以优化这段代码使其运行得更快吗?
谢谢!
您可以进行很多改进,其中几个主要改进是:
1) 读取和写入作品sheet 上的单元格非常慢,字符串操作也是如此。而是先计算出结果,然后将其写入 sheet 而不是将公式写入单元格。更好的是,将结果存储在一个数组中,并在最后将它们全部写出(但这超出了本题的范围,您可以在线搜索数组)。您可以使用 application.worksheetfunction 重新创建 VBA 中的现有公式,或者您可以考虑创建自己的函数来执行此操作。
2) 再次避免选择单元格 - 操作非常缓慢。而是使用带有 Cells 引用的 for 循环来指定受影响的单元格:
For i = 3 To Lastrow
Sheets("sample").cells(i, 39).FormulaArray = _
"=IF(ISNUMBER(MATCH(1," & Chr(10) & " (order!R2C15:R1000000C15=RC[-24])*" & Chr(10) & " (order!R2C7:R1000000C7=RC[-32])*" & Chr(10) & " (order!R2C24:R1000000C24=RC[-15])," & Chr(10) & " 0)), ""pass"",""review"")"
Next i
单元格语法是(行,列)。这里我是行号,39是AM列。
通过减少数组公式中的引用范围,我们可以加快速度。
同时删除剪贴板也会加快速度:
lastrow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
For i = 3 To lastrow
With WorksSheets("sample").Range("AM" & i)
.FormulaArray = _
"=IF(ISNUMBER(MATCH(1," & Chr(10) & " (order!R2C15:R" & lastrow & "C15=RC[-24])*" & Chr(10) & " (order!R2C7:R" & lastrow & "C7=RC[-32])*" & Chr(10) & " (order!R2C24:R" & lastrow & "C24=RC[-15])," & Chr(10) & " 0)), ""pass"",""review"")"
.Value = .Value
End With