2015-12-13 72 views
-1

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

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); 
     } 
    } 

回答

1

你有正确的想法,你只是错过了查找功能,你需要的地方“的IndexOf”的使用,并试图用捕捉文本的位置Range对象的开始和结束属性。

这些不是一种可靠的方式来处理Word文档中的文本,因为Word存储“非打印字符”的信息非常多。举个例子,如果您的页眉显示一个动态页码或日期,那么在幕后会有一个与开始和结束位置相混淆的字段代码。

因此,请在语言参考中查找FIND(Selection和Range对象的属性 - 您绝对需要RANGE.FIND)以获得它的感觉。为了找到正确的语法,在录制宏时在UI中使用它,然后查看VBA并将其与语言引用进行比较。互联网上还有大量的样本代码。

要注意的是,在成功的Find.Execute上,Find运行的RANGE对象将包含搜索项的“found”实例。所以你可以简单地使用它作为Bookmarks.Add的“目标”。

+0

谢谢辛迪。我第一次尝试使用Find函数,但我不知道如何去做。在进一步挖掘网络甚至一些个人想法之后,我能够提出一个符合我需求的代码。 –

0

我找到了解决我的问题的方法。在我的情况下,每个范围只有一个唯一的书签添加。如果第一页上的标题有一个单词“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; 
    } 
+0

伟大的:-)是的,文档中的书签名称必须是唯一的。对你的代码的一个评论:你不需要选择范围来加入书签。一般来说,“我们”不会这样做 - 特别是当一系列操作正在执行时 - 因为它会导致屏幕闪烁(烦人用户)并且会减慢处理速度。尝试注释掉rngStory.Select();并看看你的代码是否满意地执行没有?如果你想让用户“在”最后一个书签,我会在你的代码结尾做一个选择。 –

+0

感谢Cindy的建议。没有Select(),它会更好。 –