How to use OLE2 for Word

From: <dave_belton_at_my-deja.com>
Date: 2000/08/01
Message-ID: <8m6fjh$md4$1_at_nnrp1.deja.com>


This is all the information I have acquired. Hope it helps someone as I could have done with it!

2. A new instance of Excel is created each time you initiate the server

    even though the server is already up and running

Problem



In Forms, you can use OLE to call Microsoft Word or Microsoft Excel. For
example, you can create a button to invoke Excel. Consequently, more than one
Excel instance will be invoked if you press the button several times, which
uses unnecessary system resources and can lead to a system crash. To reproduce the problem:
  1. Create a button in a form.
  2. Create the following When-Button-Pressed trigger code: DECLARE appl OLE2.OBJ_TYPE; workbooks OLE2.OBJ_TYPE; workbook OLE2.OBJ_TYPE; BEGIN appl := OLE2.CREATE_OBJ('Excel.Application'); OLE2.SET_PROPERTY(appl, 'Visible', 'True'); workbooks := OLE2.INVOKE_OBJ(appl, 'Workbooks'); workbook := OLE2.INVOKE_OBJ(workbooks, 'Add'); END;
  3. Run the form, and press the button twice.

    Note that two MS Excel instances are called.

Solution



It is not enough to check if the Excel server is already running because a handle to the Excel server is required. Instead, store the handle to the Excel server in a package variable that can be used throughout the form. Hence, OLE2.Create_Obj is performed only once in a Forms session, which opens one instance of Excel. To prevent ORA-305500 from occurring if the user closes Excel
(therefore, loses the handle to the server), trap this error and
issue OLE2.Create_Obj to reacquire the handle to the server.
        OLE Automation of Word97 with Developer/2000 Forms
        ==================================================


INTRODUCTION:


This bulletin explains the Word97 Object model and how Oracle Forms can make
use of the objects exposed by the Word97 OLE automation server. It contains
examples of automating an independent Word97 application as well as for embedded
or linked Word applications.

The bulletin does NOT talk about the OLE and OLE Automation features in Oracle
Forms. References 1 & 2 are a good source of information on this subject.
The focus here is on the Word97 Object model and it builds on the examples
provided in Reference 3 (OLE Automation Guide - Oracle Forms to Microsoft
Word95).

OLE/OLE2/OLE Automation concepts:


OLE(Object Linking and Embedding):



It is the technology that allows a programmer to build software components
(interoperalble objects) that adhere to a specific interface. This
enables
you to create applications for users that allows one large document to consist
of a variety of smaller documents, each created in a different application.

OLE2:



Extended the concept of OLE from compound documents to OLE Automation and a
number of other extensions to the original specification.

OLE Automation:



OLE server applications expose the properties and methods of their component
objects to other Windows applications. OLE client applications can programmatically manipulate OLE server applications through reading/writing
their exposed properties and invoking their exposed methods. This process of
controlling of OLE server applications from OLE client applications is known as 'OLE Automation'.

Object Models compared


Word6/Word7(Word95)


Word95 supported OLE Automation through a single 'Basic' object
(Word.Basic).

This was the Word's own Macro language interpreter.

While Word95 could provide an object to another application (like Visual Basic
or Oracle Forms) for OLE Automation, it could not use OLE Automation to access
objects in other applications. In other words, applications that support OLE
Automation, such as Microsoft Excel95 or a Visual Basic application, could use
OLE Automation to access Word, but Word could not use OLE Automation to access
them.

Word97


In Word97 every element - documents, tables, paragraphs, bookmarks, fields and
so on can be represented by an object in Visual Basic. The Word97 object
model
is based on the VBA (Visual Basic for Applications) instead of the WordBasic
interpreter. The VBA is the edition of Visual Basic designed to provide
development capabilities by embedding itself directly inside the host application
and is standard across the Office97 suite.

The primary difference between Visual Basic for Applications and WordBasic is
that whereas the WordBasic language consists of a flat list of approximately
900
commands, Visual Basic consists of a hierarchy of objects, each of which
exposes
a specific set of methods and properties (similar to statements and functions
in
WordBasic). While most WordBasic commands can be run at any time, Visual Basic
only exposes the methods and properties of the available objects at a given
time.

You now have an OLE Automation object called 'Application'
(Word.Application)

which contains methods and properties which return other top-level objects.
For
example, the 'ActiveDocument' property returns a 'Document' object.

This can be best visualised by looking at:

Microsoft Word Help
|
|-->Microsoft Word Visual Basic Reference

      |
      |-->Getting Started with Visual Basic
            |
            |-->Microsoft Word Objects

In this hyperlinked chart you can see individual objects as well as the Object
Collections (collection of similar objects).

Converting from WordBasic to Visual Basic


Microsoft Word Visual Basic Reference

   |
   |-->Getting Started with Visual Basic

          |
          |-->Converting from WordBasic to Visual Basic
                 |
                 |-->Visual Basic Equivalents for WordBasic Commands


This section gives an alphabetical listing of the Visual Basic command equivalents
for WordBasic commands.

The simplest example would be to display the main application window for Word
on
the screen -

Word95


DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;

BEGIN

  • Start WordBasic and make Word visible application:=OLE2.CREATE_OBJ('Word.Basic'); OLE2.INVOKE(application, 'AppShow');

END; Word97


If you look under 'Visual Basic Equivalents for WordBasic Commands' in the
on-line help, you can find the following entry for the 'AppShow' command:

AppShow => Application.Visible = True

So the modified code should be:

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;

BEGIN

  • Create the Word.Application object and make Word visible
  • by setting the 'Visible' property to true application:=OLE2.CREATE_OBJ('Word.Application'); OLE2.SET_PROPERTY(application, 'Visible', 1);

END; OLE Automation examples with Word97


Example 1



This example creates a new Word document, inserts some text in it and saves
its contents into a new file.

