How to test for array?

468 views
Skip to first unread message

fred

unread,
May 29, 2009, 5:34:04 PM5/29/09
to
Hello,
How to test whether the array is dimmensioned ?
When I do:
If UBound(SkypeDtmfDelay) > 0 Then

there is an error: "Subscript out of range"

How to test that array SkypeDtmfDelay() without having that error?
Thanks,
Fred


Bob Butler

unread,
May 29, 2009, 5:44:12 PM5/29/09
to

"fred" <fr...@nospamme.com> wrote in message
news:eZ9j0UK4...@TK2MSFTNGP02.phx.gbl...

There are ways but they aren't as clear as just trapping the error or doing
an initial "redim SkypeDtmfDelay(0 to 0)" so that it is always defined.

fred

unread,
May 29, 2009, 7:48:38 PM5/29/09
to
Thank you, Bob.
Initilizing array to 0 ( "redim SkypeDtmfDelay(0 to 0)") is not the solution
for me.
I think, that in that case I need to flag the situation that array is NOT
redimed by introducing another variable.
Something like this:

Dim ArrayRedim as Boolean
If ArrayRedim = True then
If UBound(SkypeDtmfDelay) > 0 Then
==========================

What do you think about that?
Fred

"Bob Butler" <no...@nospam.ever> wrote in message
news:%232wm%23bK4J...@TK2MSFTNGP04.phx.gbl...

Message has been deleted

Bob Butler

unread,
May 29, 2009, 8:02:42 PM5/29/09
to

"fred" <fr...@nospamme.com> wrote in message
news:uXdq$fL4JH...@TK2MSFTNGP02.phx.gbl...

> Thank you, Bob.
> Initilizing array to 0 ( "redim SkypeDtmfDelay(0 to 0)") is not the
> solution for me.
> I think, that in that case I need to flag the situation that array is NOT
> redimed by introducing another variable.
> Something like this:
>
> Dim ArrayRedim as Boolean
> If ArrayRedim = True then
> If UBound(SkypeDtmfDelay) > 0 Then
> ==========================
>
> What do you think about that?

I think trapping the error makes more sense. Errors and error handling are
not taboo.

Nobody

unread,
May 29, 2009, 8:06:01 PM5/29/09
to

Karl E. Peterson

unread,
May 29, 2009, 8:43:54 PM5/29/09
to
Ed wrote:
> If (Not SkypeDtmfDelay()) = -1 Then MsgBox "Array Not Dimensioned"

I would *absolutely* advise avoiding this one! It caused me many hours of grief
once, as I tried to track down an Error 0. Turned out, that was it.
--
.NET: It's About Trust!
http://vfred.mvps.org


fred

unread,
May 29, 2009, 8:46:57 PM5/29/09
to
That looks like a good solution.
Is it valid in any situations or there are some limitations to it?
Thanks,
Fred

"Ed" <nos...@hotmail.com> wrote in message
news:52u0259quo25nqfn5...@4ax.com...

Karl E. Peterson

unread,
May 29, 2009, 9:04:03 PM5/29/09
to
fred wrote:
> That looks like a good solution.

It is. Until it's not. :-(

> Is it valid in any situations or there are some limitations to it?

Some very weird ones. You'll really, truly wish you'd never seen it, if they bite
you!

If error trapping isn't an option, do this instead:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination
As Any, Source As Any, ByVal Length As Long)

Public Function ArrayDimmed(vArray As Variant) As Boolean
Dim pSA As Long
'Make sure an array was passed in:
If IsArray(vArray) Then
'Get the pointer out of the Variant:
CopyMemory pSA, ByVal VarPtr(vArray) + 8, 4&
If pSA Then
'Try to get the descriptor:
CopyMemory pSA, ByVal pSA, 4
'Array is initialized only if we got the SAFEARRAY descriptor:
ArrayDimmed = (pSA <> 0)
End If
End If
End Function

Bob Butler

unread,
May 29, 2009, 9:05:31 PM5/29/09
to

"fred" <fr...@nospamme.com> wrote in message
news:eBBFjEM...@TK2MSFTNGP06.phx.gbl...
>I have already trapping error in that procedure, however I cannot invoke it
>in that case.
> The reasons:
> 1.
> I have to continue with the code
> 2.
> Using Resume Next will start the timer which is not desirable if the array
> is not redim.

