Edit Microsoft Word Document From Your Application

Create & edit Microsoft Word document from Windows application Form by using C#

Introduction

I faced this problem when I was developing a small tool to write official letters. My requirements were, letter template & content can be changed any time and application will help to get only inputs like, sent to name, organization name, date, etc. and after that when user presses finish button, the letter should be ready for print out along with predefined content & inputs.

Background

To solve this, I used Microsoft VS 2005 with C# 2.0.

Here are the steps I followed:

Add Microsoft.Office.Interop.Word reference to the project from COM Component as follows:

This will automatically add VBIDE, Microsoft.Office.Core along with Microsoft.Office.Interop.Word as references.

Now create a Microsoft Word document with the fields <Name>, <Date>, <Subject> and letter body. Then place all 3 variables (I called these variables because these will be changed automatically based on user input) where they belong. I did the following:

Now design your form in VS IDE. I did it like this:

Using the Code

Now let's do some coding…..ya….. so here is my sample coding.

using Word = Microsoft.Office.Interop.Word;//<- this is what I am talking about

Comments and Discussions

The Find class has a M:Microsoft.Office.Interop.Word.Find.ClearFormatting method, and the T:Microsoft.Office.Interop.Word.Replacement class also has its own M:Microsoft.Office.Interop.Word.Replacement.ClearFormatting method. When you are performing find-and-replace operations, you must use the ClearFormatting method of both objects. If you use it only on the Find object, you might get unanticipated results in the replacement text.

Also, you left out Marshal.ReleaseComObject(object) to release from memory otherwise you have exposed memory leaks. Clearly you didn't do your homework!

You have explained replacing text box data from our application very well.Thanks for that.But plz guide me how to handle check box and radio button as well.In my application I am replacing text box data successfully in the word doc but when user click on a particular check box/radio button(some times multiple check box) how to modify same in the word doc.
I have a web page same as my word doc including check box and radio buttons.
Please suggest me some one.

A word document contains text with variety of fonts. I want extract texts in some font, process it and replace that text by processed one. For example, a word document has text in fonts Arial, Calibri, Times and Times New Roman. And I'm willing to replace the text in Arial Font by a phrase say "Arial". Before replacing that text I have to store the original text to some data string.

i'm working on VS 2010 Ultimate running on windows 7 ... when i try to run the application i have the following Error in the wordApp.Selection.Find.Execute(...) call" Attempted to read or write protected memory. This is often an indication that other memory is corrupt."any ideas???

regarding using this strategy what if i have multiple users working at the same time and replacing the template. i need to print it out autimatically without saving. do i have to worry about how many users, which office version is on the client machines, and do i have to kill or remove resources from the server?

In theory, this should work because the VBA in Word 2007 is supposed to be backward compatible with Word 2003.

However, as a professional developer, if my customers have Office 2007, I would work against the 2007 PIAs. If I have to serve many customers who are on different versions, I would feel safer having 2 version of the application.

In practice, I do not know, because for me and my customers, Office 2007 is crap. None of my customers are using it, and even if I received a free licence from Microsoft, I did not install it in my environment.

Microsoft usually has an offer for a trial version of Office 2007 that is good for 60-120 days. You can download it to make your tests. If you do not risk to corrupt your Office 2003 environments, use Virtual PC (free from Microsoft) and install the Office 2007 in a virtual environment to make your tests.

Another thing to try, and it might result in a better performance anyway, would be to code everything in a VBA macro that accepts parameters for the values you need to insert. That macro would be saved in the Word document or template. The only thing your .NET code would then have to do is to call that macro (there is a Run or RunMacro command somehwere, sorry, I am in a rush and do not have time to check) and pass the parameters. This is so simple that it should not create problems between the different PIAs. And since you .NET code calls Word only one time, it is a lot more efficient than calling 25 methods between .NET and Word (25 calls through an interop service that translates the .NET code to COM code is sometimes very time consuming).

That means however that you know VB well enough to code the VBA side of things.

Good intentions, and I suppose that this is code that might works in that simple situation. But it shows a lack of understanding of how to manipulate Word and is a very bad example of techniques to use on a general basis. There are a few dangerous things in that code, and things that could be done a lot better.

-----

First of all, marking the document with <Tags> works, but there is a better way, by using bookmarks in the document. Bookmarks being objects, they are a lot more interesting for programmer to mark places where they should intervene in a document. Search Word documentation for bookmarks. They also make your code work a lot faster than FindAndReplace in big documents.

-----

<pre>killprocess("winword");</pre>

If the user has a copy of Word opened with one or more documents opened, you are forcing Word to close and the user will probably lose all the modifications made to the documents since the last save. <b>Never kill a process that is an application that could have been started by the user</b>.

