DDEによるプロセス間通信


 
Dosの時代
 

 Dosの時代はシングルタスク。プロセス間通信はありませんでした。 EXCELのバージョンが2だった頃、シ-トの株価を通信ソフトで 取得し、リアルタイムに変ていたそうですが、特殊なケース だったでしょう。
 ところうが、マルチタスクOSでは、プロセス間通信は必須のことです。 Unixでは、長い歴史があるのでしょう。

 DDEはDynamic Data Exchangeの略でWindowsが提供するプロセス間通信の一つです。 DDEにもサーバー(ソース)とクライアン(デスチネーション)という立場があって、プロトコルがあるようです。

  Windowsでは、通常DDEを直接使わずにデータ交換ライブラリ(DDEML.dll)を使います。
 DDEを始めるには、クライアントとしてサーバーに、交信開始を通知する事から始めます。クライアント側はサービス名トピックス名をDDEMLに渡し、DDEMLは、受け取ったサービス名を持つサーバーにトピック名を渡します。サーバー側では、受け取ったトピックス名を調べてデータ交換を始めるかどうかを決めます。
 サービス名やトピック名を渡すときには、文字列ではなく文字列ハンドルというものを作って渡します。データ交換もハンドルを用いて行います。
データをサーバーに送る場合には
(クライアント側)
  データハンドルを作る
  データハンドルを渡す
(サーバー側)
  データハンドルを受け取る
  データハンドルからデータの内容を得る
  処理する
  データハンドルを解放する
  終了
というような流れになります。


 
DDEの情報を集める

 DDEを使うと次のようなことが出来ます。
DDEInitiate.リンクの確立をする
DDEReques要求トランザクションデータをサーバーに要求する
DDEPokeポークトランザクションデータをサーバーに送る
.アドバイズトランザクション サーバーデータを定期的に受け取る
DDEExecute実行トランザクションコマンドライン文字列を渡してサーバーに何かをさせる
DDETerminate.リンクの切断をする

 Windows98のシステムファイルを点検してみると、C\windows\systemにDDEML.dellがありましたから、DDEは実行できるようです。
 DDEサーバー DDEクライアントのプログラムは DDEMLDLLをインクルードしてCで書かれますが、VBもDLLを利用できます。では、EXCELのVBAではどうでしょうか。
 EXCELのVisualBasicEditoでオブジェクトブラウザを開いて見ます。DDE一式がコマンドとして使えるようです。ヘルプには、以下の記述があります。

