locked
Error Handling of Wrong Variable Type in Class Module (Using Let Property) RRS feed

  • Question

  • Hi,

    I'm just starting to get to grips with using class modules and on the whole have appreciated how useful they've been for strengthening and neatening my code.

    In particular my understanding is that one of the most powerful features is the ability to include validation code within the LET procedure of a property. I've used this to test for specific things (i.e. property is within a specific range etc) but I've hit a problem with validating the data type.

    In the code below I'm attempting to check that the value assigned to the property "Location" (taken from a user input cell) is of the correct type (long) and has a value of either 1 or 2 and move to my ErrHandler subroutine if not.

    The check for 1 or 2 works by itself but the VarType check seems to be useless here because if I try to assign a value of the wrong type the code returns an error and breaks before it can even get to this point (breaks on the line Thing.Location = ActiveCell.Value).

    I've tried using On Error Resume Next but that just skips out writing the value to the property entirely.

    So in short I guess my question is:

    Is there a way to use the Property Let method to validate the variable type and run an error handling routine?

    Thanks in advance for your help!

    'REGULAR MODULE CODE'

    Sub GetInputData()

    Set Thing as New CThing

    'Goes to pre-selected cell to find user-inputted variable and writes it to Thing.Location'

    Thing.Location = ActiveCell.Value ' CODE LINE BREAKS HERE'

    End Sub

    'CLASS MODULE CODE for CThing'

    Private pLocation           As Long Public Property Let Location(value As Long) 'check that a valid value of Location is given' If VarType (value) = vbLong And (value = 1 Or value = 2) Then    pLocation= value Else    ErrHandler End If End Property


    Thursday, September 11, 2014 8:33 AM

All replies

  • I think the problem is caused at the property definition level:

    Public Property Let Location(value as Long)

    The property itself expects a Long type variable so when it's called from your Module1 it will throw a run-time error if the argument variable is not of Long type. 

    This design is good because you don't need to check inside the function if the variable passed is of the expected type - ie. The function does what it needs to do with the Long type variable - it's will be shorter and reusable granted the correct type parameter - extending to check whether it has been passed the correct data type is a bit unnecessary here - it's like trying to kill two birds with one stone. The function is supposed to just take a Long and work with that type and any checking should really be done outside the functions body

    This means that your On Error GoTo <Label> should actually be in your Module1 before the call to set the property to be effective. 

    Now, you have two ways of handling this:

    (1)  - (NOT RECOMMENDED - see comments in the code)  change the Long to Variant datatype for the expected parameter type and then inside the functions body check whether the argument is of Long type. This is not a great way to solve the problem but I think it achieves what you want.

    Public Property Let Location(value As Variant)
    
        If VarType(value) = vbLong And (value = 1 Or value = 2) Then
             pLocation = value
        Else
             ' not Long type
             ' meaning you can't really proceed/assign and
             ' you are already inside this function
             ' this means you can't really properly handle this
             ' you should NOT allow not a LONG type to enter this function
        End If
    
    End Property


    (2)  - Create a simple If-Else statement before the call to set the property in the Module1

    Your property should be:

    Public Property Let Location(value As Long) If value = 1 Or value = 2 Then pLocation = value Else ' leave as default (0) ' show user a message that the value has to be 1 or 2 End If End Property

    Public Property Get Location()
        Location = pLocation
    End Property


    and your module 

    Sub GetInputData()
    
        Dim Thing As New CThing
        Thing.Location = ActiveCell.value
        
        Debug.Print Thing.Location
    
    End Sub
    

    And now if the value stored in `pLocation` <> 0 it means it has been assigned - otherwise it has not.


    Thursday, September 11, 2014 9:12 AM