Array Dimensioned or not

16 views
Skip to first unread message

uo

unread,
Nov 30, 2004, 3:16:50 PM11/30/04
to
How can I check whether an array has been dimensioned in order to avoid an
error when calling ubound() with an undimensioned array ? Is there any
elegant/simple way of doing this other than trapping errors.

Thanks.


Saga

unread,
Nov 30, 2004, 3:21:25 PM11/30/04
to

Create a boolean function, create an error handler and
then access the first element of the array. If it does not
error out, set the function to true. Do nothing in the error
handler so the function will return false.

Not elegant, but simple <g>
Saga

"uo" <not...@notreal.com> wrote in message
news:Q_-dndVjn_J...@igs.net...

Douglas Marquardt

unread,
Nov 30, 2004, 3:26:38 PM11/30/04
to
Hi:

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...

Ken Halter

unread,
Nov 30, 2004, 3:26:09 PM11/30/04
to
"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..


Bonj

unread,
Nov 30, 2004, 3:37:00 PM11/30/04
to
there's always ((Not myArray) != -1)...

"uo" <not...@notreal.com> wrote in message
news:Q_-dndVjn_J...@igs.net...

Bonj

unread,
Nov 30, 2004, 3:37:24 PM11/30/04
to
Or call UBound. It might be dimmed (2,5).

"Saga" <anti...@somewhere.com> wrote in message
news:OrREwpx1...@TK2MSFTNGP10.phx.gbl...

Ken Halter

unread,
Nov 30, 2004, 3:52:47 PM11/30/04
to
!= ? <g>

--
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...

Mike D Sutton

unread,
Nov 30, 2004, 4:10:18 PM11/30/04
to
> there's always ((Not myArray) != -1)...

Cute..

Mike


- Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://EDais.mvps.org/


Saga

unread,
Nov 30, 2004, 4:41:02 PM11/30/04
to

You're right, ubound is a better option, thanks <g>
Saga

"Bonj" <benjtaylor at hotpop d0t com> wrote in message

news:ONR1oxx1...@TK2MSFTNGP15.phx.gbl...

Bonj

unread,
Nov 30, 2004, 5:17:41 PM11/30/04
to
NMR guv, NMR .

"Mike D Sutton" <ED...@mvps.org> wrote in message
news:O$2GAEy1E...@TK2MSFTNGP14.phx.gbl...

Harvey Triana

unread,
Nov 30, 2004, 9:45:56 PM11/30/04
to
mmm
Dim a() As Single
...
MsgBox "Is dimensioned? " & Not ((Not a) = -1)


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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...

YYZ

unread,
Nov 30, 2004, 10:24:37 PM11/30/04
to
"Harvey Triana" <harvey...@hotmail.com> wrote in message
news:evp$$901EH...@TK2MSFTNGP12.phx.gbl...

> mmm
> Dim a() As Single
> ...
> MsgBox "Is dimensioned? " & Not ((Not a) = -1)

Okay, I give. Why does this work? In all situations? I don't get it. I
like it, though...

Matt


Mark Alexander Bertenshaw

unread,
Dec 1, 2004, 1:19:04 AM12/1/04
to

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


Bonj

unread,
Dec 1, 2004, 2:09:58 AM12/1/04
to
It "just does". It's apparently a Matt Curland method, who is basically a
hackmaster. If a new version of VB6 was on the way, you would expect to be
slightly more wary of it, but since it isn't, you can probably use it with
confidence.

"YYZ" <d> wrote in message news:%23frlLV1...@TK2MSFTNGP11.phx.gbl...

Tony Proctor

unread,
Dec 1, 2004, 5:13:41 AM12/1/04
to
It's all very clever, but it doesn't work in all cases. If the array
variable points to an empty SafeArray descriptor, as opposed to no
descriptor at all, then it says it's dimensioned when it isn't. For instance

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...

Mike D Sutton

