Excel MaxIF函数失败,但作为子运行

我一直在试图写一个MaxIf用户定义函数。 代码完美地作为一个子运行,但是Do循环失败了,没有错误。 我作为一个function,通过它,但没有透露任何线索。

Public Function udfMaxIf(criteria As Range, criteria_range As Range, max_range As Range) Dim dblValues() As String Dim lngMax As Long Dim lngX As Long, intLastRow As Integer Dim strSearch As String Dim rngCriteria As Range, strFirst As String, strLast As String strSearch = criteria.Value '# setting after = to last row in range forces the Find to start from, and including, the first line of the range. Else it starts from top '# row but doesn't search it until last. With criteria_range intLastRow = .Rows.Count Set rngCriteria = .Find(strSearch, after:=criteria_range.Cells(intLastRow, 1), LookIn:=xlValues, searchorder:=xlByRows, searchdirection:=xlNext) End With If Not rngCriteria Is Nothing Then '# set the value of the first appearance of rngCriteria to array(0) ReDim dblValues(0) strFirst = rngCriteria.Address strLast = criteria_range.Find(strSearch, LookIn:=xlValues, searchorder:=xlByRows, searchdirection:=xlPrevious).Address dblValues(0) = Cells(rngCriteria.Row, max_range.Column).Value '# add subsequent values to the array but break when it reaches last row. If this was only value it would have been picked up above. Do Until rngCriteria.Address = strLast Set rngCriteria = criteria_range.FindNext(rngCriteria) ReDim Preserve dblValues(UBound(dblValues) + 1) dblValues(UBound(dblValues)) = Cells(rngCriteria.Row, max_range.Column).Value Loop End If On Error GoTo UBound_handler: lngMax = dblValues(0) For lngX = 0 To UBound(dblValues) If dblValues(lngX) > lngMax Then lngMax = dblValues(lngX) End If Next lngX On Error Resume Next udfMaxIf = lngMax Exit Function UBound_handler: If Err.Number = 9 Then MsgBox "Criteria not found in criteria range", vbInformation Else: MsgBox Err.Number & ": " & Err.Description End If Exit Function End Function 

方法可以改进,但我更关心的是为什么它不能作为一个function。 谢谢。

就个人而言,我更喜欢迭代数组,因为我发现它比其他方法更可靠和更快。 像这样的东西可以用作MaxIf UDF:

 Public Function MaxIf(ByVal rCriteria As Range, ByVal sCriteria As String, ByVal rMax As Range) As Variant Dim aCrit As Variant Dim aValues As Variant Dim i As Long, j As Long Dim dMax As Double aCrit = rCriteria.Value aValues = rMax.Value If rCriteria.Rows.Count & "," & rCriteria.Columns.Count <> rMax.Rows.Count & "," & rMax.Columns.Count Then MaxIf = CVErr(xlErrRef) Exit Function End If If Not IsArray(aCrit) Then If LCase(aCrit) Like LCase(sCriteria) Then MaxIf = aValues Else MaxIf = 0 Else dMax = -10 ^ 308 For i = 1 To UBound(aCrit, 1) For j = 1 To UBound(aCrit, 2) If LCase(aCrit(i, j)) Like LCase(sCriteria) Then If IsNumeric(aValues(i, j)) Then If aValues(i, j) > dMax Then dMax = aValues(i, j) End If End If Next j Next i If dMax > -10 ^ 308 Then MaxIf = dMax Else MaxIf = 0 End If End Function 
 dblValues(0) = Cells(rngCriteria.Row, max_range.Column).Value 

这样的行可能会有问题,因为您没有将Cells()作用域限定在特定的工作表中,所以它将默认为Activesheet(除非在sheet工作表中有此代码)