Microsoft KB Archive/265261

= How To Improve Speed of Word Automation =

Article ID: 265261

Article Last Modified on 6/30/2004

-

APPLIES TO

 Microsoft Visual FoxPro 6.0 Professional Edition, when used with:  Microsoft Word 2000 Standard Edition

 Microsoft Word 95 Standard Edition 

-



This article was previously published under Q265261



SUMMARY
The bottleneck in automation is frequently the cross-process calls from Visual FoxPro to Word. The trick to speeding up automation is to reduce the number of cross-process calls. There are two techniques that you can use to do this: first, send as much of your text over in large chunks as you can, and second, find ways to do your formatting for you with one call, instead of several.



MORE INFORMATION
Compare the difference in speed between the two techniques in the following code sample: LOCAL loWord, loDoc, loRange, lnSeconds, lcStr, i

loWord = CREATEOBJECT(&quot;Word.Application&quot;) loWord.Visible = .T. loDoc = loWord.Documents.Add loRange = loDoc.Range

WITH loRange lnSeconds = SECONDS *!* Insert &quot;Text n&quot; using 1000 cross-process calls. FOR i = 1 TO 1000 .InsertAfter(&quot;Text &quot; + STR(i)) ENDfor ? &quot;Time for 1000 insertions = &quot; + ; STR(SECONDS - lnSeconds, 10, 4) + &quot; seconds&quot; lnSeconds = SECONDS *!* Build a string with 1000 occurrences of &quot;Text n&quot;, *!* but only go cross-process once. lcStr = &quot;&quot; FOR i = 1 TO 1000 lcStr = lcStr + &quot;Text &quot; + STR(i) ENDfor .InsertAfter(lcStr)

? &quot;Time for single insertion of 1000 items = &quot; + ; STR(SECONDS - lnSeconds, 10, 4) + &quot; seconds&quot; ENDwith

loWord.Quit(0) As you can see, the version that only calls across the boundary once is much faster.

Another way to speed things up is the ConvertToTable Method.
 * 1) DEFINE vfpCR CHR(13)
 * 2) DEFINE vfpTAB CHR(9)
 * 3) DEFINE wdSeparateByTabs 1
 * 4) DEFINE wdTableFormatColorful2 9

LOCAL loWord, loDoc, loRange, lcTable, lcField, i

CLEAR

loWord = CREATEOBJECT(&quot;Word.Application&quot;) loWord.Visible = .T.

loDoc = loWord.Documents.Add loRange = loDoc.Range

USE ? ALIAS SelTable

lcTable = &quot;&quot; FOR i = 1 TO FCOUNT lcTable = lcTable + FIELD(i) + vfpTab ENDfor lcTable = lcTable + vfpCR
 * !* Build a string consisting of all the fields in the table,
 * !* separated by tabs with the records separated by carriage
 * !* returns. The first line is the field names.

SCAN FOR i = 1 TO FCOUNT lcField = &quot;SelTable.&quot; + FIELD(i) lcTable = lcTable + TRANSFORM(&lcField) + vfpTAB ENDfor lcTable = lcTable + vfpCR ENDscan

loRange.InsertAfter(lcTable)
 * !* Then send the entire table to Word in one call and convert
 * !* it there.

loRange.ConvertToTable(wdSeparateByTabs,, , , wdTableFormatColorful2) There are several techniques that can reduce the cross-process calls for formatting. One way is to create macros that will do it for you. This article, however, demonstrates a slightly simpler case: applying pre-defined style sheets to the text.  Open a new document in Word.</li> Go to the Format menu, and choose &quot;Style...&quot;.</li> Click New, and name the style KBTitle.</li> Click the format command button and change the font size to 18pt, the paragraph alignment to centered, and the border to shadowed. Click OK.</li> Click New, and name the style KBHeader.</li> Change the font to bold, and the paragraph left indent to -0.5. Click OK.</li> There is no need to create a normal style here, since we already have one, but if you like, either create a KBNormal style (and change the code below) or edit the Normal style (which will affect the styles defined above, since they are based on it).</li> Click Close.</li> Go to File:Save As... and save this document as KBSamp.dot. You will need to change the &quot;Save as type&quot; to &quot;Document Template&quot;.</li>  Run the following code, making changes as needed to the path of the Word document if necessary.
 * 1) DEFINE wdParagraph 4
 * 2) DEFINE wdCollapseEnd 0
 * 3) DEFINE vfpCR CHR(13)

LOCAL loWord, loDoc, loRange

loWord = CREATEOBJECT(&quot;Word.Application&quot;) loWord.Visible = .T.

loDoc = loWord.Documents.Add(&quot;KBSamp.dot&quot;) && Specify path if needed.
 * !* Create the Word document based on the template we
 * !* created above.

loRange = loDoc.Range WITH loRange *!* These styles are all paragraph-based, so we need *!* to make sure we're on a new paragraph before changing *!* them. .Style = loDoc.Styles(&quot;KBTitle&quot;) .InsertAfter(&quot;Title&quot; + vfpCR) .Collapse(wdCollapseEnd)

.Style = loDoc.Styles(&quot;Normal&quot;) .InsertParagraphAfter .Collapse(wdCollapseEnd) .Style = loDoc.Styles(&quot;KBHeader&quot;) .InsertAfter(&quot;Header 1&quot; + vfpCR + vfpCR) .Collapse(wdCollapseEnd)

.Style = loDoc.Styles(&quot;Normal&quot;) && Or &quot;KBNormal&quot;, if defined above .InsertAfter(REPLICATE(&quot;You mean he's like that all the time? &quot;, 60)) .Collapse(wdCollapseEnd) ENDwith </li></ol>

<div class="references_section">