DECLARE

  • Declare the OLE objects MyApplication OLE2.OBJ_TYPE; MyDocuments OLE2.OBJ_TYPE; MyDocument OLE2.OBJ_TYPE; MySelection OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Create the Word.Application object and make Word visible
  • by setting the 'Visible' property to true MyApplication:=OLE2.CREATE_OBJ('Word.Application'); OLE2.SET_PROPERTY(MyApplication, 'Visible', 1);
  • get a handle on Documents collection MyDocuments:=OLE2.GET_OBJ_PROPERTY(MyApplication, 'Documents');
  • Add a new document to the Documents collection Mydocument :=OLE2.INVOKE_OBJ(MyDocuments,'Add');
  • get a handle on Selection object MySelection:=OLE2.GET_OBJ_PROPERTY(MyApplication, 'Selection');
  • Insert the text 'Hello Word97!' into word document OLE2.SET_PROPERTY(MySelection, 'Text', 'Hello Word97!');
  • Save the document to the filesystem as EXAMPLE.DOC args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'D:\VPURI\DOCS\EXAMPLE.DOC'); OLE2.INVOKE(MyDocument, 'SaveAs', args); OLE2.DESTROY_ARGLIST(args);
  • Close the document OLE2.INVOKE(MyDocument, 'Close');
  • Release the OLE objects OLE2.RELEASE_OBJ(MySelection); OLE2.RELEASE_OBJ(MyDocument); OLE2.RELEASE_OBJ(MyDocuments); OLE2.RELEASE_OBJ(MyApplication);

END; The Visual Basic code to achive the same functionality as above:


Sub Example1()

 Set MyApplication = GetObject(, "Word.Application")  MyApplication.Visible = True

 Set MyDocuments = MyApplication.Documents  Set MyDocument = MyDocuments.Add

 Set MySelection = MyApplication.Selection  MySelection.Text = "Hello Word97!"

 MyDocument.SaveAs FileName:="D:\VPURI\DOCS\EXAMPLE.DOC"  MyDocument.Close

 Set MySelection = Nothing
 Set MyDocuments = Nothing
 Set MyApplication = Nothing

End Sub

Example 2


This example illustrates the use of a predefined bookmark in a Word document

DECLARE

  • Declare the OLE objects MyApplication OLE2.OBJ_TYPE; MyDocuments OLE2.OBJ_TYPE; MyDocument OLE2.OBJ_TYPE; MySelection OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Create the Word.Application object and make Word visible
  • by setting the 'Visible' property to true MyApplication:=OLE2.CREATE_OBJ('Word.Application'); OLE2.SET_PROPERTY(MyApplication, 'Visible', 1);
  • get a handle on Documents collection MyDocuments:=OLE2.GET_OBJ_PROPERTY(MyApplication, 'Documents');
  • Open a new document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'D:\VPURI\DOCS\EXAMPLE.DOC'); Mydocument :=OLE2.INVOKE_OBJ(MyDocuments,'Open',args); OLE2.DESTROY_ARGLIST(args);
  • get a handle on Selection object MySelection:=OLE2.GET_OBJ_PROPERTY(MyApplication, 'Selection');
  • Navigate to the Bookmark called 'MyBookmark'
  • VBA Syntax: Selection.Goto(What, Which, Count, Name)
  • Which, Count are optional and are specified only because the values
  • of the parameters are position dependent.

  args:=OLE2.CREATE_ARGLIST;
  OLE2.ADD_ARG(args, -1); -- What => constant 'wdGoToBookmark' = -1

  OLE2.ADD_ARG(args,0);             -- Which
  OLE2.ADD_ARG(args,0);             -- Count
  OLE2.ADD_ARG(args, 'MyBookmark'); -- Name => bookmark name
  OLE2.INVOKE(MySelection,'GoTo',args);

  • Insert some text at the bookmark location OLE2.SET_PROPERTY(MySelection, 'Text', '** Inserting at MyBookmark **');
  • Release the OLE objects OLE2.RELEASE_OBJ(MySelection); OLE2.RELEASE_OBJ(MyDocument); OLE2.RELEASE_OBJ(MyDocuments); OLE2.RELEASE_OBJ(MyApplication);

END; Visual Basic code:


Sub Example2()

 Set MyApplication = GetObject(, "Word.Application")  MyApplication.Visible = True

 Set MyDocuments = MyApplication.Documents  Set MyDocument = MyDocuments.Open(FileName:="D: \VPURI\DOCS\EXAMPLE.DOC")  Set MySelection = MyApplication.Selection  MySelection.GoTo What:=wdGoToBookmark, Name:="mybookmark"  'wdGoToBookmark = -1
 MySelection.Text = "** Inserting at MyBookmark **"

 Set MySelection = Nothing
 Set MyDocuments = Nothing
 Set MyDocuments = Nothing

 Set MyApplication = Nothing

End Sub

Example 3


If the tasks you want to perform in Word are completely self-contained and do
not require any parameters to be passed in from Oracle Forms, it may be preferable to create a VBA macro within Word itself and invoke the macro via
OLE automation. The following example opens a word document EXAMPLE.DOC and
executes the VBA macro called 'MyMacro'

DECLARE

  • Declare the OLE objects MyApplication OLE2.OBJ_TYPE; MyDocuments OLE2.OBJ_TYPE; MyDocument OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Create the Word.Application object and make Word visible
  • by setting the 'Visible' property to true MyApplication:=OLE2.CREATE_OBJ('Word.Application'); OLE2.SET_PROPERTY(MyApplication, 'Visible', 1);
  • get a handle on Documents collection MyDocuments:=OLE2.GET_OBJ_PROPERTY(MyApplication, 'Documents');
  • Open a new document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'D:\VPURI\DOCS\EXAMPLE.DOC'); Mydocument :=OLE2.INVOKE_OBJ(MyDocuments,'Open',args); OLE2.DESTROY_ARGLIST(args);
  • Execute the macro called 'MyMacro' args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'MyMacro'); OLE2.INVOKE(MyApplication,'Run',args); OLE2.DESTROY_ARGLIST(args);
  • Release the OLE objects OLE2.RELEASE_OBJ(MyDocument); OLE2.RELEASE_OBJ(MyDocuments); OLE2.RELEASE_OBJ(MyApplication);

