Passing an undimensioned array to the VB6's Ubound function will cause an error, so I want to check if it has been dimensioned yet before attempting to check its upper bound. How do I do this?
There's no way to test that at runtime -- an uninitialized array looks just like one that has been initialized with garbage. Depending on what you're doing, you need either to make sure the array is actually initialized or explicitly pass around a flag that tells you whether the values in the array are meaningful yet.
To initialize an array variable by using an array literalEither in the New clause, or when you assign the array value, supply the element values inside braces ( {} ). The following example shows several ways to declare, create, and initialize a variable to contain an array that has elements of type Char .
In visual basic, Arrays can be declared by specifying the type of elements followed by the brackets () like as shown below. Dim array_name As [Data_Type](); Here, array_name represents the name of an array and Data_type will represent the data type of elements to store in an array.
In VB6 an array is a variable that contains a finite number of elements that have a common name and data type. Each element of an array is identified by a unique index number. Changes made to one element of an array don't affect the other elements. The Individual elements of an array are identified using an index.
Note: the code has been updated, the original version can be found in the revision history (not that it is useful to find it). The updated code does not depend on the undocumented
GetMem4
function and correctly handles arrays of all types.
Note for VBA users: This code is for VB6 which never got an x64 update. If you intend to use this code for VBA, see https://stackoverflow.com/a/32539884/11683 for the VBA version. You will only need to take the
CopyMemory
declaration and thepArrPtr
function, leaving the rest.
I use this:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long) Private Const VT_BYREF As Long = &H4000& ' When declared in this way, the passed array is wrapped in a Variant/ByRef. It is not copied. ' Returns *SAFEARRAY, not **SAFEARRAY Public Function pArrPtr(ByRef arr As Variant) As Long 'VarType lies to you, hiding important differences. Manual VarType here. Dim vt As Integer CopyMemory ByVal VarPtr(vt), ByVal VarPtr(arr), Len(vt) If (vt And vbArray) <> vbArray Then Err.Raise 5, , "Variant must contain an array" End If 'see https://msdn.microsoft.com/en-us/library/windows/desktop/ms221627%28v=vs.85%29.aspx If (vt And VT_BYREF) = VT_BYREF Then 'By-ref variant array. Contains **pparray at offset 8 CopyMemory ByVal VarPtr(pArrPtr), ByVal VarPtr(arr) + 8, Len(pArrPtr) 'pArrPtr = arr->pparray; CopyMemory ByVal VarPtr(pArrPtr), ByVal pArrPtr, Len(pArrPtr) 'pArrPtr = *pArrPtr; Else 'Non-by-ref variant array. Contains *parray at offset 8 CopyMemory ByVal VarPtr(pArrPtr), ByVal VarPtr(arr) + 8, Len(pArrPtr) 'pArrPtr = arr->parray; End If End Function Public Function ArrayExists(ByRef arr As Variant) As Boolean ArrayExists = pArrPtr(arr) <> 0 End Function
Usage:
? ArrayExists(someArray)
Your code seems to do the same (testing for SAFEARRAY** being NULL), but in a way which I would consider a compiler bug :)
I just thought of this one. Simple enough, no API calls needed. Any problems with it?
Public Function IsArrayInitialized(arr) As Boolean Dim rv As Long On Error Resume Next rv = UBound(arr) IsArrayInitialized = (Err.Number = 0) End Function
Edit: I did discover a flaw with this related to the behavior of the Split function (actually I'd call it a flaw in the Split function). Take this example:
Dim arr() As String arr = Split(vbNullString, ",") Debug.Print UBound(arr)
What is the value of Ubound(arr) at this point? It's -1! So, passing this array to this IsArrayInitialized function would return true, but attempting to access arr(0) would cause a subscript out of range error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With