如何加速Delphi XE2的文字自动化

时间:2012-04-25 11:14:10

标签: delphi automation ms-word ole

我使用Delphi应用程序中的Word自动化,速度非常慢。我已将我的代码剥离到最低限度,并且希望有经验的人可以告诉我哪里出错了(而且我实际上希望我 出错了所以我可以加快速度)

我的应用程序中自动化的本质是处理书签。应用程序打开一个带有一些特殊书签的文档,运行这些书签并根据它们的名称进行更改。真实版本还大量处理文档变量和字段代码。典型的文档有50-80个书签,其中一些是嵌套的。我还使用一些临时文档来构建文本块和图像,这些文本和图像连续放置在要生成的文档中。附加的代码是一个没有此功能的非常简化的版本,但它显示了不需要的行为(即生成文档的时间)。在附带的示例中,生成文档大约需要2.5秒。对于典型的真实文档,它需要大约30-40秒,有时甚至更多。

我所希望的是有人说“你这样做是错的。从Delphi做Word Automation时,你必须永远记住XXX!”。

由于整个项目,即使完全剥离,也是非常大的,我已经做了这个小应用程序。如果我这样做有一个明显的错误,那么希望从这段代码中可以看出它。

请创建一个新的VCL表单应用程序。打开Word,然后创建一个新文档。在第一行输入一些文本,标记并插入书签。在第二行输入一些文本,并将其加入书签。将文件另存为“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.

3 个答案:

答案 0 :(得分:2)

你可以尝试:

vWordApp.ScreenUpdating := False;

也许

vWordApp.Visible := False;

(记得在完成时回到以前的值)。

答案 1 :(得分:0)

您是否尝试过向VBA提供参数并在单词内进行替换?几年前,我为客户在word文档中做了几百个宏。从我记忆中看,这是一个更快的实现。那是来自Java代码库。

Word首先花费大量时间加载和解析文档。这可能是花费大部分时间的地方。我会通过不做书签替换来进行时序测试。另一件事是,它可能正在为每个替换进行全文扫描。这可能就是VBA更好的原因。

答案 2 :(得分:0)

如果您只使用书签和域代码来做基本工作(不要介意IF构造),则可以考虑将文档转换为RTF并在那里进行更改。我这样做可以在每个文档0.005秒内运行代码。 保存文件大约需要0.2-2秒,具体时间取决于磁盘驱动器的速度。