Solved

How do I pass data to MS Word from App?

Posted on 1998-03-10
9
692 Views
Last Modified: 2008-02-01
I use Delphi 2 Professional and would like to know how to pass data from a Delphi application to a MS Word document. I believe it is something to do with OLE but am not sure. I looked up the Word Help and it mentions fields but it isn't too clear as to what I should do. I need to input data into a template word doc and need to be able to put the data in the exact place in the document. For instance a persons' name and address would need to be put into the document at the left hand side and billing data within text in the doc etc. There would be standard text with only a few details changing that I'd pass to word.
Any help will be gratefully appreciated. Thanks in advance,

Dave.
0
Comment
Question by:scotslad
  • 4
  • 4
9 Comments
 
LVL 5

Expert Comment

by:ronit051397
Comment Utility
This is from Delphi Help file:

Example

The following example shows a simple example that takes data from a query, inserts it into a Microsoft Word document, and formats the inserted text as a table. You must have Microsoft Word running with a document open for the automation to work.

1      Create a new application with a blank form.
2      Add a uses clause to the implementation part of the blank form's unit that adds the OleAuto unit:

uses OleAuto;      { put this in the implementation part }

3      Place a Query component on the form.
4      Set the query's DatabaseName property to the DBDEMOS alias.
5      Place a Button component on the form.
6      Attach the following handler to the button's OnClick event:

procedure TForm1.Button1Click(Sender: TObject);
var  MSWord: Variant;
  I: Integer;
  S: string;
begin
  Query1.SQL := 'select company, contact, phone from customer ' +
    'where lastinvoicedate >= ''1/1/95''';      { SQL statement for query }
  with Query1 do
  begin
    Open;      { open the query }
    try
      while not EOF do
      begin
        for I := 0 to Query1.FieldCount - 1 do

          S := S + Query1.Fields[I].AsString + #9;      { add tab-separated fields to string }
        Next;      { repeat for each record }
      end;
      MSWord := CreateOleObject('word.basic');      { create object for server }
      MSWord.Insert(Copy(S, 1, Length(S) - 1));      { insert text }
      MSWord.ParaUp(1, 1);      { move to top of paragraph }
      MSWord.TextToTable(ConvertFrom := 1, NumColumns := FieldCount,
        Format := 16);      { convert to table }
    finally

      Close;       { always close the query }
    end;
  end;
end;
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Hi scotslad,

Here another example :

DDE and WORD


----------------------
DBS.PAS
----------------------

program Dbs;

uses
  Forms,
  Mainscan in 'MAINSCAN.PAS' {Form1};

{$R *.RES}

begin
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.


------------------------
MAINSCAN.PAS
------------------------


unit Mainscan;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, DdeMan, StdCtrls, Grids, ExtCtrls, Menus, Gauges;

type
  TForm1 = class(TForm)
    InfoPanel: TPanel;
    ProcessLog: TMemo;
    Gauge1: TGauge;
    StartBtn: TButton;
    ExitBtn: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure StartBtnClick(Sender: TObject);
    procedure ExitBtnClick(Sender: TObject);
  private
    { Private declarations }

    DocList : TStringList;
    WordPath : string;

    procedure ShowInfo(S : String);

    procedure FindDocuments;
    procedure ProcessDocuments;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation


{$R *.DFM}

procedure TForm1.ShowInfo(S : string);
begin
  InfoPanel.Caption := S;
  ProcessLog.Lines.Add(S);
end;


procedure TForm1.FindDocuments;
var
  DocRec : TSearchRec;
begin
  try
    if FindFirst('*.DOC', faAnyFile, DocRec) = 0 then
      repeat
        DocList.Add(DocRec.Name);
      until FindNext(DocRec) <> 0;
  finally
    FindClose(DocRec);
  end;
end;


procedure TForm1.ProcessDocuments;
var
  DocNo : integer;
  DocName : string;

  { Word Conversation Parameters }
  DDEWordConv : TDDEClientConv;
  WordStarted : Boolean;
  DocPath : array [0..150] of char;

  { Document related parameters }
  DDEDocConv : TDDEClientConv;
  Pbook : Pchar;

