Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / Office / MS-Word

Your Own Word Bookmark Editor

5.00/5 (1 vote)
15 Apr 2018CPOL7 min read 12.4K   417  
Word Bookmark Editor for Word Reports easy handling

Sample Image - maximum width is 600 pixels

Introduction

A lot of people suffer from the necessity for fulfilling reports, timetable plans and other various wise documents' forms of any kind. These continuous reports usually have a few changes one from another and it is not too much inconvenience while the forms of the above remain unchanged. But a great headache occurred when your wise coordinators again and again used to change the forms of the reports as in its discretion it may think fit with almost the same document contents. Under these circumstances, it may prove useful to have some document template with the contents sample and to apply it to any new form your visionary coordinators should provide you with. In this article, the complete application for Word Reports easy handling has been provided based on Word Bookmarks.

Background

The demo project WordMark has been created  with the standard Visual Studio C# Appwizard. It is a compilation of the standard C# tutorial samples and some CodeProject articles: "Word Automation using C#: Create a Word Table Programmatically" by koolprasadd, "Word Automation" by Prathapachandran, etc. As opposed to the samples of the articles above, WordMark.exe is not just a demo: it is the completed application that may be practised by any MS Word user.

Before you start building the project provided, it is highly recommended to have a look to the demo presentation enclosed in order to get an idea of the output expected.

Demo Explanations

The executable WordMark.exe has been built with MSVS-2015 pro C#.

The simplest case of demo performance is as follows:

  • Call Menu->File->Open Target File; in the FileDialog that appears, select WeeklyReportBlank.doc.
  • Call Menu->File->Open Source File; in the FileDialog that appears, select WeeklyReportTable.doc.
  • Call Menu->Edit->Apply Source Text to Target.

The texts of the report from the WeeklyReportTable.doc prepared jump into WeeklyReportBlank.doc at the Bookmarks corresponding and you may save the Result report with any name at any pathway.

Pressing the 'BookMarks Combo' Button by the 'BookMarks' Combo Box becomes visible and you may browse BookMarks in the Target Doc with the Text selection.

When you've closed the application and start once more, just uncheck the 'Visible' Check Box, call the same commands and call Menu->File->save Target File As and save the Result report with any name at any pathway: if Source and Target files are completely prepared to join - no need to open Docs visible. Needless to say that both Source and Target docs may be prepared separately by means of the standard Word without the application provided.

Some menu and some special Control handling keys arranged for proper WordMark application operation:

Image 2

Menu->File

  • Open Target File: Open Doc File Subject to fulfill BookMarks Text (Bookmarks in document prepared understood)
  • Save Target File As: Save Target File with the Path and Name specified
  • Close Target File: Close with File Saving Prompt if changed
  • Open Source File: Open Doc File with the BookMarks labels and Text Cells Table (the Table prepared understood)
  • Save Source File As: Save Source File with the Path and Name specified
  • Close Source File: Close with File Saving Prompt if changed
  • Exit: Close the Application with File Saving Prompt if changed

Menu->Edit

  • New BookMark: Calls the 'Bookmark Name' Dialog and if Ok, the new Bookmark with the Name typed appears in Target doc
  • Delete BookMark Combo: Deletes the Bookmark specified in Combo Box from the Target doc
  • Clear Bookmarks' Text(s): Clear the Texts from Target doc at the Bookmarks selected in Source doc; if no Selection all the Texts to clear
  • Clear Bookmark(s): Remove the Bookmarks from Target doc selected in Source doc; if no Selection all the BookMarks to remove
  • Create BookMark Table: Create the Table with the BookMarks and Text Cells in Source Document (created if not opened yet)
  • Apply Source Text to Target: Apply the Text and Font from the Source Table into Target Doc at the corresponding BookMarks 

 Menu->Help

  • WordMark Help: Help Dialog Box with the current Help Text.
  • About WordMark: Application Copyrights and License Info

 Controls

  • 'Visible' Check Box: If Source and Target files are completely prepared to join - no need to open Docs visible
  • 'BookMarks Combo' Button: Make 'BookMarks' Combo Box visible
  • 'BookMarks' Combo Box: Browse BookMarks in the Target Doc with the Text selection
  • 'BookMarks Sort->by Order' Radio Button: Sort the BookMarks in the Combo Box by the order in the Target Doc
  • 'BookMarks Sort->by Name' Radio Button: Sort the BookMarks in the Combo Box by the names alphabetically
  • 'Table Rows Sort->by Order' Radio Button: Sort the BookMarks labels in the Table of the Source Doc by   by the order in the Target Doc
  •  
  • 'Table Rows Sort->by Name' Radio Button: Sort the BookMarks labels in the Table of the Source Doc  by the names alphabetically
