Reputation: 35733
I want to replace the text content of bookmarks without loosing the bookmark.
foreach(Bookmark b in document.Bookmarks)
{
b.Range.Text = "newtext"; // text is set in document but bookmark is gone
}
I tried to set the new Range of the bookmark before the Text setting but I still have the same problem.
I also tried to re-add the bookmark with document.Bookmarks.Add(name, range);
but I can't create an instance of range.
Upvotes: 3
Views: 2876
Reputation: 53
With the above approach, you still lose the bookmark before it is added back in. If you really need to preserve the bookmark, I find that you can create an inner bookmark that wraps around the text (a bookmark within bookmark). After having the inner bookmark, you simply need to do:
innerBookmark.Range.Text = newText;
After the text replacing, the inner bookmark is gone and the outer bookmark is preserved. No need to set range.End
.
You can create the inner bookmark manually or programmatically depending on your situation.
Upvotes: 1
Reputation: 35733
I had to readd the bookmarks and save the range temporarily. I also had to add a list of processed items to evade an endless loop.
List<string> bookmarksProcessed = new List<string>();
foreach (Bookmark b in document.Bookmarks)
{
if (!bookmarksProcessed.Contains(b.Name))
{
string text = getTextFromBookmarkName(b.Name);
var newend = b.Range.Start + text.Length;
var name = b.Name;
Range rng = b.Range;
b.Range.Text = text;
rng.End = newend;
document.Bookmarks.Add(name, rng);
bookmarksProcessed.Add(name);
}
}
Upvotes: 3
Reputation: 743
Looks like you solved your problem, but here is a cleaner way to do it:
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Word;
using System.Text.RegularExpressions;
using Word = Microsoft.Office.Interop.Word;
//declare and get the current document
Document extendedDocument = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument);
List<string> bookmarksProcessed = new List<string>();
foreach(Word.Bookmark oldBookmark in extendedDocument.Bookmarks)
{
if(bookmarksProcessed.Contains(oldBookmark.Name))
{
string newText = getTextFromBookmarkName(oldBookmark.Name)
Word.Range newRange = oldBookmark.Range;
newRange.End = newText.Length;
Word.Bookmark newBookmark = extendedDocument.Controls.AddBookmark(newRange, oldBookmark.Name);
newBookmark.Text = newText;
oldBookmark.Delete();
}
}
Code isn't tested but should work.
Upvotes: 0