使SMALL(,INDEX(FREQUENCY ..)适应VBA

时间:2018-11-07 07:27:29

标签: excel vba excel-vba excel-formula

我正在尝试找到最小的非零值。我在网上找到了以下示例,并试图将其改编成适用于VBA的示例。

=SMALL((A1,C1,E1),INDEX(FREQUENCY((A1,C1,E1),0),1)+1)

这是我的适应范围:

myarr = Array(A, B, C)
.Range(Cells(D, 1), Cells(WorksheetFunction.Small(myarr,WorksheetFunction.Index(WorksheetFunction.Frequency(myarr, 0), 1) + 1),1)).EntireRow.Delete

其中A,B,C,D是四个整数。

在调试窗口中,SMALL函数返回“上下文无关”,并且在执行此行代码后,编译器将退出子程序,就像执行了“退出子程序”命令一样。

我的猜测是FREQUENCY函数不起作用。如何运作?

对于仅三个值,使用嵌套IF之类的非函数解决方案很容易,但是我对如何使这些函数在将来可能需要的功能感兴趣。

2 个答案:

答案 0 :(得分:1)

这里有几个选项-如果您拥有Office 365,最简单的选项 是使用MINIFS函数,例如:WorksheetFunction.MinIf(myarr, myarr, "<>0")

但是,由于您尚未将问题标记为,因此我将使用其他选项:

Private Function MinPositive(Values As Variant) As Variant
    MinPositive = CVErr(xlErrValue)
    On Error GoTo FuncErr
    Dim TempVal As Double, Pointer As Long
    If IsArray(Values) Then
        TempVal = WorksheetFunction.Max(Values) 'High bound
        If TempVal <= 0 Then Exit Function 'No values greater than 0
        For Pointer = LBound(Values) To UBound(Values)
            If CDbl(Values(Pointer)) > 0 And CDbl(Values(Pointer)) < TempVal Then
                TempVal = CDbl(Values(Pointer)) 'Swap for lower number
            End If
        Next Pointer
    End If
    MinPositive = TempVal 'Output the Min value greater than 0
FuncErr:
End Function

答案 1 :(得分:0)

不能完全确定您在做什么,但是可以在Evaluate中使用数组执行MIN IF

Option Explicit
Public Sub GetMinGreaterThanZero()
    Dim arr()
    arr = Array(0, 4, 2, 1)
    Debug.Print Evaluate("=MIN(IF({" & Join(arr, ";") & "}>0,{" & Join(arr, ";") & "}))")
End Sub