END; Example 4


This example shows the automation of an embedded/linked word document - it Runs a macro called 'MyMacro' in the embedded/linked document.

DECLARE

  • Declare the OLE objects MyApplication OLE2.OBJ_TYPE; MyDocument OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Open Word97 and activate it FORMS_OLE.ACTIVATE_SERVER('OLEWORD.DOC');
  • Verb index 1 => Open the embedded document for editing FORMS_OLE.EXEC_VERB('OLEWORD.DOC',1);
  • Get a handle on the Word document in the OLE container MyDocument := FORMS_OLE.GET_INTERFACE_POINTER('OLEWORD.DOC');
  • Get a handle on the Application object MyApplication := OLE2.GET_OBJ_PROPERTY(MyDocument,'Application');
  • Execute the macro called 'MyMacro' args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'MyMacro'); OLE2.INVOKE(MyApplication,'Run',args); OLE2.DESTROY_ARGLIST(args);
  • Release the OLE objects OLE2.RELEASE_OBJ(MyDocument); OLE2.RELEASE_OBJ(MyApplication);
  • Close Word FORMS_OLE.CLOSE_SERVER('OLEWORD.DOC');
END; CONCLUSION:

This bulletin compared the Word97 and Word95 Object models. It explained
with the help of simple examples how you can make use of the new object model to redesign your existing Oracle Forms Applications which can make use of the advanced OLE Automation features in Word'97.

Guide to OLE Automation - Oracle Forms to Microsoft Word 95


Introduction



This article explains the basic concepts of OLE automation and in particular
how to use the OLE automation facilities within Oracle Forms V4.5 to automate
Microsoft Word. Code examples are included.

Basic OLE Automation principles



Objects are the fundamental components of OLE applications. Every element of
an OLE server application can be represented as an object. Each of these
objects is defined by its properties (physical and logical characteristics)
and its methods (actions which the object can perform).

OLE server applications expose the properties and methods of their component
objects to other Windows applications. OLE client applications can programmatically manipulate OLE server applications through reading/writing
their exposed properties and invoking their exposed methods. This process of
'remote control' of OLE server applications from OLE client applications is
known as 'OLE Automation'.

The original OLE ('Object Linking and Embedding') specification, created in
1991 concentrated on the creation of compound documents via the linking or
embedding of server application documents inside container applications
(a process from which OLE gained its original and now obsolete title).
The much broader OLE2 specification introduced the concept of OLE automation
along with a number of other extensions to the original OLE specification.
Only applications supporting the OLE2 specification can therefore participate
in OLE automation. Separate aspects of the OLE2 specification cover OLE automation client and OLE automation server functionality so an application
must support the respective aspects of the OLE2 specification to function as
an OLE automation client, OLE automation server or both.

Before writing code to perform OLE automation, it is necessary for an application developer to understand the following things:

 o The object classes exposed by the OLE automation server and the    relationships between them (the OLE automation server's 'Object    Model').

 o The properties of the OLE automation server's objects, their    datatypes and valid values

 o The methods of the OLE automation server's objects, their syntax    and arguments

 o The methods used by the OLE automation client to access the    methods and properties of the OLE automation server's objects

This article will describe the Object Model of Word and the methods used by
Oracle Forms to perform OLE automation with Word.

The Microsoft Word Object Model



Microsoft Word can function as an OLE automation client or OLE automation
server. This section describes the Object Model which enables Word to be
used as an OLE automation server.

In most OLE server applications (e.g. Microsoft Excel) there are many different OLE object classes in the Object Model (e.g. Worksheets, Charts,
Titles in Excel) which can be individually manipulated via their properties
and methods. In Microsoft Word there is just one object of interest. This
is the WordBasic interpreter used by Microsoft Word to execute commands written in Word's own macro language, WordBasic. Instead of executing methods or setting properties for specific objects (e.g. Document, Header,
Footer, Paragraph) within a Word document, WordBasic macro statements are
sent to the WordBasic interpreter to perform the requested tasks on behalf of
the OLE client application.

Although this method of automation doesn't strictly comply to the spirit of
OLE, it does make the process of remote automation of Word simple. All that
is required is to create an OLE object of the class "Word.Basic" and send
WordBasic macro statements to this object for execution.

Oracle Forms and OLE Automation



Oracle Forms can operate as an OLE automation client only.

OLE automation client functionality is implemented in Oracle Forms through a
number of built-in PL/SQL procedures and functions contained in the OLE2 PL/SQL package. The OLE2 PL/SQL package provides a PL/SQL API for creating
OLE automation server objects and accessing the properties and methods of
these objects.

The OLE2 PL/SQL package defines two additional PL/SQL datatypes which are
used by the OLE2 built-ins:

OBJ_TYPE        A handle to an OLE object
LIST_TYPE       A handle to an OLE argument list

Each of the PL/SQL procedures and functions in the OLE2 package is described
below along with its PL/SQL specification:

