Search code examples
vbaexcelis-empty

How can I build a default empty object that can be differentiated from 0 in vba?


I'm reading a text file that contains data about mechanical fasteners. I built an object fastener (via a class) with the following attributes :

type as string
number as long
master as long
slave as long

I want to fill a collection of fasteners:

Cfastener as collection

In the text file the type, number, master and slave can come in random order and are not always all present. In order to deal with that I defined a current fastener (sort of buffer) and a default "empty" fastener:

currentfastener as fastener
initfastener as fastener
with initfastener
    .type = "-1"
    .number = -1
    .master = -1
    .slave = -1
end with

I read my text file and when I detect a keyword that refers to one of these attribute I test for the value in current fastener:

Do until .atendofstream
    line = .readline
    Select case line
        Case masterkeyword
            if currentfastener.master <> -1 then 'We already have a master. This means that we need to save the currentfastener and start a new one.
                Cfasteners.add currentfastener
                currentfastener = initfastener
            else 'master is "empty": we fill the currentfastener. 
                currentfastener.master= "value read from the text stream"
            end if
    End Select
Loop

Until now I’m using -1 for numbers and "-1" for string as default empty argument. Until now it was fine because the arguments could not get this value. But now, I want to add a spatial position for the master and slave, and it can be -1. So I wanted to go back to my first idea that was do define all initfixation arguments as empty.

But if I’m not mistaken it is not possible to differentiate the 0 value from the empty value in vba, and this will cause trouble.

Do you know a default value, that is not 0, that can be differentiated from 0 and that is not -1?


Solution

  • Empty is used with the Variant type. Setting a String or Long to Empty and then testing its emptiness with IsEmpty() won't work.

    You can use variants to store your data, however, and then you can safely use the Empty value to signify an empty/missing value.

    You're right that VB will cast Empty to 0 for numeric comparisons. For example:

    Dim v As Variant
    Debug.Print (v = 0)        ' => True 
    

    But you can use the VarType() function to test if a variant has the Empty value:

    Dim v As Variant
    Debug.Print VarType(v) = vbEmpty    ' => True (empty/uninitialized)
    v = 0
    Debug.Print VarType(v) = vbEmpty    ' => False
    v = Empty
    Debug.Print VarType(v) = vbEmpty    ' => True (empty)