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:
Code:
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.
Code:
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:
Code:
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:
Code:
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