Word Interop添加书签到标题

时间:2015-12-13 11:20:32

标签: c# templates ms-word office-interop bookmarks

我有一个.doc Word文档,标题中有一个文本。 我想从标题中找到单词“MyWord”并为其添加书签(书签也称为“MyWord”)。 目前我的代码能够在页眉和页脚中搜索,但我不知道如何选择感兴趣的单词。我使用字符串变量来加载标题的文本内容,然后找到单词的开头和结尾。但是,当我选择此范围时,选择会突出显示不同的区域。 这是代码:

    public static void AddBookmarkAnywhere(Microsoft.Office.Interop.Word.Application app, string findText, string bookmarkName)
    {
        var doc = app.ActiveDocument;
        foreach (Microsoft.Office.Interop.Word.Range rngStory in doc.StoryRanges)
        {
            var internalRangeStory = rngStory;
            do
            {
                AddBookmarkInStory(internalRangeStory, findText, bookmarkName);
                try
                {
                    switch (internalRangeStory.StoryType)
                    {
                        case Microsoft.Office.Interop.Word.WdStoryType.wdEvenPagesHeaderStory: // 6
                        case Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryHeaderStory:   // 7
                        case Microsoft.Office.Interop.Word.WdStoryType.wdEvenPagesFooterStory: // 8
                        case Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryFooterStory:   // 9
                        case Microsoft.Office.Interop.Word.WdStoryType.wdFirstPageHeaderStory: // 10
                        case Microsoft.Office.Interop.Word.WdStoryType.wdFirstPageFooterStory: // 11

                        if (internalRangeStory.ShapeRange.Count > 0)
                        {
                            foreach (Microsoft.Office.Interop.Word.Shape oShp in internalRangeStory.ShapeRange)
                            {
                                if (oShp.TextFrame.HasText != 0)
                                {
                                    AddBookmarkInStory(oShp.TextFrame.TextRange, findText, bookmarkName);
                                }
                            }
                        }
                        break;

                        default:
                            break;
                    }
                }
                catch
                {
                    MessageBox.Show("Some error in function FindReplaceAnywhere");
                }

                internalRangeStory = internalRangeStory.NextStoryRange;
            }
            while (internalRangeStory != null); 
        }

    }

    private static void AddBookmarkInStory(Microsoft.Office.Interop.Word.Range rngStory, string strSearch, string strBookmarkName)
    {
        string text = rngStory.Text;
        int start = text.IndexOf(strSearch);
        int end = start + strSearch.Length;

        if(start >= 0)
        {
            rngStory.Start = start; // incorrect value
            rngStory.End = start + strSearch.Length;
            rngStory.Select();
            rngStory.Bookmarks.Add(strBookmarkName, rngStory);
        }
    }

2 个答案:

答案 0 :(得分:1)

您有正确的想法,您只是错过了FIND功能,您需要使用它来代替" IndexOf"并尝试使用Range对象的Start和End属性捕获文本的位置。

这些不是在Word文档中处理文本的可靠方法,因为Word会存储如此多的信息和非打印字符"。举个例子,如果您的标题显示动态页码或日期,那么幕后的字段代码会影响开始和结束位置。

所以在语言参考中查找FIND(Selection和Range对象的属性 - 你肯定想要RANGE.FIND)以获得它的感觉。为了找到正确的语法,在录制宏的同时在UI中使用它,然后查看VBA并将其与语言参考进行比较。互联网上还有大量的示例代码。

需要注意的是,在成功的Find.Execute上,Find运行的RANGE对象将包含" found"搜索词的实例。因此,您可以简单地将其用作"目标"对于Bookmarks.Add。

答案 1 :(得分:0)

我找到了解决问题的方法。就我而言,每个Range只有一个唯一的书签要添加。如果第一页上的标题有一个单词" MyWord"在我想要放置书签的地方,下面的代码将放置" MyWord1"。如果另一页上的标题具有相同的单词" MyWord",则书签名为" MyWord2"将被安置。

    public static void AddBookmarkAnywhere(Microsoft.Office.Interop.Word.Application app, string findText, string bookmarkName)
    {
        var doc = app.ActiveDocument;
        bool bFound;
        int occurenceNumber = 1; 
        foreach (Microsoft.Office.Interop.Word.Range rngStory in doc.StoryRanges)
        {
            var internalRangeStory = rngStory;
            do
            {
                bFound = AddBookmarkInStory(internalRangeStory, findText, bookmarkName + occurenceNumber.ToString());
                if(bFound)
                {
                    occurenceNumber++;
                }

                try
                {
                    switch (internalRangeStory.StoryType)
                    {
                        case Microsoft.Office.Interop.Word.WdStoryType.wdEvenPagesHeaderStory: // 6
                        case Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryHeaderStory:   // 7
                        case Microsoft.Office.Interop.Word.WdStoryType.wdEvenPagesFooterStory: // 8
                        case Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryFooterStory:   // 9
                        case Microsoft.Office.Interop.Word.WdStoryType.wdFirstPageHeaderStory: // 10
                        case Microsoft.Office.Interop.Word.WdStoryType.wdFirstPageFooterStory: // 11

                        if (internalRangeStory.ShapeRange.Count > 0)
                        {
                            foreach (Microsoft.Office.Interop.Word.Shape oShp in internalRangeStory.ShapeRange)
                            {
                                if (oShp.TextFrame.HasText != 0)
                                {
                                    AddBookmarkInStory(oShp.TextFrame.TextRange, findText, bookmarkName);
                                }
                            }
                        }
                        break;

                        default:
                            break;
                    }
                }
                catch
                {
                    MessageBox.Show("Some error in function AddBookmarkAnywhere");
                }

                internalRangeStory = internalRangeStory.NextStoryRange;
            }
            while (internalRangeStory != null); 
        }
    }

    private static bool AddBookmarkInStory(Microsoft.Office.Interop.Word.Range rngStory, string strSearch, string bookmarkName)
    {
        rngStory.Find.ClearFormatting();
        rngStory.Find.Replacement.ClearFormatting();
        rngStory.Find.Text = strSearch;
        rngStory.Find.Replacement.Text = string.Empty;

        object findText = strSearch;
        object replaceText = strSearch;
        object matchCase = true;
        object matchWholeWord = true;
        object matchWildCards = false;
        object matchSoundsLike = false;
        object matchAllWordForms = false;
        object forward = true;
        object format = false;
        object matchKashida = false;
        object matchDiacritics = false;
        object matchAlefHamza = false;
        object matchControl = false;
        object read_only = false;
        object visible = true;
        object replace = 0;  // replace = 0 replaces None, replace = 1 replaces One, replace = 2 replaces All
        object wrap = 1;

        string bookmarkStr;
        bool isFound = false;
        isFound = rngStory.Find.Execute(strSearch, matchCase, matchWholeWord,
            matchWildCards, matchSoundsLike, matchAllWordForms, forward, 
            wrap, format, replaceText, replace, matchKashida, 
            matchDiacritics, matchAlefHamza, matchControl);            

        if(isFound) {
            rngStory.Select();
            rngStory.Bookmarks.Add(bookmarkName, rngStory);
            return true;
        }

        return false;
    }