2011-03-22 76 views
4

從Delphi XE開始使用som自動執行Word時,我同時打開兩個文檔。我想將一個文檔的給定範圍的內容複製到另一個文檔中的另一個範圍。我怎樣才能做到這一點?OLE自動化:如何在不使用剪貼板的情況下在Word文檔之間複製文本

考慮下面的代碼:

procedure TForm1.ManipulateDocuments; 
var 
    vDoc1,vDoc2 : TWordDocument; 
    vFilename : olevariant; 
    vRange1,vRange2 : Range; 
begin 
    vDoc1 := TWordDocument.Create(nil); 
    vDoc2 := TWordDocument.Create(nil); 
    try 
    vFilename := 'c:\temp\test1.doc'; 
    vDoc1.ConnectTo(FWordApp.Documents.Open(vFilename,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam)); 

    vFilename := 'c:\temp\test2.doc'; 
    vDoc2.ConnectTo(FWordApp.Documents.Open(vFilename,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam)); 

    vRange1 := GetSourceRange(vDoc1); 
    vRange2 := GetDestinationRange(vDoc2); 

    vRange2.CONTENTS := vRange1.CONTENTS; //What should I substitute for CONTENTS? 
    finally 
    vDoc1.Free; 
    vDoc2.Free; 
    end; 
end; 

有什麼我可以代替內容是什麼?我不能使用文本,因爲我想複製格式,書籤,字段代碼等。我必須以另一種方式完成這些任務嗎?有什麼建議麼?

回答

3

我不知道早期版本的Word的一種方式,但對於較新的版本(2007年及以後),您可以將export a range從文檔轉換爲片段文件,然後從其他文檔中獲取import。如果你想早綁定,你可能需要導入類型庫(msword.olb),我不知道Delphi XE是否擁有它。否則,代碼可能是這樣的:

function GetTempFileName(Prefix: string): string; 
begin 
    SetLength(Result, MAX_PATH); 
    GetTempPath(MAX_PATH, PChar(Result)); 
    windows.GetTempFileName(PChar(Result), PChar(Prefix), 0, PChar(Result)); 
end; 

procedure TForm2.Button1Click(Sender: TObject); 
const 
// wdFormatDocument = 0; 
    wdFormatRTF = $00000006; 
var 
    WordApp : OleVariant; 
    fragment: string; 
    vDoc1, vDoc2: OleVariant; 
    vRange1, vRange2: OleVariant; 
begin 
    try 
    WordApp := GetActiveOleObject('Word.Application'); 
    except 
    WordApp := CreateOleObject('Word.Application'); 
    end; 
    WordApp.Visible := True; 

    vDoc1 := WordApp.Documents.Open(ExtractFilePath(Application.ExeName) + 'test1.doc'); 
    vRange1 := vDoc1.Range(20, 120);  // the export range 
    fragment := GetTempFileName('frg'); 
    vRange1.ExportFragment(fragment, wdFormatRTF); 
    try 
    vDoc2 := WordApp.Documents.Open(ExtractFilePath(Application.ExeName) + 'test2.doc'); 
    vRange2 := vDoc2.Range(15, 15); // where to import 
    vRange2.ImportFragment(fragment); 
    finally 
    DeleteFile(fragment); 
    end; 
end; 

用我的測試中,「文件」格式拋出一個錯誤(有點像不能夠插入XML格式),因此,RTF格式的使用。

編輯:

與早期版本,這似乎是可以插入從一個文檔命名選擇到另一個文檔中進行選擇。如果其中一個選項恰好處於某些文本的中間,則結果似乎並不完美。但否則它似乎運作良好。

... 
    WordApp.Visible := True; 

    vDoc1 := WordApp.Documents.Open(ExtractFilePath(Application.ExeName) + 'test1.doc'); 
    vRange1 := vDoc1.Range(20, 188);     // the transfer range 
    vDoc1.Bookmarks.Add('TransferSection', vRange1); // arbitrary bookmark name 

    vDoc2 := WordApp.Documents.Open(ExtractFilePath(Application.ExeName) + 'test2.doc'); 
    vRange2 := vDoc2.Range(103, 104);   // where to import the bookmark 
    vRange2.Select; 
    vDoc2.ActiveWindow.Selection.InsertFile(vDoc1.FullName, 'TransferSection'); 

    vDoc1.Bookmarks.Item('TransferSection').Delete; // no need for the bookmark anymore 
  
+0

我已經注意到這些函數(exportfragment/importfragment),它們對我的需要來說是完美的。不幸的是,Word 2007不適合我。我們的解決方案需要運行Word 2003的用戶,可能甚至更早,這些功能不可用。不過謝謝。到目前爲止最好的建議:-) – 2011-03-24 07:13:58

+0

更新:由於沒有其他答案,我會接受這個最好的。不過,它讓我感到害怕,沒有涉及剪貼板或使用外部文件的方法,沒有好的辦法。這似乎很基本: -/ – 2011-04-04 07:38:12

+0

@Svein - 我已經用另一種方法更新了答案。如果它仍然不能令人滿意,我會建議在標籤中加入'msword'並且暫時保持這個問題不被回答。 – 2011-04-05 22:41:30

-3

爲什麼不使用剪貼板?如果在vDoc1中選擇了所有文本,則將其複製到剪貼板只需一個簡單的調用:vDoc1.copy。同樣,將剪貼板的內容複製到第二個文檔需要一個簡單的調用:vDoc2.paste。剪貼板緩衝區將保存所有的格式信息。

+3

首先,如果我使用剪貼板,我會刪除用戶放在那裏的任何東西。這不是一件好事。此外,此應用程序通常在剪貼板與本地剪貼板同步的終端服務器上運行,從而導致性能問題。 – 2011-03-23 10:26:01

+2

-1剪貼板屬於用戶,而不是你。除非用戶啓動剪貼板(例如複製或剪切或粘貼),否則您絕對不應做任何影響剪貼板內容的操作。 – 2011-03-23 11:28:52

1

如果你可以使用Office Open XML -format(即在Word 2007年推出的docx文件格式),那麼你就可以做到這一點沒有自動化。

的Word 2007年之前的版本必須安裝compatibility pack這將使DOCX,文件的Word 2003,2002年和2000年

的的docx文件實際上是一個zip文件,其中包含一些XML的文件。嘗試將docx文件的擴展名從.docx更改爲.zip,然後在例如.doc中打開該文件。 WinZip的。

因此...解壓縮docx文件並獲取您需要的xml部分。作爲純字符串或xml文檔。然後你可以將這個XML部分注入到其他docx文件中。不過,您需要知道,其中在xml結構中可以抓取/插入xml。這將取決於您如何瞭解文檔結構以及允許用戶在文檔中進行多少編輯。

我不知道Word如何處理重複的書籤名稱等與此方法。

0

看來我發現了這個問題的標準解決方案,同時挖掘到類似的問題。 FormattedText Range對象的屬性確切地說是你需要的。只需使用:

vRange2.FormattedText := vRange1; 

和vRange1的內容將被複制到vRange2。此外,這也適用:

vRange2 := vRange1; 

雖然,第二條語句不復制格式。

相關問題