Hey, Scripting Guy! Question

Hey, Scripting Guy! I saw your article about inserting text into a Microsoft Word bookmark. How can I do the same sort of thing in a text file?

-- LR

SpacerHey, Scripting Guy! AnswerScript Center

Hey, LR. You’ll have to forgive the Scripting Guy who writes this column if he seems a little less enthusiastic today than usual. As it turns out, he happened to see a commercial on TV right before he left for work this morning, and he’s been a little down-in-the-dumps ever since.

Note. Yes, for reasons the Scripting Guy who writes this column doesn’t fully understand, the TV in the Scripting Household must be on at all times. One time the Scripting Guy who writes this column was home by himself, and didn’t bother to turn the TV on. When the rest of the family returned home and saw that the TV was off, they immediately called 9-1-1, figuring that the Scripting Guy who writes this column must be dead. After all, if he wasn’t dead then why wouldn’t he have turned the TV on?

Anyway, in this commercial there’s a guy in a brand-new car, a car perched on the road. High in the air is a helicopter toting a similar new car. On the signal, the guy on the ground hits the gas pedal and starts racing down the road; meanwhile, the helicopter cuts the other car loose. The whole thing turns out to be a race: can the car on the ground accelerate quickly enough to avoid being hit by the car falling from the sky.

And, yes, it turns out that he can accelerate quickly enough to avoid getting squashed. Whew!

So why did this commercial make the Scripting Guy who writes this column so sad? Well, it wasn’t so much the commercial as it was the disclaimer accompanying that commercial:

Professional driver on a closed course. Do not attempt this at home.

Do not attempt this at home?!? Oh, great; now what is the Scripting Guy who writes this column supposed to do with his helicopter and the two new cars he just bought? If, like this Scripting Guy, you had hoped to spend the weekend dropping cars from helicopters, well, you might want to think about changing those plans.

Of course, that said, we aren’t convinced that car companies have the right to tell us what we can and can’t drop from our own helicopters. We’ll look into this and let you know what we find out.

In the meantime, you are more than welcome to insert text into a text file “bookmark” at home, at work, or anywhere else you might desire:

Const ForReading = 1
Const ForWriting = 2

Set objNetwork = CreateObject("Wscript.Network")
strUser = objNetwork.UserName

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForReading)

strText = objFile.ReadAll
objFile.Close

strText = Replace(strText, "[BOOKMARK #1]", Date)
strText = Replace(strText, "[BOOKMARK #2]", strUser)

Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForWriting)
objFile.WriteLine strText
objFile.Close

Before we discuss how the script works we should note that this script won’t work unless you have a text file that includes the specified “bookmarks” (which, in this case, simply refer to readily-identifiable chunks of text). For this example, we’re using a simple little text file (C:\Scripts\Test.txt) that looks like this:

This text file was updated on [BOOKMARK #1] by [BOOKMARK #2].

Our script is going to replace the text [BOOKMARK #1] with the current date, then replace the text [BOOKMARK #2] with the name of the logged-on user. Note that the text we used for the bookmarks is arbitrary; the only caveat here is that you need to make sure that the text you use is separate and distinct from any other text found in the file. For example, if the word computer appears multiple times in your file then using computer as a bookmark name would be a bad idea. Why? Because the script will replace every instance of the word computer – not just the bookmark text – with the new text. That’s why a unique construction such as [COMPUTER NAME] is a better way to go.

As for the script itself, we start out by defining a pair of constants – ForReading and ForWriting – that we’ll use when working with the file. We then use these two lines of code to create an instance of the Wscript.Network object, get the logon name of the logged-on user, and then store that value in a variable named strUser:

Set objNetwork = CreateObject("Wscript.Network")
strUser = objNetwork.UserName

Once that’s done we create an instance of the Scripting.FileSystemObject, then use the OpenTextFile method to open the file C:\Scripts\Test.txt for reading (note the constant ForReading passed as a method parameter):

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForReading)

With the text file open we use the ReadAll method to read the entire contents of the file into a variable named strText; we then immediately close the file:

strText = objFile.ReadAll
objFile.Close

So why do we close the file, especially since we want to replace the bookmarks in that file? Well, that’s due to the eccentricities of the FileSystemObject: this object lets you read from a file or write to a file, but it doesn’t let you do both operations at the same time. Having read from the file, we have to close and reopen it before we can write to it.

However, before we do that we need to modify the value of strText. That’s what these two lines of code are for:

strText = Replace(strText, "[BOOKMARK #1]", Date)
strText = Replace(strText, "[BOOKMARK #2]", strUser)

Good question: what are we doing with these two lines of code? Well, in the first line we’re using the Replace function to search through strText and look for the value [BOOKMARK #1]. If we find that value, we’re going to replace {BOOKMARK #1] with the current date (hence the VBScript Date function passed as parameter 3). In line 2, we’re going to look for the text [BOOKMARK #2] and, if found, replace it with the name of the logged-on user. In both cases, the resulting value will be stored in the variable strText.

What that means, of course, is that strText will then contain a “virtual text file” in which the bookmark designators have been replaced by the specified values. Because of that we can then replace the real text file (C:\Scripts\Test.txt) with this modified version. That’s what this block of code is for:

Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForWriting)
objFile.WriteLine strText
objFile.Close

When that’s done C:\Scripts\Test.txt will look like this:

This text file was updated on 2/15/2007 by kenmyer.

And there you have it.

As a public service, we should also note that there is another car commercial on TV these days, one which shows a car driving up and down a bunch of buildings. Before you get too excited, however, keep in mind that this commercial also includes a disclaimer, one that notes “This is a fantasy. Car cannot really drive on buildings.” Are they serious: a brand-new car and you can’t even drive on buildings with it? In that case, you can go ahead and remove the Scripting Guy who writes this column from the list of potential buyers. After all, he already has a car that can’t drive on buildings; why would he want another one?

Well, unless they’ll let him drop that car from a helicopter. Hmmm ….

Note. What, no mention of the 2007 Winter Scripting Games and how there’s still times to enter at least one event and win a Dr. Scripto Bobblehead doll or a copy of the book Windows PowerShell in Action? No, sorry, we aren’t even going to mention the Scripting Games today. After all, we don’t want people to think we’re pushy or anything.