Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 418
  • Last Modified:

Need help with simpl VBS array dimensioning

Instructions looke pretty clear, but not working for me.  I am populating an array to eventually write out to a file without knowing ahead of time how many records there will be.  I have tried this:

Dim newArray()
For n = 1 to 10
newArray(n) = n
Next

If I dimension with () I get an "Subscript out of range" error on line3.  If I dimenion without () I get a "Type mismatch" error.
0
Mike Caldwell
Asked:
Mike Caldwell
  • 7
  • 3
  • 2
2 Solutions
 
Patrick MatthewsCommented:
You need to either do this:



Dim newArray(10), n

For n = 1 To 10
    newArray(n) = n
Next

Open in new window



Or:


Dim newArray(), n

ReDim newArray(10)
For n = 1 To 10
    newArray(n) = n
Next

Open in new window




In either case, be advised that the lower bound of the array will actually be 0, and not 1.
0
 
Bill PrewCommented:
A couple of additional thinks I'll mention.

First, it is possible to dynamically dimension an array at runtime, rather than statically in the original DIM statement. Since you mentioned not knowing the size you'll need, this might be useful.  Here's a quick little example of the REDIM statement in action.

' define array with no actual dimension
dim a()

' set variable to size of array we need
i = 10

' redimension the array to this size
redim a(i)

' add an entry to the array and display it
a(1) = 111
wscript.echo a(1)

Open in new window

Another powerful way to create an array at runtime based on an unknown number of elements is the SPLIT function. It chops apart a delimited list of values into array elements, and automatically dimensions the array size.  This can be very useful when trying to load a text file into an array for processing, as in:

Option Explicit
 
CONST ForWriting = 2
CONST ForReading = 1
 
Dim objFSO, strTextFile, strData, strLine, arrLines, n, objFile
 
'name of the text file
strTextFile = "EE27421002.txt"
 
'Create a File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
 
'Open the text file - strData now contains the whole file
Set objFile = objFSO.OpenTextFile(strTextFile,ForReading)
strData = objFile.ReadAll
objFile.close

'Split the text file into lines
arrLines = Split(strData,vbCrLf)
 
'Print each line
For Each strLine in arrLines
   Wscript.Echo strLine
Next

'Cleanup
Set objFile = Nothing
Set objFSO = Nothing

Open in new window

Hope this helps, questions welcome.

~bp
0
 
Mike CaldwellDirector of Business Development, AnaquaAuthor Commented:
Out of Range errors at the point of writing to the array.
Option Explicit
 
CONST ForWriting = 2
CONST ForReading = 1
CONST ForAppending = 8
 
Dim objFSO, strTextFile, strData, strLine, arrLines, n, objFile, nLines, strText, strTargetFile, LineCnt, strPos, strLen, strNew
Dim newArray(),m
 
'name of the text file
strTextFile = "D:\Junk\STRFILE.txt"
strTargetFile = "D:\Junk\STRFILE2.txt"
 
'Create a File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
 
'Open the text file - strData now contains the whole file
Set objFile = objFSO.OpenTextFile(strTextFile,ForReading)
strData = objFile.ReadAll
objFile.close

'Split the text file into lines
arrLines = Split(strData,vbCrLf)
 
nLines = UBound(arrLines)

m=0
For n = 0 to (nLines-1)

If Len(arrlines(n)) > 1 THEN
	strPos = Instr(arrLines(n),",")		' Find the comma
	strLen = Len(arrLines(n))
	strNew = Right(arrLines(n),strLen-strPos-1) & " " & Left(arrLines(n), (strPos - 1))
	newArray(m) = strNew & vbCrLf
	m = m + 1
ELSE
	m = m + 1
END IF
Next


Set objFile = objFSO.OpenTextFile(strTargetFile,ForAppending)

  for n = 0 to m			' ubound(arrLines)
    'strText = arrLines(n)     ' the vbCrLf will add a line break after each item
  objFile.WriteLine(newArray(n))
  next

objFile.close

msgbox "Done"

