我有一张Excel工作表,其中包含一个在VBA中执行索引/匹配公式的表,并将值复制到表中。代码如下:
Private Sub worksheet_change(ByVal target As Range)
If Not Intersect(target, Me.ListObjects("ProjectEntry").ListColumns("Asset No").DataBodyRange) Is Nothing Then
With Me.Range("ProjectEntry[Description]")
.Formula = "=IF(ISNA(INDEX(DieMaster,MATCH(B4,DieMaster[Asset No],FALSE),2)),"""",INDEX(DieMaster,MATCH(B4,DieMaster[Asset No],FALSE),2))"
.Value = .Value
End With
End If
End Sub
我发现此代码虽然有效,但会在表中的所有单元格上执行。现在我希望它只在我选择的行中执行。例如,如果我在A5中执行更改,我希望代码仅在第5行中执行。
我尝试过使用Offset,因为当数据不在表格中时,它可以在Excel中使用。使用以下代码:
Private Sub worksheet_change(ByVal target As Range)
If Not Intersect(target, Me.ListObjects("ProjectEntry").ListColumns("Asset No").DataBodyRange) Is Nothing Then
With target.Offset(0, 1)
.FormulaR1C1 = "=IF(ISNA(INDEX(DieMaster,MATCH(rc1,DieMaster[Asset No],FALSE),2)),"""",INDEX(DieMaster,MATCH(rc1,DieMaster[Asset No],FALSE),2))"
.Value = .Value
End With
End If
End Sub
但它似乎无法奏效。这是否意味着Offset在表中不起作用?如果没有,还有另一种方式吗?
答案 0 :(得分:0)
虽然使用RC2
修复了您的问题,但使用RC[-1]
可以更好地远。如果移动表或将列插入其左侧,则代码将使用绝对引用中断,但不使用相对引用。
您最好使用IFERROR()
函数而不是IF(ISNA())
,因为它会产生一个避免重复的公式,并且只有一半的长度:
With Target.Offset(0, 1)
.FormulaR1C1 = "=IFERROR(INDEX(DieMaster,MATCH(RC[-1],DieMaster[Asset No],0),2),"""")"
.Value = .Value
End With
但是,仅刷新已编辑行的最佳方法是在VBA中进行计算并将结果写入工作表。
以下代码执行此操作:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("ProjectEntry[Asset No]")) Is Nothing Then Exit Sub
Dim Ä As Excel.Application: Set Ä = Excel.Application
Dim varValue As Variant
With Ä.Range("DieMaster").ListObject.ListColumns
varValue = Ä.Index(.Item(2).DataBodyRange, Ä.Match(Target.Value2, Ä.Range("DieMaster[Asset No]"), 0))
End With
Target.Offset(0, 1).Value = IIf(IsError(varValue), vbNullString, varValue)
End Sub
请注意使用Application.
代替WorksheetFunction.
来访问工作表函数。这与使用Variant类型变量相结合,允许我们捕获匹配失败时发生的错误。