Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Subscript out of range

Status
Not open for further replies.

jtheis

Technical User
Sep 9, 2004
41
0
0
US
I'm getting a "subscript out of range error" in my script at the following line
Code:
Groups.OPCItems.AddItems NumItems, szItems(), clntHdls(), svrHdls(), Errors()

Before this line is called I do the following
Code:
Set objServer = CreateObject("OPC.Automation")
Set Groups = objServer.OPCGroups.Add("PlanGroup")

NumItems = 48
ReDim szItems(NumItems)
ReDim clntHdls(NumItems)
ReDim svrHdls(NumItems)
ReDim Errors(NumItems)

The error comes back as "subscript out of range" but it doesn't tell me which of the arrays is the problem. I've checked and they all return back with an UBound of 48. What I don't understand is what sets the upper bound for what .AddItems is looking for in the arrays? I thought it was NumItems, but I don't think that's it now.

Thanks for any help!


Joe


 
Is there any chance that your Groups object is going 0-47 instead of 1-48 or something like that?
 
Sheco,

Time for me to ask another stupid question - how would I know if it is going from 0 to 47 instead of 1 to 48? Is there something I could write to check this?

If I understand what I've read about arrays, since I ReDim'd the arrays to NumItems, it should be creating the dynamic array with 49 indexes, 0 through 48. If the size of the array is 49 indexes and I only write a value to indexes 1 through 48, will it give me this error if the zero index value is empty? If the other arrays (Errors, svrHdls, etc) are ReDim'd but empty will that also generate the subscript out of range error? The explanation for the error that I found states that 'the array you are trying to access contains fewer elements than expected.' Doesn't the first NumItems in the .AddItems tell how many elements are expected?

Thanks!


Joe


 
>how would I know if it is going from 0 to 47 instead of 1 to 48?
[tt] x=lbound(szItems)
y=ubound(szItems)
[/tt]etc... should give you x=0 and y=47.
 
tsuji,

Thanks for reminding me. I had checked the UBound before on all of them and got a 48 back. I double checked and for all of the arrays they come back with a 0 for the LBound and 48 for the UBound. So now I have confirmation that the arrays are all 49 elements (0 to 48) but I still don't think I understand how the Groups.AddItems is working. I downloaded the Data Access Automation Interface Standard manual (which is for VB, but it at least explains how these are supposed to work) and I thought that since I am using NumItems it would be looking for 48 elements. Since I have 49 elements, it doesn't make sense to me that the array has fewer elements than .AddItems is looking for.

I don't know if my posts are helping to clear things up or if I'm confusing the issue more. Thanks again for the help!


Joe
 
[tt]>Groups.OPCItems.AddItems NumItems, szItems(), clntHdls(), svrHdls(), Errors()[/tt]
Try this?
[tt]Groups.OPCItems.AddItems NumItems, szItems, clntHdls, svrHdls, Errors[/tt]
 
tsuji,

Good idea, but I get a type mismatch error without the (). That seems like the kind of thing that would be different between VB and VBScript. Thanks!


Joe
 
>That seems like the kind of thing that would be different between VB and VBScript.
I don't think so.

>Before this line is called I do the following
[tt]>NumItems = 48
>ReDim szItems(NumItems)
>ReDim clntHdls(NumItems)[/tt]

If you do nothing about them, they would be "empty", and that could be reason for type mismatch. Check documentation and sample.
[tt]
>ReDim svrHdls(NumItems)
>ReDim Errors(NumItems)
[/tt]
Maybe have to leave them alone
[tt]
Dim svrHdls()
Dim Errors()
[/tt]
Then call the additems without the parentheses (), szItems etc..
 
tsuji,

I agree that the arrays would be empty, or uninitialized, if I didn't ReDim them. What I meant was that omitting the () in the .AddItems is the kind of thing I'm used to seeing as being different between VB and VBScript.

For grins, I did take the ReDim statements out. I get the out of range error as soon as I try to assign something to szItems(1) since I never initialized the array.

 
I don't know... try look at samples and documentation. Take a random ref:
You see, you have to initialize the 2nd & 3rd arguments (arrays) before passing to additems. (Besides, collection OPCItems is 1-based indexed.) 4th & 5th are passed byRef. In any case, they are fed without paraentheses. Maybe those samples and syntax could help. If in any doubt, additem one-by-one which seems less involved and with less uncertainty to start with for porting to vbs.
 
