?
Solved

Fill in Microsoft Word Template from Windows Forms C# Application

Posted on 2005-04-27
5
Medium Priority
?
8,204 Views
Last Modified: 2010-08-05
Hi!

What I would like to do is have my application launch a word document which has fields specified (just text).  For instance:
<firstname> <lastname>
<city>, <state> <zip>

Then I would like for my app to find those tags and replace with some data.  This is proving to be very hard!

I have code that works so far, and what it does is finds and replaces one of the tags, but when it gets to the second tag to replace, it just goes over the code and does not work.

Here is what I have so far:

private void linkLabel1_LinkClicked_1(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
            {

                  object oMissing = System.Reflection.Missing.Value;
                  object oTemplate = Application.StartupPath + "\\letter.doc";

                  Word.Application ThisApplication;
                  Word._Document oDoc;                  
            
                  ThisApplication = new Word.Application();

                  ThisApplication.Documents.Open(ref oTemplate, ref oMissing, ref oMissing, ref oMissing
                        , ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

                  string sqlString = "Select * From Contacts where ContactID = " + Convert.ToInt32(lvContacts.SelectedItems[0].Text);                                    

                  GenericDB.FillTable(sqlString);

                  DataRow dRow = GenericDB.dTable.Rows[0];            

                  InsertWord("<lastname>", dRow["LastName"], ThisApplication);
                  InsertWord("<firstname>", dRow["FirstName"], ThisApplication);                  
                  InsertWord("<city>", dRow["City"], ThisApplication);
                  InsertWord("<state>", dRow["State"], ThisApplication);
                  InsertWord("<address>", dRow["Address"], ThisApplication);
                  InsertWord("<zip>", dRow["ZipCode"], ThisApplication);
                  InsertWord("<customername>", this.txtCustomertName.Text, ThisApplication);
                  
            }

      private void InsertWord(object findText, object replaceText, Word.Application ThisApplication)
            {
                  object oMissing = System.Reflection.Missing.Value;
                  Word.Find myFind = ThisApplication.Selection.Find;                         
                  
                  object[] Parameters;
                  Parameters = new object[15];
                  Parameters[0] = findText;
                  Parameters[1] = oMissing;
                  Parameters[2] = oMissing;
                  Parameters[3] = oMissing;
                  Parameters[4] = oMissing;
                  Parameters[5] = oMissing;
                  Parameters[6] = oMissing;
                  Parameters[7] = oMissing;
                  Parameters[8] = oMissing;
                  Parameters[9] = replaceText;
                  Parameters[10] = oMissing;
                  Parameters[11] = oMissing;
                  Parameters[12] = oMissing;
                  Parameters[13] = oMissing;
                  Parameters[14] = oMissing;

                  myFind.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, myFind, Parameters );                                    
            }


Any help is greatly appreciated as I am on a tight schedule!!

Thanks!!
0
Comment
Question by:The_machine
  • 3
  • 2
5 Comments
 
LVL 23

Expert Comment

by:Jens Fiederer
ID: 13885957

Try adding

            object replaceAll = Word.WdReplace.wdReplaceAll;

and
            Parameters[10] = replaceAll;

in appropriate places in your InsertWord function.

(Alternatively, you can reset your position to the start after each InsertWord, if you don't want ALL instances of, say, <city>
replaced by the replacement value).
0
 

Author Comment

by:The_machine
ID: 13886066
For your first option:
I think this will fail because replace all will replace all occurences of the same string.  So if I had <city> called out twice or three times then city would be replaced all over the document instead of the first occurence.

For your second option:
Can you please show me how to reset the position to the start of the document after I run through my InsertWord function?

EG:
ThisApplication.Position.SendToStart();  //Something like this after I run through all the other code?

Thanks for your reply!!!
0
 
LVL 23

Accepted Solution

by:
Jens Fiederer earned 2000 total points
ID: 13886962
First option:
"Failure" is a matter of preference here.  Most template applications actually prefer to replace all instances of a token, allowing constructs such as:

<firstname> <lastname>
<address>
<city>, <state> <zip>

Dear <firstname>,

In your lovely town of <city>,

etc.
It is rare to actually want to preserve instances of <city> (for example) in the document, but it is conceivable, so
for second option:

Try
            ThisApplication.Selection.SetRange(ThisApplication.ActiveDocument.Content.Start,
                ThisApplication.ActiveDocument.Content.End);
at the beginning of your InsertWord function.
0
 

Author Comment

by:The_machine
ID: 13887012
Good point, I did not think of that!

I will try the code later today and let you know what happens.

Thanks again for your help!!!!
0
 

Author Comment

by:The_machine
ID: 13887460
Works perfectly!

Thank you so much!!!
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Loops Section Overview
Suggested Courses

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question