Object Management

  CREATE_OBJ
  Creates an OLE object and returns an object handle.   CREATE_OBJ(OBJECT IN VARCHAR2) RETURN OBJ_TYPE   RELEASE_OBJ
  Deallocates all resources for an OLE object created by CREATE_OBJ   and destroys the object handle.
  RELEASE_OBJ(OBJECT IN OBJ_TYPE) Object Property Access

  GET_CHAR_PROPERTY
  Reads a character property of an OLE object.   GET_CHAR_PROPERTY(OBJECT IN OBJ_TYPE, PROPERTY IN VARCHAR2, ARGLIST   IN LIST_TYPE) RETURN VARCHAR2   GET_NUM_PROPERTY
  Reads a number property of an OLE object.   GET_NUM_PROPERTY(OBJECT IN OBJ_TYPE, PROPERTY IN VARCHAR2, ARGLIST   IN LIST_TYPE) RETURN NUMBER   GET_OBJ_PROPERTY
  Reads an object property of an OLE object.   GET_OBJ_PROPERTY(OBJECT IN OBJ_TYPE, PROPERTY IN VARCHAR2, ARGLIST   IN LIST_TYPE) RETURN OBJ_TYPE   SET_PROPERTY
  Sets the value of a number or character property of an OLE object.   SET_PROPERTY(OBJECT IN OBJ_TYPE, PROPERTY IN VARCHAR2, VALUE IN   NUMBER, ARGLIST IN LIST_TYPE)
  or
  SET_PROPERTY(OBJECT IN OBJ_TYPE, PROPERTY IN VARCHAR2, VALUE IN   VARCHAR2, ARGLIST IN LIST_TYPE) Object Method Execution

  INVOKE
  Executes a method of an OLE object which returns nothing.   INVOKE(OBJECT IN OBJ_TYPE, METHOD IN VARCHAR2, ARGLIST IN   LIST_TYPE)   INVOKE_CHAR
  Executes a method of an OLE object which returns a character   string.
  INVOKE(OBJECT IN OBJ_TYPE, METHOD IN VARCHAR2, ARGLIST IN   LIST_TYPE) RETURN VARCHAR2   INVOKE_NUM
  Executes a method of an OLE object which returns a number.   INVOKE(OBJECT IN OBJ_TYPE, METHOD IN VARCHAR2, ARGLIST IN   LIST_TYPE) RETURN NUMBER   INVOKE_OBJ
  Executes a method of an OLE object which returns an object handle.   INVOKE(OBJECT IN OBJ_TYPE, METHOD IN VARCHAR2, ARGLIST IN   LIST_TYPE) RETURN OBJ_TYPE Argument List Management

  CREATE_ARGLIST
  Creates an argument list to be used by an invoked method and   returns an argument list handle.
  CREATE_ARGLIST RETURN LIST_TYPE   ADD_ARG
  Appends a number or character string argument to an argument list.   ADD_ARG(LIST IN LIST_TYPE, VALUE IN NUMBER)   or
  ADD_ARG(LIST IN LIST_TYPE, VALUE IN VARCHAR2)   DESTROY_ARGLIST
  Destroys an argument list created by CREATE_ARGLIST.   DESTROY_ARGLIST(LIST IN LIST_TYPE) Exception Handling

  LAST_EXCEPTION
  Returns the most recent OLE exception code. Some examples of   conditions when OLE exceptions are raised are     o sending OLE commands to an inactive server application     o invoking non-existent methods
  LAST_EXCEPTION RETURN NUMBER The OLE2 PL/SQL package can be used to automate an independently executing
OLE automation server application. It can also be used to automate an embedded or linked OLE object associated with an OLE container item in an
Oracle Forms application. The remainder of this article will look at automating Word using both methods.

Automating an independently executing Word application



Before any OLE automation to Word can be performed, the WordBasic interpreter
must be started. This is achieved through the creation of an OLE object representing the WordBasic interpreter. The creation of this WordBasic OLE
object (and an object handle for it) establishes an entry point to Word from
which OLE automation can begin.

The WordBasic interpreter is not visible. If you want to display the Word
application on the screen during OLE automation you will need to send the
macro command 'AppShow' to WordBasic.

The following PL/SQL example creates a WordBasic object, obtains an object
handle to it and displays the main application window for Word on the screen:

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;

BEGIN

  • Start WordBasic and make Word visible application:=OLE2.CREATE_OBJ('Word.Basic'); OLE2.INVOKE(application, 'AppShow');

END; At this point there are no open documents in Word and OLE automation is restricted only to the operations that can be performed from Word's File menu
(e.g. create/open a document, create/open a template, execute a
macro). To
perform more extensive OLE automation, a Word document needs to be opened.
The following PL/SQL example extends the previous example by creating a new
document and inserting some text ( comments are preceded by -- ) :

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Start WordBasic and make Word visible application:=OLE2.CREATE_OBJ('Word.Basic'); OLE2.INVOKE(application, 'AppShow');
  • Create a new Word document OLE2.INVOKE(application, 'FileNew');
  • Insert the text 'Hello there!' into the Word document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'Hello there!'); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Save the document to the filesystem args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'EXAMPLE.DOC'); OLE2.INVOKE(application, 'FileSaveAs', args); OLE2.DESTROY_ARGLIST(args);
  • Release the OLE object OLE2.RELEASE_OBJ(application);

END; The equivalent WordBasic macro for these actions is shown below:

     Sub MAIN
       FileNew .Template = "C:\OFFICE95\Templates\Normal.dot",
            .NewTemplate = 0
       Insert "Hello there!"
       FileSaveAs .Name = "EXAMPLE.DOC", .Format = 0, .LockAnnot = 0,
                 .Password = "",.AddToMru = 1, .WritePassword = "",
                 .RecommendReadOnly = 0, .EmbedFonts = 0,
                 .NativePictureFormat = 0, .FormsData = 0,
                     .SaveAsAOCELetter = 0
End Sub

The following points are worth noting :

o It is important to release all OLE objects and argument lists as early as
  possible to minimise Windows resource usage and at the very least these
  objects should be released at the end of the PL/SQL procedure.

o Argument names are not required for the WordBasic commands, just the   values.

o Default values will be used in place of missing WordBasic arguments.   (e.g. in the FileNew command it was not necessary to specify which   document template should be used as this defaults to Normal.dot).