tsuji,

Thanks for the link. I'll read up on it and post back with my results.


Joe
 
I've got an update on this one. Instead of using .AddItems, I made a loop and used .AddItem instead. So where I had
Code:
Group.OPCItems.AddItems NumItems, szItems(), clntHdls(), svrHdls(), Errors()
I now have
Code:
For I = 0 To NumItems
	szItem = szItems(I)
	clntHdl = clntHdls(I)
	Group.OPCItems.AddItem szItem, clntHdl
Next
and this seems to run without any problems. Of course, the next line in my script has .SyncWrite used as
Code:
Group.SyncWrite NumItems, svrHdls(), OutValues(), Errors()
and it gives me the same subscript out of range error!

I'm still trying to work through this one. If anyone has any ideas, I'd love to hear them!

Thanks!


Joe
 
>[tt]Group.SyncWrite NumItems, svrHdls(), OutValues(), Errors()[/tt]
Either you have a good reason to using () on passing an array or you just cannot get rid of the habit...
 
tsuji,

OK, I think I understand what you're getting at. When I take out the (), I get the type mismatch because SyncWrite is expecting that NumItems, svrHdls, and Errors will all be Long and OutValues will be Variants. I think the only one that would be right by default is the OutValues, because VBScript makes everything Variant by default. So what I tried was
Code:
CLng(svrHdls)
as a test. My problem with that is that the package I'm using the VBScript with (ICONICS Genesis) doesn't support CLng and returns an error that says 'Variable uses an Automation type not supported in VBScript: 'CLng''.
 
This shows you how you get out-of-range error.
[tt]
dim a()
redim a(2)
for i=0 to 2
a(i)=i
next

b=proc(a)
wscript.echo join(b,"-")

proc_2 a
wscript.echo join(a,"-")

'any of these will give subscription out-or-range runtime error
'proc_2 a()
'c=proc(a())

function proc(x)
dim y()
redim y(ubound(x))
for i=0 to ubound(x)
y(i)=x(i)+i
next
proc=y
end function

sub proc_2(x)
for i=0 to ubound(x)
x(i)=x(i)+i*2
next
end sub
[/tt]
Besides, the documentation you follows show clearly the syntax as well.

To make entries long, you can only clng(a(i)) on each and every entry. You cannot clng(a) to get it long.
 
tsuji,

Thank you for being so patient on this one. Yes, I now understand the problem with using () and I will never use them again! I also understand that CLng can only be used on the individual elements of the array and not on the entire array. My question now - since I can convert each element in the array to type Long, is there a way to convert the array to type Long instead of type Variant?

As a test I did the following
Code:
Dim arrTest()
Dim lngarrTest()

NumItems = 5

ReDim arrTest(NumItems)
ReDim lngarrTest(NumItems)

For I = 0 To NumItems
	arrTest(I) = I
	lngarrTest(I) = CLng(arrTest(I))
	MsgBox TypeName(arrTest(I)), 0, "arrTest(" & I & ") Type"
	MsgBox (arrTest(I)), 0, "arrTest(" & I & ") Value"
	MsgBox TypeName(lngarrTest(I)), 0, "lngarrTest(" & I & ")"
	MsgBox (lngarrTest(I)), 0, "lngarrTest(" & I & ") Value"
Next

MsgBox TypeName(arrTest), 0, "arrTest"
MsgBox TypeName(lngarrTest), 0, "lngarrTest"

The arrTest Values all come back as type Integer. The lngarrTest Values all come back as type Long. But both arrays come back as type Variant. Am I trying to do something that can't be done in VBScript? I know in VB you have to declare the type that the array is, but I haven't seen anything to tell me if it is possible in VBScript.
 
All VBScript variables are arrays. Period. They can be stored as some specific sub-type of the variant class. The TypeName function returns the Variant sub-type of the argument.

[red]"... isn't sanity really just a one trick pony anyway?! I mean, all you get is one trick, rational thinking, but when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick[/red]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top