begin
  DDEWordConv := TDDEClientConv.Create(Self);
  { Start DDE Connection to WinWord }
  WordStarted := False;
  with DDEWordConv do
  begin
    ConnectMode := ddeManual;
    ServiceApplication := WordPath;
    if SetLink('WINWORD', 'SYSTEM') then
    begin
      if OpenLink then
      begin
        ShowInfo('Word conversation is open');
        WordStarted := True;
        ServiceApplication := '';
      end else
        ShowInfo('Word Conversation is not open     <--- N.B.');
    end else
      ShowInfo('WORD not opened     <--- N.B.');
  end;

  { Process documents if word is started }
  if WordStarted then
  begin
    DocNo := 0;
    while DocNo < DocList.Count do
    begin
      { Open Word Document }
      DocName := DocList.Strings[DocNo];
      StrPCopy(DocPath, Format('[FileOpen("%s")]', [DocName]));
      if DDEWordConv.ExecuteMacro(DocPath, True) then
      begin
        ShowInfo(Format('Document %s is loaded', [DocName]));

        { Start Communication with Document }
        DDEDocConv := TDDEClientConv.Create(Self);
        with DDEDocConv do
        begin
          ConnectMode := ddeManual;
          if SetLink('winword', DocName) then
          begin
            ShowInfo('Link to Doc is established');
            if DDEDocConv.openlink then
            begin
              ShowInfo('Link to Doc opened');
              { Retrieve info from Document }

{
              Pbook := DDEDocConv.RequestData('bookmark1');
              StrDispose(Pbook);

}


              { Close Conversation with the document }
              DDEDocConv.CloseLink;
              ShowInfo('Link to Doc closed')
            end else
              ShowInfo('Link to Doc not opened     <--- N.B.');
          end else
            ShowInfo('Link to Doc not established     <--- N.B.');
        end;
        DDEDocConv.Free;

        { Close Document in Word }
        with DDEWordConv do
          if ExecuteMacro('[FileClose(2)]', false) then
            ShowInfo('File Closed')
          else
           ShowInfo('File not Closed     <--- N.B.');
      end else
        ShowInfo('Document is not loaded     <--- N.B.');

      { Process next document and show progress }
      Inc(DocNo);
      Gauge1.Progress := Round(100.0 * DocNo / DocList.Count);
    end;
    DDEWordConv.CloseLink;
    ShowInfo('Link to WINWORD closed')
  end;
  DDEWordConv.Free;

  { Unload WinWord  ?????}
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  DocList := TStringList.Create;
  WordPath := 'C:\MSOffice\Winword\WINWORD.EXE';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  DocList.Free;
end;

procedure TForm1.StartBtnClick(Sender: TObject);
begin
  StartBtn.Enabled := false;

  ProcessLog.Lines.Clear;
  ShowInfo('******************************');
  ShowInfo('Logging started');
  ShowInfo(' ');
  DOCList.Clear;
  FindDocuments;
  ProcessDocuments;
  ShowInfo(' ');
  ShowInfo('Logging stopped');
  ShowInfo('******************************');
end;

procedure TForm1.ExitBtnClick(Sender: TObject);
begin
  Close;
end;

end.



---------------------------------
MAINSCAN.DFM (...........)
---------------------------------

object Form1: TForm1
  Left = 263
  Top = 506
  Width = 659
  Height = 361
  Caption = 'Form1'
  Font.Color = clWindowText
  Font.Height = -14
  Font.Name = 'System'
  Font.Style = []
  PixelsPerInch = 96
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  TextHeight = 16
  object Gauge1: TGauge
    Left = 136
    Top = 8
    Width = 313
    Height = 25
    BorderStyle = bsNone
    Progress = 0
  end
  object InfoPanel: TPanel
    Left = 0
    Top = 309
    Width = 651
    Height = 25
    Align = alBottom
    Alignment = taLeftJustify
    BevelInner = bvLowered
    BevelOuter = bvNone
    TabOrder = 1
  end
  object ProcessLog: TMemo
    Left = 0
    Top = 121
    Width = 651
    Height = 188
    Align = alBottom
    Lines.Strings = (
      '')
    ReadOnly = True
    ScrollBars = ssVertical
    TabOrder = 0
  end
  object StartBtn: TButton
    Left = 168
    Top = 64
    Width = 89
    Height = 33
    Caption = 'Start'
    TabOrder = 2
    OnClick = StartBtnClick
  end
  object ExitBtn: TButton
    Left = 312
    Top = 64
    Width = 89
    Height = 33
    Caption = 'Exit'
    TabOrder = 3
    OnClick = ExitBtnClick
  end
end

And another ....

