June 27th, 2007

How Can I Search For Red Text in a Microsoft Word Document?

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a huge document that features occasional lines printed in red. How can I extract just the lines that are printed in red?

— GH

SpacerHey, Scripting Guy! AnswerScript Center

Hey, GH. To begin with, the Scripting Guy who writes this column would like to say just one thing: never mind. In yesterday’s column the Scripting Guy who writes this column bemoaned the fact that nothing interesting had happened to him in a long, long time. So guess what? Shortly after finishing the column something interesting did happen to him. And, as it turns out, interesting things aren’t always all that much fun.

So what did happen? Well, if he owned a Rolls Royce, he would say that his car experienced a “failure to proceed.” Surprisingly enough, however, the Scripting Guy who writes this column doesn’t own a Rolls Royce. Therefore, he would say this: his car just plain died.

If there’s any solace to be taken in having a dead car, at least there’s this: the death was quick and painless. One moment the Scripting Guy was driving along without a care in the world, the next moment he was driving along without a car in the world. Pulling out of the grocery store parking lot the engine suddenly stopped running and would not restart, period. And before you ask, yes, the radio, the power windows, and all the other electrical stuff continued to work just fine; it was just the engine that no longer worked. Unfortunately, though, an engine that no longer works is about all it takes to bring a car to a dead stop. Talk about a single point of failure, huh?

The preliminary diagnosis is that the car has a broken ECM. The Scripting Guy who writes this column doesn’t know much about ECMs; he didn’t even know what ECM stood for. Since then, however, he has learned at least two things: 1) the ECM is the central computing system that controls pretty much everything in the car, and 2) replacing an ECM will cost at least $2,000.

Hurray!

Anyway, if you’ve been busy trying to think up ways to make this Scripting Guy’s life more interesting, well, thanks but no thanks. Granted, a life where nothing interesting ever happens can be a bit boring at times. Nevertheless, it’s a heck of a lot cheaper.

In fact, from now on the Scripting Guy who writes this column is going to limit his interests to scripting (something his manager has been trying to get him to do for years). For example, wouldn’t it be interesting to have a script that could extract only the lines in a Word document that were printed in red? Let’s see if we can determine just how interesting that would be:

Const wdColorRed = 255

Set objWord = CreateObject(“Word.Application”) objWord.Visible = True

Set objDoc = objWord.Documents.Open(“C:\Scripts\Test.doc”) Set objSelection = objWord.Selection

objSelection.Find.Forward = True objSelection.Find.Format = True objSelection.Find.Font.Color = wdColorRed

Do While True objSelection.Find.Execute If objSelection.Find.Found Then Wscript.Echo objSelection.Text Else Exit Do End If Loop

Gosh; that’s way more interesting than a broken ECM, isn’t? As you can see, we start out by defining a constant named wdColorRed and setting the value to 255; we’ll use this constant later on to tell Word the color of the text we’re searching for. What if you wanted to search for text of a different color? Tell you what: send us, oh, say, $2000, and we’ll help you out with that.

Or, better yet, seeing as how the Scripting Editor is giving us that look again, don’t send us $2000; instead just check out the wdColor enumeration in the Microsoft Word VBA Language Reference.

Note. But if you do feel like sending us $2000, well ….

After defining the constant wdColorRed we next create an instance of the Word.Application object and then set the Visible property to true; that gives us a running instance of Word that we can view onscreen. We then use these two lines of code to open the document C:\Scripts\Test.doc and create an instance of the Word Selection object, the object we need in order to search the document:

Set objDoc = objWord.Documents.Open(“C:\Scripts\Test.doc”)
Set objSelection = objWord.Selection

Cool; this just keeps getting more and more interesting, doesn’t it?

Our next step is to configure the properties of the Find object, which happens to be a child object of the Selection object. That’s what these three lines of code are for:

objSelection.Find.Forward = True
objSelection.Find.Format = True
objSelection.Find.Font.Color = wdColorRed

What does all this mean? Well, to begin with, setting the Forward property to True tells the script to search forward through the document; in other words, start searching at the beginning of the document and continue on through the end of the document. Setting the Format property to True tells the script that we want to search for formatting in addition to (or, in this case, instead of) text. Finally, we specify which formatting we’re interested in: fonts that have a color equal to the constant wdColorRed (Font.Color).

At this point we’re ready to start searching. To that end, the first thing we do is set up a Do While loop that continues to run as long as True is equal to True. (That sounds like an endless loop, but don’t worry: we’ll show you a way out in a minute.) Inside that loop we then use the following command to start the search process and ferret out the first instance of red text:

objSelection.Find.Execute

So how will we know if the Find object actually finds any red text? That’s easy; in that case, the value of the Found property will be True:

If objSelection.Find.Found Then

If the Found property is equal to True then the found text (that is, the red text) will automatically be selected; in turn, all we have to do to report what we found is to echo back the Text property of our Selection object:

Wscript.Echo objSelection.Text

And then we simply loop around, call the Execute method, and then search for the next instance of our target text. This process continues until the Found property is no longer True, which can mean only one thing: there’s no more red text left to find. When that happens we simply call the Exit Do statement and exit our not-so-endless loop:

Exit Do

As you just saw, this script merely echoes back the found text. In his email, though, GH asked how he could go about extracting this text and adding it to a brand-new Word document. Here’s a revised script that can do just that:

Const wdColorRed = 255

Set objWord = CreateObject(“Word.Application”) objWord.Visible = True

Set objDoc = objWord.Documents.Open(“C:\Scripts\Test.doc”) Set objSelection = objWord.Selection

Set objDoc2 = objWord.Documents.Add() Set objSelection2 = objWord.Selection

objSelection.Find.Forward = True objSelection.Find.Format = True objSelection.Find.Font.Color = wdColorRed

Do While True objSelection.Find.Execute If objSelection.Find.Found Then strText = strText & objSelection.Text & vbCrLf Else Exit Do End If Loop

objSelection2.TypeText strText

So what’s the difference between this script and the first script we showed you? Well, for one thing, this script features two Word documents: C:\Scripts\Test.doc (with an object reference of objDoc) and a new document created using the Add method (with an object reference of objDoc2):

Set objDoc2 = objWord.Documents.Add()

In addition, this time around we don’t echo back the text as we find it; instead, we store all the found text in a variable named strText (tacking a carriage return-linefeed onto the end of each segment):

strText = strText & objSelection.Text & vbCrLf

And then, last but surely not least, after we’ve finished searching Test.doc we use the TypeText method to add all the found text to our second document:

objSelection2.TypeText strText

And there you have it.

As for the ECM, well, the Scripting Guy who writes this column is already learning way more about ECMs than he ever wanted to know (starting with the fact that ECM is apparently short for Electronic Control Module). For example, Volkswagen Passats can’t be hot-wired; you have to start them with the key fob because the fob sends a signal to the ECM that says, “It’s OK; go ahead and start the car.” Unfortunately, though, the ECM will sometimes malfunction and refuse to start the car even though you have the key fob. (And yes, this unnecessary layer of security does remind us of something. But we’re not going to say what.) At other times the ECM can malfunction and apply a “virtual speed governor” that limits the car to a top speed of 5 miles an hour. Needless to say, that’s bad.

Well, unless you live in Seattle. With the traffic we have around here, you rarely reach a top speed of 5 miles an hour anyway.

At any rate, we’ll keep you posted about this … interesting … new development. And remember, if you do want to send us $2,000 go right ahead. Just make sure you address the envelope to The Scripting Guy Who Writes That Column and not to The Scripting Editor. Thanks!

Author

0 comments

Discussion are closed.