2015-12-13 71 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(),它會更好。 –