none
How do I use the Microsoft Word API and Bookmarks feature to programmatically add different text to the same bookmark collection? RRS feed

  • Question

  • I am trying to bookmark all the fields with text 'sample' in a word document. I need to bookmark all of them with the bookmark Name "fld_sample". I am using Microsoft.Office.Interop.Word API to do this programatically. The code below is sample code that I have tried from my end.

    using Microsoft.Office.Interop.Word;
    using System.Reflection;

    Object oTrue = true; Object oFalse = false;
    Application oWord = new Application();
    Document oWordDoc = new Document();
    oWord
    .Visible = true;
    Object oTemplatePath = @"string Path";

    oWordDoc
    = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref      oMissing);

    //selecting the range of text to bookmark.
    Range rng = oWordDoc.Range(12, 18);

     oWordDoc
    .Bookmarks.Add("fld_sample", rng);

     
    //selecting the next range of text to bookmark with same name
     
    Range rng1 = oWordDoc.Range(102, 108);

     oWordDoc
    .Bookmarks.Add("fld_sample", rng1);

    But the bookmark is only added for second range of values and not for first range of text. Can anyone help me with this code.

    Monday, August 13, 2012 9:11 PM

Answers

  • You can use numbers in a bookmark, as long as they are not the first character.

    So, you can keep a running total of all the bookmarks you've inserted, and include the total in the name. E.g:

    oWordDoc.Bookmarks.Add("fld_sample" + bookmarkCount.ToString(), rng);
    bookmarkCount++;

    Your task is going to be easier if there are no existing bookmarks in the document. If you insert a bookmark with a name that already exists, the original bookmark will be deleted (at least in my experience; it may be different  for different versions of Word).

    Edit:

    To search for the bookmarks, you could use something like:

    foreach (Word.Bookmark b in oWordDoc.Bookmarks)
    {
    if (b.Name.Length < 11) continue;
    
    if (b.Name.Remove(10) != "fld_sample") continue;
    
    // Now we are left with just bookmarks in the doc that start with fld_sample
    }
    Or, since you say you want to identify Fields, you could use a range's GoTo method, specifying the 'What' parameter as wdGoToField.
    Tuesday, August 14, 2012 6:42 PM

All replies

  • Hi,

    Based on your issue, I' m afraid you are not able to use the same name  "fld_sample" for all bookmarks. Every bookmark has one single name to specify.Please refer to this http://msdn.microsoft.com/en-us/library/office/ms263109

    Therefore, the bookmark is the same one you add twice. That's the reason why the bookmark for the first range of text disappears. As a suggestion, you should use different name for bookmarks like this

    Range rng = oWordDoc.Range(12, 18);
    oWordDoc.Bookmarks.Add("fld_sample1", rng);
    Range rng1 = oWordDoc.Range(102, 108);
    oWordDoc.Bookmarks.Add("fld_sample2", rng1);

    Hope this can help you.

    Best Regards,


    Leo_Gao [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, August 14, 2012 8:04 AM
    Moderator
  • Hi Leo,

    Thanks for your reply. I now understand that we can only use unique bookmark names to identify the text in word document. Can you provide me with an alternate solution to tag all fields with text "sample", so that I can traverse through the collection and identify each object with text "sample". The reason why I need this is, My actual requirement is to replace all the text "sample" with user provided input. 

    Tuesday, August 14, 2012 2:56 PM
  • You can use numbers in a bookmark, as long as they are not the first character.

    So, you can keep a running total of all the bookmarks you've inserted, and include the total in the name. E.g:

    oWordDoc.Bookmarks.Add("fld_sample" + bookmarkCount.ToString(), rng);
    bookmarkCount++;

    Your task is going to be easier if there are no existing bookmarks in the document. If you insert a bookmark with a name that already exists, the original bookmark will be deleted (at least in my experience; it may be different  for different versions of Word).

    Edit:

    To search for the bookmarks, you could use something like:

    foreach (Word.Bookmark b in oWordDoc.Bookmarks)
    {
    if (b.Name.Length < 11) continue;
    
    if (b.Name.Remove(10) != "fld_sample") continue;
    
    // Now we are left with just bookmarks in the doc that start with fld_sample
    }
    Or, since you say you want to identify Fields, you could use a range's GoTo method, specifying the 'What' parameter as wdGoToField.
    Tuesday, August 14, 2012 6:42 PM
  • Thanks for your reply. I now understand that we can only use unique bookmark names to identify the text in word document. Can you provide me with an alternate solution to tag all fields with text "sample", so that I can traverse through the collection and identify each object with text "sample". The reason why I need this is, My actual requirement is to replace all the text "sample" with user provided input. 

    Which version of Word are we discussing? That affects the options available.

    Why would you not use Word's built-in Range.Find.Replace functionality to accomplish this?


    Cindy Meister, VSTO/Word MVP

    Sunday, August 19, 2012 3:05 PM
    Moderator