o The WordBasic arguments are position dependant so ensure values are   supplied for all arguments up to the highest positioned argument you wish to
  use.

o When using an argument list with a different set of arguments it is   necessary to destroy and recreate the argument list. Failing to do this
  will result in a new set of arguments being appended to an old set.

Word bookmarks can be used to position the insertion point at a specific location within a document. These bookmarks can either be created and named
in advance or can be created by macro commands (the latter is useful if you
want to mark a location to revisit later). The following PL/SQL procedure
illustrates the use of a predefined bookmark in a Word document:

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Start WordBasic and make Word visible application:=OLE2.CREATE_OBJ('Word.Basic'); OLE2.INVOKE(application, 'AppShow');
  • Open a Word document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'C:\TEMP\EXAMPLE.DOC'); OLE2.INVOKE(application, 'FileOpen', args); OLE2.DESTROY_ARGLIST(args);
  • Navigate to the bookmark called 'LetterHead' args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'LetterHead'); OLE2.INVOKE(application, 'EditGoto', args); OLE2.DESTROY_ARGLIST(args);
  • Insert text at the bookmark location args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'OLE Automation Limited'); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Release the OLE object OLE2.RELEASE_OBJ(application);

END; As well as executing WordBasic commands, it is possible to return information
from Word to Oracle Forms by invoking WordBasic functions. For example, the
WordBasic function FONT$() returns a character string with the name of the
font in use at the insertion point of a document. The following PL/SQL example demonstrates how this function can be called via OLE automation:

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;
  • Declare the PL/SQL variable to receive the font name fontname VARCHAR2(30);

BEGIN

  • Start WordBasic and make Word visible application:=OLE2.CREATE_OBJ('Word.Basic'); OLE2.INVOKE(application, 'AppShow');
  • Open a Word document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'C:\TEMP\EXAMPLE.DOC'); OLE2.INVOKE(application, 'FileOpen', args); OLE2.DESTROY_ARGLIST(args);
  • Display the font in use at the insertion point fontname:=OLE2.INVOKE_CHAR(application, 'Font$'); MESSAGE(fontname);
  • Release the OLE object OLE2.RELEASE_OBJ(application);

END; The following points are worth noting:

o To call a WordBasic function, the OLE2.INVOKE_CHAR or OLE2.INVOKE_NUM   procedures are used instead of the OLE2.INVOKE procedure.

o To determine whether to use OLE2.INVOKE_CHAR or OLE2.INVOKE_NUM you need to
  know the datatype of the item being returned from the WordBasic function.
  You can derive this from the WordBasic function name. Functions returning
  a character string have a $ as the last letter of the function name whereas
  functions returning numbers do not.

o WordBasic functions are distinguished from commands by brackets following
  the function name. Do not use these brackets when referring to the   function in a PL/SQL procedure.

The following PL/SQL procedure illustrates how OLE automation can be used to
perform a mail merge in Word. The example assumes that the main and data
source documents have already been created and the placeholders for data
source fields have been created in the main document (refer to the Word online help for details of setting up mail merge documents). The PL/SQL
procedure simply populates the data source document with data from the Oracle
database, invokes the mail merge and saves the resulting file.

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;
  • Declare a SQL cursor to be used to fetch the records from
  • the database. CURSOR emp_cursor IS select ename, sal from emp;

BEGIN

  • Start WordBasic and make Word visible application:=OLE2.CREATE_OBJ('Word.Basic'); OLE2.INVOKE(application, 'AppShow');
  • Open the mail merge data source document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'C:\TEMP\MERGE1.DOC'); OLE2.INVOKE(application, 'FileOpen', args); OLE2.DESTROY_ARGLIST(args);
    • Move to end of first row in data table (merge field names) OLE2.INVOKE(application, 'NextCell');
    • Fetch each employee record and pass values of employee name
    • and salary into the mail merge data table

  FOR emp_record IN emp_cursor LOOP

  • Move onto next row of data table OLE2.INVOKE(application, 'NextCell');
  • Insert employee name args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, emp_record.ename); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Move to next column of data table OLE2.INVOKE(application, 'NextCell');
  • Insert salary args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, TO_CHAR(emp_record.sal)); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);

  END LOOP;

  • Open the mail merge main document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'C:\TEMP\MERGE2.DOC'); OLE2.INVOKE(application, 'FileOpen', args); OLE2.DESTROY_ARGLIST(args);
  • Perform the mail merge to create the merged document OLE2.INVOKE(application, 'MailMergeToDoc');
  • Save the merged document to disk args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'C:\TEMP\MERGE3.DOC'); OLE2.INVOKE(application, 'FileSaveAs', args); OLE2.DESTROY_ARGLIST(args);
  • Close all three documents (without prompting to save any changes)
  • ( FileCloseAll 2 = close all without saving ) args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 2); OLE2.INVOKE(application, 'FileCloseAll', args); OLE2.DESTROY_ARGLIST(args);
  • Release the OLE object OLE2.RELEASE_OBJ(application);

END; The following points are worth noting :

o It is not possible to use a numeric datatype as an argument to the   WordBasic Insert command. To insert a salary figure the TO_CHAR function
  was used to convert to a character string first.

The following example invokes Word to perform a spelling check against an
Oracle Forms text field ('LONGFIELD1' in block 'CONTROL') and return the corrected text:

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;
  • Declare a temporary local variable for returned text sel_text VARCHAR2(1000);

BEGIN

  • Start WordBasic application:=OLE2.CREATE_OBJ('Word.Basic');
  • Create a temporary document to do the spell check in OLE2.INVOKE(application, 'FileNew');
  • Insert the text of field CONTROL.LONGFIELD into temporary document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, :CONTROL.LONGFIELD1); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Invoke the spell checker OLE2.INVOKE(application, 'ToolsSpelling');
  • Return corrected text to Oracle Forms OLE2.INVOKE(application, 'EditSelectAll'); sel_text:=OLE2.GET_CHAR_PROPERTY(application, 'Selection');

 --Release the OLE object
 OLE2.RELEASE_OBJ(application);

  • The text brought back contains an extraneous control character
  • (a paragraph marker) so get rid of it :CONTROL.LONGFIELD1:=SUBSTR(sel_text, 1, (LENGTH(sel_text)-1) );

