Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to use OLE2 for Word

2,618 views
Skip to first unread message

dave_...@my-deja.com

unread,
Aug 1, 2000, 3:00:00 AM8/1/00
to
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...@usw-ex0107-050.remarq.com>,
> Anne <goodwina...@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.

0 new messages