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 Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need to Read & Write to same file - can't find in documentation 4

Status
Not open for further replies.

tradle

Programmer
Jan 7, 2004
94
US
I've been given a task to write a script using VBScript, a language that I know not a darn thing about, to take 3 different strings or string collections and insert them into various places within all files in a given directory.

I've downloaded the Windows Script Documentation after reading several posts in this forum, but I'm afraid that I haven't yet found what I need to complete this task.

Essentially, this is what I need to do - open each file as a text stream, find a string within the file, insert a new string on a new line, and then do two more "search and insert" methods to repeat that behavior, and then save the file and move to the next one in the directory.

I've found how to either read or write to a file but not both within the same file. If there's some part of the Windows Script Documentation that you could point me to, that would be hugely helpful, especially if it contains some examples for me to model my code after.

Thanks!!!!!
 
You can't Read and Write (ie Update) a TextStream, but you can Read one and Write another in the same loop and then delete the old one and rename the new one.
Another way, if the files to process are not to big is to play with the ReadAll method, Close the file, Open it ForOutput and Write the modified data.
As you have the help file, take a look at ReadAll and Split.
Feel free to come back with what you have so far if you're stuck.

Hope This Help, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884
 
i was a novice at the time, some might say i still am ;-)

give you an idea about what PHV said, open one, open another, read line and writeline to other one.
you will want to have a look at the replace function perhaps

'Option Explicit
On Error Resume Next
Dim WshShell
Dim FSO
Dim WshSysEnv
Dim fscDrvEnv
Dim alluprogStr
Dim file2Open
Dim destFld
Dim ndataDir


Set WshShell = WScript.CreateObject("WScript.Shell")
Set FSO = Wscript.CreateObject("Scripting.FileSystemObject")
Set WshSysEnv = WshShell.Environment("SYSTEM")
fscDrvEnv = WshSysEnv("FSCDrive")

userprofStr = WshShell.ExpandEnvironmentStrings("%USERPROFILE%")


file2Open = fscDrvEnv & "\LOTUS\Notes\V5.08_DE\_SCRIPT\_FILES\notes.ini"
ndataDir = "\fscnotesdata"
file2Create = userprofStr & ndataDir & "\notes.ini"

'Wscript.Echo file2Create
'Wscript.Echo file2Open

If FSO.FileExists(file2Open) Then
Set tsIni = FSO.OpenTextFile(file2Open)
Else
'Wscript.Echo "cant find source notes.ini"
End If

Set newInifile = fso.CreateTextFile(file2Create, True)

newInifile.WriteLine "[Notes]"
Do While Not tsIni.AtEndOfStream
sLine = Trim(tsIni.ReadLine)

eqPos = InStr(1, sline, "=")
If (eqPos > 1) Then

endKeyPos = eqPos-1
'Wscript.Echo endKeyPos
sKey = Left(sLine, endKeyPos)

'Wscript.Echo eqPos
'Wscript.Echo sKey
Select Case sKey
Case "Directory"
sLine = sKey & "=" & userprofStr & ndataDir
'Wscript.Echo sLine & " from within dir scase"
newInifile.WriteLine sLine
Case "WinNTIconPath"
sLine = sKey & "=" & userprofStr & ndataDir & "\W32"
'Wscript.Echo sLine & " winicon scase"
newInifile.WriteLine sLine
Case "MailServer"
sLine = sKey & "="
'Wscript.Echo sLine & " mailserver scase"
newInifile.WriteLine sLine
Case "MailFile"
sLine = sKey & "="
'Wscript.Echo sLine & " mailfile scase"
newInifile.WriteLine sLine
Case Else
newInifile.WriteLine sLine
End Select
End If
Loop

newInifile.Close
tsIni.Close
 
