VBA Public Function "Compile Error: Expected: List separator or )"
VBA Public Function "Compile Error: Expected: List separator or )"
我正在编写我的第一个函数,并且正在为加权平均公式创建一个函数。
当我将它用作子项并定义值时,这工作正常,但在立即测试函数时出现此错误 window。
我试过各种数据类型都无济于事。
如有任何帮助,我们将不胜感激。
enter image description here
Public Function WeightedAverage(data() As Range, values() As Range, TotalValue As Range) As Double
Dim i As Integer
Dim Sum As Variant
For i = 1 To UBound(data)
Sum = Sum + values(i, 1) / TotalValue * data(i, 1)
Next i
WA = Sum / UBound(data)
End Function
enter image description here
正如@Skin 提到的,您可以稍微修改一下代码。我删除了参数部分中的括号。此外,您应该在单元格内调用该函数并将每个参数分配给 cell/a 单元格范围。
您的代码中没有定义变量“WA”。这可能会导致你的错误。要从用户定义的函数 (UDF) 中获取 return 值,您应该将变量“sum”分配给函数名称。
如果我的反馈是您问题的有效答案,请将其标记为答案。谢谢!
Public Function WeightedAverage( _
data As Range, _
values As Range, _
TotalValue As Range _
) As Double
Dim i As Integer
'You need containers for your parameters, which can be more then one cell
Dim arrData As Variant: arrData = data
Dim arrValues As Variant: arrValues = values
Dim Sum As Double
'Both arrays need the same size, optional, I thought that might help a little bit
If UBound(arrData, 1) <> UBound(arrValues) Then Exit Function
For i = 1 To UBound(arrData, 1)
Sum = Sum + arrValues(i, 1) / TotalValue * arrData(i, 1)
Next i
'Assign the variable "sum" to the functions name
WeightedAverage = Sum / UBound(arrData, 1)
End Function
加权平均 UDF
- 无论你在这里做什么,根据这个 link,这不是你计算加权平均值的方式(最后一个参数似乎多余,循环中的除法是错误的)。
- 如果存在不包含数值的单元格,则提供的 link 中建议的
SUMPRODUCT/SUM
公式解决方案将失败,而以下函数将忽略(跳过)这些单元格。
加权平均值
Option Explicit
Function WeightedAverage( _
ByVal ScoreColumnRange As Range, _
ByVal WeightColumnRange As Range) _
As Double
' Compare the number of rows and use the smaller number.
Dim rCount As Long: rCount = ScoreColumnRange.Rows.Count
Dim wrCount As Long: wrCount = WeightColumnRange.Rows.Count
If wrCount < rCount Then rCount = wrCount
' Create the references to the column ranges.
Dim srg As Range: Set srg = ScoreColumnRange.Cells(1).Resize(rCount)
Dim wrg As Range: Set wrg = WeightColumnRange.Cells(1).Resize(rCount)
' Write the values from the column ranges to arrays.
Dim sData As Variant, wData As Variant
If rCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
ReDim wData(1 To 1, 1 To 1): wData(1, 1) = wrg.Value
Else
sData = srg.Value
wData = wrg.Value
End If
' Declare additional variables to be used in the For...Next loop.
Dim sVal As Variant, wVal As Variant ' Current Values
Dim r As Long ' Rows Counter
Dim tWeight As Double ' Total Weight
Dim tProduct As Double ' Total Sum
' Calculate the total weights and the total products.
For r = 1 To UBound(sData, 1)
sVal = sData(r, 1)
If IsNumeric(sVal) Then ' prevent invalid score
wVal = wData(r, 1)
If IsNumeric(wVal) Then ' prevent invalid weight
tWeight = tWeight + wVal
tProduct = tProduct + sVal * wVal
End If
End If
Next r
If tWeight = 0 Then Exit Function ' all were invalid
' Calculate and return the weighted average (the result).
WeightedAverage = tProduct / tWeight ' maybe you want to round?
End Function
您的代码已修改
Function WeightedAverage( _
ByVal DataColumnRange As Range, _
ByVal ValuesColumnRange As Range, _
ByVal TotalValue As Double) _
As Double
' Compare the number of rows and use the smaller number.
Dim rCount As Long: rCount = DataColumnRange.Rows.Count
Dim vrCount As Long: vrCount = ValuesColumnRange.Rows.Count
If vrCount < rCount Then rCount = vrCount
' Create the references to the column ranges.
Dim drg As Range: Set drg = DataColumnRange.Cells(1).Resize(rCount)
Dim vrg As Range: Set vrg = ValuesColumnRange.Cells(1).Resize(rCount)
' Write the values of the column ranges to arrays.
Dim dData As Variant, vData As Variant
If rCount = 1 Then
ReDim dData(1 To 1, 1 To 1): dData(1, 1) = drg.Value
ReDim vData(1 To 1, 1 To 1): vData(1, 1) = vrg.Value
Else
dData = drg.Value
vData = vrg.Value
End If
' Declare additional variables to be used in the For...Next loop.
Dim dVal As Variant, vVal As Variant ' Current Values
Dim r As Long ' Rows Counter
Dim tCount As Long ' Total Count
Dim Total As Double ' Total Value
' Calculate the Total? (there should be a math term for it)
For r = 1 To UBound(dData, 1)
dVal = dData(r, 1)
If IsNumeric(dVal) Then ' prevent invalid data
vVal = vData(r, 1)
If IsNumeric(vVal) Then ' prevent invalid value
tCount = tCount + 1
Total = Total + dVal * vVal / TotalValue
End If
End If
Next r
If tCount = 0 Then Exit Function ' all were invalid
' Calculate and return the weighted average (the result).
WeightedAverage = Total / tCount ' maybe you want to round?
End Function
我正在编写我的第一个函数,并且正在为加权平均公式创建一个函数。
当我将它用作子项并定义值时,这工作正常,但在立即测试函数时出现此错误 window。
我试过各种数据类型都无济于事。
如有任何帮助,我们将不胜感激。
enter image description here
Public Function WeightedAverage(data() As Range, values() As Range, TotalValue As Range) As Double
Dim i As Integer
Dim Sum As Variant
For i = 1 To UBound(data)
Sum = Sum + values(i, 1) / TotalValue * data(i, 1)
Next i
WA = Sum / UBound(data)
End Function
enter image description here
正如@Skin 提到的,您可以稍微修改一下代码。我删除了参数部分中的括号。此外,您应该在单元格内调用该函数并将每个参数分配给 cell/a 单元格范围。
您的代码中没有定义变量“WA”。这可能会导致你的错误。要从用户定义的函数 (UDF) 中获取 return 值,您应该将变量“sum”分配给函数名称。
如果我的反馈是您问题的有效答案,请将其标记为答案。谢谢!
Public Function WeightedAverage( _
data As Range, _
values As Range, _
TotalValue As Range _
) As Double
Dim i As Integer
'You need containers for your parameters, which can be more then one cell
Dim arrData As Variant: arrData = data
Dim arrValues As Variant: arrValues = values
Dim Sum As Double
'Both arrays need the same size, optional, I thought that might help a little bit
If UBound(arrData, 1) <> UBound(arrValues) Then Exit Function
For i = 1 To UBound(arrData, 1)
Sum = Sum + arrValues(i, 1) / TotalValue * arrData(i, 1)
Next i
'Assign the variable "sum" to the functions name
WeightedAverage = Sum / UBound(arrData, 1)
End Function
加权平均 UDF
- 无论你在这里做什么,根据这个 link,这不是你计算加权平均值的方式(最后一个参数似乎多余,循环中的除法是错误的)。
- 如果存在不包含数值的单元格,则提供的 link 中建议的
SUMPRODUCT/SUM
公式解决方案将失败,而以下函数将忽略(跳过)这些单元格。
加权平均值
Option Explicit
Function WeightedAverage( _
ByVal ScoreColumnRange As Range, _
ByVal WeightColumnRange As Range) _
As Double
' Compare the number of rows and use the smaller number.
Dim rCount As Long: rCount = ScoreColumnRange.Rows.Count
Dim wrCount As Long: wrCount = WeightColumnRange.Rows.Count
If wrCount < rCount Then rCount = wrCount
' Create the references to the column ranges.
Dim srg As Range: Set srg = ScoreColumnRange.Cells(1).Resize(rCount)
Dim wrg As Range: Set wrg = WeightColumnRange.Cells(1).Resize(rCount)
' Write the values from the column ranges to arrays.
Dim sData As Variant, wData As Variant
If rCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
ReDim wData(1 To 1, 1 To 1): wData(1, 1) = wrg.Value
Else
sData = srg.Value
wData = wrg.Value
End If
' Declare additional variables to be used in the For...Next loop.
Dim sVal As Variant, wVal As Variant ' Current Values
Dim r As Long ' Rows Counter
Dim tWeight As Double ' Total Weight
Dim tProduct As Double ' Total Sum
' Calculate the total weights and the total products.
For r = 1 To UBound(sData, 1)
sVal = sData(r, 1)
If IsNumeric(sVal) Then ' prevent invalid score
wVal = wData(r, 1)
If IsNumeric(wVal) Then ' prevent invalid weight
tWeight = tWeight + wVal
tProduct = tProduct + sVal * wVal
End If
End If
Next r
If tWeight = 0 Then Exit Function ' all were invalid
' Calculate and return the weighted average (the result).
WeightedAverage = tProduct / tWeight ' maybe you want to round?
End Function
您的代码已修改
Function WeightedAverage( _
ByVal DataColumnRange As Range, _
ByVal ValuesColumnRange As Range, _
ByVal TotalValue As Double) _
As Double
' Compare the number of rows and use the smaller number.
Dim rCount As Long: rCount = DataColumnRange.Rows.Count
Dim vrCount As Long: vrCount = ValuesColumnRange.Rows.Count
If vrCount < rCount Then rCount = vrCount
' Create the references to the column ranges.
Dim drg As Range: Set drg = DataColumnRange.Cells(1).Resize(rCount)
Dim vrg As Range: Set vrg = ValuesColumnRange.Cells(1).Resize(rCount)
' Write the values of the column ranges to arrays.
Dim dData As Variant, vData As Variant
If rCount = 1 Then
ReDim dData(1 To 1, 1 To 1): dData(1, 1) = drg.Value
ReDim vData(1 To 1, 1 To 1): vData(1, 1) = vrg.Value
Else
dData = drg.Value
vData = vrg.Value
End If
' Declare additional variables to be used in the For...Next loop.
Dim dVal As Variant, vVal As Variant ' Current Values
Dim r As Long ' Rows Counter
Dim tCount As Long ' Total Count
Dim Total As Double ' Total Value
' Calculate the Total? (there should be a math term for it)
For r = 1 To UBound(dData, 1)
dVal = dData(r, 1)
If IsNumeric(dVal) Then ' prevent invalid data
vVal = vData(r, 1)
If IsNumeric(vVal) Then ' prevent invalid value
tCount = tCount + 1
Total = Total + dVal * vVal / TotalValue
End If
End If
Next r
If tCount = 0 Then Exit Function ' all were invalid
' Calculate and return the weighted average (the result).
WeightedAverage = Total / tCount ' maybe you want to round?
End Function