Is there a way to set the starting read line in vbscript? - vbscript

I have a text file and it has more than 85k lines
Is there a way to set the starting line? For example; I've already read and write the lines 1-10 to other file and want to get a value in line 12 to add it in the last line that I wrote. I want to read only the line 12.
Text/Sample/1/GetValue/12
Text/Sample/2/GetValue/11
Text/Sample/3/GetValue/10
Text/Sample/4/GetValue/9
Text/Sample/5/GetValue/8
Text/Sample/6/GetValue/7
Text/Sample/7/GetValue/6
Text/Sample/8/GetValue/5
Text/Sample/9/GetValue/4
Text/Sample/10/GetValue/3
Text/Sample/11/GetValue/2
Text/Sample/12/GetValue/1

The TextStream object provides sequential forward reading only. See the Docs for .Skip, .SkipLine, .Read, .ReadLine, and .ReadAll.
So you have to skip/read to the desired position, or do some Mid string work on the full content (.Readall) of the file.

Here is an example of function that can did the trick for you :
Option Explicit
Dim Title,FromLine,ToLine,fso,Readfile,strBuff,InputFile,TotalNbLines
Title = "Extract Lines From TextFile"
InputFile = "c:\test.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
Set Readfile = Fso.OpenTextFile(InputFile,1)
strBuff = Readfile.ReadAll
TotalNbLines = Readfile.Line
Readfile.Close
'*******************************************************************************************************
MsgBox "The total number of lines in this file """& InputFile &""" = "& TotalNbLines,VbInformation,Title
'*******************************************************************************************************
MsgBox "Extract the 3 last lines" & vbcrlf & vbcrlf &_
ExtractLinesFromTextFile(InputFile,TotalNbLines - 2,TotalNbLines),64,Title 'To extract the 3 last lines
'*******************************************************************************************************
MsgBox "Extract line from line 1 to 2" & vbcrlf & vbcrlf &_
ExtractLinesFromTextFile(InputFile,1,2),64,Title 'Extract line from line 1 to 2
'*******************************************************************************************************
MsgBox "Extract line N°2" & vbcrlf & vbcrlf &_
ExtractLinesFromTextFile(InputFile,2,2),64,Title 'Extract line N°2
'*******************************************************************************************************
MsgBox "Extract line from line 1 to 5" & vbcrlf & vbcrlf &_
ExtractLinesFromTextFile(InputFile,1,5),64,Title 'Extract line from line 1 to 5
'*******************************************************************************************************
MsgBox "Extract line from line 1 to 10" & vbcrlf & vbcrlf &_
ExtractLinesFromTextFile(InputFile,1,10),64,Title'Extract line from line 1 to 10
'*******************************************************************************************************
MsgBox "Extract line N° 12" & vbcrlf & vbcrlf &_
ExtractLinesFromTextFile(InputFile,12,12),64,Title'Extract line N° 12
'*********************************************************************************************************
Public Function ExtractLinesFromTextFile(ByRef TextFile, ByRef FromLine, ByRef ToLine) '<-- Inclusive
Const TristateUseDefault = -2 'To Open the file using the system default.
On Error Resume Next
If FromLine <= ToLine Then
With CreateObject("Scripting.FileSystemObject").OpenTextFile(TextFile,1,true,TristateUseDefault)
If Err.number <> 0 Then
MsgBox err.description,16,err.description
Exit Function
Else
Do Until .Line = FromLine Or .AtEndOfStream
.SkipLine
Loop
Do Until .Line > ToLine Or .AtEndOfStream
ExtractLinesFromTextFile = ExtractLinesFromTextFile & (.ReadLine & vbNewLine)
Loop
End If
End With
Else
MsgBox "Error to Read Line in TextFile", vbCritical,"Error to Read Line in TextFile"
End If
End Function
'*********************************************************************************************************

Related

Strange VBScript error: Object required: 'objFolder'

I have done extensive search on internet but still was not able to find the solution. The interesting thing is that my code worked before. I am using html page with VBScript code, opened using IE 9.
My code is below:
29: Function TraverseDirectory(objFolder, searchTerm, outFile)
30: if objFolder.SubFolders.Count > 0 then <-- ERROR shown in this line: Object required: 'objFolder'
31: MsgBox objFolder.SubFolders.Count <-- This message is shown without an issue
32: Set fc = objFolder.SubFolders
33: For Each f1 in fc
34: ProcessFolder f1, searchTerm, outFile
35: TraverseDirectory f1, searchTerm, outFile
36: Next
37: else
38: ProcessFolder objFolder, searchTerm, outFile
39: end if
40: End Function
I am showing the error in line 30: Object required 'objFolder'
I added a message box in line 31 and it was reached, outputting message box with a number of subfolders in a give folder. If the problem was actually in line 30, it would never reach line 31. If I completely remove line 31 (the one with a message box), I still get the same error in line 30.
My function above is called the following way:
Set objFolder = objFSO.GetFolder("C:\Test")
TraverseDirectory objFolder, str, outFile
The folder exists and is retrieved without a problem. Not sure what is happening. Can someone shed some light on the issue?
Next script collects/echoes some debugging info as advised in my previous comment
option explicit
'On Error Resume Next
On Error GoTo 0
Dim strResult: strResult = Wscript.ScriptName
Dim objfso, str, outfile, objFolder
set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("D:\TestC")
'Set objFolder = objFSO.GetFolder("C:\attachments") 'an empty folder for debugging'
Wscript.Echo "start" & vbTab _
& VarType( objFolder) & " " & TypeName(objFolder) & vbTab & objFolder
TraverseDirectory objFolder, str, outFile
Wscript.Echo strResult
Wscript.Quit
Function TraverseDirectory(objFolder, searchTerm, outFile)
Dim fc, f1, aux
Wscript.Echo "debug" & vbTab _
& VarType( objFolder) & " " & TypeName(objFolder) & vbTab & objFolder
aux = objFolder.SubFolders.Count
if aux > 0 then '<-- ERROR shown in this line: Object required: 'objFolder'
'MsgBox objFolder.SubFolders.Count ' <-- This message is shown without an issue
Set fc = objFolder.SubFolders
For Each f1 in fc
strResult = strResult & vbNewLine & Cstr( aux) _
& vbTab & VarType( f1) & " " & TypeName(f1) & vbTab & f1
'ProcessFolder f1, searchTerm, outFile
TraverseDirectory f1, searchTerm, outFile
Next
else
'ProcessFolder objFolder, searchTerm, outFile
strResult = strResult & vbNewLine & Cstr( aux) & vbTab _
& VarType( objFolder) & " " & TypeName(objFolder) & vbTab & objFolder
end if
End Function
Debugging scenario:
==> tree "D:\TestC"
Folder PATH listing for volume DataDisk
Volume serial number is … … …
D:\TESTC
├───bubu
│ └───foobar
├───kuku
├───New Folder 12
└───New Folder 21
└───New folder XX
Output shows that leafs in folder tree are processed twice so the script above requires more thinking and debugging: note that strResult variable is updated in place of original ProcessFolder call:
==> cscript D:\VB_scripts\SO\38056552.vbs
start 8 Folder D:\testC
debug 8 Folder D:\testC
debug 8 Folder D:\testC\bubu
debug 8 Folder D:\testC\bubu\foobar
debug 8 Folder D:\testC\kuku
debug 8 Folder D:\testC\New Folder 12
debug 8 Folder D:\testC\New Folder 21
debug 8 Folder D:\testC\New Folder 21\New folder XX
38056552.vbs
4 8 Folder D:\testC\bubu
1 8 Folder D:\testC\bubu\foobar
0 8 Folder D:\testC\bubu\foobar
4 8 Folder D:\testC\kuku
0 8 Folder D:\testC\kuku
4 8 Folder D:\testC\New Folder 12
0 8 Folder D:\testC\New Folder 12
4 8 Folder D:\testC\New Folder 21
1 8 Folder D:\testC\New Folder 21\New folder XX
0 8 Folder D:\testC\New Folder 21\New folder XX

vbscript replacing text without overwriting in a text file

Below is part of a script I already wrote:
For i = 1 to arrsize
strText=""
Set objFile = objFSO.OpenTextFile(filetable(i), ForReading)
wscript.echo filetable(i)
On Error Resume Next
Do Until objFile.AtEndOfStream
strline = objFile.ReadLine
If instr(strline, source_string) > 0 Then
wscript.echo strline
Do Until instr(strline, " TEXT ") > 0 or instr(strline, Chr(9) & "TEXT ")
strline = objFile.ReadLine
Loop
strNewText = Replace(strline, "TEXT " & Chr(34), "TEXT " & Chr(34) & "Critical: ",1,-1,0)
wscript.echo strNewText
'up to here everything is OK
Set objFile = objFSO.OpenTextFile(filetable(i), ForWriting)
objFile.WriteLine strNewText
objFile.close
'The three line above are overwriting the text file
End If`enter code here`
Loop
Next
My script is to search in an array of files for a specific string registered in source_string variable, then if it matches it should search for "TEXT" word preceded by space or tab, when matches and it should it will then replace the line with the same line as per the following format:
TEXT "Critical: ****".
I hope it is clear and thanks in advanced
I think here you open the text file again and you start at the start of stream and thus the first line (and not the found line) :
Set objFile = objFSO.OpenTextFile(filetable(i), ForWriting)
objFile.WriteLine strNewText
objFile.close
Maybe you should try opening the file for reading&writing, readline, when you str is found, then change that line and move on ...
For i = 1 to arrsize
Set objFile = objFSO.OpenTextFile(filetable(i), ForReading)
wscript.echo filetable(i)
On Error Resume Next
Dim filearray()
Linenb = 0
Do Until objFile.AtEndOfStream
Linenb = Linenb + 1
Redim Preserve filearray(Linenb)
filearray(Linenb) = objFile.ReadLine
' wscript.echo filearray(Linenb)
If instr(filearray(Linenb), source_string) > 0 Then
' wscript.echo filearray(Linenb)
Do Until instr(filearray(Linenb), " TEXT ") > 0 or instr(filearray(Linenb), Chr(9) & "TEXT ")
Linenb = Linenb + 1
Redim Preserve filearray (Linenb)
filearray(Linenb) = objFile.ReadLine
' wscript.echo filearray(Linenb)
Loop
filearray(Linenb) = Replace(filearray(Linenb), "TEXT " & Chr(34), "TEXT " & Chr(34) & "Critical: ",1,-1,0)
' wscript.echo filearray(Linenb)
End If
Loop
For j = 1 to Linenb
Set objFile = objFSO.OpenTextFile(filetable(i), ForWriting)
objfile.WriteLine filearray(j)
Next
Redim Preserve filearray (1)
Next

How to apply a VBA macro to all files in a directory?

I have a sub-directory with ~1000 Word Documents I'd like to apply the following macro to style hyperlinks to each of them, but I can't really open each of them to run the script. Is there any way I can set it to apply to every document in the directory? Could I call it from a bash script?
Sub FormatLinks()
Dim H As Hyperlink
For Each H In ActiveDocument.Hyperlinks
H.Range.Select ' (A)
Selection.ClearFormatting ' (B)
H.Range.Style = ActiveDocument.Styles("Hyperlink") ' (C)
Next H
End Sub
This is from Filter, a program that filters stdin to stdout. This part here is from run a command line specifed script on each line in a file. Dir /b gives you a list of files.
Set Arg = WScript.Arguments
set WshShell = createObject("Wscript.Shell")
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
RawScript = Arg(1)
'Remove ^ from quoting command line and replace : with vbcrlf so get line number if error
Script = Replace(RawScript, "^", "")
Script = Replace(Script, "'", chr(34))
Script = Replace(Script, ":", vbcrlf)
'Building the script with predefined statements and the user's code
Script = "Dim gU" & vbcrlf & "Dim gdU" & vbcrlf & "Set gdU = CreateObject(" & chr(34) & "Scripting.Dictionary" & chr(34) & ")" & vbcrlf & "Function UF(L, LC)" & vbcrlf & "Set greU = New RegExp" & vbcrlf & "On Error Resume Next" & vbcrlf & Script & vbcrlf & "End Function" & vbcrlf
'Testing the script for syntax errors
On Error Resume Next
set ScriptControl1 = wscript.createObject("MSScriptControl.ScriptControl",SC)
With ScriptControl1
.Language = "VBScript"
.UseSafeSubset = False
.AllowUI = True
.AddCode Script
End With
With ScriptControl1.Error
If .number <> 0 then
Outp.WriteBlankLines(1)
Outp.WriteLine "User function syntax error"
Outp.WriteLine "=========================="
Outp.WriteBlankLines(1)
Outp.Write NumberScript(Script)
Outp.WriteBlankLines(2)
Outp.WriteLine "Error " & .number & " " & .description
Outp.WriteLine "Line " & .line & " " & "Col " & .column
Exit Sub
End If
End With
ExecuteGlobal(Script)
'Remove the first line as the parameters are the first line
'Line=Inp.readline
Do Until Inp.AtEndOfStream
Line=Inp.readline
LineCount = Inp.Line
temp = UF(Line, LineCount)
If err.number <> 0 then
outp.writeline ""
outp.writeline ""
outp.writeline "User function runtime error"
outp.writeline "==========================="
Outp.WriteBlankLines(1)
Outp.Write NumberScript(Script)
Outp.WriteBlankLines(2)
Outp.WriteLine "Error " & err.number & " " & err.description
Outp.WriteLine "Source " & err.source
Outp.WriteLine "Line number and column not available for runtime errors"
wscript.quit
End If
outp.writeline temp
Loop
General Use
filter <inputfile >outputfile
filter <inputfile | other_command
other_command | filter >outputfile
other_command | filter | other_command
Vbs
filter vbs "text of a vbs script"
filter vb "text of a vbs script"
Use colons to seperate statements and lines. Use single quotes in place of double quotes, if you need a single quote use chr(39). Escape brackets and ampersand with the ^ character. If you need a caret use chr(136).
The function is called UF (for UserFunction). It has two parameters, L which contains the current line and LC which contains the linecount. Set the results of the script to UF. See example.
There are three global objects available. An undeclared global variable gU to maintain state. Use it as an array if you need more than one variable. A Dictionary object gdU for saving and accessing previous lines. And a RegExp object greU ready for use.
Example
This vbs script inserts the line number and sets the line to the function UF which Filter prints.
filter vbs "uf=LC ^& ' ' ^& L"<"%systemroot%\win.ini"
This is how it looks in memory
Dim gU
Set gdU = CreateObject("Scripting.Dictionary")
Set greU = New RegExp
Function UF(L, LC)
---from command line---
uf=LC & " " & L
---end from command line---
End Function
If there is a syntax error Filter will display debugging details.
User function syntax error
1 Dim gU
2 Dim gdU
3 Set greU = CreateObject("Scripting.Dictionary")
4 Function UF(L, LC)
5 On Error Resume Next
6 uf=LC dim & " " & L
7 End Function
Error 1025 Expected end of statement
Line 6 Col 6
User function runtime error
1 Dim gU
2 Dim gdU
3 Set greU = CreateObject("Scripting.Dictionary")
4 Function UF(L, LC)
5 On Error Resume Next
6 uf=LC/0 & " " & L
7 End Function
Error 11 Division by zero
Source Microsoft VBScript runtime error
Line number and column not available for runtime errors
Other examples
Reverse each line
filter vbs "uf=StrReverse^(L^)"<"%systemroot%\win.ini"

How can we programmatically know the syntax error using msscript.ocx?

I have implemented msscript.ocx using c# and it works for VBScript.
Consider the following VBScript code:
For i = 0 To 5
'The following line has missing 'Then'. It should show an error.
If i = 2
Exit For
End If
Next
How can we tell if there is an error in line containing If (missing Then) without running the script?
You get the error when loading.
Set Arg = WScript.Arguments
set WshShell = createObject("Wscript.Shell")
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
Sub VBSCmd
RawScript = Arg(1)
'Remove ^ from quoting command line and replace : with vbcrlf so get line number if error
Script = Replace(RawScript, "^", "")
Script = Replace(Script, "'", chr(34))
Script = Replace(Script, ":", vbcrlf)
'Building the script with predefined statements and the user's code
Script = "Dim gU" & vbcrlf & "Dim gdU" & vbcrlf & "Set gdU = CreateObject(" & chr(34) & "Scripting.Dictionary" & chr(34) & ")" & vbcrlf & "Function UF(L, LC)" & vbcrlf & "Set greU = New RegExp" & vbcrlf & "On Error Resume Next" & vbcrlf & Script & vbcrlf & "End Function" & vbcrlf
'Testing the script for syntax errors
On Error Resume Next
set ScriptControl1 = wscript.createObject("MSScriptControl.ScriptControl",SC)
With ScriptControl1
.Language = "VBScript"
.UseSafeSubset = False
.AllowUI = True
.AddCode Script
End With
With ScriptControl1.Error
If .number <> 0 then
Outp.WriteBlankLines(1)
Outp.WriteLine "User function syntax error"
Outp.WriteLine "=========================="
Outp.WriteBlankLines(1)
Outp.Write NumberScript(Script)
Outp.WriteBlankLines(2)
Outp.WriteLine "Error " & .number & " " & .description
Outp.WriteLine "Line " & .line & " " & "Col " & .column
Exit Sub
End If
End With
ExecuteGlobal(Script)
'Remove the first line as the parameters are the first line
'Line=Inp.readline
Do Until Inp.AtEndOfStream
Line=Inp.readline
LineCount = Inp.Line
temp = UF(Line, LineCount)
If err.number <> 0 then
outp.writeline ""
outp.writeline ""
outp.writeline "User function runtime error"
outp.writeline "==========================="
Outp.WriteBlankLines(1)
Outp.Write NumberScript(Script)
Outp.WriteBlankLines(2)
Outp.WriteLine "Error " & err.number & " " & err.description
Outp.WriteLine "Source " & err.source
Outp.WriteLine "Line number and column not available for runtime errors"
wscript.quit
End If
outp.writeline temp
Loop
End Sub
Vbs
filter vbs "text of a vbs script"
Use colons to seperate statements and lines. Use single quotes in place of double quotes, if you need a single quote use chr(39). Escape brackets and ampersand with the ^ character. If you need a caret use chr(136).
The function is called UF (for UserFunction). It has two parameters, L which contains the current line and LC which contains the linecount. Set the results of the script to UF. See example.
There are three global objects available. An undeclared global variable gU to maintain state. Use it as an array if you need more than one variable. A Dictionary object gdU for saving and accessing previous lines. And a RegExp object greU ready for use.
Example
This vbs script inserts the line number and sets the line to the function UF which Filter prints.
filter vbs "uf=LC ^& ' ' ^& L"<"%systemroot%\win.ini"
This is how it looks in memory
Dim gU
Set gdU = CreateObject("Scripting.Dictionary")
Set greU = New RegExp
Function UF(L, LC)
---from command line---
uf=LC & " " & L
---end from command line---
End Function
If there is a syntax error Filter will display debugging details.

VBScript Error code 800A0409, Unterminated string constant, on line 1

I'm getting Error code 800A0409, Unterminated string constant, on line 1, 54 with the code below.
Option Explicit
Dim ObjProgressMsg
Dim fso,objText,strVstup,strVystup,f,dtmVyt,dtmF,dDiff,fName,fExt,fShort,dtmAkt,tx,msgText
Dim strMessage,strWindowTitle,strTemp,wshShell,objTempMessage,strTempVBS
Set fso = CreateObject("Scripting.FileSystemObject")
Set objText = fso.GetFile("l:\bat\posledni.den")
strVstup = "l:\filefolder\"
strVystup = "l:\backup"
dtmVyt = objText.DateLastModified
msgText = "Some text about copying and renaming" & VbCrLf & "files, please wait..."
ProgressMsg msgText
For Each f In fso.GetFolder(strVstup).Files
dtmF = f.DateLastModified
dDiff = DateDiff("s", dtmF, dtmVyt)
If dDiff < 0 Then
ProgressMsg ""
WScript.Echo f
End If
Next
WScript.Echo "Some text about the task being finished."
Function ProgressMsg( strMessage )
' Written by Denis St-Pierre
' Displays a progress message box that the originating script can kill in both 2k and XP
' If StrMessage is blank, take down previous progress message box
' Using 4096 in Msgbox below makes the progress message float on top of things
' CAVEAT: You must have Dim ObjProgressMsg at the top of your script for this to work as described
Set wshShell = WScript.CreateObject( "WScript.Shell" )
strTEMP = wshShell.ExpandEnvironmentStrings( "%TEMP%" )
If strMessage = "" Then
' Disable Error Checking in case objProgressMsg doesn't exists yet
On Error Resume Next
' Kill ProgressMsg
objProgressMsg.Terminate( )
' Re-enable Error Checking
On Error Goto 0
Exit Function
End If
strTempVBS = strTEMP + "\" & "Message.vbs" 'Control File for reboot
' Create Message.vbs, True=overwrite
Set objTempMessage = fso.CreateTextFile( strTempVBS, True )
objTempMessage.WriteLine( "MsgBox""" & strMessage & """, 4096, """ & "a_sp_rano" & """" )
objTempMessage.Close
' Disable Error Checking in case objProgressMsg doesn't exists yet
On Error Resume Next
' Kills the Previous ProgressMsg
objProgressMsg.Terminate( )
' Re-enable Error Checking
On Error Goto 0
' Trigger objProgressMsg and keep an object on it
Set objProgressMsg = WshShell.Exec( "%windir%\system32\wscript.exe " & strTempVBS )
End Function
The script should show a msgbox while searching for files newer than last modified date of posledni.den file. Then once it finds a file it should close msgbox and echo the file it found.
It works just fine if I change this:
msgText = "Some text about copying and renaming" & VbCrLf & "files, please wait..."
to this:
msgText = "Some text about copying and renaming" & "files, please wait..."
Removal of VbCrLf seems to fix that error, just no line break is obviously happening. I can't figure out why it's behaving like that, what am I doing wrong. Every kind of insight on the problem would be much appreciated.
Thank you in advance. :)
The error occurs in the execution of the generated .vbs. What you do is:
>> msg1 = "A" & vbCrLf & "B"
>> code = "MsgBox """ & msg1 & """"
>> WScript.Echo code
>>
MsgBox "A
B"
>> Execute code
>>
Error Number: 1033
Error Description: Unterminated string constant
What you should do:
>> msg1 = """A"" & vbCrLf & ""B"""
>> WScript.Echo msg1
>>
"A" & vbCrLf & "B"
>> code = "MsgBox " & msg1 & ", 4096"
>> WScript.Echo code
>>
MsgBox "A" & vbCrLf & "B", 4096
>> Execute code
>>
>> <-- no news are good news; message displayed

Resources