END; Generally, the best approach for developing PL/SQL code to perform sophisticated OLE automation to Word is to use Word's own macro recorder to
record a WordBasic macro for the required actions and convert the resulting
WordBasic macro into a series of OLE2.INVOKE, OLE2.INVOKE_CHAR and OLE2.INVOKE_NUM statements, using argument lists where appropriate.

For further information on the syntax of WordBasic commands refer to Word's
own online help and the documentation supplied with the Microsoft Office
Developer's kit.

Automating Embedded or Linked Word documents



The original concept behind OLE concerned the embedding or linking of objects
created by an OLE server application inside a document created by a different
application (referred to as an OLE container application). It is possible to
combine this aspect of OLE with OLE automation to automate an embedded or
linked object.

Oracle Forms includes a special OLE container item into which an OLE object
can be embedded or linked. The OLE object classes which can be embedded or
linked into an OLE container are registered in the Windows OLE registration
database when an OLE server application is installed. The 'OLE Class' property of an Oracle Forms OLE container indicates which object class it
contains and must be one of those listed in the OLE registration database.
The 'OLE Tenant Types' property indicates whether the OLE container holds an
embedded or linked OLE object. The 'OLE In-Place Activation' property indicates whether the OLE server application shares the Oracle Forms application Window when it is activated or whether a separate Window is opened.

For Word documents, the OLE container's 'OLE Class' property should be set to
'Word.Document'. However, Word's simplified OLE object model does not permit
direct automation of the embedded or linked 'Word.Document' object class
(unlike Excel which allows direct automation of the 'Excel.Worksheet'
object
class). All OLE automation against the 'Word.Document' class must be performed via the 'Word.Basic' class.

To automate an embedded or linked Word document, the OLE2 PL/SQL package must
be used in conjunction with the following PL/SQL procedures from the separate
PL/SQL built-in package FORMS_OLE:

  ACTIVATE_SERVER
  Activates an OLE server application associated with an OLE container item
  and prepares it for OLE automation. Takes the name or item id of an Oracle
  Forms OLE container item as an argument.

  EXEC_VERB
  Causes an OLE server to execute a verb identified by a verb name or verb
  index. An OLE verb specifies an action you can perform on an OLE object.

  CLOSE_SERVER
  Deactivates an OLE server application associated with an OLE container item.
  Terminates the connection between the OLE server and the OLE container.

The following example illustrates how the FORMS_OLE and OLE2 procedures are
used to automate an embedded or linked Word document (in this case a standard
letter template). The document is stored in the Oracle database and displayed
in the OLE container item 'DOC' of block 'OLEWORD'. The PL/SQL procedure
opens the template document and fills it in by sending the contents of Oracle
Forms fields to bookmarks in the document. The resulting document is then
saved to disk, the changes undone to restore the template to its original
state and the document is closed:

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Activate Word FORMS_OLE.ACTIVATE_SERVER('OLEWORD.DOC');
  • Start WordBasic application:=OLE2.CREATE_OBJ('Word.Basic');
  • Open the embedded document for editing FORMS_OLE.EXEC_VERB('OLEWORD.DOC',1);
  • Go to EmployeeName bookmark args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'EmployeeName'); OLE2.INVOKE(application, 'EditGoto', args); OLE2.DESTROY_ARGLIST(args);
  • Transfer contents of the EMP field to document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, :EMP.ENAME); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Go to Salary bookmark args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'Salary'); OLE2.INVOKE(application, 'EditGoto', args); OLE2.DESTROY_ARGLIST(args);
  • Transfer contents of Salary field to document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, TO_CHAR(:EMP.SAL)); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Save the completed document to disk args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'C:\TEMP\LETTER1.DOC'); OLE2.INVOKE(application, 'FileSaveAs', args); OLE2.DESTROY_ARGLIST(args);
  • Restore the letter template to it's original state OLE2.INVOKE(application, 'EditUndo'); OLE2.INVOKE(application, 'EditUndo');
  • Release the OLE object OLE2.RELEASE_OBJ(application);
  • Close Word FORMS_OLE.CLOSE_SERVER('OLEWORD.DOC');
END; The following points are worth noting:

o The ACTIVATE_SERVER, CREATE_OBJ and EXEC_VERB commands must be performed in
  the order given. Due to the relationship between the 'Word.Document' and
  'Word.Basic' object classes, failure to use this sequence may cause   unexpected behaviour (e.g. the Word application window does not close when
  the CLOSE_SERVER command is issued).

o Verb index 1 is used by EXEC_VERB to open a Word document for editing.

o There is no need to use an AppShow command as the EXEC_VERB statement will
  make Word visible.

o There is no need to close the embedded document via WordBasic. This is
  done implicitly by the CLOSE_SERVER command.

o In place of the FileSaveAs command a FilePrint could have been used to send
  the document to the printer rather than disk.

o If the embedded Word document is attached to a Word template (.DOT file), a
  copy of the .DOT file must exist on all PCs using the document from within
  Oracle Forms. The .DOT file is not stored in the database with the   embedded document. Without this file on the hard disk, macros, autoText
  entries and custom toolbar, menu and shortcut keys defined in the .DOT file
  will be inaccessible.

o With Word V7.0 for Windows 95, the previous example only works if the   'In-place Activation' property of the OLE container is set to 'False'.   If this property is set to 'True', WordBasic does not permit the use of any
  commands available from the File menu (e.g. FileSave, FileSaveAs,   FilePrint).
  These commands will just be ignored.
  If no commands from the File menu are issued via OLE automation,   'In-place Activation' can be set to 'True' or 'False'.

