oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Programming Word from .NET
Pages: 1, 2, 3, 4, 5, 6, 7

Creating the Letter

The second half of the code in the Save button event handler opens the prototype Word document created earlier, fills in text at the designated bookmarks, and saves the file as <patient name>.doc.

To begin, you need an instance of the Word application:

Microsoft.Office.Interop.Word.Application wordApp = 
    new Microsoft.Office.Interop.Word.Application();

You are now ready to open the specific document (the boilerplate letter we created and named Patient Letter.doc in the Temp directory). Two things to keep in mind, however, are:

  1. All parameters must be passed by reference.
  2. There are a lot of parameters, and they are all required.

Given the second requirement, the pattern is to initialize the parameters you don't care about with Type.Missing.

object fileName = @"C:\Temp\Patient Letter.doc";
object confirmConversions = Type.Missing;
object readOnly = Type.Missing;
object addToRecentFiles = Type.Missing;
object passwordDoc = Type.Missing;
object passwordTemplate = Type.Missing;
object revert = Type.Missing;
object writepwdoc = Type.Missing;
object writepwTemplate = Type.Missing;
object format = Type.Missing;
object encoding = Type.Missing;
object visible = Type.Missing;
object openRepair = Type.Missing;
object docDirection = Type.Missing;
object notEncoding = Type.Missing;
object xmlTransform = Type.Missing;

You can now pass these objects (by reference) to the method that returns the document.

Microsoft.Office.Interop.Word .document doc = wordApp.Documents.Open(
    ref fileName, ref confirmConversions, ref readOnly, ref addToRecentFiles,
    ref passwordDoc, ref passwordTemplate, ref revert, ref writepwdoc,
    ref writepwTemplate, ref format, ref encoding, ref visible, ref openRepair,
    ref docDirection, ref notEncoding, ref xmlTransform);

The object you get back (doc) is the Word document, ready for you to edit it. Your task will be to replace each bookmark with a block of text. Because this action is repeated with different bookmarks and different blocks of text, you'll factor it out to a common helper method:

private void ReplaceBookmarkText ( 
    Microsoft.Office.Interop.Word .document doc,
    string bookmarkName, 
    string text)
    if ( doc.Bookmarks.Exists(bookmarkName) )
        Object name = bookmarkName;
        Microsoft.Office.Interop.Word.Range range = 
            doc.Bookmarks.get_Item( ref name ).Range;
        range.Text = text;
        object newRange = range;
        doc.Bookmarks.Add(bookmarkName, ref newRange);

The helper method not only inserts the text but it replaces the bookmark when it is done (tidy). Note: We could move Microsoft.Office.Interop.Word .document doc to a member variable and then not have to pass it to the method, but since it is passed to only one method, I'm inclined to use the parameter.

We invoke this helper method for each of the text blocks we want in the letter:

ReplaceBookmarkText(doc, "PatientName", patientName);
ReplaceBookmarkText(doc, "Diagnosis", diagnosisString);
ReplaceBookmarkText(doc, "PatientAddress", patientName);
if ( txtNotes.Text.Length > 0 )
    ReplaceBookmarkText(doc, "notes", "Notes:\n" + txtNotes.Text);

That done, it is time to retrieve the patient's previous medications from the database, and then to add both the new medications and the existing medications to the respective bookmarks:

List<string> existingMedications = GetExistingMedications(patientID);
string existingMeds = string.Empty;
foreach ( string med in existingMedications )
    existingMeds += med + ", ";

ReplaceBookmarkText(doc, "ExistingMedications", existingMeds);
ReplaceBookmarkText(doc, "NewMedications", newMeds);

The helper method GetExistingMedications queries the database for all the medications for the given patient. To get the information needed, I join two tables: MedicationName (to get the name rather than the ID) and PatientToMedication (to get the medications for the current patient). The medicaiton names are returned in a type-safe list:

private List<string> GetExistingMedications(int patientID)
    string connString  = 
    SqlConnection conn = new SqlConnection(connString);
    string sqlString = 
    "select MedicationName from PatientToMedication pm " +
    " join MedicationNames m on m.MedicationID = pm.MedicationID " +
    " where pm.PatientID = " + patientID.ToString();

    SqlCommand cmd = new SqlCommand(sqlString, conn);
    SqlDataReader rdr = cmd.ExecuteReader();
    List<string> meds = new List<string>();
    while (rdr.Read())
    return meds;

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow