从传递的列/行/范围VBA Excel中获取一个单元格

我正在为VBA中的excel编写用户定义的函数。

用户可以将整个列/行传递给函数而不是一个单元格。 你如何获得在同一行(对于列情况)和同一列(对于行情况)中的函数所在的单元格。

例如,当你在Excel中写单元格时,比方说C3,公式“= A:A * B:B”实际上就是计算A3 * B3。 我想在我的UDF中有相同的行为。

为了简单起见,我们假设返回传递参数的函数。 此代码无效(对列/行/范围返回#VALUE!):

Public Function MyTestFunction(ByVal arg1) As Variant MyTestFunction = arg1 End Function 

我的select如下,但我担心的是性能和事实,用户可能想传递一个值,而不是范围的公式。

 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 

你怎么解决这个问题?


感谢有价值的评论代码已经稍微更新,现在可以在其他公式中使用来过滤input值。

 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 

在第一个代码片段中,将MyTestFunction = arg1更改为Set MyTestFunction = arg1 。 还要添加一个识别arg1TypeName()的小机制,并确保该函数正在接收Rangetypes对象。

 Public Function MyTestFunction(ByVal arg1) As Variant Set MyTestFunction = arg1 End Function 

在这里输入图像说明


然后,如果您到达电子表格并在任意行input=MyTestFunction(A:A) ,您将从传递给位于同一行的函数的列中收到相同的值。

和你的第二个想法得到一个类似的行为=A:A*B:B你可以实现

 Public Function MyTestFunction2(ParamArray arr() As Variant) MyTestFunction2 = arr(0) End Function 

在这里输入图像说明

我想你需要使用Application.ThisCell property来做到这一点。 根据MSDN:

Application.ThisCell – 返回用户定义的函数被调用的单元格作为Range对象。

让我来演示如何使用它的简单例子。 想象一下,我们在A:B列中提供了如下数据,并且我们希望分别得到来自= A * B的结果。

在这里输入图像说明

在这种情况下,你需要下面的函数,然后把它放在C列中: =MyTestFunction(A:A,B:B)

 Function MyTestFunction(rngA As Range, rngB As Range) Dim funRow As Long funRow = Application.ThisCell.Row MyTestFunction = rngA(funRow) * rngB(funRow) End Function 

请记住,如果您从其他VBA过程调用您的函数, Application.ThisCell将不起作用。