With Word V6.0 for Windows 3.x, even with 'In-place Activation' set to 'False' WordBasic (for some unknown reason) still disallows the use of the
FileSave and FileSaveAs commands directly against an embedded or linked document. However, the FileNew command can be used so a workaround to this
limitation is to create a temporary copy of the embedded or linked document
via OLE automation and work on that. This has the effect of reenabling the
restricted commands. The following PL/SQL procedure illustrates the previous
example modified to work with Word V6.0:

DECLARE

  • Declare the OLE object application OLE2.OBJ_TYPE;
  • Declare handle to the OLE argument list args OLE2.LIST_TYPE;

BEGIN

  • Activate Word FORMS_OLE.ACTIVATE_SERVER('OLEWORD.DOC');
  • Start WordBasic application:=OLE2.CREATE_OBJ('Word.Basic');
  • Open the embedded document for editing FORMS_OLE.EXEC_VERB('OLEWORD.DOC',1);
  • Create a temporary copy of the document to enable the FileSave command OLE2.INVOKE(application,'EditSelectAll'); OLE2.INVOKE(application,'EditCopy'); OLE2.INVOKE(application,'FileNew'); OLE2.INVOKE(application,'EditPaste');
    • Go to EmployeeName bookmark args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'EmployeeName'); OLE2.INVOKE(application, 'EditGoto', args); OLE2.DESTROY_ARGLIST(args);
  • Transfer contents of the EMP field to document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, :EMP.ENAME); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Go to Salary bookmark args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'Salary'); OLE2.INVOKE(application, 'EditGoto', args); OLE2.DESTROY_ARGLIST(args);
  • Transfer contents of Salary field to document args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, TO_CHAR(:EMP.SAL)); OLE2.INVOKE(application, 'Insert', args); OLE2.DESTROY_ARGLIST(args);
  • Save the completed document to disk args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 'C:\TEMP\LETTER1.DOC'); OLE2.INVOKE(application, 'FileSaveAs', args); OLE2.DESTROY_ARGLIST(args);
  • Close the temporary document (without prompting to save any changes)

  args:=OLE2.CREATE_ARGLIST;

  OLE2.ADD_ARG(args, 2);
  OLE2.INVOKE(application, 'FileClose', args);
  OLE2.DESTROY_ARGLIST(args);

  • Close the embedded document FORMS_OLE.CLOSE_SERVER('OLEWORD.DOC');
  • Release the OLE object OLE2.RELEASE_OBJ(application);

END; The following points are worth noting:

o In this procedure there is no need to undo changes as the embedded document
  is never modified. Only the temporary document is modified which is   discarded at the end.

o A FileClose is required to close the temporary document but not the   embedded document as this is implicitly closed by the CLOSE_SERVER   command.

Conclusion



This article has described the fundamental concepts of using the built- in
OLE automation features of Oracle Forms V4.5 to manipulate Microsoft Word.
Once these basic concepts and limitations are understood, the reader should
be able to adapt the examples given in this article using the documentation
provided with Microsoft Word to implement their specific OLE automation requirements.

for Word97 you need to reference MSWord8.olb (Microsoft Word 8.0 Object Library)

objActiveDoc := OLE2.GET_OBJ_PROPERTY(Word.hApp, 'ActiveDocument');
> objBookmarks := OLE2.GET_OBJ_PROPERTY(objActiveDoc, 'Bookmarks');
> numBookmarkCount := OLE2.GET_NUM_PROPERTY(objBookmarks, 'Count');



FUNCTION GotoBookMark (DocumentHandle in OLE2.OBJ_TYPE, Bookmark in VARCHAR2) return OLE2.OBJ_TYPE is
hArgs OLE2.LIST_TYPE;
hRange OLE2.OBJ_TYPE;
begin
hArgs := OLE2.CREATE_ARGLIST;

OLE2.ADD_ARG(hArgs,-1); /* What? = wdGoToBookmark */
OLE2.ADD_ARG(hArgs, 0); /* Which? */
OLE2.ADD_ARG(hArgs, 0); /* Count */
OLE2.ADD_ARG(hArgs, Bookmark); /* Name */
hRange := OLE2.INVOKE_OBJ(DocumentHandle,'Goto',hArgs); OLE2.DESTROY_ARGLIST(hArgs);
OLE2.INVOKE(hRange,'Select');
return hRange;
end;

--Print the Word document, nb. all arguements optional

ole_args:= ole2.create_arglist;

ole2.add_arg(ole_args,'True'); --Background
ole2.add_arg(ole_args,'False'); --Append
ole2.add_arg(ole_args,'wdPrintAllDocument'); --Range
--
wdPrintAllDocument,wdPrintCurrentPage,wdPrintFromTo,wdPrintRangeOfPages,
wdPri ntS election

ole2.add_arg(ole_args, 'False'); --OutputFileName
ole2.add_arg(ole_args, 'null'); --From
ole2.add_arg(ole_args, 'null'); --To
ole2.add_arg(ole_args, 'wdPrintDocumentContent'); --Item
--
wdPrintAutoTextEntries,wdPrintComments,wdPrintDocumentContent,wdPrintKey
Assig nme nts,wdPrintProperties,wdPrintStyles.

ole2.add_arg(ole_args, '1'); --Copies
ole2.add_arg(ole_args, 'null'); --Pages
ole2.add_arg(ole_args, 'wdPrintAllPages'); --PageType
-- wdPrintAllPages,wdPrintEvenPagesOnly,wdPrintOddPagesOnly
ole2.add_arg(ole_args, 'False'); --PrintToFile
ole2.add_arg(ole_args, 'True'); --Collate
ole2.add_arg(ole_args, 'null'); --FileName
ole2.add_arg(ole_args, 'null'); -- ActivePrinterMacGX
ole2.add_arg(ole_args, 'null'); -- ManualDuplexPrint