neither point makes much sense to me; you can use "resume next", assign the
upper bound to a variable, then restore your original error handler and test
the value.

fred

unread,
May 29, 2009, 9:19:59 PM5/29/09
to
>assign the upper bound to a variable etc
I am not sure if that has any extra advantages fom the "flagging" solution I
showed above.
Fred

"Bob Butler" <no...@nospam.ever> wrote in message

news:Ou9LeMM4...@TK2MSFTNGP02.phx.gbl...

fred

unread,
May 29, 2009, 8:54:03 PM5/29/09
to
I have already trapping error in that procedure, however I cannot invoke it
in that case.
The reasons:
1.
I have to continue with the code
2.
Using Resume Next will start the timer which is not desirable if the array
is not redim.
Fred

"Bob Butler" <no...@nospam.ever> wrote in message

news:uYB$XpL4J...@TK2MSFTNGP03.phx.gbl...

MikeD

unread,
May 29, 2009, 9:53:14 PM5/29/09
to

"fred" <fr...@nospamme.com> wrote in message
news:u1LkCTM4...@TK2MSFTNGP05.phx.gbl...

> >assign the upper bound to a variable etc
> I am not sure if that has any extra advantages fom the "flagging" solution
> I showed above.


Besides another variable to keep track of? What happens if just ONE time,
you don't assign True to that variable or if you erase the array you don't
assign False? It introduces "complexity" that you simply don't have to have.
Just trap the error. Why are you so against doing that?

--
Mike

mayayana

unread,
May 29, 2009, 10:25:16 PM5/29/09
to
> I am not sure if that has any extra advantages fom the "flagging" solution
I
> showed above.

Another option: I usually just start with 1 if
I'm returning an array from a function. So the
return is always an array. Array(0) provides
a handy place to store the ubound or other
data about the array contents, while any returned
data is contained in array(1)+.


fred

unread,
May 29, 2009, 10:34:19 PM5/29/09
to
You are completely right, Mike.
I have already put my code to work and of course I forgot assign False to my
variable when erasing the array.

I am not sure how to trap the error, but continue with the procedure and NOT
deploying the timer.
Here is the code:
==============
Private Sub moSkype_CallStatus(ByVal pCall As SKYPE4COMLib.ICall, ByVal
Status As SKYPE4COMLib.TCallStatus)
On Error GoTo err_StatusCallback
<more code in here>
If UBound(SkypeDtmfDelay) > 0 Then
tmrStartStop.Enabled = False
tmrStartStop.Interval = SkypeDtmfDelay(1) * 1000
tmrStartStop.Enabled = True
End If
<more code in here>
Exit Sub
err_StatusCallback:
Debug.Print "StatusCallback ==> " & CStr(err.Number) & " : " &
err.Description
If err.Number = 9 Then Resume Next
End Sub
================
Thanks,
Fred

"MikeD" <nob...@nowhere.edu> wrote in message
news:e3XRqlM...@TK2MSFTNGP03.phx.gbl...

Larry Serflaten

unread,
May 30, 2009, 7:56:42 AM5/30/09
to

"fred" <fr...@nospamme.com> wrote

> I am not sure how to trap the error, but continue with the procedure and NOT
> deploying the timer.
> Here is the code:
> ==============
> Private Sub moSkype_CallStatus(ByVal pCall As SKYPE4COMLib.ICall, ByVal
> Status As SKYPE4COMLib.TCallStatus)
> On Error GoTo err_StatusCallback
> <more code in here>
> If UBound(SkypeDtmfDelay) > 0 Then
> tmrStartStop.Enabled = False
> tmrStartStop.Interval = SkypeDtmfDelay(1) * 1000
> tmrStartStop.Enabled = True
> End If
> <more code in here>
> Exit Sub
> err_StatusCallback:
> Debug.Print "StatusCallback ==> " & CStr(err.Number) & " : " &
> err.Description
> If err.Number = 9 Then Resume Next
> End Sub
> ================

Compare:

Dim amt as long


