使用索引和匹配更新列的值 (Excel/VBA)
Update values of a column using Index & Match (Excel/VBA)
下面是我的部分代码,我的编码快完成了,但现在我发现了一个大问题,需要更正。
我在超过 10000 行的 sheet 上使用此代码,我的目的是使用索引和匹配函数更新列。它所做的是用另一个 sheet 中的相应值替换 J 列中范围内的所有单元格。最大的问题是我不希望没有匹配项的单元格被替换为 #N/A 并且它们保留旧值。
我该怎么办?
Dim SourceRange As Range
Dim fillRange As Range
'bellow formula in A1 notation:
'=INDEX('[myWB.xls]Sheet1'!$A:$B;
'IF(INDEX('[myWB.xls]Sheet1'!$A:$A;MATCH(C4;'[myWB.xls]Sheet1'!$A:$A))=C4;
' MATCH(C4;'[myWB.xls]Sheet1'!$A:$A);
' NA());
' 2)
ActiveCell.FormulaR1C1 = _
"=INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2)"
' autofill formula in column
Set SourceRange = Cells(2, 10)
Set fillRange = Range(Cells(2, 10), Cells(10000, 10))
With SourceRange
.AutoFill Destination:=fillRange, Type:=xlCopy
End With
'replace formula with its value
With Range(Cells(2, 10), Cells(10000, 10))
.Value = .Value
End With
更新
这是我当前的代码,有一些改进。感谢 Rob Anthony 的帮助。
Dim calc As XlCalculation
Dim f as String
With Workbooks(FinalWB.xls).Worksheets(1) 'Worksheet to be updated
calc = Application.Calculation
Application.Calculation = xlCalculationAutomatic 'Ensure automatic calculation is ON
Application.ScreenUpdating = False
Application.EnableEvents = False
'Copy Column J to Column Z
Range(.Cells(2, 26), .Cells(10000, 26)).Value = _ ' Col Z =
Range(.Cells(2, 10), .Cells(10000, 10)).Value ' Col J
f = "=if(ISERROR(INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2)),RC[16],INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2))"
With Range(.Cells(2, 10), .Cells(10000, 10))
.FormulaR1C1 = f 'fill formula without Autofill
.Value = .Value 'replace formula with its value
End With
'Delete Column Z
.Columns(26).EntireColumn.Delete
End With
Application.Calculation = calc
Application.ScreenUpdating = True
Application.EnableEvents = True
'This is above formula. now seems so easy to understand :)
' f =
' "=IF( 'if calculations result an error...
' ISERROR(
' INDEX([myWB.xls]Sheet1!C1:C2,
' IF(
' INDEX([myWB.xls]Sheet1!C1,
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1)
' )=R[-11]C[-12],
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1),
' NA()
' ),
' 2
' )
' ),
' RC[16], 'use previousely copied value of the cell...
' INDEX([myWB.xls]Sheet1!C1:C2, 'else use that calculations
' IF(
' INDEX([myWB.xls]Sheet1!C1,
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1)
' )=R[-11]C[-12],
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1),
' NA()
' ),
' 2
' )
' )
' "
解决此问题的最简单方法是将 J 列复制并粘贴到新列(例如 Z)中。然后,将此公式放入 J
列
=if(ISERROR(INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2)),RC[16],INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2))
我检查公式 returns 是否是一个有效值,如果不是,那么我输入 Z 列的值(我假设 RC[16] 是这个的有效参考,根据您之前的评论),否则我输入计算值。
如果不查看您的电子表格,就很难准确了解您要做什么。或许可以缩短此功能。
下面是我的部分代码,我的编码快完成了,但现在我发现了一个大问题,需要更正。
我在超过 10000 行的 sheet 上使用此代码,我的目的是使用索引和匹配函数更新列。它所做的是用另一个 sheet 中的相应值替换 J 列中范围内的所有单元格。最大的问题是我不希望没有匹配项的单元格被替换为 #N/A 并且它们保留旧值。
我该怎么办?
Dim SourceRange As Range
Dim fillRange As Range
'bellow formula in A1 notation:
'=INDEX('[myWB.xls]Sheet1'!$A:$B;
'IF(INDEX('[myWB.xls]Sheet1'!$A:$A;MATCH(C4;'[myWB.xls]Sheet1'!$A:$A))=C4;
' MATCH(C4;'[myWB.xls]Sheet1'!$A:$A);
' NA());
' 2)
ActiveCell.FormulaR1C1 = _
"=INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2)"
' autofill formula in column
Set SourceRange = Cells(2, 10)
Set fillRange = Range(Cells(2, 10), Cells(10000, 10))
With SourceRange
.AutoFill Destination:=fillRange, Type:=xlCopy
End With
'replace formula with its value
With Range(Cells(2, 10), Cells(10000, 10))
.Value = .Value
End With
更新
这是我当前的代码,有一些改进。感谢 Rob Anthony 的帮助。
Dim calc As XlCalculation
Dim f as String
With Workbooks(FinalWB.xls).Worksheets(1) 'Worksheet to be updated
calc = Application.Calculation
Application.Calculation = xlCalculationAutomatic 'Ensure automatic calculation is ON
Application.ScreenUpdating = False
Application.EnableEvents = False
'Copy Column J to Column Z
Range(.Cells(2, 26), .Cells(10000, 26)).Value = _ ' Col Z =
Range(.Cells(2, 10), .Cells(10000, 10)).Value ' Col J
f = "=if(ISERROR(INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2)),RC[16],INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2))"
With Range(.Cells(2, 10), .Cells(10000, 10))
.FormulaR1C1 = f 'fill formula without Autofill
.Value = .Value 'replace formula with its value
End With
'Delete Column Z
.Columns(26).EntireColumn.Delete
End With
Application.Calculation = calc
Application.ScreenUpdating = True
Application.EnableEvents = True
'This is above formula. now seems so easy to understand :)
' f =
' "=IF( 'if calculations result an error...
' ISERROR(
' INDEX([myWB.xls]Sheet1!C1:C2,
' IF(
' INDEX([myWB.xls]Sheet1!C1,
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1)
' )=R[-11]C[-12],
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1),
' NA()
' ),
' 2
' )
' ),
' RC[16], 'use previousely copied value of the cell...
' INDEX([myWB.xls]Sheet1!C1:C2, 'else use that calculations
' IF(
' INDEX([myWB.xls]Sheet1!C1,
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1)
' )=R[-11]C[-12],
' MATCH(R[-11]C[-12],
' [myWB.xls]Sheet1!C1),
' NA()
' ),
' 2
' )
' )
' "
解决此问题的最简单方法是将 J 列复制并粘贴到新列(例如 Z)中。然后,将此公式放入 J
列=if(ISERROR(INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2)),RC[16],INDEX([myWB.xls]Sheet1!C1:C2,IF(INDEX([myWB.xls]Sheet1!C1,MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1))=R[-11]C[-12],MATCH(R[-11]C[-12],[myWB.xls]Sheet1!C1),NA()),2))
我检查公式 returns 是否是一个有效值,如果不是,那么我输入 Z 列的值(我假设 RC[16] 是这个的有效参考,根据您之前的评论),否则我输入计算值。
如果不查看您的电子表格,就很难准确了解您要做什么。或许可以缩短此功能。