2012-11-09 40 views
2

我試圖在列表之前插入文本。我有列表的Microsoft.Office.Interop.Word.Range,並獲得列表之前的前一個範圍。然後,我嘗試將段落文本添加到前一個範圍,但是,該段落將作爲列表中的第一個項目添加,而不是添加到列表之前。使用Word Interop在列表前插入文本

// rangeObj is the Range object for the list 
var previousRange = rangeObj.Previous(MSWord.WdUnits.wdCharacter, 1); 

Paragraph paragraph; 
if (previousRange == null) 
{ 
    var rangeCopy = rangeObj.Duplicate; 
    rangeCopy.InsertParagraphBefore(); 
    paragraph = rangeCopy.Paragraphs[1]; 
} 
else 
{ 
    paragraph = previousRange.Paragraphs[1]; 
} 

Range range = paragraph.Range; 
range.Text = String.Format("{0} {1}", "My list", range.Text); 

例如, 前:

  1. 項目1
  2. 項目2

後(我想):

我的目錄

  1. 項目1
  2. 項目2

之後(什麼我目前得到):

  1. 我的目錄
  2. 項目1個
  3. 項目2

編輯: 每拉塞的回答和我的評論,除了下面的邊緣情況,我正在讓所有的工作都可以工作。注意:第二個列表不是第一個列表的子列表,每個列表之間沒有空行。

if (previousRange.ListParagraphs.Count > 0) 

之前:

  1. 項目1
  2. 項目2

    1. 項目3
    2. 項目4

後(我想):

  1. 項目1
  2. 項目2

    另一個列表:

    1. 項目3
    2. 項目4
+0

並且將「\ r」添加到我的文本末尾也不起作用。它在列表項目2處添加一個空項目,並將項目1和2在列表中向下移動。 –

回答

1

在此代碼:

else 
{ 
    paragraph = previousRange.Paragraphs[1]; 
} 

..你有冒險覆蓋任何東西之前的列表(包括其中只有\r空行),當我運行它的樣本,這是很有道理的事情被覆蓋,最終發生奇怪。

在此代碼:

if (previousRange == null) 
{ 
    var rangeCopy = rangeObj.Duplicate; 
    rangeCopy.InsertParagraphBefore(); 
    paragraph = rangeCopy.Paragraphs[1]; 
} 

..你插入列表之前一個新段落(這是好的 - 儘管,我不明白爲什麼有必要克隆的範圍內,爲the range automatically expands to include the newly inserted paragraph)和然後將新段落的範圍存儲在本地變量paragraph中。在這一點上,paragraph = '\r'的內容 - (如果您在調試階段通過應用程序瀏覽應用程序,同時在調試階段保持單詞可見,則會看到此內容)。所以,在這一點上,光標就在列表中,這是你希望它是前定位 - 但你執行以下操作:

Range range = paragraph.Range; 
range.Text = "My paragraph"; 

...含義而非預未決文本到您只需覆蓋包括\r在內的所有內容,這會導致Word將文本插入到列表中而不是之前。

爲了繞過這個,我做了一個似乎可行的替代實現。它基於您在列表之前使用範圍來插入文本的想法。我已經加入了大部分線路的意見,所以它應該是直截了當地遵循什麼是對:)

using System; 
using System.Linq; 
using Microsoft.Office.Interop.Word; 
using Application = Microsoft.Office.Interop.Word.Application; 

namespace WordDocStats 
{ 
    internal class Program 
    { 
     private static void Main() 
     { 
      var wordApplication = new Application() { Visible = true }; 

      // Open document A 
      var documentA = wordApplication.Documents.Open(@"C:\Users\MyUser\Documents\documentA.docx", Visible: true); 

      // This inserts text in front of each list found in the document 
      const string myText = "My Text Before The List"; 
      foreach (List list in documentA.Lists) 
      { 
       // Range of the current list 
       var listRange = list.Range; 

       // Range of character before the list 
       var prevRange = listRange.Previous(WdUnits.wdCharacter); 

       // If null, the list might be located in the very beginning of the doc 
       if (prevRange == null) 
       { 
        // Insert new paragraph 
        listRange.InsertParagraphBefore(); 
        // Insert the text 
        listRange.InsertBefore(myText); 
       } 
       else 
       { 
        if (prevRange.Text.Any()) 
        { 
         // Dont't append the list text to any lines that might already be just before the list 
         // Instead, make sure the text gets its own line 
         prevRange.InsertBefore("\r\n" + myText); 
        } 
        else 
        { 
         // Insert the list text 
         prevRange.InsertBefore(myText); 
        } 
       } 
      } 

      // Save, quit, dones 
      Console.WriteLine("Dones"); 
      Console.ReadLine(); 
      documentA.Save(); 
      wordApplication.Quit(); 
     } 
    } 
} 

在做空,代碼插入文本中的每個列表之前的字符串。如果列表前的行上已有文本,則實現會確保將列表描述文本插入到列表之前,並且已經位於列表之前的行上的文本之後。

希望這有助於:)

--- UPDATE來回答編輯的問題:

辦法實現你問這裏的第二輪做這樣的事情:

... 
// The paragraph before the current list is also a list -> so in order to insert text, we must do "some magic" 
else if(prevRange.ListParagraphs.Count > 0) 
{ 
    // First, insert a new line -> this causes a new item to be inserted into the above list 
    prevRange.InsertAfter("\r"); 

    // Modify current range to be on the line of the new list item 
    prevRange.Start = prevRange.Start + 1; 
    prevRange.End = prevRange.Start; 

    // Convert the list item line into a paragraph by removing its numbers 
    prevRange.ListFormat.RemoveNumbers(); 

    // Insert the text 
    prevRange.InsertBefore(myText); 
} 
... 

只是,代碼添加到if-elseforeach循環示例代碼我提供的內d以上,你應該很好:)我已經在我的機器上用MS Word 2013測試過它,它似乎工作。

+0

我實際上想把我的文本預先放在現有段落的前面,所以我用'previousRange.Paragraphs [1] .Range.InsertBefore(markingText +「」);'代替。我修正了我的代碼示例來說明這一點。除了一個邊緣情況以外,其他一切都很好。我仍然有問題試圖在兩個列表之間添加一行。對於這種情況,我不想在前一段(列表項)前面添加文本,而是添加一行。思考?我會和我的問題約會以顯示這個例子。 –

+0

@JoeW我現在已經更新了我的答案,以反映你的編輯以及:) –

+0

非常感謝!值得注意的是,我使用'prevRange.Paragraphs [1] .Reset();'來保留當前段落格式,而不是'prevRange.ListFormat.RemoveNumbers();',它將刪除所有格式。其他一切都按照我的需要工作。 –

相關問題