用户定义的函数返回#Value

时间:2016-03-15 14:26:52

标签: excel vba udf

我遇到过一种情况,要求我对Vlookups数组的结果进行平均。我不知道如何使用公式来实现这一点,而且看起来StackOverflow上的其他任何人都没有任何想法。

所以我决定写一个函数为我做这个工作。不幸的是它会返回" #VALUE!"错误,我不明白为什么!使用msgbox测试时,该功能正常。我在下面注释了我的代码:

Option Explicit

Public Function AvgVlookup(Target_Array As String, Lookup_Array As String, Column_Index As Long) As Double

Dim Result As Double
Dim Total As Double
Dim Counter As Long
Dim TargetRange As Range
Dim LookupRange As Range
Dim Cell As Range

' Remove Absolute Indicator
Target_Array = Replace(Target_Array, "$", "")
Lookup_Array = Replace(Lookup_Array, "$", "")

' Convert String to Range
Set TargetRange = Range(Left(Target_Array, InStr(1, Target_Array, ":") - 1), Mid(Target_Array, InStr(1, Target_Array, ":") + 1))
Set LookupRange = Range(Left(Lookup_Array, InStr(1, Lookup_Array, ":") - 1), Mid(Lookup_Array, InStr(1, Lookup_Array, ":") + 1))

' Set Variables to 0
Counter = 0
Total = 0

' For each cell in defined array
For Each Cell In TargetRange

' Vlookup the cell and save lookup value to Result variable
    Result = Application.WorksheetFunction.vlookup(Cell, LookupRange, Column_Index, "False")

' Update variables used to calculate average
    Total = Total + Result
    Counter = Counter + 1

Next Cell

' Perform calculation
AvgVlookup = Total / Counter

End Function
Sub test()

MsgBox AvgVlookup("A5:A8", "G5:H8", 2)

End Sub

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

两件事:

首先,您设置范围的方式有点长,可以简单地截断为:

Set TargetRange = Range(Target_Array)

删除$后无需解析字符串。

其次,如果目标范围中的一个值不在查找范围内,则需要进行错误检查。

整个代码:

Public Function AvgVlookup(Target_Array As String, Lookup_Array As String, Column_Index As Long) As Double


Dim Total As Double
Dim Counter As Long
Dim TargetRange As Range
Dim LookupRange As Range
Dim Cell As Range

' Remove Absolute Indicator
Target_Array = Replace(Target_Array, "$", "")
Lookup_Array = Replace(Lookup_Array, "$", "")

' Convert String to Range
Set TargetRange = Range(Target_Array)
Set LookupRange = Range(Lookup_Array)

' Set Variables to 0
Counter = 0
Total = 0

' For each cell in defined array
For Each Cell In TargetRange

' Vlookup the cell and save lookup value to Result variable
    Dim Result
    Result = Application.VLookup(Cell, LookupRange, Column_Index, "False")
    If IsNumeric(Result) Then
        Total = Total + Result
        Counter = Counter + 1
    End If


Next Cell

' Perform calculation
AvgVlookup = Total / Counter

End Function

使用上述函数从工作表调用,您需要像这样调用它:=AvgVlookup("A5:A8", "G5:H8", 2)

但这不是很有帮助。如果您将输入更改为范围:

Public Function AvgVlookup(TargetRange As Range, LookupRange As Range, Column_Index As Long) As Double

Dim Result As Double
Dim Total As Double
Dim Counter As Long
Dim Cell As Range


' Set Variables to 0
Counter = 0
Total = 0

' For each cell in defined array
For Each Cell In TargetRange

' Vlookup the cell and save lookup value to Result variable
    Dim t
    t = Application.VLookup(Cell, LookupRange, Column_Index, "False")
    If IsNumeric(t) Then
        Total = Total + t
        Counter = Counter + 1
    End If


Next Cell

' Perform calculation
AvgVlookup = Total / Counter

End Function

然后你会简单地称之为=AvgVlookup($A$5:$A$8,$G$5:$H$8,2)。这样你就可以突出显示正确的范围,它会起作用。当您想输入的内容是一个范围时,尝试将字符串转换为范围的输入也较少。

enter image description here