I am trying to make a Weighted Average Ifs function with the capability of having up to three ifs. as it stands, the function only works when the optionality is removed and all arguments are filled by the user. When the function is run #Value! is returned when optional arguments are not filled. here is the complete code in question.
Function WeightedAvgIfs(ByVal values As Range, ByVal weights As Range, _
ByVal ConditionRange1 As Range, ByVal Condition1 As String, _
Optional ByVal ConditionRange2 As Range = Nothing, Optional ByVal Condition2 As String = "=ZZZ", _
Optional ByVal ConditionRange3 As Range = Nothing, Optional ByVal Condition3 As String = "=ZZZ") As Double
Dim ValuesArray(), WeightsArray(), Condition1Array(), Condition2Array(), Condition3Array() As Variant
Dim i As Long
Dim dsum As Double
Dim StringOperator As String
Dim Condition As Variant
ValuesArray = Range(values.Address(1, 1, xlA1, 1))
WeightsArray = Range(weights.Address(1, 1, xlA1, 1))
Condition1Array = Range(ConditionRange1.Address(1, 1, xlA1, 1))
Condition2Array = Range(ConditionRange2.Address(1, 1, xlA1, 1))
Condition2Array = Range(ConditionRange3.Address(1, 1, xlA1, 1))
'Condition 1
For i = LBound(ValuesArray) To UBound(ValuesArray)
Select Case Left(Condition1, 2)
Case Is = "<="
StringOperator = "<="
Condition = Val(Mid(Condition1, 3, Len(Condition1)))
Case Is = ">="
StringOperator = ">="
Condition = Val(Mid(Condition1, 3, Len(Condition1)))
Case Is = "<>"
StringOperator = "<>"
If IsNumeric(Mid(Condition1, 3, Len(Condition1))) And Not IsEmpty(Condition1) Then
Condition = Val(Mid(Condition1, 3, Len(Condition1)))
Else
Condition = UCase(Mid(Condition1, 3, Len(Condition1)))
End If
Case Else
Select Case Left(Condition1, 1)
Case Is = "<"
StringOperator = "<"
Condition = Val(Mid(Condition1, 2, Len(Condition1)))
Case Is = ">"
StringOperator = ">"
Condition = Val(Mid(Condition1, 2, Len(Condition1)))
Case Is = "="
StringOperator = "="
If IsNumeric(Mid(Condition1, 2, Len(Condition1))) And Not IsEmpty(Condition1) Then
Condition = Val(Mid(Condition1, 2, Len(Condition1)))
Else
Condition = UCase(Mid(Condition1, 2, Len(Condition1)))
End If
End Select
End Select
Select Case StringOperator
Case Is = ">="
If Condition1Array(i, 1) < Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = ">"
If Condition1Array(i, 1) <= Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = "<="
If Condition1Array(i, 1) > Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = "<"
If Condition1Array(i, 1) >= Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Else
Select Case StringOperator
Case Is = "="
If IsNumeric(Condition1Array(i, 1)) And Not IsEmpty(Condition1Array(i, 1)) Then
If Val(Condition1Array(i, 1)) <> Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Else
If UCase(CStr(Condition1Array(i, 1))) <> Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
End If
Case Is = "<>"
If IsNumeric(Condition1Array(i, 1)) And Not IsEmpty(Condition1Array(i, 1)) Then
If Val(Condition1Array(i, 1)) = Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Else
If UCase(CStr(Condition1Array(i, 1))) = Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
End If
End Select
End Select
Next i
If ConditionRange2 Is Nothing Then
GoTo FinalCalc
End If
'Condition 2
For i = LBound(ValuesArray) To UBound(ValuesArray)
Select Case Left(Condition2, 2)
Case Is = "<="
StringOperator = "<="
Condition = Val(Mid(Condition2, 3, Len(Condition2)))
Case Is = ">="
StringOperator = ">="
Condition = Val(Mid(Condition2, 3, Len(Condition2)))
Case Is = "<>"
StringOperator = "<>"
If IsNumeric(Mid(Condition2, 3, Len(Condition2))) And Not IsEmpty(Condition2) Then
Condition = Val(Mid(Condition2, 3, Len(Condition2)))
Else
Condition = UCase(Mid(Condition2, 3, Len(Condition2)))
End If
Case Else
Select Case Left(Condition2, 1)
Case Is = "<"
StringOperator = "<"
Condition = Val(Mid(Condition2, 2, Len(Condition2)))
Case Is = ">"
StringOperator = ">"
Condition = Val(Mid(Condition2, 2, Len(Condition2)))
Case Is = "="
StringOperator = "="
If IsNumeric(Mid(Condition2, 2, Len(Condition2))) And Not IsEmpty(Condition2) Then
Condition = Val(Mid(Condition2, 2, Len(Condition2)))
Else
Condition = UCase(Mid(Condition2, 2, Len(Condition2)))
End If
End Select
End Select
Select Case StringOperator
Case Is = ">="
If Condition2Array(i, 1) < Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = ">"
If Condition2Array(i, 1) <= Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = "<="
If Condition2Array(i, 1) > Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = "<"
If Condition2Array(i, 1) >= Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Else
Select Case StringOperator
Case Is = "="
If IsNumeric(Condition2Array(i, 1)) And Not IsEmpty(Condition2Array(i, 1)) Then
If Val(Condition2Array(i, 1)) <> Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Else
If UCase(CStr(Condition2Array(i, 1))) <> Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
End If
Case Is = "<>"
If IsNumeric(Condition2Array(i, 1)) And Not IsEmpty(Condition2Array(i, 1)) Then
If Val(Condition2Array(i, 1)) = Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Else
If UCase(CStr(Condition2Array(i, 1))) = Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
End If
End Select
End Select
Next i
If ConditionRange3 Is Nothing Then
GoTo FinalCalc
End If
'Condition 3
For i = LBound(ValuesArray) To UBound(ValuesArray)
Select Case Left(Condition3, 2)
Case Is = "<="
StringOperator = "<="
Condition = Val(Mid(Condition3, 3, Len(Condition3)))
Case Is = ">="
StringOperator = ">="
Condition = Val(Mid(Condition3, 3, Len(Condition3)))
Case Is = "<>"
StringOperator = "<>"
If IsNumeric(Mid(Condition3, 3, Len(Condition3))) And Not IsEmpty(Condition3) Then
Condition = Val(Mid(Condition3, 3, Len(Condition3)))
Else
Condition = UCase(Mid(Condition3, 3, Len(Condition3)))
End If
Case Else
Select Case Left(Condition3, 1)
Case Is = "<"
StringOperator = "<"
Condition = Val(Mid(Condition3, 2, Len(Condition3)))
Case Is = ">"
StringOperator = ">"
Condition = Val(Mid(Condition3, 2, Len(Condition3)))
Case Is = "="
StringOperator = "="
If IsNumeric(Mid(Condition3, 2, Len(Condition3))) And Not IsEmpty(Condition3) Then
Condition = Val(Mid(Condition3, 2, Len(Condition3)))
Else
Condition = UCase(Mid(Condition3, 2, Len(Condition3)))
End If
End Select
End Select
Select Case StringOperator
Case Is = ">="
If Condition3Array(i, 1) < Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = ">"
If Condition3Array(i, 1) <= Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = "<="
If Condition3Array(i, 1) > Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Is = "<"
If Condition3Array(i, 1) >= Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Case Else
Select Case StringOperator
Case Is = "="
If IsNumeric(Condition3Array(i, 1)) And Not IsEmpty(Condition3Array(i, 1)) Then
If Val(Condition3Array(i, 1)) <> Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Else
If UCase(CStr(Condition3Array(i, 1))) <> Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
End If
Case Is = "<>"
If IsNumeric(Condition3Array(i, 1)) And Not IsEmpty(Condition3Array(i, 1)) Then
If Val(Condition3Array(i, 1)) = Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
Else
If UCase(CStr(Condition3Array(i, 1))) = Condition Then
ValuesArray(i, 1) = 0
WeightsArray(i, 1) = 0
End If
End If
End Select
End Select
Next i
FinalCalc:
dsum = Application.WorksheetFunction.Sum(WeightsArray)
For i = LBound(WeightsArray) To UBound(WeightsArray)
WeightsArray(i, 1) = WeightsArray(i, 1) / dsum
Next i
For i = LBound(ValuesArray) To UBound(ValuesArray)
ValuesArray(i, 1) = ValuesArray(i, 1) * WeightsArray(i, 1)
Next i
WeightedAvgIfs = Application.WorksheetFunction.Sum(ValuesArray)
End Function