Visual Basic Helper Routines
CopyMemory: Determining Array Initialization State and Dimensions
Posted:   Thursday June 29, 1999
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows NT4
OS restrictions:   None
Author:   Jon Lister, VBnet - Randy Birch


Pure VB: Determine if an Array has been Dimensioned

Pure VB: Determine if an Array has been Dimensioned showed one way to determine whether an array is in its uninitialized state, or whether it has been dimensioned using Dim or ReDim. The technique on that page used VB's error trapping to prevent errors when testing the UBound condition of the passed array.

This code, provided to VBnet by Jon Lister, uses CopyMemory to return the number of actual dimensions that an array may have.

In addition, I have added an additional condition that will also allow the function to indicate whether the passed array is initialized (dimensioned) or not (thus duplicating the functionality on the above page).  When the array is uninitialized, either because the it has not yet been dimensioned or because the Erase statement was used, the function returns 0. When the array has been dimensioned, the code accurately returns the current number of dimensions in the array, regardless of how large (UBound) each dimension is, or whether each dimension are all the same or of differing sizes.

 BAS Module Code
Add the following code to a form or BAS module, and declare as appropriate:

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
'Jon Lister
'Pi Developments Ltd
'Milton Hall,
'Church Lane, Milton, Cambridge
'CB4 6AB
'United Kingdom

'the workhorse of all VB memory operations
Public Declare Sub CopyMemory Lib "kernel32" _
   Alias "RtlMoveMemory" _
  (pDest As Any, _
   pSrc As Any, _
   ByVal ByteLen As Long)

Public Function GetArrayDimensions(ByVal arrPtr As Long) As Integer
   Dim address As Long
  'get the address of the SafeArray structure in memory
   CopyMemory address, ByVal arrPtr, ByVal 4
  'if there is a dimension, then
  'address will point to the memory
  'address of the array, otherwise
  'the array isn't dimensioned
   If address <> 0 Then
     'fill the local variable with the first 2
     'bytes of the safearray structure. These
     'first 2 bytes contain an integer describing
     'the number of dimensions
      CopyMemory GetArrayDimensions, ByVal address, 2
   End If
End Function

Public Function VarPtrArray(arr As Variant) As Long

  'Function to get pointer to the array
   CopyMemory VarPtrArray, ByVal VarPtr(arr) + 8, ByVal 4
End Function
 Form Code
To the form, add the following code:

Option Explicit

Dim testArray() As String

Private Sub Form_Load()
   Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
   Option1(0).Value = True
End Sub

Private Sub Command1_Click()

   Dim nDims As Integer
   Dim msg As String

  'Read Array Structure out of memory
  'into local structure type
   nDims = GetArrayDimensions(VarPtrArray(testArray))
  'Display number of dimensions
   If nDims >= 1 Then
      msg = "The array has " & nDims & " dimension(s)."
      msg = "The array has not been initialized."
   End If
   MsgBox msg, vbOKOnly Or vbInformation, "GetArrayDimensions Result"

End Sub

Private Sub Command2_Click()

   Unload Me
End Sub

Private Sub Option1_Click(Index As Integer)
  'nuke the existing array
   Erase testArray
  'Recreate array of differing dimensions
   Select Case Index
      Case 0  ' uninitialized by Erase statement above

      Case 1  ' 1 dimension
         ReDim testArray(10)
      Case 2  ' 2 dimensions
         ReDim testArray(10, 5)
      Case 3  ' 3 dimensions
         ReDim testArray(10, 5, 5)
      Case 4  ' 4 dimensions
         ReDim testArray(10, 5, 10, 5)
      Case 5  ' 5 dimensions
         ReDim testArray(10, 5, 10, 5, 10)
   End Select
End Sub


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter