Re: array size

Tech-Archive recommends: Fix windows errors by optimizing your registry



This may be a better method then Kelly. It doesn't use Variants. It shows
examples of initialised 1-d & 2-d arrays, and uninitialised arrays,
including those of a UDT type. Although the code isn't primarily for testing
for uninitialised arrays, you can easily see that the descriptor address is
also 0 for such arrays.

Tony Proctor

=========== Form1 ==========
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
pDst As Any, pSrc As Any, ByVal ByteLen As Long)

' Returns address of the address of the associated SafeArray descriptor
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" ( _
Ptr() As Any) As Long

Private Type SAFEARRAYBOUND
cElements As Long
lLbound As Long
End Type

Private Type SAFEARRAY
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
Bounds(1 To 10) As SAFEARRAYBOUND
End Type

Private Sub ShowA(ByVal lpAddr As Long)
' Shows the contents of a SafeArray descriptor. The given address is of the
pointer to the descriptor
' rather than the descriptor itself
Dim desc As SAFEARRAY
Dim iBound As Integer

On Error GoTo ErrorHandler
Debug.Print "Address of Descriptor pointer = &H" & Hex(lpAddr)
If lpAddr = 0 Then Exit Sub

CopyMemory ByVal VarPtr(lpAddr), ByVal lpAddr, 4
Debug.Print "Address of Descriptor = &H" & Hex(lpAddr)
If lpAddr = 0 Then Exit Sub

' Read body of the SafeArray descriptor
CopyMemory ByVal VarPtr(desc), ByVal lpAddr, LenB(desc)
With desc
Debug.Print "cDims=" & .cDims
Debug.Print "fFeatures=" & Hex(.fFeatures)
Debug.Print "cbElements=" & .cbElements
Debug.Print "cLocks=" & .cLocks
Debug.Print "pvData=" & Hex(.pvData)
For iBound = 1 To .cDims
Debug.Print "bound" & CStr(iBound) & "=" &
CStr(.Bounds(iBound).lLbound) & " To " & _
CStr(.Bounds(iBound).cElements + .Bounds(iBound).lLbound -
1)
Next iBound
End With
Exit Sub

ErrorHandler:
Debug.Print "ShowA exception: " & Err.Description
End Sub

Private Sub Form_Load()
Dim Init(2 To 5) As Byte, Uninit() As Long
Dim Init2(3 To 4, 10 To 20) As String
Dim InitT(10) As SAFEARRAY
Dim UninitT() As SAFEARRAY

ShowA VarPtrArray(Init)
ShowA VarPtrArray(Uninit)
ShowA VarPtrArray(Init2)
ShowA VarPtrArray(InitT)
ShowA VarPtrArray(UninitT)
End Sub
==========================

"Kelly Ethridge" <kelly@xxxxxxxxxxxxxxxxx> wrote in message
news:eMjdLfTbFHA.580@xxxxxxxxxxxxxxxxxxxxxxx
> The only problem with getting the pointer to a SafeArray descriptor
generically
> through dereferencing the array pointer out of the Varaint, as in the
method shown
> in your link, is that passing an uninitialized array of objects or UDTs
will cause the
> array to be initialized to a zero element array. So the example code will
always
> return 1 for the number of dimensions of an uninitialized array of objects
or UDTs.
>
>
> "Norm Cook" <normcookNOSPAM@xxxxxxxxxxxx> wrote in message
news:%23MCydNPbFHA.2756@xxxxxxxxxxxxxxxxxxxxxxx
> > 1. What's wrong with error checking or keeping a boolean flag?
> >
> > 2. You missed the link in Mike's google page:
> > http://vbnet.mvps.org/index.html?code/helpers/getarraydims.htm
> > This code not only determines whether or not the array is initialized
> > but also gives the number of dimensions. Note, however, that
> > even that code has to do an If call,
> > If address <> 0 Then
> > which is just another form of error checking.
> >
> > 3. How about
> > Dim A() as whatever
> > ReDim A(0)
> > Now it is dynamic & you can resize it, check its bounds, etc
> >
> > "sali" <sali@xxxxxxxxxxx> wrote in message
> > news:O0F6KZObFHA.724@xxxxxxxxxxxxxxxxxxxxxxx
> >> "Mike D Sutton" <EDais@xxxxxxxx> wrote in message
> >> news:ufUpEXNbFHA.1456@xxxxxxxxxxxxxxxxxxxxxxx
> >> > [Ignore previous post..]
> >> >
> >> >> "dim arr()"
> >> >> to have dynamic aray, and after sometimes
> >> >> "redim arr(some_size)"
> >> >> but then, to check the current size with
> >> >> "ubound(arr)"
> >> >> gives error if arr is not yet "redimed"
> >> >>
> >> >> is it possible to check for empty array [no one element] *without*
> > having
> >> >> to
> >> >> catch errors?
> >> >> [and without auxilary variable to hold "not-yet-redim"]
> >> >
> >> > Try this:
> >> >
> >
http://groups.google.co.uk/group/microsoft.public.vb.general.discussion/msg/946e66e23a0010f5
> >> > Hope this helps,
> >>
> >> thanks, but unfortunately, it uses error catching [on error resume
next]
> >>
> >> isn't it little bit unusual not to have *built in* tool for complete
> >> variable handling?
> >>
> >> or, are there some advices to use "dictionary object" or "collection"
[or
> >> something else] for representing dynamic data structures that tends to
be
> >> sometimes "empty"?
> >> maybe the collection is the best candidate, because it employes access
by
> >> numeric index as well?
> >>
> >>
> >>
> >
> >
>
>


.



Relevant Pages

  • Re: Updated datestamp doesnt work
    ... Public Sub StoreMyOldVals ... ' store values of current row in array ... Dim dbs As DAO.Database, rst As DAO.Recordset ... Dim var As Variant ...
    (microsoft.public.access.gettingstarted)
  • Re: Multiple OUs?
    ... something is up with adding multiple values to the array... ... ' If the AD enumeration runs into an OU object, call the Sub again to ... strLine = Trim ... strNewContents = strNewContents & strLine & vbCrLf ...
    (microsoft.public.scripting.vbscript)
  • Re: Packages and returning errors
    ... > array intact. ... sub is_a_instance_method { ... my $class = shift; ... You need to fix the scope of $error by moving its declaration outside ...
    (comp.lang.perl.misc)
  • Re: Updated datestamp doesnt work
    ... Public Sub StoreMyOldVals ... ' store values of current row in array ... Dim dbs As DAO.Database, rst As DAO.Recordset ... Dim var As Variant ...
    (microsoft.public.access.gettingstarted)
  • Re: Updated datestamp doesnt work
    ... Public Sub StoreMyOldVals ... ' store values of current row in array ... Dim dbs As DAO.Database, rst As DAO.Recordset ... Dim var As Variant ...
    (microsoft.public.access.gettingstarted)