{"id":63303,"date":"2008-01-11T21:44:00","date_gmt":"2008-01-11T21:44:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/01\/11\/hey-scripting-guy-how-can-i-tally-all-the-items-in-a-microsoft-word-document\/"},"modified":"2008-01-11T21:44:00","modified_gmt":"2008-01-11T21:44:00","slug":"hey-scripting-guy-how-can-i-tally-all-the-items-in-a-microsoft-word-document","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-tally-all-the-items-in-a-microsoft-word-document\/","title":{"rendered":"Hey, Scripting Guy! How Can I Tally All the Items in a Microsoft Word Document?"},"content":{"rendered":"<p><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hey, Scripting Guy! We have an application that repeatedly runs a test and writes the result of each test pass to a Microsoft Word document. Periodically I\u2019d like to be able to use a script to tally up the number of times a test passed, the number of times a test failed, and the number of times a test failed to run. How can I write a script like that?<\/p>\n<p>&#8212; GK<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><img decoding=\"async\" class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\" \/><\/a> <\/p>\n<p>Hey, GK. Before we begin we\u2019d like to take a moment to address the Scripting Son. Hey, Scripting Son: ha!<\/p>\n<table class=\"dataTable\" id=\"E5C\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. What\u2019s that? Really? Wow. We always assumed that any time parents had something to tell their children they did it through a daily scripting column. Guess you learn something new every day, huh?<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>If you\u2019re wondering what that\u2019s all about (a surprisingly common occurrence for readers of this column) every now and then the Scripting Son will tell the Scripting Dad a story about one of his friends. \u201cYou know, you have some weird friends,\u201d the Scripting Dad will say. \u201cWell, at least I <i>have<\/i> friends,\u201d the Scripting Son will shoot back. To which the Scripting Dad will say \u2013 well, not much. After all, when you\u2019re a career-driven workaholic like the Scripting Guy who writes this column, well, who has time to make friends?<\/p>\n<p>Now, however, the Scripting Guy who writes this column has the perfect rejoinder to the Scripting Son: ha!<\/p>\n<p>As of this writing, the Scripting Guys group on Facebook has 517 members. No friends? How about <i>517<\/i> friends, Scripting Son? That\u2019s way more members than the interestingly-named <i>I Went School At Brokington College<\/i>, which only has 70 members. And while we still lag behind <i>Keith Olbermann is Our Edward R. Murrow<\/i> (646 members), well, better keep looking over your shoulder, Keith. The Scripting Guys are gaining on you.<\/p>\n<table class=\"dataTable\" id=\"E1D\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. How are the Scripting Guys doing in their <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/dec07\/hey1203.mspx\"><b>Facebook battle<\/b><\/a> against MSDN and TechNet? We\u2019re <i>so<\/i> glad you asked that question. At the moment, MSDN has 99 members and TechNet has 56. Hey, MSDN and TechNet: ha!<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>So why do the Scripting Guys have so many friends? Well, we\u2019d like to think it\u2019s because of our charming personalities. More likely, however, it\u2019s because we have scripts that can tally the items found in a Microsoft Word document:<\/p>\n<pre class=\"codeSample\">Set objWord = CreateObject(\"Word.Application\")\nobjWord.Visible = True\n\nSet objDoc = objWord.Documents.Open(\"C:\\Scripts\\Test.doc\")\nSet colParagraphs = objDoc.Paragraphs\n\nFor Each objParagraph in colParagraphs\n    strText = objParagraph.Range.Text\n    intLength = Len(strText)\n    strText = Left(strText, intLength - 1)\n    Select Case strText \n        Case \"Passed\" intPassed = intPassed + 1\n        Case \"Failed\" intFailed = intFailed + 1\n        Case \"Not run\" intNotRun = intNotRun + 1\n    End Select\nNext\n\nWscript.Echo \"Passed: \" &amp; intPassed\nWscript.Echo \"Failed: \" &amp; intFailed\nWscript.Echo \"Not run: \" &amp; intNotRun\n<\/pre>\n<p>As you can see, we kick things off by creating an instance of the <b>Word.Application<\/b> object and then setting the <b>Visible<\/b> property to True; that gives us a running instance of Microsoft Word that we can see onscreen. <\/p>\n<table class=\"dataTable\" id=\"EYE\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p><b>Note<\/b>. In our sample scripts we typically make Word visible simply so you know for sure that <i>something<\/i> is happening. However, this script works just fine even if Word is <i>never<\/i> visible on screen. To keep Word from appearing, comment out the line of code that sets the Visible property to True, and then add this line of code to the end of the script:<\/p>\n<pre class=\"codeSample\">objWord.Quit\n<\/pre>\n<p>This ensures that Word properly terminates after the script finishes doing its thing.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Once we have an instance of Word up and running we use the <b>Open<\/b> method to open the document C:\\Scripts\\Test.doc. We then use this line of code to return a collection of all the paragraphs in that document:<\/p>\n<pre class=\"codeSample\">Set colParagraphs = objDoc.Paragraphs\n<\/pre>\n<p>Why do we want a collection of all the paragraphs in the document? Well, as GK noted in her email, each \u201cparagraph\u201d in the document is simply a line indicating whether a test pass succeeded, did not succeed, or failed to run. In other words, it looks something like this:<\/p>\n<pre class=\"codeSample\">Passed\nFailed\nFailed\nPassed\nFailed\nNot run\n<\/pre>\n<p>By grabbing all the paragraphs and looking at the text of each one, we can easily count the number of times a test passed, the number of times it failed, and the number of times it did not run. Which is just exactly what we\u2019re going to do next.<\/p>\n<p>With our collection of paragraphs safely in hand, our next step is to set up a For Each loop to loop through each item in this collection:<\/p>\n<pre class=\"codeSample\">For Each objParagraph in colParagraphs\n<\/pre>\n<p>The first thing we do inside this loop is grab the value of the <b>Range.Text<\/b> property; as you might have guessed, this returns the text for each paragraph:<\/p>\n<pre class=\"codeSample\">strText = objParagraph.Range.Text\n<\/pre>\n<p>We then encounter these two lines of code:<\/p>\n<pre class=\"codeSample\">intLength = Len(strText)\nstrText = Left(strText, intLength - 1)\n<\/pre>\n<p>What are these two lines for? Well, the \u201ctext\u201d for each paragraph also includes an end-of-paragraph mark that makes it harder for us to pinpoint the actual text. And what do you do if something causes you a problem? That\u2019s right: you get rid of it altogether. <i>(Editor\u2019s Note: This doesn\u2019t always work, which should be obvious by the fact that there still <\/i>is<i> a Scripting Editor. Ha!)<\/i> That\u2019s exactly what we\u2019re doing here. In the first line, we use the <b>Len<\/b> function to determine the length (number of characters) in the string strText. In the second line, we use the <b>Left<\/b> function to grab everything except the last character (the length of the string minus 1). For example, suppose strText equals this, with the asterisk representing that troublesome last character:<\/p>\n<pre class=\"codeSample\">Passed*\n<\/pre>\n<p>Here\u2019s what strText will be equal to after we execute those two lines of code:<\/p>\n<pre class=\"codeSample\">Passed\n<\/pre>\n<p>Much better.<\/p>\n<p>The rest is easy. Our next step is to set up a Select Case block based on the value of strText:<\/p>\n<pre class=\"codeSample\">Select Case strText \n    Case \"Passed\" intPassed = intPassed + 1\n    Case \"Failed\" intFailed = intFailed + 1\n    Case \"Not run\" intNotRun = intNotRun + 1\nEnd Select\n<\/pre>\n<p>As you can see, if strText is equal to <i>Passed<\/i> we increment a counter variable named intPassed by 1. Because intPassed has never been used or declared, that means it starts life with a value of 0; that also means that, the first time we encounter the word <i>Passed<\/i>, we add 1 to the variable, making it equal to 1. If strText is equal to <i>Failed<\/i> we increment a variable named intFailed, and if strText is equal to <i>Not run<\/i> we increment a variable named intNotRun. Could it <i>be<\/i> any easier?<\/p>\n<p>All that\u2019s left at that point is to echo back the results of our tally:<\/p>\n<pre class=\"codeSample\">Wscript.Echo \"Passed: \" &amp; intPassed\nWscript.Echo \"Failed: \" &amp; intFailed\nWscript.Echo \"Not run: \" &amp; intNotRun\n<\/pre>\n<p>That final report will look something like this:<\/p>\n<pre class=\"codeSample\">Passed: 12\nFailed: 9\nNot run: 6\n<\/pre>\n<p>That\u2019s all there is to it.<\/p>\n<p>By the way, in case you\u2019re wondering, the Scripting Son has 100 friends on his MySpace page. By now you should know what we have to say about <i>that<\/i>. <\/p>\n<table class=\"dataTable\" id=\"ENH\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. You say that you\u2019d like to jump on the bandwagon, too? We\u2019d love to have you; <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/newswire\/facebook.jpg\"><b>click here<\/b><\/a> for details on joining the Scripting Guys Facebook group.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! We have an application that repeatedly runs a test and writes the result of each test pass to a Microsoft Word document. Periodically I\u2019d like to be able to use a script to tally up the number of times a test passed, the number of times a test failed, and the number [&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-63303","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! We have an application that repeatedly runs a test and writes the result of each test pass to a Microsoft Word document. Periodically I\u2019d like to be able to use a script to tally up the number of times a test passed, the number of times a test failed, and the number [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63303","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=63303"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63303\/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=63303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}