none
Bookmark adds text instead of replacing RRS feed

  • Question

  • Hi everybody,

    I'm using VS2015 and Word 2016 and I've difficulties to update a bookmark.

    As per title the text I will be added at the front of the bookmark and not replacing the old with the new text.

    Her is how I tried it:

    if (iDocument != null)
                {
                    
                    Range mRange;
    
                    if (iDocument.Bookmarks.Exists(aTextmarkeName))
                    {
                        iDocument.Bookmarks.Item(aTextmarkeName).Select();
                        iWordApp.Selection.TypeText(aTextmarkeWert);
                        //mRange = iDocument.Bookmarks.Item(aTextmarkeName).Range;
                        //mRange.Text = aTextmarkeWert;
                    }
                    else
                        throw new Exception("Bookmark not found.");
    
                    // iWordApp.Visible = true;
    
                }

    Is this something related to Word2016 or - and I hope it's not - somehow related to the custom framework we have to use?

    The classes for Range and iWordApp look like this.

    public interface Range : ICommonWord
        {
            string Text { set; get; }
    
    // .....
    }
    
    public interface ICommonWord : IDisposable
        {
            Application Application { get; }
            object Parent { get; }
        }
    
        [ComProgId("Word.Application")]
        public interface Application : ICommonWord, ApplicationEvents3
        {
            Document ActiveDocument { get; }
            IWindow ActiveWindow { get; }
            IDocuments Documents { get; }
            Selection Selection { get; }
            IDialogs Dialogs { get; }
            IOptions Options { get; }
    }

    Thursday, December 13, 2018 11:01 AM

Answers

  • What you're describing is the normal behaviour. To replace the bookmarked text, you must re-apply the bookmark to anything you want to replace. In VBA one might use:

    Sub UpdateBookmark(StrBkMk As String, StrTxt As String)
    Dim BkMkRng As Range
    With ActiveDocument
      If .Bookmarks.Exists(StrBkMk) Then
        Set BkMkRng = .Bookmarks(StrBkMk).Range
        BkMkRng.Text = StrTxt
        .Bookmarks.Add StrBkMk, BkMkRng
      End If
    End With
    Set BkMkRng = Nothing
    End Sub

    calling it with:
    Call UpdateBookmark("BookmarkName","New Text")

    I'll leave it to you to do the VSTO conversion.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by PachN Friday, December 14, 2018 2:04 PM
    Thursday, December 13, 2018 8:16 PM
  • Okay, got it.

    I had to change the .dot template. 

    The template used "placeholder" bookmark.

    I changed them to "enclosing" bookmarks and now the code runs fine.

    Thanks for your help.

    • Marked as answer by PachN Friday, December 14, 2018 2:05 PM
    Friday, December 14, 2018 2:05 PM

All replies

  • What you're describing is the normal behaviour. To replace the bookmarked text, you must re-apply the bookmark to anything you want to replace. In VBA one might use:

    Sub UpdateBookmark(StrBkMk As String, StrTxt As String)
    Dim BkMkRng As Range
    With ActiveDocument
      If .Bookmarks.Exists(StrBkMk) Then
        Set BkMkRng = .Bookmarks(StrBkMk).Range
        BkMkRng.Text = StrTxt
        .Bookmarks.Add StrBkMk, BkMkRng
      End If
    End With
    Set BkMkRng = Nothing
    End Sub

    calling it with:
    Call UpdateBookmark("BookmarkName","New Text")

    I'll leave it to you to do the VSTO conversion.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by PachN Friday, December 14, 2018 2:04 PM
    Thursday, December 13, 2018 8:16 PM
  • Hi PachN,

    Did Macropod's answer solve your problem? You can mark it as answer if it helped and please help us close

    the thread.

    Best Regards,

    Bruce


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.


    Friday, December 14, 2018 5:41 AM
    Moderator
  • Hi Bruce, 

    I've yet to test it, but will report back if it helped.

    Thanks so far to both of you.


    • Edited by PachN Friday, December 14, 2018 8:37 AM
    Friday, December 14, 2018 8:37 AM
  • So here I'm again... 

    Unfortunately it still doesn't work for me. So I broke it down into a little test project and it still adds the text infront of the old text.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Office.Interop.Word;
    
    namespace WordTest
    {
        class Program
        {
            static string wordDOT;
            static Application wordApp;
            static Document document;
            static void Main(string[] args)
            {
                wordDOT = @"C:\temp\Vorlage.dot";
                wordApp = new Application();
    
                wordApp.Visible = true;
                document = wordApp.Documents.Open(wordDOT);
    
                writeToBookmark("Line1", "Mr.");
                writeToBookmark("Line2", "John Doe");
                writeToBookmark("Line3", "Main Drive 1");
                writeToBookmark("Line4", "");
                writeToBookmark("Line5", "12345 City");
                writeToBookmark("Line6", "");
                writeToBookmark("Line7", "some text");
    
                updateBookmark("Line1", "To");
                updateBookmark("Line2", "1337 ACME Corp.");
                updateBookmark("Line3", "");
                updateBookmark("Line4", "");
                updateBookmark("Line5", "");
                updateBookmark("Line6", "");
                updateBookmark("Line7", "");
    
            }
    
            public static void writeToBookmark(string aTextmarkeName, string aTextmarkeWert)
            {           
                if (document != null)
                {
                    if (document.Bookmarks.Exists(aTextmarkeName))
                    {
                        document.Bookmarks[aTextmarkeName].Select();
                        wordApp.Selection.TypeText(aTextmarkeWert);                    
                    }
                    else
                        throw new Exception("Bookmark nicht im Dokument enthalten.");
                }
            }
    
            public static void updateBookmark(string bookmark, string newText)
            {
                if (document != null)
                {
                    Range range;
                    if (document.Bookmarks.Exists(bookmark))
                    {
                        range = document.Bookmarks[bookmark].Range;
                        range.Text = newText;
                        document.Bookmarks.Add(bookmark, range);
                    }
                }
            }
    
        }
    }


    The word .dot file is just a blank file with 7 bookmarks on 7 lines.

    I inserted the bookmarks like this:

    Select text, a picture, or a place in your document where you want to insert a bookmark.

    Click Insert > Bookmark.

    Under Bookmark name, type a name and click Add.

    I can not see what I'm doing wrong. I guess it gets the range wrong?


    • Edited by PachN Friday, December 14, 2018 10:55 AM
    Friday, December 14, 2018 9:56 AM
  • Okay, got it.

    I had to change the .dot template. 

    The template used "placeholder" bookmark.

    I changed them to "enclosing" bookmarks and now the code runs fine.

    Thanks for your help.

    • Marked as answer by PachN Friday, December 14, 2018 2:05 PM
    Friday, December 14, 2018 2:05 PM
  • In effect, the same problem is occurring with your writeToBookmark routine.

    Your updateBookmark routine actually works fine in your test case, and arguably it is all you need.

    The problem is the writeToBookmark routine.

    For a "point" bookmark (which is what you seem to be starting with, it will leave the bookmark and .TypeText will insert text after the bookmark. So then updateBookmark updates the bookmark and the new text appears before the text you just inserted.

    For a bookmark that already "covers" some text, writeToBookmark will replace that with its text, but will delete the bookmark as it does so. So updateBookmark cannot then find the bookmark.

    I think it would be the same even if you changed writeToBookmark to use

    Selection.Text = TextmarkeWert;

    instead of 

    Selection.TypeText(TextmarkeWert);

    (actually, you can use the former in VBA with suitable syntax but OTTOMH can't remember if it works in C#)


    Peter Jamieson

    Friday, December 14, 2018 2:09 PM