4

Delphi アプリケーションから Word オートメーションを使用していますが、非常に低速です。私は自分のコードを最小限に抑えました.経験のある人がどこで間違ったのか教えてくれることを望んでいました.

私のアプリケーションの自動化の本質は、ブックマークを扱います。アプリケーションは、いくつかの特別なブックマークを含むドキュメントを開き、これらを実行して名前に基づいて変更します。実際のバージョンでは、ドキュメント変数とフィールドコードも頻繁に扱います。一般的なドキュメントには 50 ~ 80 個のブックマークがあり、そのうちのいくつかはネストされています。また、いくつかの一時ドキュメントを使用してテキストと画像のブロックを作成し、生成されるドキュメントに連続して配置します。添付のコードは、この機能のない非常に簡素化されたバージョンですが、望ましくない動作 (つまり、ドキュメントを生成する時間) が表示されます。添付のサンプルでは、​​ドキュメントの生成に約 2.5 秒かかります。典型的な実際のドキュメントの場合、約 30 ~ 40 秒かかり、場合によってはそれ以上かかります。

私が望んでいるのは、誰かが「あなたはこれをすべて間違っています。Delphi から Word Automation を実行するときは、常に XXX を覚えておく必要があります!」と言ってくれることです。

プロジェクト全体は、完全に削除されたとしてもかなり大きいので、この小さなアプリケーションを作成しました。私のやり方に明らかな誤りがある場合は、このコードから明らかになることを願っています。

新しい VCL フォーム アプリケーションを作成してください。Word を開き、新しい文書を作成します。最初の行にテキストを入力し、それをマークしてブックマークを挿入します。2 行目にテキストを入力し、これもブックマークします。ファイルを「c:\temp\bm.doc」として Word 97-2003 ドキュメントとして保存します。アプリケーションを実行すると、最初の行に乱数があり、ブックマークがない新しいドキュメント ('c:\temp\bm_generated.doc') が作成されます。

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.
4

3 に答える 3

2

あなたは試すことができます:

vWordApp.ScreenUpdating := False;

そして多分また

vWordApp.Visible := False;

(完了したら、前の値に戻すことを忘れないでください)。

于 2012-04-25T11:57:15.023 に答える
0

パラメータを VBA に指定して、Word 内で置換を行ってみましたか? 数年前、私はクライアントのために Word ドキュメントで数百のマクロを作成しました。私が覚えている限り、それははるかに迅速な実装でした。それはJavaコードベースからのものでした。

Word は、最初にドキュメントの読み込みと解析に多くの時間を費やします。そこに多くの時間が費やされているのかもしれません。ブックマークの置換を行わないことで、タイミング テストの基準を設定します。もう 1 つのことは、置換ごとに全文スキャンを実行している可能性があることです。それが、VBA の方がうまく機能した理由かもしれません。

于 2012-04-25T18:21:07.510 に答える