Results 1 to 10 of 10

Threaded View

  1. #1

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002

    Classic VB - How do I check if array has been initialized?

    One of the common problems when dealing with arrays is to know when the array has been initialized and when it isn't. Luckily there is an easy native VB code solution:

    Not Not ArrayName

    What this does is to take the 32-bit pointer value in the array variable, mirror the bits, and then mirror them again. You now effectively know the pointer to the safe array structure. As a side effect you also know whether you can access the array with LBound and UBound.

    An example code showing a way to make a new array item:
        Dim lngNewIndex As Long
        ' check whether our array is initialized: if it is, take UBound and increase it by one
        If Not Not udtItems Then lngNewIndex = UBound(udtItems) + 1
        ' now change the size of the array
        ReDim Preserve udtItems(lngNewIndex)

    Problems & Issues

    There is one major problem: for whatever reason VB IDE does not like this method, and will raise an error in some cases, for example when floating point numbers are coerced to other datatypes. The error does not happen when the program is compiled. Luckily the solution to the issue is short and simple: add this code to run at the beginning of your application.
    Private Sub Form_Load()
        Dim IDEbug() As Long
        Debug.Assert Not IDEbug Or App.hInstance
    End Sub
    What happens here is that first we make a call to push up the possible error condition. Then we make a call to App.hInstance: we could make a call pretty much to any VB method, but since hInstance returns a Long number we use that. This, for whatever reason, makes all the following Not ArrayName calls work flawlessly. After the line has once executed in the IDE you can even comment the line and it's effects still remain. Only closing VB and opening it again will reset the condition so that you need to make the call again.

    Finally, since Debug.Assert will not be compiled into the final executable, you have next to nothing to lose. You only have that one extra line of code that should be executed before getting the array's pointer. (Thanks to Milk for pointing out the App.hInstance, it really simplified this problem a great deal.)

    Bonus code

    Here we have a code that gets the dimensions of an array:
    Option Explicit
    Private Declare Sub GetMem2 Lib "msvbvm60" (Destination As Any, Value As Any)
    Public Function ArrayDimensions(ByVal Not_Not_Array As Long) As Integer
        ' have pointer of safe array structure?
        If Not_Not_Array Then
            ' get the dimensions
            GetMem2 ByVal Not_Not_Array, ArrayDimensions
        End If
    End Function
    A sample usage:
    Private Sub Form_Load()
        Dim lngTest() As Long, lngA As Long
        ' to fix the ide bug
        Debug.Assert Not lngTest Or App.hInstance
        ' put in some dimensions
        ReDim lngTest(1 To 1, 1 To 2, 1 To 3)
        ' loop the dimensions
        For lngA = 1 To ArrayDimensions(Not Not lngTest)
            ' print out the bounds for each dimension
            Debug.Print lngA, LBound(lngTest, lngA), UBound(lngTest, lngA)
        Next lngA
    End Sub
    Last edited by Merri; Jul 20th, 2008 at 12:23 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts


Click Here to Expand Forum to Full Width

We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.