> On Error GoTo err_StatusCallback
> <more code in here>

On Error goTo SkipTimer
amt = SkypeDtmfDelay(1) * 1000
> tmrStartStop.Enabled = False
> tmrStartStop.Interval = amt
> tmrStartStop.Enabled = True
> SkipTimer: On Error GoTo err_StatusCallBack


> <more code in here>
> Exit Sub
> err_StatusCallback:

... Etc....

If the array assignment fails, it skips over the Timer code and
resets the error target to what it was. If the assignment succeeds,
the timer is stopped, Interval set, and started again, followed by
resetting the error target back to what it was....

LFS


Bob Butler

unread,
May 30, 2009, 9:25:15 AM5/30/09
to

"fred" <fr...@nospamme.com> wrote in message
news:%234NKl8M...@TK2MSFTNGP06.phx.gbl...

> You are completely right, Mike.
> I have already put my code to work and of course I forgot assign False to
> my variable when erasing the array.
>
> I am not sure how to trap the error, but continue with the procedure and
> NOT deploying the timer.
> Here is the code:
> ==============
> Private Sub moSkype_CallStatus(ByVal pCall As SKYPE4COMLib.ICall, ByVal
> Status As SKYPE4COMLib.TCallStatus)
> On Error GoTo err_StatusCallback
> <more code in here>
> If UBound(SkypeDtmfDelay) > 0 Then
> tmrStartStop.Enabled = False

Private Sub moSkype_CallStatus(ByVal pCall As SKYPE4COMLib.ICall, _
ByVal Status As SKYPE4COMLib.TCallStatus)
Dim lMax As Long


On Error GoTo err_StatusCallback
<more code in here>

On Error Resume Next
lMax=UBound(SkypeDtmfDelay)
On Error GoTo err_StatusCallback
If lMax > 0 Then
tmrStartStop.Enabled = False


Rick Rothstein

unread,
May 30, 2009, 10:39:46 AM5/30/09
to

While I would go with the On Error method others have outlined for you, I
just wanted to mention there is an API solution that does not involve using
error trapping...

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

Function IsInitialized(arr As Variant) As Boolean
Dim Address As Long, ArrPtr As Long
CopyMemory ArrPtr, ByVal VarPtr(arr) + 8, ByVal 4
CopyMemory Address, ByVal ArrPtr, ByVal 4
IsInitialized = Address <> 0
End Function

Just add the above code to your Form's code window (or put it in a BAS
Module to make it globally available) and call the IsInitialized function
(passing in the array name as the argument) when needed. For example...

Private Sub Command1_Click()
Dim MyArray() As String
' ....
' .... Some code here
' ....
If IsInitialized(MyArray) Then
' Do this
Else
' Do that
End If
' ....
' .... Rest of code here
' ....
End Sub

--
Rick (MVP - Excel)

Nobody

unread,
May 30, 2009, 1:06:47 PM5/30/09
to
As others suggested, using On Error is normal for testing if an array is
dimmed before, and many other purposes. However, I sense that you prefer to
return error handling back to the default disabled state, so any error in
the IDE would show up. Here is how to do it:

On Error Resume Next
x = UBound(arr)
If Err.Number = 9 Then
' Not dimmed
Exit Function
End If
' Back to normal
On Error GoTo 0

But it's a bad habit not to use error handling. To simplify error handling,
use centralized error handling, see "Centralized Error Handling" on MSDN
Library. Use "Search title only" to find it. Here is the online version:

Centralized Error Handling:
http://msdn.microsoft.com/en-us/library/aa240795(VS.60).aspx

MZTools lets you add error handlers easily, and it's free:

http://www.mztools.com/v3/mztools3.aspx


fred

unread,
May 30, 2009, 1:42:23 PM5/30/09
to
Larry, with that one code you created a big dilemma for me.
Until now I was convinced that the recommended (?) way of placing On Error
statement is to use it only once in the procedure,
but if there is a need to use it again then first should be used On Error Go
To 0 followed by the new error trapping.
The flow I'd expect:
==================

> Dim amt as long
>> On Error GoTo err_StatusCallback
>> <more code in here>
On Error goTo 0

