Board index » delphi » Word question: Late binding faster than early binding???

Word question: Late binding faster than early binding???

The following code will search for a '<' in a document.  If found, it will
replace the characters at that position with the string 'merged stuff'.  The
logic assumes there are no more than 20 characters between '<' and '>'
pairs.

My question -- is there any way to make this go any faster?  The reason why
i'm concerned is that i'm finding equivalent late-binding logic to be faster
than this early binding logic.  What gives??

(please note that i'm not interested in using ms-word's merge capabilities)

Thanks very much for the attention
Charles McAllister

procedure TForm1.NewButtonClick(Sender: TObject);
var
  WordApp : WordApplication;
  TextRange : Range;
  Text_variant : OleVariant;
  File_variant : OleVariant;
  Index : Integer;
  Variable_str : string;
  Index_pos : Integer;
  Boolean_variant : OleVariant;
  Changes_variant : OleVariant;
  RevertVariant : OleVariant;
  CopiesVariant : OleVariant;
  BackgroundVariant : OleVariant;
begin
  ElapsedCount := GetTickCount;

  WordApp := CoWordApplication.Create;

  WordApp.ActivePrinter := Printer.Printers[0];

  File_variant := 'C:\SOMEDOC.DOC';
  RevertVariant := TRUE;
  CopiesVariant := 1;
  BackgroundVariant := False;

  for Index := 1 to TimesEdit.Value do begin
    WordApp.Documents.Open (File_variant, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, RevertVariant, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam);

    repeat
      TextRange := WordApp.ActiveDocument.Content;

      Text_variant := '<';

      TextRange.Find.Execute (Text_variant, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, Boolean_variant, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
      if TextRange.Find.Found then begin
        TextRange.End_ := TextRange.Start + 20;
        Variable_str := TextRange.Text;
        Boolean_variant := True;

        Index_pos := Pos('>', Variable_str);
        if Index_pos > 0 then begin
          Variable_str := LowerCase(Copy(Variable_str, 1, Index_pos));

          Text_variant := Variable_str;
          TextRange.Find.Execute (Text_variant, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, Boolean_variant, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);

          TextRange.Text := 'merged stuff';
        end;
      end else
        Break;
    until False;
    {WordApp.ActiveDocument.PrintOut (BackgroundVariant, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, CopiesVariant,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam);}
  end;

  Changes_Variant := wdDoNotSaveChanges;
  WordApp.Quit (Changes_Variant, EmptyParam, EmptyParam);
  WordApp := nil;
  ShowMessage ('done' + InttoStr(GetTickCount - ElapsedCount));
end;

procedure TForm1.OldButtonClick(Sender: TObject);
var
  WordVariant : Variant;
  Index : Integer;
  Variable_str : string;
  Index_pos : Integer;
  Temp_position : Integer;
begin
  ElapsedCount := GetTickCount;
  WordVariant := CreateOLEObject ('WORD.BASIC');

  for Index := 1 to TimesEdit.Value do begin
    WordVariant.FileOpen (Name := 'C:\SOMEDOC.DOC', Revert := 1, ReadOnly :=
1);
    {WordVariant.StartOfDocument;}

    repeat
      WordVariant.EditFind (Find := SearchEdit.Text);
      if WordVariant.EditFindFound then begin
        Temp_position := WordVariant.GetSelStartPos;

        Variable_str := WordVariant.GetText(Temp_position, Temp_position +
19);
        Index_pos := Pos('>', Variable_str);
        if Index_pos > 0 then begin
          Variable_str := LowerCase(Copy(Variable_str, 1, Index_pos));

          WordVariant.CharLeft (1, 1);  // De-select first character of
variable so Find will work
          WordVariant.EditReplace (Find := Variable_str, Replace := '',
ReplaceOne := 1);
          WordVariant.Insert ('merged stuff');
        end;
      end else
        Break;
    until False;

    {//WordVariant.FilePrint (NumCopies := 1, Background := 0);}
    WordVariant.FileClose (2);
  end;

  WordVariant.AppClose;
  ShowMessage ('done' + InttoStr(GetTickCount - ElapsedCount));
end;

 

Re:Word question: Late binding faster than early binding???


<<Charles McAllister:
The reason why i'm concerned is that i'm finding equivalent
late-binding logic to be faster than this early binding
logic.  What gives??

Quote

Well, GetTickCount is not a reliable tool for profiling
code; and you aren't using equivalent late bound code,
actually, but the old WordBasic stuff. Normally the newer
VBA (Word.Application) calls should be faster than that,
but there's no guarantee.

There aren't any obvious optimizations that leap out at me,
at least assuming you have turned screen updates off. Find
is not a fast operation (particularly the first time it's
called, ISTM), so if you've found a faster way, go for it.
:)

--
Deborah Pate (TeamB) http://delphi-jedi.org

  Use Borland servers; TeamB don't see posts via ISPs
  http://www.borland.com/newsgroups/genl_faqs.html

Re:Word question: Late binding faster than early binding???


Deborah Pate (TeamB) wrote in <VA.0000024f.006a7...@cableinet.co.not-this-
bit.uk>:

Quote
>Well, GetTickCount is not a reliable tool for profiling
>code;

Oh, why not? I've used it a fair bit and it always seemed ok. Could you
enlighten me on that one?

Thanks

Marc Pelletier

-----------------------------------------------------------------------------
Data Donkey - Geophysical Data Processing, Consulting and Software
Development
            Creator of the POWER TOOLBOX utilities for OASIS montaj
      contact: m...@datadonkey.com  tel (306) 931-6853 or www.datadonkey.com

Re:Word question: Late binding faster than early binding???


<<Marc Pelletier:
Oh, why not? I've used it a fair bit and it always seemed
ok.

Quote

Because Windows can organize its time as it likes, you
don't get reliable consistency. Here are a couple of
freeware tools you might like:
http://www.poboxes.com/astoyanov/index.htm
http://www.optimalcode.com/tools.htm

--
Deborah Pate (TeamB) http://delphi-jedi.org

  Use Borland servers; TeamB don't see posts via ISPs
  http://www.borland.com/newsgroups/genl_faqs.html

Re:Word question: Late binding faster than early binding???


"Deborah Pate (TeamB)" <d.p...@cableinet.co.not-this-bit.uk> wrote in
message news:VA.00000274.0020bd55@cableinet.co.not-this-bit.uk...

Quote
> <<Marc Pelletier:
> Oh, why not? I've used it a fair bit and it always seemed
> ok.

I use my stopwatch component sometimes for really accurate timing.  But
alas, one doesn't need a timer to really see that one of the events I listed
is faster than the other...so after rewriting a lot of my application, I've
gone back to word basic for now.

Charles

type
  TcmvcStopWatch = class(TComponent)
    private
      Frequency : TLargeInteger;
      StartCount, EndCount : TLargeInteger;
    published
      property ElapsedStr : string...
      etc...
  end;

procedure TcmvcStopWatch.Star{*word*53}ch;
begin
  QueryPerformanceFrequency (Frequency);
  QueryPerformanceCounter (StartCount);
  if Assigned(FOnStar{*word*53}ch) then
    FOnStar{*word*53}ch (Self);
end;

procedure TcmvcStopWatch.StopWatch;
begin
  QueryPerformanceCounter (EndCount);
  ElapsedValue := (EndCount - StartCount) / Frequency;
  ElapsedStr := FloatToStrF (ElapsedValue, StringFormat, 10, 10);
  if Assigned(FOnStopWatch) then
    FOnStopWatch (Self);
end;

Other Threads