You do not need to kill a previously running instance of Word to start another one. Creating a new one with new Word.ApplicationClass() will simply start a second invisible copy of Word. The user can continue to work in the copy that he/she started, and your application works in the new one you created.

-----

Instances of Word started from an application are not Visible by default, which is often a good thing, because they will run faster (they do not have to refresh the screen each time you do something in the document), and the user is in your application, he does not need to see the document.

However, since it is invisible, the user cannot close the copy of Word you are starting through code (unless you make the Application object (wordApp) visible through its Visible property).

It is thus very important for your code to close the Word instance once your work is done by calling the Quit method of the Application object (wordApp).

Failing to do so, if the user calls your code 25 times, there will 25 copies of Word running on the computer. At 10 MBs or more a piece, that is a lot of memory.

You do not see them as applications because they are invisible to the user, but if you go in the Windows Task List, you will see them running as processes. They will close down only if killed from the task list of if the user reboot the computer.

A .NET application that starts a COM object such as any of the Office applications should be very careful to close the application, specially if it is not visible to the user.

-----

<pre>File.Copy("C:\\OfferLetter.doc", "c:\\temp.doc", true);</pre>

Although this does what it is supposed to do , it is not the right way to work in Word. The template document should be saved as a template (an option in Word), and the new document should be created from that template. See Templates in Word help. Not only is more efficient in the long run but it also makes for simpler code when you want to create the document.

Note that Missing.Value is part of the System.Reflection namespace and is not available unless you specify that namespace or add a using clause for it.

-----

<i>For all users</i>

The Office Primary Interop Assembly (PIA) should be installed on the development computer and the client computers if you want everything to work correctly. Otherwise, you will have problems with properties or methods that use Variant variables which are quite common in Office, but not available in .NET. The PIA, available from Microsoft or installed as an option both when you install Visual Studio and Office (in office, it is called the .NET components or something like that the installation option windows). They are also available only for Office 2003 and over.

<i>For VB users</i>

Do not use a Word.ApplicationClass, use a Word.Application object instead. The Word ApplicationClass is a wrapper that handles a few problems C# has with Word, such as optional parameters for some methods. VB does not need the wrapper sinde Optional parameters are available in VB.

You thus do not have to pass all those useless Missing parameters since VB does not requires them on optional parameters.

If you do not want to use <tags> but bookmarks, how can you replace an unknown number of eg. "Customer name" with bookmarks? I can use unlimited <customername> tags in my document, but bookmarks are unique and you will have to make "CustomerName1", "CustomerName2" etc. So you don't know how many "customer name" there is in an unknown document.

In order to properly code against Word (or any software that uses VBA as its macro language), you need to know how to use the software first. Otherwise you end up working in a bad way and/or writing 200 lines of codes where 1 is enough. Unfortunately, most programmers that try to program Word documents ends up with crap because they do not know how to use Word. They treat a Word document as if it was an ASCII text file, and I think you will thinks as I do : a .doc file has nothing to compare it to a .txt file.

Bookmarks can be referenced through special fields in a Word Document.

When creating the template, you create one Bookmark of a given name, and if you want to reuse the content of the bookmark in other places in the document, you set the cursor to that place and you do the following:

Insert... Cross-reference. In the Reference type you select Bookmark. In the Insert reference to you then select Bookmark text. You select your bookmark from the list at the bottom of the screen. OK.

A field referencing the content of the bookmark will be created at the cursor. If you change the content of the bookmark, the field will be updated with the new content.

Note that using that technique, selecting the bookmark page instead of the bookmark text, you could create something such as "As we have seen on page <reference to the bookmark>". The field is then updated to the page where the bookmark resides instead of its content.

That is one of the reasons why working with bookmarks in a document is a lot more interesting than working with tags.

I have been working and giving training in VBA for Office for many years. The problem I see everywhere is that, as I have stated before, programmers are trying to code on a piece of software that they do not know. Even if you connect to Office through .NET, you are actually calling objects that were designed for VBA, not for .NET. And VBA for Office was firstly designed as a macro language for the different applications. You need to know how to use the software to code properly against it.

Most programmers know Excel quite well, so they write code that is not so bad against Excel.

But most programmers do not know Word, so the code they write is not efficient. How many programmer out there know about Bookmarks, Fields and Sections in Word? Those are the things a secretary use, VBA for Word has been created for her, so those are also the things a programmer should use.

I often told to my students: if you do not know how to do something manually in an Office document, don't try to code right away. Go and see someone who is as good a user of the software as you can find (usually a secretary for Word; not one that creates simple letters, but the one that create the 200-300 pages documents in the company). Start the macro recorder in the software and ask her/him to perform manually what you want to do with your code. Stop the macro recorder, and go look at the code that was generated. This is usually not efficient code, but this is where you will find about all those things such as Bookmarks and Fields objects that are the best ones to use in the code.