> On Error goTo SkipTimer
> amt = SkypeDtmfDelay(1) * 1000
>> tmrStartStop.Enabled = False
>> tmrStartStop.Interval = amt
>> tmrStartStop.Enabled = True
>> SkipTimer:
On Error goTo 0

On Error GoTo err_StatusCallBack
>> <more code in here>
>> Exit Sub
>> err_StatusCallback:
> ... Etc....
=====================
Please comment on that
Thanks,
Fred

"Larry Serflaten" <serf...@usinternet.com> wrote in message
news:ePeR41R4...@TK2MSFTNGP03.phx.gbl...

MP

unread,
May 30, 2009, 2:15:55 PM5/30/09
to

"Nobody" <nob...@nobody.com> wrote in message
news:%23OeDJkU...@TK2MSFTNGP03.phx.gbl...


I've always wondered about GoTo 0
all my procs have an error trap
Sub someProc()
On Error GoTo someProc_Err

now if i want to use Resume Next for a specific loop or action,
On Error Resume Next
' some anticipated localized error
If Err then
' ....
End if
On Error GoTo 0 '<<<<<< does this go back to someProc_Err or just
disable error trapping all together?
... should i instead of goTo 0 repeat the original direction
On Error GoTo someProc_Err

thnaks...oops(kind of like snacks but less filling)
mark


Message has been deleted

Larry Serflaten

unread,
May 30, 2009, 7:59:15 PM5/30/09
to

"fred" <fr...@nospamme.com> wrote

> Larry, with that one code you created a big dilemma for me.
> Until now I was convinced that the recommended (?) way of placing On Error
> statement is to use it only once in the procedure,
> but if there is a need to use it again then first should be used On Error Go
> To 0 followed by the new error trapping.

I'd suggest that is a bit like setting a variable to 0 before assigning it a different value.
The act of assigning the new value, in effect, replaces the old value whatever it was.

So it is with the error handler. It can only point to one lable in the procedure.
Re-assigning it to a new label simply replaces the old label, and away you go....

You can disable the error handler before enabling again, if you want, but like setting a
variable to 0 before giving it a new value, its more or less a futile command at that point.

Some might say it is there for readability, and if you agree then leave it in, it isn't going to
hurt anything. Or, if your intent is to disable the error handler for some amount of code,
then you really would need to use On Error GoTo 0.

But if the very next command after 'GoTo 0' is going to enable the Error handler again,
why bother?

LFS


Henning

unread,
May 30, 2009, 8:41:42 PM5/30/09
to

"MP" <Nos...@Thanks.com> skrev i meddelandet
news:OCfcWKV4...@TK2MSFTNGP04.phx.gbl...
On Error Goto 0 disables errortrapping.

/Henning


Nobody

unread,
May 31, 2009, 12:25:16 AM5/31/09
to
"MP" <Nos...@Thanks.com> wrote in message
news:OCfcWKV4...@TK2MSFTNGP04.phx.gbl...

> I've always wondered about GoTo 0
> all my procs have an error trap
> Sub someProc()
> On Error GoTo someProc_Err
>
> now if i want to use Resume Next for a specific loop or action,
> On Error Resume Next
> ' some anticipated localized error
> If Err then
> ' ....
> End if
> On Error GoTo 0 '<<<<<< does this go back to someProc_Err or just
> disable error trapping all together?
> ... should i instead of goTo 0 repeat the original direction
> On Error GoTo someProc_Err
>
> thnaks...oops(kind of like snacks but less filling)
> mark

You need to use "On Error GoTo someProc_Err" to go back to the previous
error handler. "On Error GoTo 0" returns error handling to the default
disabled state, so if any error happens, the IDE breaks with an error
message and highlighting the line that caused the error as usual.

But rather than commenting out "On Error ..." statements back and forth to
make the IDE show you the errors as if you didn't have error handlers, you
may want to right click the IDE window, and select Toggle-->Break on All
Errors. This basically make VB ignore all "On Error GoTo Label/Resume Next",
so you see all errors as if you didn't have these lines.


MP

unread,
May 31, 2009, 5:28:43 PM5/31/09
to
Thanks
mark

"Nobody" <nob...@nobody.com> wrote in message

