Wayne Molina
Wayne Molina

Reputation: 19586

Why am I getting "subscript out of range" when the subscript IS in the range?

I'm working with some legacy spaghetti code that processes some hairy EDI. Most of the code is indecipherable and has no indentation or comments or even good variable names but there's one line that gives me trouble when I remove the On Error Resume Next statement which causes the script to always timeout.

If UBound(arylin) >= 1 Then
    Do Until arylin(0) = "PB" and arylin(1) = "DEF"
        ' Processing goes here - not relevant for this
    Loop
End If

The script executes the conditional but errors at the "Do Until" line, saying:

Microsoft VBScript runtime error '800a0009' 

Subscript out of range: '[number: 0]' 

Now, why on Earth would this be giving an error if I'm testing the upper bound before checking it, and it's saying that the upper bound is at least 1?

I can post more of the code if I have to but I'd rather not since my predecessor was a complete hack and the code is extremely ugly.

Upvotes: 3

Views: 30915

Answers (2)

slashmais
slashmais

Reputation: 7155

See AnthonyWJones comment)
(With VB you can set the base of arrays to start at either 0 or 1 - it should be at or near the top of a module: look for Option Base 1 or Option Base 0.)

LBound will always return 0.(You can also use LBound() to check the lower boundary of the array.)
(Just goes to show: don't expect MS to be consistent!)

Although you check that the array-size is >= 1 - which will ensure that arylin(0) is valid, but not necessarily arylin(1). The index is zero-based so if one element exists, it will be at index=0, and index=1 will be out-of-bounds.

You must check that the array-size >= 2 in this case. If you use two entries following each other consistently, then the check must be made for (array-size) mod 2 = 0.

Also make sure what value UBound actually returns. I googled and got contradicting information: this says it returns the 'count' while this one says it returns the physical limit (= 'count' -1).

About the 'On Error Resume Next' thing, maybe it should stay there ...

Upvotes: 3

Joel Coehoorn
Joel Coehoorn

Reputation: 415820

UBound() returns the index of the last element in the array. By default, arrays in vb languages prior to vb.net start at 1 rather than 0 (meaning the count and the index are normally the same thing, though you can change the default with Option Base).

Put those together you'll see that it's failing here:

arylin(0) = "PB"

Upvotes: 2

Related Questions