--ole2.invoke(ole_application, 'PrintOut');
ole2.invoke(ole_application, 'PrintOut', ole_args);
ole2.destroy_arglist(ole_args);

elsif :cg$ctrl.cmm_code = 'MGW' then

/*
**** MAILING ****
*/

-- Create the Word.Application and make it visible
ole_application:= ole2.create_obj('Word.Application');
ole2.set_property(ole_application,'Visible',1);

-- Get a handle on the documents collection
ole_document := ole2.get_obj_property(ole_application, 'Documents');

-- What word file to open
ole_args:= ole2.create_arglist;

/* * This is hardcoded stuff at the moment for testing purposes only */
message('file '|| 'q:
\in.mgw\agee\'||:global.eas$mnt_id||:global.eas$mtn_seq_no||'.'||:cg$ctr
l.cmm _co de); ole2.add_arg(ole_args, 'q:
\in.mgw\agee\'||:global.eas$mnt_id||:global.eas$mtn_seq_no||'.'||:cg$ctr
l.cmm _co de); -- Open Word document specified in the argument list
ole_document
:= ole2.invoke_obj(ole_document, 'Open', ole_args);
ole2.destroy_arglist(ole_args);

--Mail the Word document
ole_args:= ole2.create_arglist;
--ole2.add_arg(ole_args, '?'); --Item
ole2.invoke(ole_application, 'SendMail');
--ole2.invoke(ole_application, 'SendMail', ole_args);
ole2.destroy_arglist(ole_args);

elsif :cg$ctrl.cmm_code = 'FAX' then

/* **** FAX ***** */ message('file '|| 'q:
\in.mgw\agee\'||:global.eas$mnt_id||:global.eas$mtn_seq_no||'.'||:cg$ctr
l.cmm _co de); ole2.add_arg(ole_args, 'q:
\in.fax\agee\'||:global.eas$mnt_id||:global.eas$mtn_seq_no||'.'||:cg$ctr
l.cmm _co de); -- Open Word document specified in the argument list
ole_document
:= ole2.invoke_obj(ole_document, 'Open', ole_args);
ole2.destroy_arglist(ole_args);

--Fax the Word document
ole_args:= ole2.create_arglist;
ole2.add_arg(ole_args, '01865843967'); --fax
number
ole2.add_arg(ole_args, 'EASE TEST FAX'||to_char(sysdate,'DD-MON- YYYY
HH24:MI')); --subject line <=255 characters
--ole2.invoke(ole_application, 'SendFax');
ole2.invoke(ole_application, 'SendFax', ole_args);
ole2.destroy_arglist(ole_args);
else
/*
**** SOMETHING ELSE !!! should never happen *****
*/

message('ERROR - :cg$ctrl.cmm_code ='||:cg$ctrl.cmm_code);
end if;

--Release the OLE objects
ole2.release_obj(ole_application);
ole2.release_obj(ole_document);

else --must be using mapi.dll and intermediate datatype .dll
null;

end if;
EXCEPTION
when others then
dbmserrcode :=DBMS_ERROR_CODE;
dbmserrtext :=DBMS_ERROR_TEXT;
message(to_char(dbmserrcode)||' - '||dbmserrtext);

END;
END;







>I had done exactly this sometime ago but in MS Access as follows:
>
>1. Create a passthrough query in MS Access to get Oracle data using
>ODBC.
>
>2. Create a form to compose email message and buttons etc.
>
>3. Merge the message with data from Oracle (using some simple lines of
>code) and send as email (using sendobject macro which uses your
>existing windows messaging profole to send email).
>
>Free free to email me directly if you want to have other infomration
>regarding this.
>
>regards,
>M. Armaghan Saqib
>+---------------------------------------------------------------
>| 1. SQL PlusPlus => Add power to SQL Plus command line
>| 2. SQL Link for XL => Integrate Oracle with XL
>| 3. Oracle CBT with sample GL Accounting System
>| Download free: http://www.geocities.com/armaghan/
>+---------------------------------------------------------------
>
>In article <0722a78c.731dbc0b_at_usw-ex0107-050.remarq.com>,
> Anne <goodwinakNOgoSPAM_at_kpt.nuwc.navy.mil.invalid> wrote:
>> I need to create a process that will dump a flat file of records from
>> an Oracle database, merge this data with a Microsoft Word Form, and
>> email the merged document to multiple users. The merged document must
>> be a 'form', ie., the recipient may only enter data in certain fields
>> and the remainder of the field is not modifyable. Has anyone done
>this
>> before and can offer me some tips?

Hi everyone,

We are using Forms 4.5, Oracle Server 7.3.4 in a Win NT environment and
we use the Forms package OLE2 to start and control Word

PACKAGE BODY word IS

wdWindowStateMaximize constant number := 1;
wdtrue constant varchar2(4) := 'True';
wrd ole2.obj_type;

procedure start_word is
begin
if wrd is null then
wrd := ole2.create_obj ('Word.Application');
ole2.set_property(wrd,'visible',wdtrue);
end if;
word_venster_maximaal;
end;

procedure word_venster_maximaal is
begin
ole2.invoke (wrd, 'Activate');
ole2.set_property(wrd,'Windowstate',wdWindowStateMaximize);
end;

END;

After starting Word Visual Basic commands are used to control Word. The
Forms application only starts Word once, the next time Word is being
started, the existing Word instance is used.
See the code sample above.

However if the user himself starts Word (for example from the start
button), then this Word instance should be used by the Forms
application.

Any ideas how this can be done?

Thanks

Wilhelm


Sent via Deja.com http://www.deja.com/
Before you buy.
Received on Tue Aug 01 2000 - 00:00:00 CEST

Original text of this message