news:O$AyRfa4J...@TK2MSFTNGP04.phx.gbl...


> "MP" <Nos...@Thanks.com> wrote in message
> news:OCfcWKV4...@TK2MSFTNGP04.phx.gbl...
> > I've always wondered about GoTo 0
> > all my procs have an error trap
> > Sub someProc()
> > On Error GoTo someProc_Err
> >

MikeD

unread,
May 31, 2009, 5:53:15 PM5/31/09
to

"Nobody" <nob...@nobody.com> wrote in message
news:O$AyRfa4J...@TK2MSFTNGP04.phx.gbl...

>
> "On Error GoTo 0" returns error handling to the default disabled state, so
> if any error happens, the IDE breaks with an error message and
> highlighting the line that caused the error as usual.
>

Technically, not quite correct. It disables the *active* error handler in
that procedure, but if another error handler is enabled in a procedure in
the call stack, that error handler then becomes the active error handler.
The IDE will only break if there is no active error handler in the call
stack. You can have several enabled error handlers, but there can only be
one active error handler at any given time.

So, for example, consider this simple scenario:

Private Sub Form_Load
On Error GoTo EH

Call ProcA

On Error GoTo 0

<StatementBlock3>

Exit Sub

EH:

MsgBox "Error in Form_Load"

End Sub

Private Sub ProcA()

On Error GoTo EH

<Statement Block1>

On Error GoTo 0

<Statement Block2>

Exit Sub

EH:

MsgBox "Error in ProcA"

End Sub

In ProcA, if an error occurs during StatementBlock1, it will be handled by
the error handler in ProcA. If an error occurs during StatementBlock2, it
will be handled by the error handler in Form_Load which has now become the
active error handler (and the error message is misleading because the error
didn't happen in Form_Load; it was just handled in Form_Load). If an error
occurs in Form_Load during StatementBlock3, it will not get handled and the
IDE will break (a compiled app will terminate).

--
Mike


Karl E. Peterson

unread,
Jun 1, 2009, 7:54:16 PM6/1/09
to
Ed wrote:

> On Fri, 29 May 2009 17:43:54 -0700, "Karl E. Peterson" <ka...@exmvps.org>
> wrote:
>
>>Ed wrote:
>>> If (Not SkypeDtmfDelay()) = -1 Then MsgBox "Array Not Dimensioned"
>>
>>I would *absolutely* advise avoiding this one! It caused me many hours of grief
>>once, as I tried to track down an Error 0. Turned out, that was it.
>
> Well this is basically how I used it and works just fine,

I know it can. I used to use it as well. Then I started getting a "Runtime Error
0" in the EXE, and couldn't pin it down. (Try googling that sometime, if you're
really bored.) It wasn't until I changed this test that the problem went away.
Don't think I'm being superstitious. This one will come back to bite.

mark.tunna...@googlemail.com

unread,
Jun 2, 2009, 1:39:50 PM6/2/09
to
The force is strong in Karl.
Karl is the Yoda of VB6.
Karl says "If use it you do, painful it may be".
I think we should believe him.
:)

Gary Bouchard

unread,
Jul 22, 2009, 4:12:01 PM7/22/09
to
Fred,

I don't know if you ever received an answer that was workable, but for me,
when I test to see if an array has been initialized I use the
IsEmpty(Arrayname) which returns a boolean value.

It is referenced from "Visual Basic For Applications" and contains other
useful functions as well.

If this is not relevant than never mind :-)


"fred" wrote:

> Hello,
> How to test whether the array is dimmensioned ?
> When I do:
> If UBound(SkypeDtmfDelay) > 0 Then
>
> there is an error: "Subscript out of range"
>
> How to test that array SkypeDtmfDelay() without having that error?

> Thanks,
> Fred
>
>
>

Eduardo

unread,
Jul 22, 2009, 4:29:58 PM7/22/09
to
Gary Bouchard escribió:

Debug.Print CBool(Not Not Arrayname)

Gary Bouchard

unread,
Jul 22, 2009, 4:42:01 PM7/22/09
to
There ya go... CBool() is another function of the VBA dll.
Reply all
Reply to author
Forward
0 new messages