{"id":56133,"date":"2008-02-25T23:16:00","date_gmt":"2008-02-25T23:16:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/02\/25\/hey-scripting-guy-how-can-i-find-a-word-in-a-document-and-change-the-background-color-of-the-paragraph-where-that-word-appears\/"},"modified":"2008-02-25T23:16:00","modified_gmt":"2008-02-25T23:16:00","slug":"hey-scripting-guy-how-can-i-find-a-word-in-a-document-and-change-the-background-color-of-the-paragraph-where-that-word-appears","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-find-a-word-in-a-document-and-change-the-background-color-of-the-paragraph-where-that-word-appears\/","title":{"rendered":"Hey, Scripting Guy! How Can I Find a Word in a Document and Change the Background Color of the Paragraph Where That Word Appears?"},"content":{"rendered":"<p><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Question\" border=\"0\" title=\"Hey, Scripting Guy! Question\" class=\"nearGraphic\" \/><\/p>\n<p>Hey, Scripting Guy! I have a bunch of reports and log files that are saved as Microsoft Word documents. I&rsquo;d like to be able to search for a specific word in one of these documents (e.g., the word &ldquo;Failed&rdquo;) and then change the background color of any paragraph that the target word appears in. How can I do that?<\/p>\n<p>&#8212; XD<\/p>\n<p><img decoding=\"async\" height=\"5\" width=\"5\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" alt=\"Spacer\" border=\"0\" \/><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Answer\" border=\"0\" title=\"Hey, Scripting Guy! Answer\" class=\"nearGraphic\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><img decoding=\"async\" height=\"288\" width=\"120\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" align=\"right\" alt=\"Script Center\" border=\"0\" title=\"Script Center\" class=\"farGraphic\" \/><\/a><\/p>\n<p>Hey, XD. You know, a lot of people have written in over the course of the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/default.mspx\"><b>2008 Winter Scripting Games<\/b><\/a> to say things like this: &ldquo;I bet you guys have a really cool automated way of testing scripts. Any chance you could share that procedure with us?&rdquo; Well, to tell you the truth, we <i>could<\/i> share that procedure with you, except for one thing: we don&rsquo;t actually <i>have<\/i> such a procedure.<\/p>\n<p>Not that we wouldn&rsquo;t <i>like<\/i> to have one, mind you, and not that we don&rsquo;t have an idea as to how an automated script tester might work. However, there are a couple of problems that make automated testing, at least for the moment, impossible. For one thing (and for reasons we won&rsquo;t get into) we aren&rsquo;t allowed to have an online submission form for the Games; instead, all the entries are sent via plain old email. That makes automated testing really hard. Why? Well, to begin with, people don&rsquo;t always format their emails correctly. Some people send in entries that look like this:<\/p>\n<pre class=\"codeSample\">Ken Myer<br \/>USA<\/pre>\n<p>While others send in entries that look like this:<\/p>\n<pre class=\"codeSample\">Ken Myer<br \/>USA<\/pre>\n<p>It&rsquo;s easy for us to figure out which is the name and which is the country, but not so easy for the computer.<\/p>\n<p>Needless to say, Scripting Guys are <i>way<\/i> smarter than computers.<\/p>\n<p>We also run into major line break issues with email. For example, you might have a script that looks like this:<\/p>\n<pre class=\"codeSample\">For x = 1 to 100<br \/>&nbsp;&nbsp;&nbsp; Wscript.Echo x<br \/>Next<\/pre>\n<p>Unfortunately, by the time it gets emailed the script might look like this:<\/p>\n<pre class=\"codeSample\">For x = 1 to 100 Wscript.Echo x Next<\/pre>\n<p>Again, the Scripting Guys can &ndash; usually &ndash; figure out where the line breaks belong. (And yes, we dutifully put in all the missing line breaks before we test a script.) An automated tester would simply fail this script.<\/p>\n<p>Hmmm, spend 10 minutes trying to figure out where line breaks go in a script, or spend 1 second marking a script as having failed. Maybe the Scripting Guys <i>aren&rsquo;t<\/i> smarter than computers after all &hellip;.<\/p>\n<p>Oh, and then there are the signatures that get automatically attached to an email and &ndash; well, you get the idea. An online submission form would help eliminate most of the problems. Without one &hellip;.<\/p>\n<p>The other problem with fully-automated testing is that the Scripting Guys are soft-hearted; computers are not. Sometimes we&rsquo;ll get a script that looks like this:<\/p>\n<pre class=\"codeSample\">For x = 1 to 100<br \/>&nbsp;&nbsp;&nbsp; Wscript.Echo x<br \/>Netx<\/pre>\n<p>It&rsquo;s obvious what happened here; the script writer simply mistyped the word <i>Netx<\/i>. A computer would mark this script as having failed. For a simple problem like this (or a path that says <i>C:\\Script\\Test.txt<\/i> when it&rsquo;s supposed to say <i>C:\\<\/i><b><i>Scripts<\/i><\/b><i>\\Test.txt<\/i>), well, the Scripting Guys will usually fix the problem and then try the script again.<\/p>\n<p>We even give people a pass if we say &ldquo;Display the answer using two decimal places&rdquo; and they instead display the answer using four decimal places. Or if they display the answer in a message box when we said, &ldquo;Please write the answer to the command window.&rdquo; Etc. etc.<\/p>\n<p>But don&rsquo;t tell anyone. After all, we have a reputation for being ruthless and cold-blooded, and we&rsquo;d hate for people to know the truth. <\/p>\n<p>Anyway, if you&rsquo;re one of those people wondering about the Scripting Guys and their automated testing system, well, there&rsquo;s your answer. And if you&rsquo;re one of those people wondering about how you can change the background color of a paragraph if a specified word appears somewhere in that paragraph, well, here&rsquo;s <i>your<\/i> answer:<\/p>\n<pre class=\"codeSample\">Const wdTexture10Percent&nbsp; = 100<\/pre>\n<pre class=\"codeSample\">Set objWord = CreateObject(\"Word.Application\")<br \/>objWord.Visible = True<\/pre>\n<pre class=\"codeSample\">Set objDoc = objWord.Documents.Open(\"C:\\Scripts\\Test.doc\")<\/pre>\n<pre class=\"codeSample\">Set colParagraphs = objDoc.Paragraphs<\/pre>\n<pre class=\"codeSample\">For Each objParagraph in colParagraphs<br \/>&nbsp;&nbsp;&nbsp; strText = objParagraph.Range.Text<br \/>&nbsp;&nbsp;&nbsp; If InStr(strText, \"Failed\") Then<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objParagraph.Shading.Texture = wdTexture10Percent <br \/>&nbsp;&nbsp;&nbsp; End If<br \/>Next<\/pre>\n<p>No doubt some of you are looking at this script and thinking, &ldquo;Wait a second. That&rsquo;s not going to work; they&rsquo;re not even using Word&rsquo;s Find object to find the target text.&rdquo; That&rsquo;s true; we&rsquo;re <i>not<\/i> using Word&rsquo;s Find object to find the target text. Why not? Well, the Find object is quite good at finding text, and it&rsquo;s pretty darn good at letting you modify the found text; what it <i>isn&rsquo;t<\/i> good at is letting you work with the surrounding text. Is that a problem? You bet it is. The Find object would make it easy for us to change the background color of the target text itself (that is, the word <i>Failed<\/i>); however, it would <i>not<\/i> make it easy for us to change the background color of the entire paragraph where that word appears. <i>That&rsquo;s<\/i> the problem.<\/p>\n<p>Because of that we decided to take another approach. In this script, we return a collection of all the paragraphs in the document, then search each paragraph, one-by-one, to see if it contains the word <i>Failed<\/i>. If it does, well, at that point it&rsquo;s easy to change the background color of the paragraph; after all, we&rsquo;re already working with that paragraph. And if it <i>doesn&rsquo;t<\/i> contain the target word, hey, no big deal; we simply go on and check the next paragraph in the collection.<\/p>\n<p>To get all that to work we start by defining a constant named wdTexture10Percent and setting the value to 100; that&rsquo;s going to allow us to set the background color (technically, the <b>Shading.Texture<\/b> property) to 10% grey. After defining the constant, we create an instance of the <b>Word.Application<\/b> object and then set the <b>Visible<\/b> property to True; that gives us a running instance of Microsoft Word that we can see onscreen. After <i>that<\/i>, we use the following line of code to open the file C:\\Scripts\\Test.doc:<\/p>\n<pre class=\"codeSample\">Set objDoc = objWord.Documents.Open(\"C:\\Scripts\\Test.doc\")<\/pre>\n<p>With the document open we can retrieve a collection of all the paragraphs in that document simply by creating an object reference to the <b>Paragraphs<\/b> property:<\/p>\n<pre class=\"codeSample\">Set colParagraphs = objDoc.Paragraphs<\/pre>\n<p>At this point, we&rsquo;re ready to have to some <i>real<\/i> fun.<\/p>\n<p>Oh, never mind; we forgot that we have to finish this column. And then test about 3,000 more Scripting Games submissions. But <i>then<\/i> we&rsquo;ll be ready to have some real fun.<\/p>\n<p>In order to complete the task (and finish this column) we set up a For Each loop that enables us to walk through all the paragraphs in the document. Inside that loop, we grab the value of the paragraph&rsquo;s <b>Range.Text<\/b> property and store it in a variable named strText:<\/p>\n<pre class=\"codeSample\">strText = objParagraph.Range.Text<\/pre>\n<p>As you probably guessed, the Text property stores all the text that appears in the paragraph. With the text safely tucked into the variable strText we can then use VBScript&rsquo;s <b>InStr<\/b> method to see if the target word <i>Failed<\/i> appears anywhere in that text:<\/p>\n<pre class=\"codeSample\">If InStr(strText, \"Failed\") Then<\/pre>\n<p>If it doesn&rsquo;t, well, like we said, no big deal: we simply loop around and repeat the process with the next paragraph in the collection. If the target word <i>does<\/i> appear in the paragraph then we use this line of code to set the paragraph&rsquo;s background color to 10% grey:<\/p>\n<pre class=\"codeSample\">objParagraph.Shading.Texture = wdTexture10Percent<\/pre>\n<p>And then it&rsquo;s back to the top of the loop, where we try again with the next paragraph in the document. When all is said and done, we should have a document that looks something like this:<\/p>\n<p><img decoding=\"async\" height=\"336\" width=\"465\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/wdshading.jpg\" alt=\"Spacer\" border=\"0\" \/><\/p>\n<p>That should do it, XD. Give it a try and see for yourself.<\/p>\n<p>So how <i>do<\/i> the Scripting Guys test scripts for the Scripting Games? Well, believe it or not, the process works like this: We get an email from someone, then we copy the code from that email and paste it into a script file. We then run the script and see what happens. If the script fails with an error message we check to see if the problem was due to a line break issue or a simple typo. We then try again. This process continues until the script succeeds or until we decide that the script has failed. (Usually we keep trying until we get the script to run without an error. At that point, if the script fails to carry out the appointed task, we give the entry a 0.)<\/p>\n<p>And then we repeat the process with the next script. Thus far we&rsquo;ve tested over 3,000 scripts in this manner, with another 3,000 sitting in the Inbox waiting their turn.<\/p>\n<p>And yes, as a matter of fact that <i>is<\/i> every bit as fun as it sounds. But anything for the Scripting Games, right? <\/p>\n<p>Although, we must admit, we won&rsquo;t be <i>entirely<\/i> heartbroken when the Games are over. <\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" class=\"dataTable\" id=\"EDAAC\">\n<thead><\/thead>\n<tbody>\n<tr valign=\"top\" class=\"record\">\n<td>\n<p class=\"lastInCell\"><b>Note<\/b>. Speaking of which, the Games are <i>far<\/i> from over. (Oh, how &hellip; nice &hellip;.) The Games run through Monday, March 3<sup>rd<\/sup>, which means you have plenty of time to submit entries. And, not-so-incidentally, win some <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/games08\/prizes.mspx\"><b>fantastic prizes<\/b><\/a>.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a bunch of reports and log files that are saved as Microsoft Word documents. I&rsquo;d like to be able to search for a specific word in one of these documents (e.g., the word &ldquo;Failed&rdquo;) and then change the background color of any paragraph that the target word appears in. How [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[84,49,3,5],"class_list":["post-56133","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-microsoft-word","tag-office","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have a bunch of reports and log files that are saved as Microsoft Word documents. I&rsquo;d like to be able to search for a specific word in one of these documents (e.g., the word &ldquo;Failed&rdquo;) and then change the background color of any paragraph that the target word appears in. How [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=56133"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56133\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=56133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=56133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=56133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}