Important Notes
  • Once the document has been opened with the WordMark application, it must be closed by this application as well. Otherwise, the WordMark application seems to be in trouble.
  • If you've made some changes with the BookMarks in the Target doc by means of the standard Word while the 'BookMarks' Combo Box is visible, just press the 'BookMarks Combo' Button to synchronize.
  • If you have selection in some Table in the Target doc and select Menu->Edit->New BookMark and in 'Bookmark Name' Dialog selected Ok, the new Bookmark for every cell selected created with the Name typed with the Row-Column indexes commenced from the left top corner of the Table selection in Target doc.

Building Notes

The project provided has been developed with MSVS-2015 pro C# in Windows 10 and in Windows 7 as well.

The only problem that may occur while jumping from one computer to another is the reference to Microsoft.Office.Interop.Word installation.

If the message of the Office and Word unaccessed error occurred during compilation, just install it with the Solution Explorer->WordMark right mouse button click.

Code Explanation

All the following Menu and Control handling Commands have been done with standard MSVS C# AppWizard technologies. Therefore, I feel nothing to explain better than in the standard tutorials. Just mention a few points which I've not found in tutorials and I've found out for myself by the hit-and-miss fashion.

Here, I must admit that it is my first contact with C#. Therefore, some of my assertions seemed awkward for sophisticated people. I'll be happy to read the comments and advice, if any.

1. Text in the Cell of the Table

Text in the Cell of the Table ended with two bites: '\13' and '\7'. Even if the Cell seemed as empty, these two bytes presented. Therefore, if the Text borrowed from the Table's Cell must be cut short on two bites:

private bool ApplyTextAtBookmarkFromRow(int iRow)
   {
       Word.Table TableSrc = (Word.Table)docSrc.Tables[1]; //Select Table of Source Doc
        string strB = TableSrc.Cell(iRow, 1).Range.Text;   //Name of the Bookmark in row specified
       strB = strB.Substring(0, strB.Length - 2);          //Name cut with two bytes
       string strT = TableSrc.Cell(iRow, 2).Range.Text;    //Text of the Bookmark in row specified
       strT = strT.Substring(0, strT.Length - 2);          //Text cut with two bytes
       //Pick up the Font of the Cell:
       Microsoft.Office.Interop.Word.Font fontSrc = TableSrc.Cell(iRow, 2).Range.Font;
       Word.Bookmark bmk = docTgt.Bookmarks[strB];         //Select Bookmark in Target doc
   if( ApplyTextAtBookmark(bmk, strT, fontSrc) == false)   //Replace the text in the BookMark
           return false;
        return true;
   }

Also, it proved useful to have the function to identify if the Text belongs to some Tables' Cell:

private bool IsTextOfTable( string strN)
  {
      if (strN.Length < 2)    //If Text in Cell at least 2 bites present
          return false;
     string strA = strN.Substring(strN.Length - 2);//2 last symbols borrowed
     byte[] bytes = Encoding.ASCII.GetBytes(strA); //convert to bites
     return bytes[0] == 13 && bytes[1] == 7;       //true if bites 13 & 7
  }

and the function to identify  if the Bookmark belongs to some Tables' Cell:

          private bool IsBookMarkOfTable( Word.Bookmark bmk)
        {
            bool bTable = false;
            try
            {
                bTable = bmk.Range.Cells.Count > 0;
            }
            catch
            {
                bTable = false;
            }
            return bTable;
        }

2. Bookmarks' Text Replacement

