Multiple Word documents = Multiple Instances of Word?

D

Dave

Apologies for the newbie question. I have created a vb.net program for
my company that is designed to work with Word Templates (about forty of
them that we commonly use) that are selected by the user and populated
(with info from an Access database) at run-time, then saved as Word
documents. The program I have coded works fine -- it does what I need
it to do. But it has two problems: (1) it runs very slowly, and (2) it
does not seem to "let go" of the Word documents after it has created
them (the documents can be opened and printed, but not deleted, for
example), at least not until the program is run again and it takes hold
of the new batch of documents. The backbone of the program is about
forty procedures that all look like this:

Public Sub PopulateLtrPayTaxBill()
Dim wrdApp As New Microsoft.Office.Interop.Word.Application
Dim doc12 As New Microsoft.Office.Interop.Word.Document
Try
doc12 = wrdApp.Documents.Add(Template:="C:\Documents and
Settings\David\Application Data\Microsoft\Templates\FRMltr CityTown pay
tax bill.dot")
doc12.Activate()
Catch ex As COMException
MessageBox.Show("Error accessing Ltr Pay Tax Word
document.")
End Try

'Then there are many lines of code that set bookmarks in the template
document to values that have either been entered by the user or are
extracted from the database. I am leaving these out to save space.

SaveTheDocument(doc12, "ltr " & ThisCollector.CollCity & " pay
tax bill.doc")

'This SaveTheDocument procedure just checks to see whether a new client
folder has to be created, creates one if necessary, then saves the
document created from the Word template as a Word document with the
specified name

wrdApp.Quit()
MessageBox.Show("Done. Ltr Pay Tax Bill Saved to ClientFiles\"
& foldername)
End Sub


I have two main questions. The first one is, am I wasting a ton of
processing capacity by creating a new instance of Word each time I need
to create a new document from a template? Ordinarily, a user of this
program is selecting 5-6 documents that they want to create at one time
(then terminating the program). Would I be better off creating a
single instance of Word.Application every time my program runs, and
simply having each procedure create a new Word.Document object? The
second question is, am I doing enough to "clean up" after this
procedure runs? Should I be setting wrdApp to Nothing? Should I be
running a more comprehensive cleanup procedure every time I "open" and
"close" a Word Document, or the Word Application? Any advice people
have as to how I could improve/streamline the structure of this program
would be very welcome.

Dave
 
G

Guest

Dave,
I've a .Net app does reporting to word documents. I haven't fixed all of
the nuisances with slow operation but what I've found works for cleaning up
is this (sorry if I'm including too much code):

Dim inVal As Object
inVal = New System.Runtime.InteropServices.DispatchWrapper(Nothing)

Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim wdTbl As Word.Table
Dim wdPara As Word.Paragraph
Dim wdRng As Word.Range

oTemplt = "your template name"

'Create Report Name for this month
oRept = "your report name" & ".DOC"

'Open the report template
wdApp = CType(CreateObject("Word.Application"), Word.Application)
wdApp.Visible = False
wdDoc = wdApp.Documents.Open(oTemplt, , True)
wdRng = wdDoc.Bookmarks.Item("DocHeader").Range
wdRng.Text = "Open Escalations"
wdRng = wdDoc.Bookmarks.Item("DocDate").Range
wdRng.Text = Format(Today(), "MMM dd, yyyy")
wdDoc.SaveAs(oRept) 'Save with the new
report name

.... document generation ....


'Save & Close the Word Document
With wdDoc
.Save()
.Close()
End With
wdApp.Visible = True
wdApp.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(wdApp)

wdApp = Nothing
wdDoc = Nothing
wdPara = Nothing
wdRng = Nothing
wdTbl = Nothing

Hope this helps a bit
 
D

Dave

Thanks Taras! I think this may be the code I'm missing -- particularly
"System.Runtime.InteropServices.Marshal.ReleaseComObject(wdApp)"

Dave
 
D

Dave

Thanks Taras! That's definitely more closing-out and cleaning-up than
I've been doing. I will look into this line in particular, which looks
on the face of it like it may solve the problem I've been having with
the program not "letting go" --
System.Runtime.InteropServices.Marshal.ReleaseComObject(wdApp)

Dave
 
C

Charles Law

Hi Taras

I have found that the following works well, and closes Word afterwards. It
also speeds operations up quite a bit over the default.

<snip>
Dim m_WordApp As Word.Application
Dim m_Document As Word.Document
Dim m_TotalParagraphs As Integer

m_WordApp = New Word.Application

Try
m_Document = m_WordApp.Documents.Open(CType("YourFile.doc", Object),
ReadOnly:=True, AddToRecentFiles:=False, Visible:=False)

' Set options to improve speed
With m_Document
.AcceptAllRevisions()
.ShowGrammaticalErrors = False
.ShowSpellingErrors = False
.SpellingChecked = True
.GrammarChecked = True

With .Application
.ScreenUpdating = False
.Options.Pagination = False
End With
End With

' Reformat the document
m_Document.Repaginate()

' Cache the number of paragraphs here, if needed
m_TotalParagraphs = m_Document.Paragraphs.Count

' Do stuff here
' ...

Catch ex As Exception
' Any error at this stage we have to give up
Try
If Not m_Document Is Nothing Then
m_Document.Close(SaveChanges:=False)
End If

Catch ex2 As Exception

End Try

Finally
' Done
For Each doc As Word.Document In m_WordApp.Documents
doc.Close()
Next

m_WordApp.Quit()

End Try

</snip>

HTH

Charles
 
G

Guest

Charles,
You have some interesting options that I'll incorporate. Couldn't find
references where I could do those things before. What source did you get
some of the information from? The one piece that I find annoying is that
when I'm generating the report (which can take a few minutes) CPU usage is
close to 100%. Do you know of any way of spinning off a thread or something
that reduces usage?

(Dave, sorry for trying to solve some of my issues in your post)
 
C

Charles Law

Much of it was trial and error. I used the intellisense and object browser
to come up with likely looking candidates and then tried them out,
one-by-one.

The documents I process are up to 15 Mb in size and so take some to load in
a visible copy of Word. I noticed that Word would always perform a
repagination and spelling check when I opened a document (you don't notice
it on small documents because it is so quick), which gave me the idea to
turn these features off when automating Word.

Another thing that can affect speed of processing is the version of Word
used to save the document and the version used for automation. My client
uses Word 2000 and I use Word 2003. If I take a Word 2000 document directly
and automate it, it runs quite slowly. If I load it and save it using Word
2003 first, and then automate it with Word 2003 then it is quite a bit
quicker, possibly halving the time taken to process it.

With regard to the cpu percentage, I think you are probably stuck with this,
although the 'Save and Automate' technique might help slightly. I run my
processing on a different thread and it still uses 50%+ cpu. The most likely
culprit is the marshalling backwards and forwards between managed an
unmanaged code. There is quite a lot of work to do with each COM call, which
can seriously affect performance and increase cpu percentage.

HTH

Charles
 
C

Charles Law

One other thing to add: there are pros and cons to the CreateObject() and
New methods of starting Word.

By using late-binding, the former makes it more likely that your application
will work with different versions of Word on the host machine. However, I
have found that if you use the latter method and build against the lowest
version that you want to support, e.g. Word 2000, then the same solution
should also work with Word 2003. The two versions use different managed
wrappers, and Word 2000 does not work with a wrapper created for Word 2003,
but Word 2003 can work with a wrapper created for Word 2000.

Charles
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top