2016-06-30 7 views
1

Wie würde ich UDF schreiben, damit sie Vergleichsoperatoren in Argumenten akzeptieren?Wie Sie Vergleichsoperatoren in VBA Excel UDF-Argumenten verwenden?

Wenn Sie Standardfunktionen verwenden, schreiben Sie so = countif (range; x) und Sie würden die Anzahl der Zellen in dem Bereich erhalten, der gleich x ist.

Replizieren diese Funktion in VBA würde wie folgt aussehen:

Function countifUDF(rng As Range, x As Integer) 
    count = 0 
    For Each cell in rng.Cells 
     If cell.Value = x Then 
      count = count + 1 
     Next cell 
    countifUDF = sum 
End Function 

Wenn die Standardfunktion verwenden Sie einen Vergleichsoperator auf die Funktion wie dieser = countIf passieren können (Bereich; „<“ & x) und Sie würden die Anzahl der Zellen im Bereich weniger als x erhalten.

Wie könnte ich das in einer UDF tun? Meine UDF als = countifUDF (Bereich; "<" & x) Ausbeuten #value


SOLUTION

Function countifUDF(rng As Range, x As String) 
Dim arr() As String 
Dim count As Integer 
Dim i As Integer 

' breaking down x character by character and puts in array 
ReDim arr(Len(x) - 1) 
For i = 1 To Len(x) 
    arr(i - 1) = Mid$(x, i, 1) 
Next 

' if the last character in x is not numeric i assume the user want to count matching strings 
' Like allows the user to use wildcards, LCase makes the comparision case insensitive 
If IsNumeric(arr(UBound(arr))) = False Then 
    x = LCase(x) 

    For Each cell In rng.Cells 
     If LCase(cell.Value) Like x Then 
      count = count + 1 
     End If 
    Next cell 

' if the first char in x is numeric its pretty straight forward 
ElseIf IsNumeric(arr(0)) = True Then 
    For Each cell In rng.Cells 
     If cell.Value = x Then 
      count = count + 1 
     End If 
    Next cell 

' if the first character in x is < and the second is numeric less-than operator is used 
ElseIf arr(0) = "<" And IsNumeric(arr(1)) = True Then 
    ' removing < from x 
    x = Replace(x, "<", "") 
    For Each cell In rng.Cells 
     If cell.Value < x Then 
      count = count + 1 
     End If 
    Next cell 

ElseIf arr(0) = ">" And IsNumeric(arr(1)) = True Then 
    x = Replace(x, ">", "") 
    For Each cell In rng.Cells 
     If cell.Value > x Then 
      count = count + 1 
     End If 
    Next cell 

' if the first char is < and the second is > the is not operator is used 
ElseIf arr(0) = "<" And arr(1) = ">" Then 
    x = Replace(x, "<", "") 
    x = Replace(x, ">", "") 
    For Each cell In rng.Cells 
     If cell.Value <> x Then 
      count = count + 1 
     End If 
    Next cell 

ElseIf arr(0) = ">" And arr(1) = "=" Then 
    x = Replace(x, ">", "") 
    x = Replace(x, "=", "") 
    For Each cell In rng.Cells 
     If cell.Value >= x Then 
      count = count + 1 
     End If 
    Next cell 

ElseIf arr(0) = "<" And arr(1) = "=" Then 
    x = Replace(x, "<", "") 
    x = Replace(x, "=", "") 
    For Each cell In rng.Cells 
     If cell.Value <= x Then 
      count = count + 1 
     End If 
    Next cell 

End If 

countifUDF = count 

End Function 

die Antworten gegeben Ich habe es wie dort scheint keine bequeme Möglichkeit, in VBA von Vergleichsoperatoren in UDF, bitte korrigieren Sie mich, wenn ich falsch liege. Meine Lösung unterstützt sowohl Zahlen als auch Zeichenfolgen mit Platzhaltern. Zuerst versuchte ich die Split-Methode mit & als Trennzeichen zu verwenden. Appearantly VBA identifiziert ‚‚>‘& x‘ als ‚> x‘, warum hatte ich x Zeichen für Zeichen zu spalten und zu bewerten, welche Art von Vergleichsoperator in dem Benutzer getippt

Antwort

2

haben die UDF() betrachten das zweite Argument als String:

Function countifUDF(rng As Range, x As Variant) As Long 
    Dim cell As Range, Count As Long, CH As String, VL As Long 

    VL = Replace(Replace(x, ">", ""), "<", "") 
    CH = Left(CStr(x), 1) 
    Count = 0 

    If CH = ">" Then 
     For Each cell In rng.Cells 
      If cell.Value > VL Then 
       Count = Count + 1 
      End If 
     Next cell 
    ElseIf CH = "<" Then 
     For Each cell In rng.Cells 
      If cell.Value < VL Then 
       Count = Count + 1 
      End If 
     Next cell 
    Else 
     For Each cell In rng.Cells 
      If cell.Value = x Then 
       Count = Count + 1 
      End If 
     Next cell 
    End If 
    countifUDF = Count 
End Function 

In diesem Beispiel CH das erste Zeichen des seco ist nd Argument und VL ist der numerische Teil des zweiten Arguments.

+1

Danke! Ich vermutete, dass eine Lösung in etwa so aussehen würde, aber ich hoffte tatsächlich, dass es eine Möglichkeit geben würde, entweder <>,> =, <=, <, > oder = auf eine bequemere Weise zu bestehen. Ich werde für eine ähnliche Lösung gehen, aber Split mit & als Trennzeichen verwenden, da es einfacher ist, <>, <= and > = zu handhaben. –

+0

@ user3805500 Ihre Ideen sind interessant ............ Wenn Sie Ihre Frage mit Ihrem endgültigen Ansatz aktualisieren, wäre es willkommen! –

+0

Posted meine Lösung in der Frage, es ist nicht schön. –

1

starten.

Function countifUDF(rng As Range, x As Integer) 
    Dim cell As Range 
    Dim Count As Integer 

    Count = 0 
    For Each cell In rng.Cells 
     If cell.Value < x Then Count = Count + 1 
    Next cell 

    countifUDF = Count 

End Function