The Text replacement procedure at the  Bookmark specified also has some particulars in the WordMark project:

      private bool ApplyTextAtBookmark(Word.Bookmark bmk, string strSrc, Microsoft.Office.Interop.Word.Font fontSrc)
        {
            if (bmk == null)          //if no Bookmark - nothing to do
                return false;
     
            bool bTable = IsBookMarkOfTable(bmk); //Flag of Bookmark in the Table's Cell
            int nSrc = strSrc.Length; //Length of the Source Text
            string strTgt = "";       //Text at the Bookmark
            if (bmk.Range.Text != null)
                strTgt = bmk.Range.Text; //Text at the Bookmark

            if (nSrc == 0)
            {
                strSrc = " ";            //if Source Text empty assum as white space
                nSrc = strSrc.Length;
            }
            string strB = bmk.Name;      //Remember the name of the Bookmark
            if (bmk.Range.Text == null)  //if Bookmark Text not exist assum as white space
                bmk.Range.Text = " ";

            int nTgt = bmk.Range.Text.Length; //Length of the Bookmark Text
            int nDif = nSrc - nTgt;  //Difference between Source and Bookmark Text length
            if (!bTable)              //if Bookmark not in Table
                if (nDif < 0)            //if Source Text shorter then BookMarks one 
                    for (int k = 0; k < -nDif; k++)
                        strSrc += " ";   //append white space until equal  
            nSrc = strSrc.Length;    //Length of the Source Text 
            object bgnA = bmk.Start;        //Range Start
            object finA = bmk.Start + nSrc; //Range End
            bmk.Range.Text = strSrc;        //Replace the Text in BookMark
            Word.Range rgA = docTgt.Range(ref bgnA, ref finA);//new Range fixed
            rgA.Select();               //Select new Range
            rgA.Font = fontSrc;         //Apply Font to Range 
            object rng = appWord.Selection.Range;  //Select new Range
            //new Bookmark with the same Name fixed:
            Word.Bookmark bkmr = docTgt.Bookmarks.Add(strB, ref rng);
            if (bTable == false)      //if Bookmark not in Table
                if (nDif > 0)         //if New Text is longer then the old one 
                {
                    object bgn = bkmr.Range.Start + nSrc + 1;       //go to end of new Text
                    object fin = bkmr.Range.Start + nSrc + nDif + 1;//go to end + difference
                    Word.Range rg = docTgt.Range(ref bgn, ref fin);//fix range from end to diffence len
                    string strf = rg.Text;   //Pick up text from difference Range
                    int nBreak = strf.IndexOf("\n");    //End of line
                    if (nBreak > 0)
                    {
                        strf = strf.Substring(0, nBreak - 1);
                      
                        while (strf.Substring(0, 1) == " " || strf.Substring(0, 1) == "_"
                         &&  strf.Length > 1)
                        {
                            strf = strf.Substring(1);//while first simbol is empty cut first simbol
                        }
                        rg.Text = strf;  //apply the text cut at the end of new Text
                    }
                }
            return true;
        }

Please note that all these arrangements with the difference in length of the old and new Text performed just in order to keep the Text and environment not to be changed in Position (Your coordinators consider it absolutely necessary to keep their wise doc forms inviolable).

3. Multiple Bookmarks Initialization in Tables

Multiple Bookmarks initialization in the Tables also has been developed by the author and may be of interest for developers:

private void MenuNewBookMark_Click(object sender, EventArgs e)
{
    if (w.ShowDialog() == DialogResult.OK)        //new Bookmark Name Ok
    {
        int nCel = 0;                             //Number of Cells selected
        if (appWord.Selection.Tables.Count > 0)
            nCel = appWord.Selection.Cells.Count; //Number of Cells selected

        if (nCel < 2) //if no Cells or Single Cell just append new BookMark
            docTgt.Bookmarks.Add(w.textBox1.Text, appWord.Selection.Range);
        else
        {
            Word.Table tbl = appWord.Selection.Tables[1];   //Table selected
            //TopLeft corner of Selection Row index:
            int rowStart = appWord.Selection.Cells[1].Row.Index;
            //TopLeft corner of Selection Column index:
            int colStart = appWord.Selection.Cells[1].Column.Index;
            //RightBottom corner of Selection Row index:
            int rowFin = appWord.Selection.Cells[appWord.Selection.Cells.Count].Row.Index;
            //RightBottom corner of Selection Column index:
            int colFin = appWord.Selection.Cells[appWord.Selection.Cells.Count].Column.Index;

            for (int i = rowStart; i <= rowFin; i++)      //for each row selected
                for (int j = colStart; j <= colFin; j++)  //for each column selected
                {
                    tbl.Cell(i, j).Range.Select();       //Select Range of the cell
                    int ri = i - rowStart + 1;            //row index
                    int ci = j - colStart + 1;            //column  index
                    //Append new Bookmark indexed:
                    docTgt.Bookmarks.Add(w.textBox1.Text + "_" +
                                         ri.ToString("00") + "_" + ci.ToString("00"));
                }
        }
        if (comboBox1.Visible)                      //if 'BookMarks' Combo Box is visible
        {
            button1_Click(sender, e);               //synchronize Combo Box Content
            int index = comboBox1.FindString(w.textBox1.Text); //index of Name typed
                                                               //in Dialog Box
            comboBox1.SelectedIndex = index;        //select item with the Name typed
                                                    //in Dialog Box
        }
    }
}

Application Handling and Your Own Applications Development using the Project Provided

The WordMark.exe application is easy to handle for any user a little bit familiar with the Word Bookmarks. No any programming skills are required.

You may pick up this entire project, rename it and combine and improve the code as you like.

Or you may pick up any procedure file(s) contained and insert it in any of your Own C# projects with menu Project->Existing Item.

Your references to my code, if any, should be highly appreciated.

Points of Interest

I believe that this application and code should be helpful for software people with documents handling.

The idea is to develop the set of programs of Word and Excel documents forms handling which your wise folks up top provide you with to perform the great deal of paperwork.

And I believe it is possible to arrange that the comp will type the mountains of the scrap paper for the top brass people to be happy with.

History

The history just commenced.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)