2012-04-25 2 views
3

저는 Delphi 응용 프로그램에서 Word 자동화를 사용하며 속도가 매우 느립니다. 나는 내 코드를 최소한으로 제거하고 경험이있는 사람이 내가 잘못 갔다는 것을 알 수 있기를 바랬다. (실제로 나는 이 잘못되어있어 내가 속도를 낼 수 있기를 바란다)Delphi XE2에서 단어 자동화를 가속화하는 방법

내 응용 프로그램의 자동화 본질은 책갈피를 처리합니다. 응용 프로그램은 몇 가지 특수 책갈피가있는 문서를 열고이를 실행하고 이름을 기반으로 변경합니다. 실제 버전은 문서 변수와 필드 코드를 많이 다루고 있습니다. 일반적인 문서에는 50-80 개의 책갈피가 있으며 그 중 일부는 중첩되어 있습니다. 또한 임시 문서를 사용하여 생성 될 문서에 연속적으로 배치되는 텍스트 및 이미지 블록을 작성합니다. 첨부 된 코드는이 기능이없는 VERY 버전에서 제외되었지만 원하지 않는 동작 (예 : 문서 생성 시간)을 표시합니다. 첨부 된 샘플에서 문서를 생성하는 데 약 2.5 초가 소요됩니다. 일반적인 실제 문서의 경우 약 30-40 초 정도 소요됩니다.

내가 바라는 것은 "이 모든 것을 잘못하고있는 것입니다 .Delphi에서 Word Automation을 수행 할 때 항상 XXX을 기억해야합니다!"라고 말하기를 바랍니다.

전체 프로젝트가 완전히 벗겨 졌을 때도 상당히 크기 때문에이 작은 응용 프로그램을 만들었습니다. 내가하는 방식에 분명한 실수가 있다면,이 코드에서 분명히 알 수있을 것이다.

새 VCL Forms 응용 프로그램을 만드십시오. Word를 열고 새 문서를 만듭니다. 첫 번째 줄에 텍스트를 입력하고 표시하고 책갈피를 삽입하십시오. 두 번째 줄에 텍스트를 입력하고 책갈피를 지정하십시오. 'c : \ temp \ bm.doc'파일을 Word 97-2003 문서로 저장하십시오. 응용 프로그램을 실행 한 후 첫 번째 줄에는 임의 번호가 있고 책갈피는없는 새 문서 ('c : \ temp \ bm_generated.doc')가 있어야합니다.

vWordApp.ScreenUpdating := False; 

을 어쩌면 또한

vWordApp.Visible := False; 

는 (완료되면 이전 값으로 다시 설정하는 기억) :

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, OleServer, WordXP, Vcl.StdCtrls; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 

    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    vWordApp : TWordApplication; 
    vDoc  : WordDocument; 
    vFileName : OleVariant; 
    vIndex  : OleVariant; 
    vBookmark : Bookmark; 
    vSave  : OleVariant; 
begin 
    vWordApp := TWordApplication.Create(nil); 
    try 
    vWordApp.ConnectKind := ckNewInstance; 
    vWordApp.Connect; 
    vFileName := 'c:\temp\bm.doc'; 
    vDoc := vWordApp.Documents.Open(vFileName, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam); 

    //Replace bookmark text with random string: 
    vIndex := 1; 
    vBookmark := vDoc.Bookmarks.Item(vIndex); 
    vBookmark.Range.Text := inttostr(random(10000)); //Will also delete the bookmark! 

    //Delete bookmark content and bookmark 
    vIndex := 1; //This will be the bookmark that was originally the first, since that was deleted when we sat the text 
    vBookmark := vDoc.Bookmarks.Item(vIndex); 
    vWordApp.Selection.SetRange(vBookmark.Range.Start, vBookmark.Range.End_); 
    vWordApp.Selection.Text := ''; 

    vFileName := 'c:\temp\bm_generated.doc'; 
    vDoc.SaveAs2000(vFileName, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam); 

    vWordApp.NormalTemplate.Saved := true; //For å slippe spørsmål om "normal.dot" skal lagres 
    vSave := wdDoNotSaveChanges; 
    vWordApp.Quit(vSave); 
    vWordApp.Disconnect; 
    finally 
    vWordApp.Free; 
    end; 
end; 

end. 
+0

문서 작업을 할 때마다'TWordApplication' 인스턴스를 유지하거나 새로운 인스턴스를 생성합니까? 나는 당신이 그것을 지킬 것이라고 확신한다. 그래서 어리석은 쪽지로 표시된다 :-) – TLama

+0

어리석은. 한 번에 여러 문서를 생성하는 경우 동일한 TWordApplication을 사용하지만 대부분의 경우에는 그렇지 않습니다. 이것은 ERP 응용 프로그램의 인쇄 루틴의 일부이므로 인쇄 대화 상자에서 단어 - 문서가 생성되어야 함을 나타낼 때 TWordApplication을 만들고 완료되면 자유롭게 만듭니다. –

+1

그 코드는 나에게 잘 어울립니다. 아마 그것이 얼마나 오래 걸릴지도 모릅니다. –

답변

2

당신은 시도 할 수 있습니다.

+2

게시 된 코드에 애플리케이션이 표시되지 않습니다. –

+0

실제 버전에서는 단어가 보이지 않습니다. 그러나 박탈 된 버전에서 나는 그것을 포함하지 않았다. (하지만 ScreenUpdating에 대해서는 몰랐습니다.) –

+0

일부 참조 MS Word 문서를 생성하는 데 필요한 시간을 고려하면 좋을 것입니다. – truthseeker

0

VBA에 매개 변수를 제공하고 단어로 대체 하시겠습니까? 나는 몇백 년 전에 클라이언트를 위해 워드 문서에서 몇백 개의 매크로를 만들었다. 그것은 내가 기억하는 것보다 훨씬 빨리 구현되었습니다. 그것은 Java 코드베이스에서 나온 것입니다.

Word는 처음에는 문서를로드하고 구문 분석하는 데 많은 시간을 소비합니다. 시간의 대부분이 소비 된 곳 일 수도 있습니다. 책갈피 바꾸기를 수행하지 않아도 타이밍 테스트의 기준이됩니다. 다른 하나는 각 교체에 대해 전체 텍스트 스캔을 수행하고있는 것입니다. VBA가 더 효과적이었던 이유 일 수 있습니다.

+0

북마크 없이는 옵션이 아닙니다. 그리고 AFAIK VBA는 Delphi에서와 마찬가지로 객체 모델을 사용하므로 속도에 영향을 미치지 않는다고 생각합니다. –

+0

그래야 겠지만 그렇지 않을 것 같습니다. 아마도 Word는 매번 전체 환경을 인스턴스화합니다. 확실하지는 않지만 단지 문제에 대한 극적인 해결책이라는 것을 기억합니다. 매번 스레드를 뒤집어서 전화를 걸면 향상 될 수 있으므로 Application.HandleMessage를 몇 번 호출해야합니다. 그것은 많은 순수 주의자들에 의한 해킹으로 간주되며, 때때로 유용 할 것이라고 나는 주장하지 않을 것이다. 이 답변의 다른 부분은 응용 프로그램간에 수행하는 왕복 횟수를 제한하는 것입니다. 그들 모두는 지체를 유도합니다. – Michael

관련 문제