【问题标题】:Evaluate input to a VBA function before executing the function在执行函数之前评估 VBA 函数的输入
【发布时间】:2021-03-25 17:08:21
【问题描述】:

我创建了一个 VBA 函数来计算加权平均值。该函数具有可选参数(“标准”),允许将加权平均计算限制为仅行的子集(以下示例中的所有 Apple 行)。

该函数适用于以下形式的输入:

weightedAverage([5 2 5],[2 3 4], [Apple Orange Apple], Apple)

如果我按如下方式更改“条件”上的输入,函数会返回错误:

weightedAverage([5 2 5],[2 3 4], ([Apple Orange Apple]=Apple), TRUE)

有没有办法让函数首先评估第三个输入并将其转换为[TRUE FALSE TRUE]

(工作簿函数 sumproduct 能够处理sumproduct(--([Apple Orange Apple]=Apple),...) 形式的输入,这就是为什么我想知道我的函数是否也可以)

Function weightedAverage(vals As Range, weight As Range, ParamArray criterias() As Variant) As Double
' Calcualted Weighted Average of "vals" weighted by "weight"
' Optionally the weighted average can be constrained to certain "vals" only by using "criterias"


Dim totalweight As Double 'sum up weights where "vals" is a number and "criterias" is true
Dim result As Double 'sum up vals(i) * weights(i)
Dim takevalue As Boolean 'temporary variable store whether "vals" is a number and "criterias" are met


' Init
result = 0
totalweight = 0

' Loop over vals
For i = 1 To vals.Count

    ' Check whether vals is a numeric and not empty
    takevalue = IsNumeric(vals.Cells(i).Value) And Not (IsEmpty(vals.Cells(i).Value))
    
    ' Check whether criterias are satisfied
    For ii = 0 To UBound(criterias) - 1 Step 2
    
        ' Exit loop if condition is not satisfied
        If takevalue = False Then Exit For

        ' Test whether condition is true
        takevalue = ((LCase(criterias(ii).Cells(i).Value) = LCase(criterias(ii + 1).Cells(1).Value)) And takevalue)

    Next ii
    
    ' If all conditions are satisfied, add value to results and totalweight
    If takevalue Then
    
        result = result + vals(i) * weight(i)
        totalweight = totalweight + weight(i)
    
    End If

Next i

' Calculate weighted average
weightedAverage = result / totalweight

End Function

【问题讨论】:

  • 所以您希望我们重新编写您的代码?你做了什么来尝试改变代码来做你想做的事?
  • 您是否使用 Ctrl+Shift+Enter 输入您的示例weightedAverage([5 2 5],[2 3 4], ([Apple Orange Apple]=Apple), TRUE) 我不认为它会起作用。您的第一个示例更简单,不需要 CSE
  • 谢谢,@BigBen。我认为我正在循环内部循环(ii 循环)中的数组。但不知何故,问题似乎是我的第三个输入([Apple Orange Apple]=Apple)首先需要在传递给 VBA 函数之前进行评估。在 Matlab 中我会使用 eval 函数,但我在 VBA 中找不到这样的功能
  • 谢谢,蒂姆。我尝试了 Ctrl+Shift+Enter 但它不起作用。此外,我在 VBA 中搜索了 eval(来自 Matlab)是否有等价物,但我找不到任何可比的东西。到目前为止,这一切都是尝试过的。
  • “我的第三个输入([Apple Orange Apple]=Apple)首先需要在传递给 VBA 函数之前进行评估” - 这就是为什么这只能在使用 Ctrl+Shift+Enter 时起作用,因为这就是数组公式在工作表上的工作方式。在我的测试中,导致 True/False 数组作为第三个参数传入(因此不需要第四个 TRUE 参数)。

标签: vba function input evaluate


【解决方案1】:

感谢蒂姆,感谢您的帮助。该函数需要使用 Ctrl+Shift+Enter 执行,并且需要删除第四个输入。

以下 weightedAverage 函数适用于以下输入:

weightedAverage([5 2 5],[2 3 4], ([Apple Orange Apple]=Apple))

Function weightedAverage(vals As Range, weight As Range, ParamArray criterias() As Variant) As Double
' Calcualted Weighted Average of "vals" weighted by "weight"
' Optionally the weighted average can be constrained to certain "vals" only by using "criterias"


Dim totalweight As Double 'sum up weights where "vals" is a number and "criterias" is true
Dim result As Double 'sum up vals(i) * weights(i)
Dim takevalue As Boolean 'temporary variable store whether "vals" is a number and "criterias" are met


' Init
result = 0
totalweight = 0

' Loop over vals
For i = 1 To vals.Count

    ' Check whether vals is a numeric and not empty
    takevalue = IsNumeric(vals.Cells(i).Value) And Not (IsEmpty(vals.Cells(i).Value))
    
    ' Check whether criterias are satisfied
    For ii = 0 To UBound(criterias)
    
        ' Exit loop if condition is not satisfied
        If takevalue = False Then Exit For

        ' Test whether condition is true
        takevalue = (criterias(ii)(i, 1) And takevalue)

    Next ii
    
    ' If all conditions are satisfied, add value to results and totalweight
    If takevalue Then
    
        result = result + vals(i) * weight(i)
        totalweight = totalweight + weight(i)
    
    End If

Next i

' Calculate weighted average
weightedAverage = result / totalweight

End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-06
    • 2023-03-11
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多