在找到一种可行的方法之前,我必须尝试几种方法,但我想通了。
将这些函数粘贴到一个模块中:
Public Function SumIfIf(rgeData As Range, matchCriteria As String, numCompCriteria As String) As Double
Dim c As Range, arr_Distinct() As String, x As Long, totalOut As Double, str_ConcatRgeRow As String
ReDim arr_Distinct(0)
totalOut = 0
If InStr("<>=", Left(numCompCriteria, 1)) = 0 Then numCompCriteria = "=" & numCompCriteria
For Each c In rgeData.Columns(1).Cells
str_ConcatRgeRow = c.Value & c.Offset(0, rgeData.Columns.Count - 1).Value
If Not IsInArray(arr_Distinct, str_ConcatRgeRow) Then
ReDim Preserve arr_Distinct(UBound(arr_Distinct) + 1)
arr_Distinct(UBound(arr_Distinct)) = str_ConcatRgeRow
If Evaluate(c.Value = matchCriteria) And Evaluate("=(" & c.Offset(0, rgeData.Columns.Count - 1).Value & numCompCriteria & ")") Then
totalOut = totalOut + c.Offset(0, rgeData.Columns.Count - 1).Value
End If
End If
Next c
SumIfIf = totalOut
End Function
Function IsInArray(arrToCheck As Variant, valToFind As Variant) As Boolean
Dim x As Long
IsInArray = False
For x = 1 To UBound(arrToCheck)
If arrToCheck(x) = valToFind Then IsInArray = True
Next x
End Function
在您的示例中,您可以这样使用它:
用法:
SumIfIf(rgeData As Range, matchCriteria As String, numCompCriteria As String)
rgeData = 任意行数和至少 2 列的范围
函数匹配:
...然后:
matchCriteria = 文本或数字标识符,要完全匹配
numCompCriteria = 一个数字标识符,具体为以 > 或 或 = 开头的字符串,就像您为SumIf 工作表函数。
-
numCompCriteria 的示例:"=10"、"<=10"、"10"
我的屏幕时间已达到一天的限制;如果您需要进一步的解释,请告诉我。同时希望这可以解决您的问题。 :)
+1 对挑战的问题,它的好处是正是我正在做的事情所需要的!
更新,进一步回答@BOB的问题:
进行比较的代码行是这一行:
If Evaluate(c.Value = matchCriteria) And Evaluate("=(" & c.Offset(0, rgeData.Columns.Count - 1).Value & numCompCriteria & ")") Then
因此,根据您的需要,您可以通过几种方式对其进行更改。
又快又脏,如果您的新标准是永久性的,请将上面的行替换为:
If Evaluate(c.Value = matchCriteria) _
And Evaluate("=(" & c.Offset(0, rgeData.Columns.Count - 1).Value & ">10" & ")") _
And Evaluate("=(" & c.Offset(0, rgeData.Columns.Count - 1).Value & "<=35" & ")") _
Then
请注意,这将不再使用 numCompCriteria 的值,但您仍然需要指定一些内容,或者从函数声明中删除参数。或者,调整它为您的新标准添加更多参数。
按照该模式,您可以添加所有您喜欢的标准。这里使用它的方式,“Evaluate”返回 True 或 False。您可以通过以下方式进行演示:
debug.print Evaluate ("=(10>35)")
在上面的代码中
c.Offset(0, rgeData.Columns.Count - 1).Value
返回最右边列的值。