Thanks.
Not elegant, but simple <g>
Saga
"uo" <not...@notreal.com> wrote in message
news:Q_-dndVjn_J...@igs.net...
Trapping the error is the only way to check if it's not dimensioned,
and probably the simplest.
I have seen others use the logic where they always initialize an array
to zero (i.e.ReDim a(0)) and then check the ubound; where zero
means it's not been used (i.e. > 0 means that the arrary is being used).
Doug.
"uo" <not...@notreal.com> wrote in message news:Q_-dndVjn_J...@igs.net...
Nope... trapping the error *is* the "elegant/simple way" <g>... You can do
this too..... since it's already written, I guess it can't get much simpler
eh? ;-)
Determining an Array's Initialization State and Dimensions
http://vbnet.mvps.org/index.html?code/helpers/getarraydims.htm
--
Ken Halter - MS-MVP-VB - http://www.vbsight.com
Please keep all discussions in the groups..
"uo" <not...@notreal.com> wrote in message
news:Q_-dndVjn_J...@igs.net...
"Saga" <anti...@somewhere.com> wrote in message
news:OrREwpx1...@TK2MSFTNGP10.phx.gbl...
--
Ken Halter - MS-MVP-VB - http://www.vbsight.com
Please keep all discussions in the groups..
"Bonj" <benjtaylor at hotpop d0t com> wrote in message
news:%23HYhYxx...@TK2MSFTNGP12.phx.gbl...
Cute..
Mike
- Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://EDais.mvps.org/
"Bonj" <benjtaylor at hotpop d0t com> wrote in message
news:ONR1oxx1...@TK2MSFTNGP15.phx.gbl...
"Mike D Sutton" <ED...@mvps.org> wrote in message
news:O$2GAEy1E...@TK2MSFTNGP14.phx.gbl...
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Harvey Triana
Well Tracks .NET Developer (VB Hero)
(Software Engineer) ...Yet
VB Clásico: http://www.mvps.org/vexpert
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Las cosas deben ser sencillas pero no más. A.E.
"Mike D Sutton" <ED...@mvps.org> escribió en el mensaje
news:O$2GAEy1E...@TK2MSFTNGP14.phx.gbl...
Okay, I give. Why does this work? In all situations? I don't get it. I
like it, though...
Matt
The best clue can be gained by writing it like this:
-------------------------------
Private Sub Command1_Click()
Dim a() As Byte
Dim b(2) As Byte
Debug.Print Not (Not a)
Debug.Print Not (Not b)
End Sub
-------------------------------
Results:
0
1242392
In theory, doing Not Not should return the original value. In VB, an array
is actually a pointer to a SAFEARRAY structure. By using a variant declare
of CopyMemory, we can see that an undimensioned array is actually
represented as a zero, e.g.
-------------------------------
Private Declare Sub CopyMemory_ArrayToLong Lib "Kernel32.dll" Alias
"RtlMoveMemory" (ByRef pDest As Long, ByRef pArray() As Any, ByVal bytes As
Long)
Private Sub Command2_Click()
Dim a() As Byte
Dim b(2) As Byte
Dim pSafeArrayA As Long
Dim pSafeArrayB As Long
CopyMemory_ArrayToLong pSafeArrayA, a, 4
CopyMemory_ArrayToLong pSafeArrayB, b, 4
Debug.Print pSafeArrayA
Debug.Print pSafeArrayB
End Sub
-------------------------------
Results:
0
1242392
The dimensioned array always gives a non-zero value. The Not (Not a)
version of the test seems to be the most elegant.
Now as to actually *why* this works? Who knows? It's like why does On
Error Goto -1 turn off error trapping without resuming - a complete mystery.
It doesn't seem to work on any other VB pointer types, such as String and
Object.
--
Mark Bertenshaw
Kingston upon Thames
UK
"YYZ" <d> wrote in message news:%23frlLV1...@TK2MSFTNGP11.phx.gbl...
Dim s() as string
s = Split("")
Debug.Print UBound(ss) ' Gives -1 (i.e. not dimensioned)
Debug.Print Not((Not s) = -1) ' Gives True, implying it's dimensioned
Tony Proctor
"Harvey Triana" <harvey...@hotmail.com> wrote in message
news:evp$$901EH...@TK2MSFTNGP12.phx.gbl...
VB will quite happily execute L/UBound() and even a normal For loop on this array though where as an empty array (i.e. null
SafeArray) will raise an error which is the annoying one to catch IMO. Also a UBound() of -1 doesn't mean the array is
un-dimensioned, since it could be declared as:
'***
ReDim s(-5 To -1) As String
'***
With the empty SafeArray structure the low bound is set to a higher value than the high bound so For loops using L/UBound will
immediately be satisfied and never execute their contents. Basically it tells you that the array has a valid SafeArray pointer
rather than that the array is dimensioned.
Strange though that we've never seen it on the groups before, or was I just not paying attention last time it came around? :)
Cheers,
I guess I should have uses (UBound(s) < LBound(s)) as my test
Tony Proctor
"Mike D Sutton" <ED...@mvps.org> wrote in message
news:uVEouH51...@TK2MSFTNGP11.phx.gbl...
Something about bit operation...
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Harvey Triana
Well Tracks .NET Developer (VB Hero)
(Software Engineer) ...Yet
VB Clásico: http://www.mvps.org/vexpert
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Las cosas deben ser sencillas pero no más. A.E.
"Mark Alexander Bertenshaw" <mark.be...@virgin.net> escribió en el
mensaje news:eVt42z21...@TK2MSFTNGP10.phx.gbl...
fwiw, Matt was part of the VB design team at MS and listed in VB's Easter
Egg credits
Subject: Visual Basic 6 Easter Egg
http://groups.google.com/groups?selm=ebyWHnZ%24AHA.1400%40tkmsftngp05&oe=UTF-8&output=gplain
isn't it?
Were we talking about how to find out whether the array IS dimensioned, or
whether it ISN'T?
LOL!... I've never had speakers hooked up to my dev PC so I didn't even know
there was sound (after all these years!)
Mark Alexander Bertenshaw wrote:
> Now as to actually *why* this works?
To my oppinion it is a failure in the part of the VB compiler, that has
to resolve expressions. A math operator normally does not work on array
types. If a math operator is applied to an array type, eg.:
Dim arr() As Byte, x As Long
x = arr + arr 'type mismatch error at *compile time*
x = -arr 'type mismatch error at *compile time*
one gets an error message at *compile* time.
The implementation of the Not operator seems to be having a failure: it
is applied to the content of an array variable (which is a pointer or
adress value).
So with
Dim arr() As Byte, adr As Long
adr = Not arr 'ok, no errors at compile or runtime
Not arr (Not working as math operator, not as logical operator, which
btw. is the same in VB) operates on the value of the adress stored in
arr and returns it with all bits flipped. An additional Not flips the
bits back and one gets the original value.
So what the trick utilizes is, that Not arr erroneously interprets arr
as a variable being of scalar type having a value of type Long and acts
on this value (which is the adress of a safe array descriptor). Not in
this peculiar case can be seen as operator doing implicit type casting
from an array type to a Long type.
Not arr such can detect, if a safe array descriptor already has been
allocated to an array var. The quickest way then to detect this is to
check the result of Not arr being -1 or not:
If (Not arr) = -1 Then Print "Undimensioned" Else Print "Dimensioned".
Or, using VB's implicit type conversion (in this case from a number to a
boolean):
If Not (Not arr) Then Print "Dimensioned" Else Print "Undimensioned".
There is one restriction: if the array is wrapped in a variant then the
trick will fail:
Dim v As Variant
v = arr
Print Not arr 'type mismatch error at *runtime* now
ReDim arr(0 To 10)
v = arr
Print Not arr 'type mismatch error at *runtime* now
Obviously, as in this case the variant variable may contain anything,
the evaluation of the expression is deferred to run time. At run time
the OLE variant functions are used to calculate the result. Those seem
to work correct and detect the type mismatch.
The trick works under VB5 as well.
Early this year I wrote a little article (in german) contributing to the
german VB FAQ, which goes a little bit deeper into this. It can be found
as entry 2.21 with title "Wie kann ich feststellen, ob ein dynamisches
Array leer ist?" on:
This FAQ is maintained by Thorsten Dörfler, MS VB MVP.
--
Ulrich Korndoerfer
VB tips, helpers, solutions -> http://www.proSource.de/Downloads/
http://www.vbadvance.com/arrays.htm
"Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.com> wrote in message
news:O7ugBA81...@TK2MSFTNGP12.phx.gbl...
"Mike D Sutton" <ED...@mvps.org> wrote in message
news:uVEouH51...@TK2MSFTNGP11.phx.gbl...
Assuming 'a' refers to a single dimensional array, yes, but the same principle applies for each dimension of a multi-dimensional
array too, however at that point I still prefer to use the SAFEARRAY method rather than error trapping LBound/UBound or do you have
a sneaky trick for that too? :)
Yes, I would imagine that multi-dimensional arrays need special
consideration, and I wouldn't personally use the Matt Curland method anyway,
but would *certainly* use the error-handler technique on multi-dimensional
arrays.