为什么当下标在范围内时,我得到的下标超出范围?

时间:2022-11-20 16:41:45

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.

我正在处理一些遗留的通心粉代码来处理一些复杂的EDI。大多数代码都是不可破译的,没有缩进或注释,甚至没有很好的变量名,但是当我删除On Error Resume的下一个语句时,有一行代码会给我带来麻烦,这导致脚本总是超时。

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?

现在,如果我在检查上界之前测试它为什么会有误差,它说上界至少是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.

如果需要的话,我可以发布更多的代码,但我宁愿不发布,因为我的前任是一个完整的黑客,而且代码极其丑陋。

2 个解决方案

#1


2  

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

UBound()返回数组中最后一个元素的索引。默认情况下,vb语言中的数组在vb.net之前的起点是1而不是0(这意味着计数和索引通常是一样的,尽管您可以使用选项基更改默认值)。

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

把它们放在一起,你会发现它在这里失败了:

arylin(0) = "PB"

#2


3  

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

参见AnthonyWJones注释)(使用VB,您可以设置数组的基础从0或1开始——它应该在模块顶部或接近模块的顶部:查找选项1或选项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!)

LBound总是返回0。(还可以使用LBound()检查数组的下界)(如下所示:不要期望MS是一致的!)

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.

尽管要检查array-size是否为>= 1—这将确保arylin(0)是有效的,但不一定是arylin(1)。索引是基于0的,所以如果存在一个元素,它将在index=0处,index=1将是越界的。

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.

在这种情况下,必须检查数组大小的>是否为2。如果连续使用两个条目,则必须对(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).

还要确保UBound实际返回的值是什么。我在google上搜索并得到了矛盾信息:这表明它返回“count”,而这个表示它返回物理极限(= 'count' -1)。

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

关于“错误恢复”的事情,也许它应该留在那里……

#1


2  

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

UBound()返回数组中最后一个元素的索引。默认情况下,vb语言中的数组在vb.net之前的起点是1而不是0(这意味着计数和索引通常是一样的,尽管您可以使用选项基更改默认值)。

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

把它们放在一起,你会发现它在这里失败了:

arylin(0) = "PB"

#2


3  

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

参见AnthonyWJones注释)(使用VB,您可以设置数组的基础从0或1开始——它应该在模块顶部或接近模块的顶部:查找选项1或选项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!)

LBound总是返回0。(还可以使用LBound()检查数组的下界)(如下所示:不要期望MS是一致的!)

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.

尽管要检查array-size是否为>= 1—这将确保arylin(0)是有效的,但不一定是arylin(1)。索引是基于0的,所以如果存在一个元素,它将在index=0处,index=1将是越界的。

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.

在这种情况下,必须检查数组大小的>是否为2。如果连续使用两个条目,则必须对(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).

还要确保UBound实际返回的值是什么。我在google上搜索并得到了矛盾信息:这表明它返回“count”,而这个表示它返回物理极限(= 'count' -1)。

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

关于“错误恢复”的事情,也许它应该留在那里……