'Cleanup
Set objFile = Nothing
Set objFSO = Nothing

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
Mike CaldwellDirector of Business Development, AnaquaAuthor Commented:
The range error occurs at line 34.
0
 
Mike CaldwellDirector of Business Development, AnaquaAuthor Commented:
The variable m is used because the write file will have fewer lines than the read file.  Some line will be stripped out.  So m is a counter at to what array number is next for newArray, which is then written to the target file.
0
 
Mike CaldwellDirector of Business Development, AnaquaAuthor Commented:
This gets an out of range error for n=1

Dim newArray(), n
For n = 1 To 100
wscript.echo n
    newArray(n) = n
Next
0
 
Mike CaldwellDirector of Business Development, AnaquaAuthor Commented:
Here's what I have not made clear:  I will not know how many will be in the array until I am all done processing the input file.  So I need a dynamic dimension for newArray, but it seems that all methods suggested eventually require knowing how many there will be.
0
 
Mike CaldwellDirector of Business Development, AnaquaAuthor Commented:
Is this what you had in mind?  It works, but seems like a lot of overhead to keep rediminsioning.
Dim newArray()

For n = 1 To 100
Redim preserve newArray(n)
wscript.echo n
    newArray(n) = n
Next

For m = 0 to 99
wscript.echo newArray(m)
next
0
 
Patrick MatthewsCommented:
If you have to process each line in turn before deciding whether to add it to your "results" array, then yes, your only option appears to be using ReDim Preserve.  (Using ReDim without Preserve will erase and rebuild the array.)

You alternative would be to use a Dictionary object, which will allow you to add items to it as needed.

My article on using the Dictionary, while written from a VBA perspective, will still be useful to people working in VBScript:

http://www.experts-exchange.com/Software/Office_Productivity/Office_Suites/MS_Office/A_3391-Using-the-Dictionary-Class-in-VBA.html
0
 
Bill PrewCommented:
It looks like you are just processing each line of the input file, and if there is a comma in the line, reversing the part before and after the line, with a space in between.  So:

aaaaa,bbbbbbbb

becomes

bbbbbbbb aaaaa

That could be done right in the one array we have with the original lines in it.  It looks like if no comma is in the line then you just rite the line back out the way it was.

If all that is true, then this should work.

Option Explicit
 
CONST ForWriting = 2
CONST ForReading = 1
CONST ForAppending = 8
 
Dim objFSO, strTextFile, strData, strLine, arrLines, n, objFile, nLines, strText, strTargetFile, LineCnt, strPos, strLen
 
'name of the text file
strTextFile = "D:\Junk\STRFILE.txt"
strTargetFile = "D:\Junk\STRFILE2.txt"
 
'Create a File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
 
'Open the text file - strData now contains the whole file
Set objFile = objFSO.OpenTextFile(strTextFile, ForReading, False)
strData = objFile.ReadAll
objFile.close

'Split the text file into lines
arrLines = Split(strData, vbCrLf)
 
For n = 0 to UBound(arrLines)-1
    strLine = arrLines(n)
    strLen = Len(strLine)
    If strLen > 1 And Instr(strLine, ",") Then
        strPos = Instr(strLine, ",")         ' Find the comma
        arrLines(n) = Right(strLine, strLen-strPos) & " " & Left(strLine, strPos-1)
    End If
Next

' Write out the updated data
Set objFile = objFSO.OpenTextFile(strTargetFile, ForAppending, True)
objFile.WriteLine(Join(arrLines, vbCrLf))
objFile.close

MsgBox "Done"

'Cleanup
Set objFile = Nothing
Set objFSO = Nothing

Open in new window

~bp
0
 
Mike CaldwellDirector of Business Development, AnaquaAuthor Commented:
Thanks fellas.  My code has changed a lot due to change in end needs.  The key here was the fact of needed to redimension the target file with each write.  Sounds like  waste, but processed 10K lines faster than I can blink, so no problem.
0
 
Bill PrewCommented:
Glad to have helped, thanks.

~bp
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now