Using DDE, there are two possible strategies - Omnis running as client and MS Word as server, or the other way round. Normally, the task of creating a document is started in your Omnis application, in this case Omnis should be the client and MS Word the server.

Check MS Word

In the beginning, you need to open a DDE conversation. This can only be done when the application you want to talk to has been opened - so first check if MS Word is already running. Note that 'Test for program open' needs the internal name of the application, this is 'winword' for (most versions of) MS Word:

Test for program open {winword} 
If flag false
Start program maximized {[MyWordPath]} ;MyWordPath contains the path to winword.exe
If flag false OK message (Sound bell) {Cannot open [MyWordPath]}
Quit procedure (flag clear)
End If
End If

Now that we have ensured that MSWord is running, we can open our DDE conversation.

Open DDE conversation

There is one basic principle with DDE, that must be understood - you cannot talk directly to the application, but only to a 'topic' of an application. A 'topic' means a document in MS Word or a library in Omnis or a drawing in CorelDRAW.

However, every application should provide a 'system' topic - this is something like a 'null-document', so that you are not forced to open a dummy document to establish a DDE conversation. For the conversation, you must assign a DDE channel first - this is because you might want to talk to an Excel spreadsheet and to a MS Word document and to a Corel drawing at the same time - so the assigned channels keep those conversations separated for Omnis and once you've opened different conversations you just would switch from one channel to another.

Set DDE channel number {1} ;; assign channel number 

Now you can open the conversation. The general DDE syntax for this is application|topic, where for application again the internal name must be used:

Open DDE channel {winword|system} ;; opens the system topic of Word 

Now you're ready to go !

DDE Tokens

Here comes the big downside of DDE: The DDE tokens are widely undocumented. I recall there was a small textfile somewhere hidden on the Office 97 CD where at least some of the available commands were mentioned. But you still can do everything you want, and I would recommend to follow the strategy outlined below - it will save you a lot of work specially when you have to deal with different MS Word versions (yes - the tokens change between the versions, in the beginning they even were localized, so a German MS Word version would differ completely from an english version and so on).

In general, the tokens follow closely the WordBasic dialect. For test, let's maximize winword so it pops up in front of the screen. The correct token for MS Word 8 and above is AppMaximize. Note that all tokens must be written within [square brackets].

Now square brackets have their own meaning in Omnis, so you should calculate your command in a string variable and send it to the DDE channel:

Calculate mDDECommand as '[AppMaximize]' 
Send command {[mDDECommand]}

This should bring MS Word to the front and maximize it (I recall problems with one MS Word version, I however cannot remember which one).

The conversation

In my experience, everything you need to send via DDE channel are three general commands - I name them NewDocument, OpenDocument and GetDocumentName. Everything else can be done either in Omnis or in Word, without the need for a DDE conversation. WordBasic offers far better features to mix text into the document, so why do it via DDE ? All we need is to tell MS Word, where the text you want to mix can be found, and which template it should use.

This construction is quite simple, but very reliable and stable throughout all different versions of Omnis and MS Word.

You can think of a simple but flexible interface: On Omnis side, you export the required datas into a text file, on WordBasic side you open this text file, read the records and mix them into your document. The biggest advantage of this construction is that you can customize your MS Word templates for your clients (or even let them do their own customization) without touching your Omnis application - a thing you will appreciate as soon as you have more than one customer.

So lets look at the three needed methods:

NewDocument

This tells MSWord to create a new document using a specified template. The template must have an autostart macro, that reads the Omnis generated text file and does whatever it is supposed to do with the retrieved datas. We need to tell the macro the path of the generated text file - there are several ways to do this, the most simple and reliable one is to put the path string into the clipboard on Omnis side and read the contents of the clipboard within the MS Word macro.

;; first create text file with needed datas
;; then:

Copy to clipboard pPathOfTextFile ;put path of text file into the clipboard
Call procedure $openMSWord {$openMSWord} ;check if MS Word is running as pointed out above
If flag false
Quit procedure (flag clear) ;; quit when word does not respond
End If

Now we tell MS Word to create a new document using the template we specify in the variable pTemplatePath. The syntax of the DDE command is

[FileNew .NewTemplate = 0 or 1 , .Template = "Path of Template"] 

where NewTemplate = 0 means we want to create a normal document (1 would create a new template)

Calculate mDDECommand as con('[FileNew .NewTemplate = 0 ,.Template = "',pTemplatePath,'"]') 
Send command {[mDDECommand]}

This was it !

OpenDocument

I think you already got the picture. OpenDocument just opens a Word document for a given path specified in the variable pDocumentPath.

The syntax of the DDE command is

[FileOpen "Path of the document"] 

so the Omnis code looks like

Calculate mDDECommand as con('[FileOpen "',pDocumentPath,'"]') 
Send command {[mDDECommand]}

GetDocumentName

This method returns the path of the current document opened in MS Word. Now, this one is quite tricky. Remember that we opened our DDE conversation with the system topic. This topic does not know anything about the open documents, so sending a DDERequest command will fail.

So we are in the position of sitting in a swamp and trying to pull us out on our own hair - to send a DDE request we already would need to know the name of the current document, so that we can open a conversation with it.

Hence, we need to do something different. The trick is that we send a tiny WordBasic program via DDE to MS Word that writes the path of the current document into a little text file, that is opened and read by Omnis afterwards - tricky, but it works.

The WordBasic code looks something like

Open "Path of exchange file" For Output as #1 
Print #1, FileName$()
Close 1

You can combine WordBasic statements by separating them with ':'. So what we send via DDE is

[Open "Path of exchange file" For Output as #1 : Print #1, FileName$() : Close 1] 

and our Omnis code looks like

Calculate mDDECommand as con('[Open "',mExchangeFilePath,'" For Output as #1') 
Calculate mDDECommand as con(mDDECommand,':Print #1, FileName$():Close 1]')
Send command {[mDDECommand]} ;MS Word now writes the document's path name to disk

Set import file name {[mExchangeFilePath]} ;so let's read it
Prepare for import from file {One field per line}
Import field from file into mDocumentName
Close import file
Set return value {mDocumentName}

Now we are done - you can do everything you want in the Omnis/MS Word universe; of course you need to have a little practice with WordBasic. However most macros can be auto generated by recording and edited to your needs afterwards - the best way to learn about the (widely undocumented) WordBasic language. And for those who did not fell asleep till now, here comes

MISCHA'S BIG MEGA BONUS

Yes, the described method offers another advantage that is simply terrific - it works cross platform!

You can do the same on Macs. Yes. There is no change needed in your WordBasic macros, and only very little on Omnis side: Instead of setting the DDE channel and open the DDE conversation you type:

Send Finder event {Open Files (mPathOfMSWord)} 
Set event recipient {Microsoft Word}
Send Core event {Do Script (mDDECommand)}

Everything else stays the same !

Go to top
JSN Boot template designed by JoomlaShine.com