【问题标题】:Create VBA code for MAXifs为 MAXifs 创建 VBA 代码
【发布时间】:2017-04-23 05:26:20
【问题描述】:

我尝试将另一篇文章中的代码改编成更易于理解的内容。运行代码时,我仍然收到此行的错误“类型不匹配”:w(k) = z(i, 1)。有没有人对此错误有任何见解?

我的代码

Option Base 1

Function MaxIf(MaxRange As Range, Lookup_Range1 As Range, Var_Range1 As Variant, _
                Lookup_Range2 As Range, Var_Range2 As Variant) As Variant

    Dim x() As Variant, y() As Variant, z() As Variant, w() As Long
    Dim i As Long
    Dim Constraint1 As Variant, Constraint2 As Variant, k As Long

    i = 1
    k = 0
    Constraint1 = Var_Range1
    Constraint2 = Var_Range2
    x = Lookup_Range1
    y = Lookup_Range2
    z = MaxRange

    For i = 1 To Lookup_Range1.Rows.Count
        If x(i, 1) = Var_Range1 Then
            If y(i, 1) = Var_Range2 Then
                k = k + 1
                ReDim Preserve w(k)
                w(k) = z(i, 1)
            End If
        End If
    Next i
    MaxIf = Application.Max(w)

End Function            

【问题讨论】:

  • 出现错误时z(i, 1) 的值是多少?我的猜测是它包含String、错误或其他一些不能隐式转换为Long 的数据类型。您可以通过在错误行上方添加行 Debug.Assert IsNumeric(z(i, 1)) 来检查。
  • @Diedrich 尝试解释您希望您的Function 做什么?也许添加一个工作表的屏幕截图以及预期的结果。
  • 我认为当其他列中的相应单元格符合某些条件时,您正在尝试获取某个范围内的最大值。您可以通过像MAX(--(Range1 = Criteria1) * -(Range2=Criteria2) * MaxRange) 这样的简单公式来实现这一点,例如Max(--(A1:A15 = "John") * --(B1:B15=20) * C1:C15)

标签: vba excel max


【解决方案1】:

在开始编写代码后,一个限制是您受限于 2 个条件。我决定进一步使用此代码,以不限制 MaxIfs 函数的条件数量。请看这里的代码:

    Function MaxIfs(MaxRange As Range, ParamArray Criteria() As Variant) As Variant
    Dim n As Long
    Dim i As Long
    Dim c As Long
    Dim f As Boolean
    Dim w() As Long
    Dim k As Long
    Dim z As Variant

    'Error if less than 1 criteria
    On Error GoTo ErrHandler
    n = UBound(Criteria)
    If n < 1 Then
        'too few criteria
        GoTo ErrHandler
    End If

    'Define k
    k = 0

    'Loop through cells of max range
    For i = 1 To MaxRange.Count

    'Start by assuming there is a match
    f = True

        'Loop through conditions
        For c = 0 To n - 1 Step 2

            'Does cell in criteria range match condition?
            If Criteria(c).Cells(i).Value <> Criteria(c + 1) Then
                f = False
            End If

        Next c

        'Define z
        z = MaxRange

        'Were all criteria satisfied?
        If f Then
            k = k + 1
            ReDim Preserve w(k)
            w(k) = z(i, 1)
        End If

    Next i

    MaxIfs = Application.Max(w)

    Exit Function
    ErrHandler:
    MaxIfs = CVErr(xlErrValue)

End Function

此代码允许 1 到多个条件。

此代码是参考 Hans V 在 Eileen's Lounge 发布的多个代码而开发的。

迪德里希

【讨论】:

    【解决方案2】:

    由于您有兴趣返回一些最大值以在 MaxRange 范围之间进行选择,因此您可以仅循环其 numeric 值并检查 Lookup_Range1 的相应单元格中的条件和Lookup_Range2 仅限,如下所示:

    Function MaxIF(MaxRange As Range, Lookup_Range1 As Range, Var_Range1 As Variant, _
                    Lookup_Range2 As Range, Var_Range2 As Variant) As Variant
    
        Dim LU1 As Variant, LU2 As Variant
        Dim founds As Long
        Dim cell As Range
    
        LU1 = Lookup_Range1.Value2 '<--| store Lookup_Range1 values
        LU2 = Lookup_Range2.Value2 '<--| store Lookup_Range2 values
    
        ReDim ValuesForMax(1 To MaxRange.Rows.count) As Long '<--| initialize ValuesForMax to its maximum possible size
        For Each cell In MaxRange.Columns(1).SpecialCells(xlCellTypeConstants, xlNumbers)
            If LU1(cell.row, 1) = Var_Range1 Then '<--| check 'Lookup_Range1' value in corresponding row of current 'MaxRange' cell
                If LU2(cell.row, 1) = Var_Range2 Then '<--| check 'Lookup_Range2' value in corresponding row of current 'MaxRange' cell
                    founds = founds + 1
                    ValuesForMax(founds) = CLng(cell) '<--| store current 'MaxRange' cell
                End If
            End If
        Next cell
        ReDim Preserve ValuesForMax(1 To founds) '<--| resize ValuesForMax to its actual values number
        MaxIF = Application.max(ValuesForMax)
    End Function
    

    我还给变量取了更有意义的名字

    【讨论】:

    • 感谢大家的帮助。 user3598756,运行代码时出现运行时错误 9“下标超出范围”错误,在线: If LU1(cell.Row, 1) = Var_Range1 Then '
    • 你传递给函数的三个范围是什么?
    • 它们都是使用最后一行定义的范围。类似:range(worksheets("data").cells(2,defined column),worksheets("data").cells(last row,defined column)),我现在无法提供实际代码,因为我目前在工作,无法访问我的个人计算机/文件。我可以在今天晚些时候发送实际范围。再次感谢!
    • 那么他们可以有不同的行数,不是吗?
    • 数据被格式化为数据库(在工作表中),因此所有引用的长度相同。我什至尝试在单元格中使用该函数,但出现“#VALUE”错误。很抱歉我在这里没有经验,我学习 VBA 是出于个人兴趣,我意识到我还有很多东西要学。
    猜你喜欢
    • 2014-08-03
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多