unread,
Dec 1, 2004, 5:38:42 AM12/1/04
to
> It's all very clever, but it doesn't work in all cases. If the array
> variable points to an empty SafeArray descriptor, as opposed to no
> descriptor at all, then it says it's dimensioned when it isn't. For instance
>
> 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

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,

Tony Proctor

unread,
Dec 1, 2004, 5:52:09 AM12/1/04
to
You're correct of course Mike. I'd temporarily forgotten that VB arrays can
start anywhere, not just with element (0) or (1). It's something I knew, but
never use.

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...

Harvey Triana

unread,
Dec 1, 2004, 8:02:49 AM12/1/04
to
Mark -

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...

Ken Halter

unread,
Dec 1, 2004, 10:29:12 AM12/1/04
to
"Bonj" <benjtaylor at hotpop d0t com> wrote in message
news:ucKm$S31EH...@TK2MSFTNGP12.phx.gbl...

> It "just does". It's apparently a Matt Curland method, who is basically a
> hackmaster. If a new version of VB6 was on the way, you would expect to be
> slightly more wary of it, but since it isn't, you can probably use it with
> confidence.

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

Bonj

unread,
Dec 1, 2004, 10:45:01 AM12/1/04
to
Sorry, as in
((Not myArray) != -1) = OK to use = IS dimensioned ...

isn't it?
Were we talking about how to find out whether the array IS dimensioned, or
whether it ISN'T?

Bonj

unread,
Dec 1, 2004, 10:51:07 AM12/1/04
to
Nice, Ken, nice. I did that and it started playing music. People thought it
was a mobile phone going off.

Ken Halter

unread,
Dec 1, 2004, 11:08:30 AM12/1/04
to
"Bonj" <Bo...@discussions.microsoft.com> wrote in message
news:A68E796D-C3F4-4710...@microsoft.com...

> Nice, Ken, nice. I did that and it started playing music. People thought
> it
> was a mobile phone going off.
>

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!)

Ulrich Korndoerfer

unread,
Dec 1, 2004, 1:42:12 PM12/1/04
to
Hi,

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:

http://faq.vb-hellfire.de

This FAQ is maintained by Thorsten Dörfler, MS VB MVP.

--
Ulrich Korndoerfer

VB tips, helpers, solutions -> http://www.proSource.de/Downloads/

Peter Young

unread,
Dec 1, 2004, 5:44:46 PM12/1/04
to
"uo" <not...@notreal.com> wrote in message news:Q_-dndVjn_J...@igs.net...
> How can I check whether an array has been dimensioned in order to avoid an
> error when calling ubound() with an undimensioned array ? Is there any
> elegant/simple way of doing this other than trapping errors.

http://www.vbadvance.com/arrays.htm


Bonj

unread,
Dec 2, 2004, 2:04:56 AM12/2/04
to
It's got small inbuilt ones seemingly, I think they may even be in my TFT
monitor. I have the volume on so Query Analyzer makes a 'bing' when it's
finished running a long query, otherwise it'd sit having finished for hours
and I'd not know it had finished...

"Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.com> wrote in message
news:O7ugBA81...@TK2MSFTNGP12.phx.gbl...

Bonj

unread,
Dec 2, 2004, 2:07:35 AM12/2/04
to
The only important thing is, if ((Not a) <> -1) AND UBound >= LBound, is it
OK to execute a(x), where LBound <= x <= UBound ?


"Mike D Sutton" <ED...@mvps.org> wrote in message
news:uVEouH51...@TK2MSFTNGP11.phx.gbl...

Mike D Sutton

unread,
Dec 2, 2004, 4:35:57 AM12/2/04
to
> The only important thing is, if ((Not a) <> -1) AND UBound >= LBound, is it
> OK to execute a(x), where LBound <= x <= UBound ?

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? :)

Bonj

unread,
Dec 3, 2004, 9:29:03 AM12/3/04
to
> 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.

Reply all
Reply to author
Forward
0 new messages