【发布时间】:2014-01-14 07:44:34
【问题描述】:
我正在为 VBA 中的 excel 编写用户定义的函数。
用户可以将一整列/整行而不是一个单元格传递给函数。如何获取函数所在的同一行(对于列案例)和同一列(对于行案例)中的单元格。
例如,当您在 Excel 中写入单元格时,例如 C3,公式“=A:A*B:B”实际上计算的是 A3*B3。我希望在我的 UDF 中具有相同的行为。
为了简单起见,我们假设函数返回传递的参数。 此代码不起作用(为列/行/范围返回 #VALUE!):
Public Function MyTestFunction(ByVal arg1) As Variant
MyTestFunction = arg1
End Function
我的选项如下,但我担心性能以及用户可能希望将值传递给公式而不是 Range。
Public Function MyTestFunction2(ByVal arg1 As Range) As Variant
If arg1.Count = 1 Then
MyTestFunction2 = arg1.Value
Else
' Vertical range
If arg1.Columns.Count = 1 Then
MyTestFunction2 = arg1.Columns(1).Cells(Application.Caller.Row, 1).Value
Exit Function
End If
' Horizontal range
If arg1.Rows.Count = 1 Then
MyTestFunction2 = arg1.Rows(1).Cells(1, Application.Caller.Column).Value
Exit Function
End If
' Return #REF! error to user
MyTestFunction2 = CVErr(xlErrRef)
End If
End Function
你如何解决这个问题?
感谢宝贵的 cmets 代码已略微更新,现在可用于其他公式来过滤输入值。
Public Function MyTestFunction2(ByVal arg1) As Variant
If Not TypeName(arg1) = "Range" Then
MyTestFunction2 = arg1
Exit Function
End If
If arg1.Count = 1 Then
MyTestFunction2 = arg1.Value
Else
' Vertical range
If arg1.Columns.Count = 1 Then
' check for range match current cell
If arg1.Cells(1, 1).Row > Application.Caller.Row Or _
arg1.Cells(1, 1).Row + arg1.Rows.Count - 1 < Application.Caller.Row Then
' Return #REF! error to user
MyTestFunction2 = CVErr(xlErrRef)
Exit Function
End If
' return value from cell matching cell with function
MyTestFunction2 = arg1.Worksheet.Columns(1).Cells(Application.Caller.Row, arg1.Column).Value
Exit Function
End If
' Horizontal range
If arg1.Rows.Count = 1 Then
' check for range match current cell
If arg1.Cells(1, 1).Column > Application.Caller.Column Or _
arg1.Cells(1, 1).Column + arg1.Columns.Count - 1 < Application.Caller.Column Then
' Return #REF! error to user
MyTestFunction2 = CVErr(xlErrRef)
Exit Function
End If
' return value from cell matching cell with function
MyTestFunction2 = arg1.Worksheet.Rows(1).Cells(arg1.Row, Application.Caller.Column).Value
Exit Function
End If
' Return #REF! error to user
MyTestFunction2 = CVErr(xlErrRef)
End If
End Function
【问题讨论】:
-
在第一个代码中 sn -p 将
MyTestFunction = arg1更改为Set MyTestFunction = arg1。还要添加一个小机制来识别arg1的TypeName(),并确保该函数正在接收范围。然后转到您的电子表格并在任意行输入MyTestFunction(A:A),您将从传递给位于同一行的函数的列中收到等效值。 -
关于获得与
=A:A*B:B类似行为的第二个想法可以使用Public Function MyTestFunction2(ParamArray arr() As Variant)然后在新行MyTestFunction2 = arr(0)和关闭函数End Function上实现 -
非常感谢您在评论中的第一句话。它正是我需要的功能。看来它甚至不需要任何进一步的检查。
-
@mehow 如果您可以将您的 cmets 转换为答案,我会结束这个问题。