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
     

Related:  

Pure VB: Determine if an Array has been Dimensioned
     
 Prerequisites
None.

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)."
   Else
      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
 Comments

 
 

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