I am working on VB Script and I am trying to read the txt file and sore it in a array.
I check for the number of lines and use that variable for the For loop.
I am getting an error Input past end of the file.
I am not sure how to solve this problem.
looking forward for your help.
Thank you!!
Dim num As Integer
'Skip lines one by one
Do While objTextFile.AtEndOfStream <> True
objTextFile.SkipLine ' or strTemp = txsInput.ReadLine
Loop
num = objTextFile.Line - 1
Dim para()
ReDim para(num)
For i = 1 To num
para(i) = objTextFile.ReadLine
Next
For two reasons (the second coming intp play if you fix the first):
You have already read the file to the end. You would need to reset or reopen it.
You are always reading 125 lines, regardless of how many lines you found.
You can read the lines and put them in the array in one go:
Dim para()
Dim num As Integer = 0
Do While Not objTextFile.AtEndOfStream
ReDim Preserve para(num)
para(num) = txsInput.ReadLine
num = num + 1
Loop
Note: Arrays are zero based, and the code above places the first line at index 0. If you place the data from index 1 and up (as in the original code) you leave the first item unused, and you have to keep skipping the first item when you use the array.
Edit:
I see that you changed 125 to num in the code, that would fix the second problem.
I've used the following style code which is fast for small files:
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(strList, ForReading)
strText = objTextFile.ReadAll
objTextFile.Close
arrList = Split(strText, vbCrLf)
Related
'Option Explicit double checks my variables and spelling
Option Explicit
'Define variables needed throughout script in beginning
Dim fso, BC1, strTestStr1,strTestStr1Length,BC2
Dim strTestStr2,strTestStr2Length
Dim TestComp
Dim Total
Set Total = Nothing
'Set fso
Set fso = CreateObject("Scripting.FileSystemObject")
'Declare and Open BC1
Set BC1 = fso.OpenTextFile("C:\Users\GDoe\Desktop\BC1.txt",1)
strTestStr1 = BC1.ReadAll
BC1.Close
'Declare and Open BC2
Set BC2 = fso.OpenTextFile("C:\Users\GDoe\Desktop\BC2.txt",1)
strTestStr2=BC2.ReadAll
BC2.Close
'Determines if the A is within the String
If(InStr(strTestStr1,"A")) Then
msgbox(strTestStr1)
Else
msgbox("This is not an A Plate.")
Total = +1
End If
'Determines if the E is within the String
If (InStr(strTestStr2,"E")) Then
msgbox(strTestStr2)
Else
msgbox("This is not an E Plate.")
Total = +1
End If
'Cut the string "-####-######", File position 3, 12 characters long
strTestStr1Length = mid(strTestStr1,3,12)
strTestStr2Length = mid(strTestStr2,3,12)
'Comparing my Strings
TestComp = StrComp(strTestStr1Length,strTestStr2Length)
'If Comparison reveals mismatch with numbers, Message box displayed
If TestComp <> 0 Then
msgbox("Mismatch")
End If
If Total > 0 Then
msgbox(Total)
Want to have a running count of times the conditions are false to activate
Another program at the end based on the Total. If Total>0 with the errors,
Follows one path if it is correct continues script.
There are no shorthand/assignment+math operators in VBScript; so change
Total = +1 ' seen as assign +1 to Total
to
Total = Total + 1
I got this code which deletes 10 lines starting from the top.
Is it possible to do the same but starting the delete from the bottom to the top of the txt file?
So if I have 30 lines, I want the last 10 or 20 lines to be deleted.
Const FOR_READING = 1
Const FOR_WRITING = 2
strFileName = "C:\scripts\delete.txt"
iNumberOfLinesToDelete = 10
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objTS = objFS.OpenTextFile(strFileName, FOR_READING)
strContents = objTS.ReadAll
objTS.Close
arrLines = Split(strContents, vbNewLine)
Set objTS = objFS.OpenTextFile(strFileName, FOR_WRITING)
For i=0 To UBound(arrLines)
If i > (iNumberOfLinesToDelete - 1) Then
objTS.WriteLine arrLines(i)
End If
Next
If you read the entire file into an array of lines you'd use more or less the same approach for removing lines from beginning or end.
To remove lines from the beginning you start at an offset after the lines that you want removed:
filename = "C:\path\to\your.txt"
numLinesToRemove = 10
Set fso = CreateObject("Scripting.FileSystemObject")
txt = Split(fso.OpenTextFile(filename).ReadAll, vbNewLine)
Set f = fso.OpenTextFile(filename, 2)
For i = numLinesToRemove To UBound(txt)
f.WriteLine txt(i)
Next
f.Close
To remove lines from the end of the file you stop before the lines that you want removed:
filename = "C:\path\to\your.txt"
numLinesToRemove = 10
Set fso = CreateObject("Scripting.FileSystemObject")
txt = Split(fso.OpenTextFile(filename).ReadAll, vbNewLine)
Set f = fso.OpenTextFile(filename, 2)
For i = 0 To UBound(txt) - numLinesToRemove
f.WriteLine txt(i)
Next
f.Close
This approach only works for small files, though. If you need to process large files you usually can't read the entire file into memory. If you did your computer would start swapping data from memory to disk, causing the system to slow down to a crawl. To avoid this you normally read the file line by line in a loop and write to a temporary file, then replace the original file with the temp file after processing is complete.
Removing lines from the beginning of a file is still fairly trivial, because TextStream objects have a Line property that holds the current line number (i.e. the number of the line that the next ReadLine call would read).
Set f = fso.OpenTextFile(filename)
Set tmp = fso.OpenTextFile(filename & ".tmp", 2, True)
Do Until f.AtEndOfStream
If f.Line <= numLinesToRemove Then
f.SkipLine
Else
tmp.WriteLine f.ReadLine
End If
Loop
f.Close
tmp.Close
However, you can't do that for removing lines from the end of the file, because you don't know the number of lines beforhand. One way to deal with this is to create a ring buffer the size of the number of lines you want to remove, fill it as you read lines from the input file, and write lines to the output file when they are removed from the buffer. That way the last numLinesToRemove lines are still in the buffer (not written to the output file) when the loop terminates.
ReDim buf(numLinesToRemove) 'ring buffer
i = -1 'ring buffer pointer
Set f = fso.OpenTextFile(filename)
Set tmp = fso.OpenTextFile(filename & ".tmp", 2, True)
Do Until f.AtEndOfStream
i = (i + 1) Mod numLinesToRemove 'advance ring buffer pointer
'if current buffer slot is filled write it to the output file ...
If Not IsEmpty(buf(i)) Then tmp.WriteLine buf(i)
'... then put current line from input file into current buffer slot
buf(i) = f.ReadLine
Next
f.Close
tmp.Close
In both cases you'd replace the original file after processing is complete, e.g. like this:
fso.DeleteFile filename
fso.MoveFile filename & ".tmp", filename
just loop backwards in your for statement
For i=UBound(arrLines) To (UBound(arrLines) -10) step -1
Next
I understand that the FSO does not know to read the lines from the last in a file.
My scenario here is to validate the last but 1 line and get the result out of it.
Assume, if i need to get the result as PASS or FAIL in the last but 1 line. Since i go through from the first line, the scenario of me getting the correct result is limited because there is a probability of PASS or FAIL appearing in the file earlier.
My last 2 lines in the file is
Failed
Done!!!!
OR
Passed
Done!!!!
to get the actual i am using a NESTED IF validation to get the result. Below is the snippet of the same.
str1 = "Passed"
str2 = "Failed"
str3="Done!!!!"
Do Until objFile.AtEndOfStream
str=objFile.ReadLine
if StrComp(str, str1) = 0 Then
str=objFile.ReadLine
if StrComp(str,str3) = 0 Then
result="PASS"
End if
elseif StrComp(str, str2) = 0 Then
str = objFile.ReadLine
if StrComp(str,str3) = 0 Then
result="FAIL"
End if
End if
Loop
This affects the performance. Is there any alternative to get this implementation in a better manner?
Here is a function which takes a file name and returns the second to last line read:
Function PenultimateLine(fname)
Dim fso, ts, line1, line2
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(fname)
Do Until ts.AtEndOfStream
line1 = line2
line2 = ts.ReadLine
Loop
ts.Close
PenultimateLine = line1
End Function
You can use this function to extract the line and then test it against "PASS" or "FAIL" (which, by the way, can be done simply with = rather than StrCmp)
A = Split(objfile.readall, vbcrlf)
B = A(ubound(A)-2)
This uses memory and is unsuitable on very large files.
Basically I am trying to write a script to delete files after a certain filename, so based on the below file list
FILE_000001_FULL.ZIP
FILE_000002_FULL.ZIP
FILE_000003_FULL.ZIP
FILE_000004_FULL.ZIP
FILE_000005_FULL.ZIP
FILE_000006_DELTA.ZIP
FILE_000007_DELTA.ZIP
FILE_000008_FULL.ZIP
Everything up until FILE_000005_FULL.ZIP would be deleted. The files are created using a tool and will be sorted by file name, so highest number first. Basically need the 2 latest FULL files kept and the DELTA's (if any) between them. I hope that makes sense.
So far, this is what I have, but just loops constantly, not just until it finds the 2 latest fulls.
Dim fso, folder, files, ToDel, sfolder
Set fso = CreateObject("Scripting.FileSystemObject")
sFolder = ("C:\MDS")
Set ToDel = fso.CreateTextFile ("C:\MDS\FileList.txt", True)
Set folder = fso.GetFolder(sFolder)
set files = folder.files
For each folderIDX In files
ToDel.WriteLine(folderidx.Name)
Next
ToDel.close
Dim arrFileLines()
i = 0
Set ObjFile = FSO.OpenTextFile("C:\MDS\FileList.txt", 1)
Do Until objFile.AtEndOfStream
Redim Preserve arrFileLines(i)
arrFileLines(i) = objFile.ReadLine
i = i + 1
Loop
ObjFile.Close
s = 0
Do While s < 2
For l = Ubound(arrFileLines) to LBound(arrFileLines) Step -1
For Each strLine in arrFileLines
IF InStr(strLine, "FULL") <> 0 Then
wscript.echo "Found Full!!!!"
wscript.echo strLine, s
s = S + 1
End If
Next
Next
LooP
My thoughts was to delete the lines from the text file, then use this text file to delete the files from the directory.
Hopefully that all makes sense and someone can pass some advice on!
You should be able to do this with two iterations through your folder and without the need/use of a text file. During the first pass, record the numbers assigned to the two latest FULL's. Then, in your second pass, delete any files that are less than your second-highest FULL.
Here's how it might look:
' First pass: Find the two latest FULLs...
For Each File In FSO.GetFolder("c:\mds").Files
' Is this a FULL?
If Right(File.Name, 8) = "FULL.ZIP" Then
' Get the numeric value from the file name (6 digits starting as pos 6)...
intNum = CLng(Mid(File.Name, 6, 6))
' Maintain the two latest FULLs...
If intNum > intMax1 Then
intMax2 = intMax1
intMax1 = intNum
ElseIf intNum > intMax2 Then
intMax2 = intNum
End If
End If
Next
' Second pass: Delete anything prior to the second-latest FULL...
For Each File In FSO.GetFolder("c:\mds").Files
intNum = CLng(Mid(File.Name, 6, 6))
If intNum < intMax2 Then File.Delete
Next
So I have a number of text files that I'm trying to read with Visual Basic. They all have the same formatting:
[number of items in the file]
item 1
item 2
item 3
...etc.
What I'm trying to do is declare an array of the size of the integer in the first line, and then read each line into corresponding parts of the array (so item 1 would be array[0], item 2 would be array[1], etc. However, I'm not sure where to start on this. Any help would be appreciated.
Pretty basic stuff (no pun intended):
Dim F As Integer
Dim Count As Integer
Dim Items() As String
Dim I As Integer
F = FreeFile(0)
Open "data.txt" For Input As #F
Input #F, Count
ReDim Items(Count - 1)
For I = 0 To Count - 1
Line Input #F, Items(I)
Next
Close #F
try this for VB6
Dim file_id As Integer
Dim strline as string
Dim array_item() as string
'Open file
file_id = FreeFile
Open "C:\list.txt" For Input AS #file_id
Dim irow As Integer
irow = 0
'Loop through the file
Do Until EOF(file_id)
'read a line from a file
Line Input #file_id, strline
'Resize the array according to the line read from file
Redim Preserve array_item(irow)
'put the line into the array
array_item(irow) = strline
'move to the next row
irow = irow + 1
Loop
Close #file_id
The VB function you're looking for is "split":
http://www.vb-helper.com/howto_csv_to_array.html
Try this:
Dim FullText As String, l() As String
'''Open file for reading using Scripting Runtime. But you can use your methods
Dim FSO As Object, TS As Object
Set FSO = createbject("Scripting.FileSystemObject")
Set TS = createbject("Scripting.TextStream")
Set TS = FSO.OpenTextFile(FilePath)
TS.ReadLine 'Skip your first line. It isn't needed now.
'''Reading the contents to FullText and splitting to the array.
FullText = TS.ReadAll
l = Split(FullText, vbNewLine) '''the main trick
Splitting automatically resizes l() and stores all data.
Now the l() array has everything you want.