1

I know in most other languages you can write an expression if (ptr == NULL || ptr->foo()) {something bad happened} to test both the validity of a variable and a test you want to perform. VBA does not let you do that. So I am wracking my brain to figure out a way to write the following code without 1) using error catching as means of conditional branching and 2) not duplicating code.

Type Vector
   vData() as Variant
   vSize as Long
End Type

Sub add(v as Vector, elem as Variant)
   Dim oldSize as Long
   if v.vSize = 0 Or UBound(v.vData) >= v.vSize then
      oldSize = v.vSize
      ReDim Preserve v.vData(0 to (oldSize * 2 + 1))
      v.vData(oldSize) = elem
      v.vSize = v.vSize + 1
   else
      v.vData(v.vSize) = elem
      v.vSize = v.vSize + 1
   end if
End Sub

Now that code will crash on the UBound line regardless if vSize is 0 or not (if vData was never Dim'd). The only other way i can see to do it is do an additional elseif statement to check UBound, but that would duplicate the code of the doubling the vector size.

In case you think this is a duplicate: VBA Short-Circuit `And` Alternatives . This talks about alternatives to AND statements (not or). Nested ifs (aka AND statements) doesn't duplicate code like OR would.

Ibo
  • 4,081
  • 6
  • 45
  • 65
Mark Walsh
  • 985
  • 1
  • 7
  • 12

2 Answers2

2

If I understand correctly you need to check if the array has been allocated or not.

One such option is to do this (however weird it may look):

If (Not Not MyArray) <> 0 Then 'Means it is allocated

Answer taken from this thread - see for more ideas.

SnowGroomer
  • 695
  • 5
  • 14
0

Using SnowGroomer's answer I am posting the complete solution:

This is a class named Vector

Private data() As Variant
Private size As Long

Property Get vSize() As Long
    vSize = size
End Property

Property Let vData(ByVal index As Long, elem As Variant)
    If index < 0 Then Exit Property
    If index < size Then
        data(index) = elem
    Else
        Me.add elem, index
    End If
End Property

Property Get vData(ByVal index As Long) As Variant
    If index < 0 Or (Not Not data) = 0 Then
        vData = Nothing
        Exit Property
    End If
    vData = data(index)
End Property

Public Sub add(elem As Variant, Optional index As Long = -1)
    If index > -2 Then
        If index = -1 Then
            If size = 0 Or (Not Not data) = 0 Then
                ReDim data(0)
                data(size) = elem
                size = size + 1
                Exit Sub
            Else 'size <> 0
                ReDim Preserve data(0 To size * 2 + 1)
                data(size) = elem
                size = size + 1
            End If
        Else 'index <> -1
            If index >= size Then
                ReDim Preserve data(0 To index)
                data(index) = elem
                size = index + 1
            Else 'index < vSize
                data(index) = elem
            End If 'index >= vSize
        End If 'index = -1
    End If 'index > -2
End Sub 'add
Mark Walsh
  • 985
  • 1
  • 7
  • 12