CLS_Compound_Predicate

Posted on

Problem

I have a CLS_Comparison_Predicate which will take an input value, perform a logical comparison and return a Boolean.

CLS_Compound_Predicate instead takes lists of predicates and an inputValue, and performs MatchAny() or MatchAll() operations on the predicate list.

E.G.

predicate_1 has >= 3
predicate_2 has = 5

MatchAny(6) Returns True
MatchAll(6) Returns False

Thoughts?

Option Explicit

Private predicateList As Variant

Private Const NULL_ERROR_TEXT As String = "Invalid Compare input. Cannot compare against Null"
Private Const OBJECT_ERROR_TEXT As String = "Invalid Compare input. Input must be a value, not an object"
Private Const NOTHING_ERROR_TEXT As String = "Invalid Compare Input. Predicate cannot be Nothing"
Private Const EMPTY_ERROR_TEXT As String = "Invalid Compare Input. Input cannot be empty"
Private Const ZLS_ERROR_TEXT As String = "Invalid Compare Input. Input cannot be a Zero-Length-String"

Public Sub AddPredicate(ByRef inputPredicate As CLS_Comparison_Predicate)

    If inputPredicate Is Nothing Then
        PrintErrorMessage NOTHING_ERROR_TEXT
        Stop
    End If

    If IsEmpty(predicateList) Then
        ReDim predicateList(1 To 1)
        Set predicateList(1) = inputPredicate
    Else
        Dim LB1 As Long, UB1 As Long
        GetBounds LB1, UB1

        ReDim Preserve predicateList(LB1 To UB1 + 1)
        Set predicateList(UB1 + 1) = inputPredicate
    End If

End Sub

Public Sub ClearPredicates()

    If Not predicateList Is Nothing Then Erase predicateList

End Sub

Public Function MatchAny(ByVal leftValue As Variant) As Boolean
    '/ compares leftValue against predicateList. If any return true, then return true, else return false

    CheckInputValue leftValue 

    Dim LB1 As Long, UB1 As Long
    GetBounds LB1, UB1

    Dim matchesAny As Boolean
    matchesAny = False

    Dim predicate As CLS_Comparison_Predicate
    Dim ix As Long
    For ix = LB1 To UB1
        Set predicate = predicateList(ix)
        If predicate.Compare(leftValue) Then
            matchesAny = True
            Exit For
        End If
    Next ix

    MatchAny = matchesAny

End Function

Public Function MatchAll(ByVal leftValue As Variant) As Boolean
    '/ compares leftValue against predicateList. If any return false, then return false, else return true

    CheckInputValue leftValue 

    Dim LB1 As Long, UB1 As Long
    GetBounds LB1, UB1

    Dim matchesAll As Boolean
    matchesAll = True

    Dim predicate As CLS_Comparison_Predicate
    Dim ix As Long
    For ix = LB1 To UB1
        Set predicate = predicateList(ix)
        If Not predicate.Compare(leftValue) Then
            matchesAll = False
            Exit For
        End If
    Next ix

    MatchAll = matchesAll

End Function

Private Sub CheckInputValue(ByVal inputValue As Variant)
    '/ Check for NULL, Objects, Empty and ZLS

    If IsNull(inputValue) Then
        PrintErrorMessage NULL_ERROR_TEXT
        Stop
    End If

    If IsObject(inputValue) Then
        PrintErrorMessage OBJECT_ERROR_TEXT
        Stop
    End If

    If IsEmpty(inputValue) Then
        PrintErrorMessage EMPTY_ERROR_TEXT
        Stop
    End If

    On Error Resume Next
        If Len(inputValue) = 0 Then
            PrintErrorMessage ZLS_ERROR_TEXT
            Stop
        End If
    On Error GoTo 0

End Sub

Private Sub GetBounds(Optional ByRef LB1 As Long, Optional ByVal UB1 As Long)

    LB1 = LBound(predicateList)
    UB1 = UBound(predicateList)

End Sub

Solution

I learned something from this

On Error Resume Next
    If Len(inputValue) = 0 Then
        PrintErrorMessage ZLS_ERROR_TEXT
        Stop
    End If
On Error GoTo 0

I learned that On Error GoTo 0 disables error handling in the current procedure. The KB also says:

Without an On Error GoTo 0 statement, an error handler is
automatically disabled when a procedure is exited.

So you really don’t need it. I also can’t figure out under what conditions the len would error. The only thing I could think of is if it’s an object, but you’ve exited by that point. It can’t be a negative length can it?

Leave a Reply

Your email address will not be published. Required fields are marked *