Thanks so much for your help guys. I'm starting to run into a time crunch, so at this point I'm just trying to write 3 independent procedures that insert text into the files at different points. Thus far, I've had no luck whatsoever even getting ANYTHING into the files. My code that I've been playing with is below (should look really familiar from Microsoft's perspective), and I think that you'll see just how unfamiliar I am with both VB and VBScript.

Function TextStreamTest()
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim fso, f, ts
Set fso = CreateObject("Scripting.FileSystemObject")
'fso.CreateTextFile "test1.txt" Create a file.
Set f = fso.GetFile("c:\test.ps")
Set ts = f.OpenAsTextStream(ForWriting, TristateUseDefault)
ts.Write "%ADOContainsXMP SomeWhere"
ts.Close
Set ts = f.OpenAsTextStream(ForReading, TristateUseDefault)
TextStreamTest = ts.ReadLine
ts.Close
End Function
 
Hello tradle,

Your example is practically from the documentation. The only thing you have to know is that if you commented out the fso.createtextfile line, you have to make sure a file called "c:\test.ps" (whatever its contents, exists). After making sure that, just use wscript.echo outside the function, the main body, to watch the result.

wscript.echo TextStreamTest

regards - tsuji
 
Tsuji,

You're absolutely right - I took the script directly out of the documentation. I just wanted to see something - anything - happen. I'm facing a very tight deadline, and as such needed something to go the way I expected.

Essentially, I did see that the text that I wanted to see in the file got there. Essentially, I need to append to the file though, not replace it. I like the idea of reading the file into another one, and at a given point creating the new text. I just don't really know how to do that, and I also don't really know how in the world to define this such that it runs sequentially through all of the files in a given directory.

If anyone has the time to help me with this, I truly would appreciate it. I do realize that this is asking quite a lot, but I'm sort of out of time as far as going through the documentation goes.

Thanks!
 
tradle,

If you want to append, just use the switch ForAppending.
Code:
Set ts = f.OpenAsTextStream(ForAppending, TristateUseDefault)
- tsuji
 
Thanks, Tsuji -

Bit by bit I'm getting there. How do I affect all files in a given directory?

Guys, I'm still in quite a pinch - if anyone has the time to help, please let me know by emailing me at the address below...

timothy.radle@contractors.nationalcity.com

Thanks!
 
tradle,

Look through documentation: filesystemobject (fso). You'll find useful devices like getfolder(), folderobject.files collection etc.

If you care to explain the complete scope of the problem, but not bit-by-bit---because it would be very taxing on the patience, we might help you to sorte out the major scripting steps. Also do a search on the forum you'll recurrent answer to fso-related question.

regards - tsuji
 
Tsuji,

You're absolutelky right about everything that you said. I've been playing a buit, and have the following:

Function TextStreamTest()
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim fso, f, ts, ts2, ts3, ts4, ts5, ts6, ts7, ts8, ts9
Set fso = CreateObject("Scripting.FileSystemObject")
set source = fso.GetFolder("f:\advent\wrc\ps\12312003\test")
set fc = source.Files
for each file in fc
Set ts = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts.Write "%ADOContainsXMP:MainFirst"
ts.Close
Set ts2 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts2.Write "%%ControlNumber"
ts2.Close
Set ts3 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts3.Write "gsave"
ts3.Close
Set ts4 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts4.Write "Times-Roman 50 selectfont"
ts4.Close
Set ts5 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts5.Write "180 rotate"
ts5.Close
Set ts6 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts6.Write "-1 1 scale"
ts6.Close
Set ts7 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts7.Write "907 -1021 moveto"
ts7.Close
Set ts8 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts8.Write "(000000.0000.00.0000.000.000000000.000000) show"
ts8.Close
Set ts9 = f.OpenAsTextStream(ForAppending, TristateUseDefault)
ts9.Write "grestore"
ts9.Close
Next

End Function

WScript.echo TextStreamTest

Here is the full scope of my task:

For all files in source:

1. Add the string listed as ts in a new line after "%%LanguageLevel: 2".

2. Add the strings listed as ts2-ts9 in a new line after "% %%EndPageSetup"

3. Copy all text from an external file (main.txt) at a point just after "(%%[Page: 1]%%) =" - or simply create more textstring entries to handle the string values.

4. Replace the values in one of the strings from main.txt (which is an xml script) with values from a data file, tagging.txt.

That covers it. I've been trying to just get the data into the files and then manually move the data around to get through this task. At this point, with the code listed above, I'm receiving a definition issue at line 9(which is what I'm trying to work through now). I believe I failed to set up one of the variables that I used.

Thanks to Tsuiji and all who have contributed thus far!
 
Closer...

Function TextStreamTest()
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim fso, ts, ts2, ts3, ts4, ts5, ts6, ts7, ts8, ts9
Set fso = CreateObject("Scripting.FileSystemObject")
set source = fso.GetFolder("f:\advent\wrc\ps\12312003\test")
set fc = source.Files
Set StdOut = WScript.StdOut
for each file in fc
Set ts = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts.Write "%ADOContainsXMP:MainFirst" & VBNewLine
ts.Close
Set ts2 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts2.Write "%%ControlNumber" & VBNewLine
ts2.Close
Set ts3 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts3.Write "gsave" & VBNewLine
ts3.Close
Set ts4 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts4.Write "Times-Roman 50 selectfont" & VBNewLine
ts4.Close
Set ts5 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts5.Write "180 rotate" & VBNewLine
ts5.Close
Set ts6 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts6.Write "-1 1 scale" & VBNewLine
ts6.Close
Set ts7 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts7.Write "907 -1021 moveto" & VBNewLine
ts7.Close
Set ts8 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts8.Write "(000000.0000.00.0000.000.000000000.000000) show" & VBNewLine
ts8.Close
Set ts9 = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts9.Write "grestore" & VBNewLine
ts9.Close
Next

End Function

WScript.echo TextStreamTest

This runs fine - I just need to move stuff around, and add the remaining items to be added.

TRIAL BY FIRE!!!!!
 
why so many
Dim fso, ts, ts2, ts3, ts4, ts5, ts6, ts7, ts8, ts9
and therefore so many
file open and closes why not

Set ts = file.OpenAsTextStream(ForAppending, TristateUseDefault)
ts.Write "%ADOContainsXMP:MainFirst" & VBNewLine

ts.Write "%%ControlNumber" & VBNewLine

ts.Write "gsave" & VBNewLine


ts.Write "Times-Roman 50 selectfont" & VBNewLine

ts.Write "180 rotate" & VBNewLine

ts.Write "-1 1 scale" & VBNewLine
ts7.Write "907 -1021 moveto" & VBNewLine ts.Write "(000000.0000.00.0000.000.000000000.000000) show" & VBNewLine

ts.Write "grestore" & VBNewLine
ts.Close
 
Thanks, mrmovie - as I said, I was sure there is betterways of doing this.

Any advice for how I automate moving the text around?

Thanks!
 
'the below is more of less what i have already posted....


for each file in fc

Set tsIni = FSO.OpenTextFile(file)
file2create = "c:\temp\" & file.Name & "temp"
Set newInifile = fso.CreateTextFile(file2Create, True)

Do While Not tsIni.AtEndOfStream
sLine = tsIni.ReadLine
newIniFile.WriteLine sLine
Select Case sLine
Case "%%LanguageLevel: 2"
newInifile.WriteLine "%ADOContainsXMP:MainFirst" & VBNewLine
Case "% %%EndPageSetup"
newInifile.WriteLine "blaa"
newInifile.WriteLine "blaa blaa"
Case "(%%[Page: 1]%%) ="
newInifile.WriteLine "the rest of the other file?"
End Select

Loop

newInifile.Close
tsIni.Close
 
OHHHH - NOW I get it! You're the best, mrmovie!

1 task to go - replace 8 values.
 
tradle,

This is what I've come up with. I do all the coding as the info on the requirement digested, so may well have typos and logic flaws, and certainly not optimal coding. Up to here, only your (1) & (2) are coded. Test it see how it goes.
Code:
sFolder="f:\advent\wrc\ps\12312003\test"
Transform_signature sFolder

Sub Transform_signature (sFolderPath)
	Const ForReading = 1, ForWriting = 2, ForAppending = 8
	Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
	Dim fso, f, fc, ts
	Dim info, info2, sig, sig_len, sig2, sig2_len, sig3, sig3_len, pos

	info="%ADOContainsXMP:MainFirst"
	info2="%%ControlNumber" & vbcrlf & _
		"gsave" & vbcrlf & "Times-Roman 50 selectfont" & vbcrlf & _
		"180 rotate" & vbcrlf & "-1 1 scale" & vbcrlf & _
		"907 -1021 moveto" & vbcrlf & _
		"(000000.0000.00.0000.000.000000000.000000) show" & vbcrlf & _
		"grestore"

	sig="%%LanguageLevel: 2"
	sig_len=len(sig)
	sig2="%%%EndPageSetup"
	'sig2_len=len(sig2)
	'sig3=[Page: 1]%% ="
	'sig3_len=len(sig3)

	set fso = CreateObject("Scripting.FileSystemObject")

	on error resume next
	set source = fso.GetFolder(sFolderPath)
	if err<>0 then
		wscript.echo "Folder does not exists. Operation aborted."
		set fso=nothing
		exit sub
	end if
	on error goto 0

	set fc = source.Files
	for each f in fc
		'first pass <<<<<<<sig
		set ts=f.OpenAsTextStream(ForReading, TristateUseDefault)
		f_contents=ts.readall
		ts.close
		f_len=len(f_contents)
		if instr(1,f_contents,sig,1)<>0 then
			pos=instr(1,f_contents,sig,1)
			f_contents=left(f_contents,pos-1) & vbcrlf & info & vbcrlf & _
				 right(f_contents,f_len-pos-siglen+1)
		else
			wscript.echo "Cannot location " & sig & " in " & f.path"
		end if
		set ts=f.OpenAsTextStream(ForWriting, TristateUseDefault)
		ts.write f_contents
		ts.close
		'second pass <<<<<<<<sig2
		set ts=f.OpenAsTextStream(ForReading, TristateUseDefault)
		f_contents=ts.readall
		ts.close
		f_len=len(f_contents)
		if instr(1,f_contents,sig2,1)<>0 then
			pos=instr(1,f_contents,sig2,1)
			f_contents=left(f_contents,pos-1) & vbcrlf & info2 & vbcrlf & _
				 right(f_contents,f_len-pos-sig2len+1)
		else
			wscript.echo "Cannot location " & sig2 & " in " & f.path"
		end if
		set ts=f.OpenAsTextStream(ForWriting, TristateUseDefault)
		ts.write f_contents
		ts.close
	next
	set fc=nothing
	set fso=nothing
End Sub
regards - tsuji
 
Do While Not tsIni.AtEndOfStream
sLine = tsIni.ReadLine
sLine = Replace(sLine, "2find", "2replace")
newIniFile.WriteLine sLine
 
correction:

Do not comment out
sig2_len=len(sig2)
(I wanted to comment out sig3 related thing only.)

-tsuji
 
tradle and mrmovie,

I call a day off.

- tsuji
 
sorry for this multi thread tsuji.

you will prob be better off with

Do While Not tsIni.AtEndOfStream
sLine = tsIni.ReadLine
newIniFile.WriteLine Replace(sLine, "2find", "2replace")

that way it wont affect the select case statements
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top