OLE automation servers are a natural part of most major Microsoft applications
              such as Microsoft Office products and many other popular applications, which
              means you can control them from your application almost as if they were a part of
              your program.

              For example, let's take Microsoft Word 95. As you can see, it'll only take a few
              lines of code to make it possible to insert text to Word documents from your
              application (don't forget to add "OLEAuto" unit to your "uses" statement):

              procedure InsertTextToWord(
                sText : string );
              var  W : Variant;
              begin
                { create an OLE object of           }
                { type Word.Basic                   }
                W := CreateOleObject( 'word.basic' );
                { call Word.Basic's Insert function }
                W.Insert( sText );
              end;



              Using the above function, all you have to do is call it with the text you want to
              insert:

              InsertTextToWord( 'hello, word!' );

Regards, Zif.
0
 

Author Comment

by:scotslad
Comment Utility
Thanks to Zif & Ronit for their help. It has pointed me in the right direction, I think!

In the OLE Automation where you use methods such as:

            MSWord := CreateOleObject('word.basic');
            MSWord.FileOpen('test.doc');
            MSWord.Insert('hello');
            MSWord.ParaUp(1, 1);
            MSWord.TextToTable(ConvertFrom := 1, NumColumns := 2, Format := 16);
            MSWord.FileSaveAs('test.doc', 3);

is there a reference place where it lists how to get and set properties of the object, and to invoke methods on the object? I think this is what I want but I haven't found any place in the help files, MS Word or Delphi 2, that has a section explaining and listing the ways to access and update a Word document.

Does anybody also know how to insert text into a specific place in the text of the document?
I think you have to set bookmarks in the document and refernece it that way but again since I don't have a point of help/reference then it is a bit tricky. Any help gratefully accepted.
Cheers,

Dave.

0
 
LVL 5

Accepted Solution

by:
ronit051397 earned 100 total points
Comment Utility
When you need to specify a certain method that represent some action, then do the action while using the Macro recorder in Word. When you stop recording, you'll see these methods in word's editor.
To access Macro recorder, In word menu click Tools/Macro .

Wrdbasic.hlp is the word help file which explains the properties/methods.
If you don't have it, then you didn't specify it in the installation program
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:scotslad
Comment Utility
Hi Ronit,
having tried the word macros I found that it gives Visual Basic answers back. I am using Office 97 professional for reference. Albeit that their are similarities with the results that the recorded macros give in Word and the code I type into Delphi 2, I cannot seem to get the desired results to work. What I really need to know is what I type in Delphi. For instance if I want to close an opened word document and close word in Delphi I would use:

             MSWord.FileExit;

whereas in VB it is:

             ActiveDocument.Close

and

             Application.Quit

to close word.

I have to try and 2nd guess what the Delphi equivelant is and up till now I have have very little success.

What I need is to be able to call the function from Delphi, not VB, therefore I need to know the specific Delphi syntax. Any help in this area will be much appreciated. Thanks in advance,

Dave.

0
 
LVL 5

Expert Comment

by:ronit051397
Comment Utility
to close the active document write:     MSWord.DocClose;
to close the word write:                      MSWord.AppClose;
0
 

Author Comment

by:scotslad
Comment Utility
Hi Ronit,
From doing a whole lot of searching about I have discovered that word basic is used in pre office 97. Therefore word basic commands work fine in word 6 and word 95 but not in word 97 as word 97 uses Visual Basic for Applications. Since I am using office 97 the word basic commands are mostly useless. Only some work but that is no use to me. Originally in Delphi I would use OLEAuto i.e. add:

Uses OLEAuto

This is fine for office 95. I tried and the functions worked on a machine that had office 95 on it. This approach is no use for linking to a word 97 document. The commands in the word 97 help file do not work when I use OLEAuto and create a word basic object:

MSWord := CreateOleObject('word.basic');

Do I 'use' another file other than OLEAuto or do I create a different OLE object which will allow me to connect to a word 97 document?
If you can answer this then I'll give you full marks. Just by having a starting point I can normally get done what I need to do but in this case I can't even start to communicate efficiently with word 97. Thanks in advance.

Dave.
0
 
LVL 5

Expert Comment

by:ronit051397
Comment Utility
Sorry, I am not that familiar with OLE.
You are right, it's not working properly with word 97.
There is a bit more information in these places:
http://www.borland.com\/devsupport/delphi/qanda/activex.html
http://www.zdnet.com.au/wsources/content/1097/s_tb.html
Do you want me to try send commands to word 97 via DDE?
0
 

Author Comment

by:scotslad
Comment Utility
No thanks Ronit,
here's the points anyway since you have tried to help me. I have actually found out how to communicate with Word 97. Trial and error like most things. Word 97 uses Visual Basic objects so you use the command:

   MSWord := CreateOleObject('word.application');

to create a connection to a word application object. To load a file you now use the command:

   MSWord.Documents.Open(FileName := 'test.doc');

because a document is an object within the application object. In word 97 help, you pick:
'Microsoft Word Visual Basic Reference' then 'Visual Basic equivalents for WordBasic commands' to find out what methods to use to communicate to Word 97.

Thanks again. I now just need to work out how to use Fields in Word to allow me to insert data at the points in the documents that I want. I don't think bookmarks are extensive enough for what I need to do.
Cheers,

Dave.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now