Query では、DDE (Dynamic Data Exchange) がサポートされます。DDE は、2 つの アプリケーションが相互にデータを交換する通信形態です。 Visual Basic for Applications で DDE を使用すると、Query と Excel などの他の アプリケーションとの間で通信を行って、データをやり取りすることができます。 [コピー] コマンドと [形式を選択して貼り付け] コマンドを使って他のアプリケー ションとの間にリンクを設定できない場合は、リモート参照数式を使ってデータを 参照することができます。データは数式の計算結果としてワークシートに表示され ます。 リモート参照は、アプリケーション名、ファイル名またはトピック名、および参照す るセル範囲、値、フィールド、データ項目名のいずれかという、3 つの部分で構成さ れます。 アプリケーション、ファイル、トピック、またはデータ項目の名前に、スペース、 またはコロン (:)、マイナス記号 (-) など数式に関連する記号が含まれている場合 や、これらの名前がセル参照に類似している場合は、名前をクォーテーション (') で 囲みます。
 Query とは、データベース管理システムに対する処理要求(問い合わせ)文字列です。

 Wordはどうでしょうか。オブジェクトブラウザで見てみましたが、EXCELと同じようです。Wordには、これを使う標準コマンドがあるようです。



 
通信方法
 

 ホストとクライアントが繋がる事をリンクといいます。そのLINKの状態に3つあります。
自動リンクソース側のアイテムが変化したら自動で新しいデータが送られる
手動リンククライアントが要求した時だけデータを送る
通知リンクソース側のアイテムが変化したら、変化した事だけ伝える。データは送られない

 上のマニュアルは、自動リンを利用していることを表現している模様です。



オブジェクトブラウザ掲載の関数仕様
Function DDEInitiate(App As String, Topic As String) As LongTopic=system
Function DDERequest(Channel As Long, Item As String)Channel=DDEInitiateの返値
Sub DDEPoke(Channel As Long, Item, Data)ポークトランザクション
DDEExecute(Channel As Long, String As String)[FileOpen("")] [BEEP] など
Sub DDETerminate(Channel As Long).


 
DDEホスト
 

 あるアプリケーションがDDEホストの機能を持っていると、色々な連携プレーの一員に出来ます。EXCEL、WORDがDDEをサポートするのは、そのためです。
 DDEホストの機能を持つには、接続してきたクライアントに、どのようなサービスを提供しているか知らせる必要があります。Systemというトピックスがこの情報に対応します。

 DDEは、データ交換というより、データ通信です。コマンドのやり取りに適しています。この機能を活かし、EXCECUTEというサービスをします。
 SHELLのsendkeyメソッドに似ていますが、仕組みが違うようです。コマンドは、 [open][edit][close]のように表現されます。これをコードにすると、
DDEExecute ch, "[Stop]"
となります。

DDEExecute ch, "[Open""D:\temp\test.xls""]"

これは、EXCELのファイルを開くコマンドです。

FilePaht="D:\temp\test.xls"
DDEExecute ch, "[Open"""&FilePaht&"""]"
ファイルを変数にすると、このようになります。

 DDEホストのプログラムは、文字列解釈をする部分をプログラマーが書きます。 ”の中の”は””にするとか、それがいやなら’でくくるとか、ルールをコーデイングします。与えられたマシーン的制約条件とプログラマーが決めたルールがあります。 マニアルで確認するか、2、3トライアルするしかありません。

FilePaht="D:\temp\test.doc"
DDEExecute ch, "[REM _DDE_Direct][FileOpen"""&FilePaht&"""]"

これはWordのファイルを開くコマンドです。同じOFFICEの製品ですが、 ずいぶんちがいます。開発チームが違うと、こんなにも違うようです。


 
アプリケーション名前、トピッス名
 

 ActiveXオートメーションの時代に、DDE通信でもあるまい。それはそうなのですが、ActiveXオートメーションに対応しないものがあります。AutoCAD LTがそうです。本家AutoCADはオブジェクトのプロパテイを操作して、線の色や種類を外部からコントロールできます。サブセット版のLTはこれができません。

 DOS時代に、マクロが組めて結構便利なツールがありました。そんなものを、Windows時代に活用したいことがあります。この場合もDDEを使うといい場合があります。

 DDEを使うとして、アプリケーション名とトピックス名が必要です。そのソフトが、 レジストリに記入していれば、それに従います。

Sub DDECadOpn() Dim MyCh As Long Dim AppPath As String Dim FilePath As String 'アプリケーションのフルパス。 AppPath = "C:\Program Files\AutoCAD LT 2002\aclt.exe" FilePath = "D:\temp\test.dwg" Shell AppPath, 1 MyCh = DDEInitiate("AutoCAD LT.DDE", "System") MsgBox "接続チャンネルは : " & MyCh & "です" 'アプリケーションの起動。 DDEExecute MyCh, "[open(""" & FilePath & """)]" MsgBox "AutoCAD稼動中" DDEExecute MyCh, "[quit ]" '接続を切断します。 DDETerminate MyCh End Sub

 一応接続できました。quitで終了させたかったのですが、コマンドラインにquitと表示しただけです。Enterを押すと、終了しました。AutoCADはコマンドラインからの操作や、マクロ操作に特徴があります。スペース入力がEnterの役目をするのが特徴です。 [quit ]とスペースをいれました。改行コード\r\n はだめでした。CHR(13)もだめでした。


 
AutoCAD LTでDDEEXCUTEを使う
 

 AutoCAD LTはスクリプトファイルが使えます。
例えば、次のようなテキストファイルを拡張子.scrで保存します。
line 500,0 0,500 circle 200,200 50
 ツールスクリプトファイル実行を選択すると、ファイル選択のダイアログが開きます。作ったSCRファイルをダブルクイックで、ファイルのデーターを自動実行してくれます。つまり、直線と円を自動的に書いてくれます。
 例えば、用地の境界点の測量データーをもらいます。100点もあれば大変な作業です。 手入力だと読み取りミスもあります。こんな時はEXCELで測量データをもらいます。 lineコマンドを挟み込んでSCRファイルを出力するマクロを組んでおきます。 100点ぐらいは、あっと言う間にプロット完了です。

 SCRファイルは、キーボードから打ち込んだAutoCADのコマンドと数値データ を事前にテキストファイルに書いたものです。これを一行づづ読み取り、あたかもキーボードから入力したようにCADに命令してくれるインタープリタがいるわけです。 便利なのですが、一旦ファイルに落とさなければなりません。ファイルではなく、共通メモリーに出力して読みとってもらえないかと考えました。

 DDEはまさに共有メモリーを使ったデータ交換です。しかもEXCECUTEはコマンドラインメモリーの共有のようです。利用してみましょう。ただ、COM時代のDDEは、時代遅れのツールですから参考情報がありません。それに、DDEサーバープログラムをAutoDeskがどのように記述しているかわかりません。googleで拾い集めた断片的な情報を 最大限活用するしかありません。

 EXCELのVBAから利用するとして
x1 = 0 y1 = 500 x2 = 500 y2 = 0 DDEExecute MyCh, "[Line " & x1 & "," & y1 & " " & x2 & "," & y2 & " ]" x1 = 0 y1 = 0 pnam1 = "p1" DDEExecute MyCh, "[point " & x1 & "," & y1 & " ]" DDEExecute MyCh, "[text "&x1&","&y1&" 15 0 "&pnam1&Chr(13)&Chr(13)&"]" x1 = 200 y1 = 200 r1 = 50 DDEExecute MyCh, "[circle " & x1 & "," & y1 & " " & r1 & " ]" DDEExecute MyCh, "[quit ]

 AutoCAD LTではDDEのExecuteが、キーボードからの作図コマンドをサポートしているようです。今まで、一旦ファイルに落としたスクリプトを、直接転送可能です。
 EXCELでスクリプトを自動作成していました。ファイル保存の手続きを 上のようなDDE転送に書き換えればいいことになります。

 COM時代ではレトロな技術ですが、DDEを活用できる一事例です。



2004.7.16
by Kon