アプリケーション テクニック PowerBuilder® 11.5 DOCUMENT ID: DC37774-01-1150-01 LAST REVISED: September 2008 Copyright © 2008 by Sybase, Inc. All rights reserved. 本書は Sybase ソフトウェアの付属マニュアルであり、新しいマニュアルまたはテクニカル ノートで特に示されないかぎ り、後続のリリースにも付属します。このマニュアルの内容は、予告なく変更されることがありますが、Sybase,Inc. およ びその関連会社では内容の変更に関して一切の責任を負いません。このマニュアルに記載されているソフトウェアはライ センス契約に基づいて提供されるものであり、無断で使用することはできません。 予定したソフトウェアのリリース日にのみアップグレードを提供します。本書に記載されている内容は、Sybase, Inc. およ びその関連会社の書面による事前許可を得ずに、電子的、機械的、手作業、光学的、またはその他のいかなる手段によっ ても複製、転載、翻訳することを禁じます。 Sybase の商標は Sybase の商標ページ のサイト http://www.sybase.com/detail?id=1011207 に記載されています。記載の Sybase およ びマークは Sybase, Inc の商標です。® はアメリカ合衆国における登録商標を示します。 Java およびすべての Java ベースのマークは、米国および他国における Sun Microsystems, Inc. の商標または登録商標です。 Unicode および Unicode のロゴは Unicode, Inc. の登録商標です。 本書で記載されている上記以外の社名および製品名は、各社の商標または登録商標の場合があります。 本書に記載されている内容は、将来予告なしに変更することがあります。また、本ソフトウェアおよび説明書を使用した ことによる損害、または第三者からのいかなる請求についても、サイベース株式会社、その親会社である米国法人 Sybase, Inc. またはその関連会社は、一切の責任を負わないものとします。 目次 本書について ............................................................................................................................... xvii 第1部 アプリケーション テクニックの学習 第1章 サンプル アプリケーションの使い方.......................... サンプル アプリケーションについて............................................... Web サイトのサンプル ............................................................. DVD 内のサンプル .................................................................... サンプル アプリケーションのインストール .................................... サンプル アプリケーションを開く .................................................. Code Examples アプリケーションの使い方.................................... サンプルの参照 ......................................................................... サンプルの検索 ......................................................................... サンプルの実行と調査 .............................................................. 3 3 4 4 5 5 7 7 8 9 第2部 言語テクニック 第2章 オブジェクト指向プログラミング ........................... 用語の確認 ..................................................................................... PowerBuilder のテクニック ........................................................... その他のテクニック ....................................................................... 13 15 20 PowerScript についての特別なトピック ..................... ドット表記 ..................................................................................... 定数の宣言 ..................................................................................... インスタンス変数のアクセスの制御.............................................. 名前の重複の解決 .......................................................................... 先祖スクリプトからの戻り値 ........................................................ 関数とイベントの引数の型 ............................................................ 先祖変数と子孫変数 ....................................................................... データウィンドウと外部オブジェクトにおける式の最適化.......... 25 30 30 31 33 35 36 38 第3章 アプリケーション テクニック 13 25 iii 目次 第4章 PowerBuilder での例外処理 ........................................................... 例外処理の基本 ....................................................................... 例外処理用のオブジェクト ..................................................... 例外の処理 .............................................................................. ユーザ定義の例外型の作成 ..................................................... 柔軟性の向上とオブジェクトの再利用の促進 ........................ SystemError イベントと Error イベントの使い方................... ガベージ コレクションとメモリ管理............................................. メモリ管理の設定.................................................................... 効率的なコンパイルとパフォーマンス .......................................... テキスト ファイルとバイナリ ファイルの読み書き ...................... 39 40 40 41 44 46 48 49 51 53 53 PowerBuilder のクラス定義に関する情報の取得 .............. クラス定義情報の概要 ................................................................... 用語 ......................................................................................... PowerBuilder クラス定義の使用について............................... クラス定義の調査 .......................................................................... クラス定義オブジェクトの取得 .............................................. クラスに関する詳細情報の取得 .............................................. クラスのスクリプトに関する情報の取得................................ 変数に関する情報の取得......................................................... 57 58 60 61 61 62 64 67 57 第3部 ユーザ インタフェース テクニック 第5章 MDI アプリケーションの構築................................ MDI について ................................................................................. MDI フレーム ウィンドウの作成 ................................................... シートの使い方 .............................................................................. マイクロヘルプの提供 ................................................................... MDI アプリケーションにおけるツールバーの使い方 .................... ツールバーの動作のカスタマイズ .......................................... ツールバー設定の保存と復元.................................................. クライアント領域のサイズ設定..................................................... MDI アプリケーションにおけるキーボード操作について............. 71 74 75 77 78 78 80 84 87 ウィンドウ インスタンスの管理 ............................. ウィンドウ インスタンスについて ................................................ ウィンドウ インスタンスの宣言.................................................... ウィンドウ配列の使い方................................................................ 子孫オブジェクトのエンティティの参照 ...................................... 91 93 94 97 第6章 iv 71 91 PowerBuilder 目次 第7章 ウィンドウにおけるタブ コントロールの使い方 ............... 99 タブ コントロールについて ........................................................... 99 タブ ページの定義と管理............................................................. 100 タブ コントロールのカスタマイズ .............................................. 104 スクリプトにおけるタブ コントロールの使い方......................... 107 スクリプトでのタブ ページの参照 ....................................... 107 タブ ページにあるコントロールの参照 ................................ 110 タブ ページを開く、閉じる、非表示にする ......................... 111 タブ ページの履歴................................................................. 111 必要なときだけタブ ページを生成 ....................................... 112 タブ コントロールの各部分におけるイベント ..................... 114 第8章 ツリービュー コントロールの使い方........................ ツリービュー コントロールについて........................................... ツリービューの表示..................................................................... 項目挿入関数......................................................................... ルート レベルへの項目の挿入............................................... ルート レベルの下への項目の挿入 ....................................... ツリービューの項目の管理 .......................................................... 項目の削除 ............................................................................ 項目の名前の変更.................................................................. ドラッグ アンド ドロップによる項目の移動 ........................ 項目のソート......................................................................... ツリービュー ピクチャの管理 ..................................................... 項目のピクチャ ..................................................................... ピクチャ リストの設定 ......................................................... オーバーレイ ピクチャの使い方 ........................................... データウィンドウのデータのツリービューへの表示 .................. 117 117 121 122 123 124 127 128 129 130 134 136 136 137 138 139 第9章 ウィンドウでのリストの使い方 ............................ リストの提示について ................................................................. リストの使い方 ............................................................................ ドロップダウン リストの使い方 .................................................. リストビュー コントロールの使い方........................................... 詳細表示の使い方.................................................................. 143 143 144 149 152 158 第 10 章 ドラッグ アンド ドロップ機能の使い方 ..................... 161 ドラッグ アンド ドロップ機能について ...................................... 161 ドラッグ アンド ドロップのプロパティ、イベント、および関数 162 ドラッグされたコントロールの識別............................................ 164 第 11 章 オンライン ヘルプの提供.................................. 165 アプリケーション テクニック v 目次 ヘルプ ファイルの作成 ................................................................ 165 開発者に対するオンライン ヘルプの提供 ................................... 167 エンド ユーザに対するオンライン ヘルプの提供........................ 169 第4部 データ アクセス テクニック 第 12 章 トランザクション オブジェクトの使い方 .................... 173 トランザクション オブジェクトについて ................................... 173 トランザクション オブジェクトのプロパティ ..................... 174 トランザクション オブジェクトのプロパティと PowerBuilder データベース インタフェースのサポート...................... 177 トランザクション オブジェクトの使い方 ................................... 178 トランザクションの基礎....................................................... 179 デフォルト トランザクション オブジェクト ........................ 180 トランザクション オブジェクトのプロパティ値の設定 ....... 181 外部ファイルからの値の読み込み ........................................ 182 データベースへの接続 .......................................................... 183 PowerBuilder アプリケーションで接続するための[プレビュー] タブの使い方 .................................................................. 183 データベースとの接続の解除................................................ 184 複数のデータベース接続におけるトランザクション オブジェク トの定義 ......................................................................... 185 SQL 文実行後のエラー処理 .................................................. 188 データベース トランザクションのプール............................. 189 ストアド プロシージャを呼び出すためのトランザクション オブジェ クトの使い方 .................................................................. 190 ステップ 1: 標準クラス ユーザ オブジェクトの定義............ 192 ステップ 2: 外部関数としてのストアド プロシージャの宣言 193 ステップ 3: ユーザ オブジェクトの保存............................... 195 ステップ 4: SQLCA に対するデフォルトのグローバル変数の型の 指定 ................................................................................ 195 ステップ 5: アプリケーションでユーザ オブジェクトを使用する 197 ストアド プロシージャを呼び出すときサポートされている DBMS の 機能 ................................................................................ 199 第 13 章 MobiLink 同期の使い方.................................... MobiLink 同期について ................................................................ 同期の動作方法 ............................................................................ PowerBuilder 同期オブジェクトの使い方.................................... ウィザードを使用する準備 ................................................... 生成されるもの ..................................................................... vi 203 203 208 210 210 211 PowerBuilder 目次 MLSync のインスタンスの作成 ............................................ MobiLink 同期の補助オブジェクト ....................................... アプリケーションでの同期オブジェクトの使い方 ............... リモート マシンでの同期の実行時要件 ................................ 統合データベースの準備.............................................................. 接続イベント......................................................................... テーブル イベント................................................................. Sybase Central でのスクリプトおよびユーザに対する作業 リモート データベースの作成 ..................................................... パブリケーションの作成と変更 ............................................ Mobile Link ユーザの作成...................................................... サブスクリプションの追加 ................................................... 同期のテクニック ........................................................................ 212 213 216 219 222 223 224 228 231 231 234 236 237 第 14 章 PowerBuilder XML サービスの使い方 ...................... XML と PowerBuilder について ................................................... PBDOM について......................................................................... PBDOM オブジェクト階層 .......................................................... PBDOM ノード オブジェクト...................................................... PBDOM_OBJECT ................................................................. PBDOM_DOCUMENT .......................................................... PBDOM_DOCTYPE.............................................................. PBDOM_ELEMENT .............................................................. PBDOM_ATTRIBUTE ........................................................... PBDOM_ENTITYREFERENCE ............................................ PBDOM_CHARACTERDATA ............................................... PBDOM_TEXT ...................................................................... PBDOM_CDATA ................................................................... PBDOM_COMMENT............................................................. PBDOM_PROCESSINGINSTRUCTION............................... アプリケーションへの pbdom115.pbx の追加............................. PBDOM の使い方......................................................................... XML の検証 ........................................................................... XML から XML ドキュメントの作成 ..................................... 最初からの XML ドキュメントの作成................................... ノード データへのアクセス .................................................. ノード ツリー階層の操作...................................................... PBDOM 例外の処理 ..................................................................... XML 名前空間 .............................................................................. PBDOM_ATTRIBUTE の名前および名前空間の設定 ........... 241 241 242 243 244 245 247 248 248 251 254 254 255 258 258 259 260 261 261 262 264 265 267 267 269 270 第 15 章 グラフの操作 ............................................ 275 グラフの使い方 ............................................................................ 275 アプリケーション テクニック vii 目次 コードにおけるグラフ コントロールの操作 ......................... グラフへのデータ表示 ................................................................. グラフのプロパティの修正 .......................................................... グラフ要素の表示.................................................................. グラフ要素の参照.................................................................. データのプロパティへのアクセス ............................................... データの情報の取得 .............................................................. グラフのデータの保存 .......................................................... 色や模様、そのほかのデータの修正..................................... ポイント アンド クリックの使い方 ............................................. 276 277 279 280 280 281 282 283 283 283 第 16 章 リッチテキストの作成方法 ................................. 287 アプリケーションにおけるリッチテキストの使い方 .................. 287 リッチテキストの作成 .......................................................... 288 リッチテキスト アプリケーションの配布............................. 288 リッチテキスト データウィンドウ オブジェクトの使い方 ......... 289 リッチテキスト エディット コントロールの使い方 .................... 292 エンド ユーザに制御権を与える ........................................... 292 リッチテキスト エディット コントロールのためのテキスト 293 ActiveX スペル チェック コントロールの使用...................... 302 リッチテキストの書式設定 ................................................... 304 入力フィールド ..................................................................... 304 データベースのデータの使い方 ............................................ 306 リッチテキスト エディット コントロールにおけるカーソル位置 307 プレビューと印刷.................................................................. 309 リッチテキストとエンド ユーザ.................................................. 311 第 17 章 データ ソース間のデータ転送 .............................. データ パイプラインについて ..................................................... 必要なオブジェクトの作成 .......................................................... パイプライン オブジェクトの作成 ....................................... ユーザ オブジェクトの作成 .................................................. ウィンドウの作成.................................................................. パイプライン処理の前準備 .......................................................... パイプライン処理の開始.............................................................. パイプライン処理のモニタ ................................................... パイプライン処理のキャンセル ............................................ 更新処理のコミット .............................................................. エラー行の処理 ............................................................................ エラー行の修復 ..................................................................... エラー行の破棄 ..................................................................... パイプラインの後処理 ................................................................. viii 315 316 317 317 320 321 325 328 330 332 334 335 336 338 339 PowerBuilder 目次 第5部 プログラム アクセス テクニック 第 18 章 DDE の使い方 ........................................... 343 DDE について .............................................................................. 343 DDE 関数とイベント ................................................................... 344 第 19 章 アプリケーションにおける OLE の使い方 ................... 347 PowerBuilder における OLE のサポート ..................................... 347 ウィンドウにおける OLE コントロール ...................................... 348 OLE コントロールと挿入可能なオブジェクト ............................ 352 OLE コントロールの設定...................................................... 352 リンクと埋め込み.................................................................. 356 オフサイト アクティブ化とインプレース アクティブ化 ...... 358 インプレース アクティブ化に対するメニュー ..................... 359 OLE コントロール上でのオブジェクトの修正 ..................... 361 OLE カスタム コントロール ........................................................ 366 OLE カスタム コントロールの設定 ...................................... 366 ActiveX コントロールのプログラミング............................... 368 プログラム可能な OLE オブジェクト.......................................... 370 OLEObject オブジェクト型................................................... 370 OLEControl、OLECustomControl、OLEObject データ型の代入 373 オートメーション.................................................................. 375 スクリプトにおける OLE オブジェクト ...................................... 380 オートメーションのインタフェース..................................... 381 オートメーションと Any 型 .................................................. 388 効率的な OLEObjects 変数の使い方 ..................................... 389 エラー処理 ............................................................................ 390 ホット リンクの作成 ............................................................. 393 OLE サーバで使用できる言語............................................... 395 OLE オブジェクトへの低レベル アクセス............................ 396 データウィンドウ オブジェクトにおける OLE オブジェクト 396 オブジェクト ブラウザでの OLE 情報......................................... 400 OLE オブジェクトの高度な操作 .................................................. 402 OLE ストレージの構造 ......................................................... 403 ストレージとストリームに対するオブジェクト データ型 ... 404 ストレージを開く、保存する................................................ 405 ストリームを開く.................................................................. 411 ストレージを使用する際のストラテジ ................................. 416 第 20 章 MAPI の使い方........................................... 417 MAPI について ............................................................................. 417 アプリケーション テクニック ix 目次 MAPI の使い方 ............................................................................. 418 第 21 章 外部関数とそのほかの拡張処理機能の使い方 ................. 外部関数の使い方 ........................................................................ 外部関数の宣言 ..................................................................... 外部関数の宣言例.................................................................. 引数の受け渡し ..................................................................... UNIX での外部関数とプログラムの呼び出し........................ ユーティリティ関数の使い方 ...................................................... Windows メッセージの送信......................................................... メッセージ オブジェクト............................................................. メッセージ オブジェクトのプロパティ ................................ コンテキスト情報 ........................................................................ コンテキスト情報サービス ................................................... コンテキスト キーワード サービス ...................................... CORBACurrent サービス ...................................................... エラー ロギング サービス..................................................... インターネット サービス...................................................... Secure Sockets Layer サービス............................................ トランザクション サーバ サービス ...................................... 第6部 分散アプリケーションの開発 第 22 章 PowerBuilder を使った分散アプリケーション開発 ........... 445 分散アプリケーションのアーキテクチャ .................................... 445 サーバのサポート ........................................................................ 446 第 23 章 EAServer コンポーネントの構築 ........................... EAServer コンポーネントの構築について .................................. ウィザードの使い方について................................................ 開発プロセスについて .......................................................... アプリケーション サーバ プロファイルの作成 .................... 共有コンポーネントおよびサービス コンポーネントの操作....... 共有コンポーネントについて................................................ サービス コンポーネントについて ....................................... スレッド実行の問題とコンポーネントの種類 ...................... EAServer Thread Manager の使い方 .................................... インスタンス プーリングのサポート........................................... トランザクションのサポート ...................................................... EAServer コンポーネントからデータベースへのアクセス ......... 接続キャッシュの使い方....................................................... 検索操作の実行 ..................................................................... x 421 421 422 423 425 428 429 430 432 432 434 435 437 438 438 439 442 442 453 453 454 454 455 457 457 458 460 463 463 467 474 475 479 PowerBuilder 目次 更新の実行 ............................................................................ 結果集合の受け渡し .............................................................. コンポーネント インタフェースの定義 ....................................... 既存インタフェースの実装 .......................................................... 別のサーバ コンポーネントのメソッドの呼び出し ..................... コンポーネント プロパティへのアクセス ................................... Web サービスとしての NVO の公開 ........................................... コンポーネントのテストとデバッグ............................................ ライブ編集 ............................................................................ リモート デバッグ................................................................. EAServer ログへのメッセージ出力 ...................................... データの印刷................................................................................ Solaris オペレーティング システムでの印刷........................ PDF への印刷........................................................................ EAServer へのコンポーネントの配布.......................................... 480 485 488 493 495 497 502 504 504 506 509 509 510 514 515 第 24 章 EAServer クライアントの構築............................. EAServer クライアントの構築について ...................................... ウィザードの使い方について................................................ 開発プロセスについて .......................................................... EAServer への接続 ...................................................................... コードを手書きする方法....................................................... ウィザードを使用した接続オブジェクトの作成................... EAServer プロキシ オブジェクトの生成 ..................................... コンポーネント メソッドの呼び出し........................................... コンポーネント メソッドの呼び出し.................................... EJB コンポーネント メソッドの呼び出し ............................ インスタンスの破棄 .............................................................. JaguarORB オブジェクトの使用 ................................................. String_To_Object を使用したインスタンス化 ...................... ネーミング サービス API によるインスタンス化 ................. クライアントとコンポーネントを区別するトランザクション .... サーバ メッセージ返送の要求 ..................................................... 例........................................................................................... エラー処理 ................................................................................... CORBA 例外の処理............................................................... Error イベントのスクリプト作成 .......................................... SystemError イベントのスクリプト作成 .............................. クライアント アプリケーションの配布 ....................................... 519 519 520 520 521 521 523 524 526 526 528 532 533 534 536 538 541 542 546 548 549 550 551 第 25 章 PowerBuilder クライアントでの SSL の使い方 .............. 553 EAServer とのセキュアな接続 .................................................... 553 PowerBuilder での SSL 接続........................................................ 555 アプリケーション テクニック xi 目次 SSL プロパティ..................................................................... ORB プロパティ.................................................................... セキュアな接続の確立 ................................................................. SSL コールバックの使い方 ......................................................... セッション情報の取得 .......................................................... SSLCallback オブジェクトの実装 ........................................ SSLCallback オブジェクトの指定 ........................................ セッション セキュリティ情報の取得........................................... 555 558 559 562 562 563 565 566 第 26 章 COM/COM+ コンポーネントの構築 ......................... 567 COM/COM+ コンポーネントの構築について .............................. 567 ウィザードの使い方について................................................ 568 開発プロセスについて .......................................................... 569 コンポーネント オブジェクト モデルについて ........................... 570 PowerBuilder COM サーバについて ..................................... 571 オートメーション サーバと PowerBuilder COM サーバの比較... 571 コンポーネント インタフェースの定義 ....................................... 574 メソッドとデータ型 .............................................................. 574 コーディング上の制約 .......................................................... 576 ログ ファイルへのエラー記録............................................... 577 COM コンポーネントからデータベースへのアクセス ................ 578 結果集合の受け渡し .............................................................. 579 トランザクションのサポート ...................................................... 582 別のサーバ コンポーネントのメソッドの呼び出し ..................... 585 セキュリティ問題 ........................................................................ 586 プロジェクト ペインタでの COM/COM+ コンポーネントの構築 587 コンポーネントの自動登録 ................................................... 589 COM+ にコンポーネントを配布 ........................................... 589 カスタム インタフェースとデュアル インタフェースの選択 589 埋め込み PBD の設定............................................................ 590 PowerBuilder COM オブジェクトの実行 ..................................... 590 メモリの割り当て.................................................................. 591 PowerBuilder COM サーバの配布................................................ 591 COM 対応のアプリケーションによる PowerBuilder COM サーバ の使い方 ......................................................................... 591 クライアントから PowerBuilder COM サーバへのアクセス ....... 593 クライアントとしての Visual Basic...................................... 593 クライアントとしての C++................................................... 594 DCOM での PowerBuilder COM サーバとオブジェクトの使い方 597 第 27 章 COM/COM+ クライアントの構築 ........................... 601 xii PowerBuilder 目次 COM/COM+ クライアントの構築について.................................. COM サーバへの接続................................................................... COM コンポーネントとのやり取り ............................................. クライアントからのトランザクション制御................................. 601 602 603 604 第 28 章 EJB クライアントの構築 .................................. EJB クライアントの構築について............................................... アプリケーションへの pbejbclient115.pbx の追加 ...................... EJB プロキシ オブジェクトの生成.............................................. EJB プロキシ プロジェクトの使い方 ................................... ejb2pb115 ツールの使い方 ................................................... 生成されたプロキシの表示方法 ............................................ データ型マッピング .............................................................. Java VM の作成 ........................................................................... サーバへの接続 ............................................................................ コンポーネント メソッドの呼び出し........................................... 例外処理....................................................................................... クライアント管理のトランザクション ........................................ クライアントのデバッグ.............................................................. 607 607 609 610 610 614 615 617 618 621 622 627 629 630 第7部 WEB アプリケーションの開発 第 29 章 PowerBuilder での Web アプリケーション開発 ............. Web アプリケーションの作成 ..................................................... .NET Web フォーム アプリケーションとコンポーネント........... Web サービス .............................................................................. Web データウィンドウ ................................................................ データウィンドウ Web コントロール ActiveX ............................ 第 30 章 Web サービス クライアントの構築 ......................... 637 Web サービスについて ................................................................ 637 Web サービス クライアントの構築について........................ 638 Web サービス エンジンの選択 ............................................. 639 Web サービスにアクセスするためのファイアウォール設定の指定 641 エクステンション ファイルのオブジェクトのインポート .......... 642 Web サービス プロキシ オブジェクトの生成.............................. 644 SOAP サーバへの接続 ................................................................. 649 Web サービス メソッドの起動 .................................................... 651 例外処理....................................................................................... 651 UDDI 照会 API の使い方 .............................................................. 652 アプリケーション テクニック 633 633 634 634 635 636 xiii 目次 第8部 全般的なテクニック 第 31 章 アプリケーションの国際化 ................................. 国際化アプリケーションの開発................................................... Unicode の使い方......................................................................... Unicode について.................................................................. PowerBuilder での Unicode サポート ................................... ユーザ インタフェースの国際化.................................................. 第 32 章 利用しやすいアプリケーションの作成 ....................... 665 アクセシビリティの課題についての理解 .................................... 665 ソフトウェアおよび Web アプリケーションのアクセシビリティ要件 668 PowerBuilder を使用した利用しやすいソフトウェア アプリケーショ ンの作成 ......................................................................... 670 VPAT について ............................................................................ 674 製品のアクセシビリティのテスト ............................................... 674 第 33 章 印刷 ..................................................... 印刷関数....................................................................................... 印刷の基礎 ................................................................................... ジョブの印刷................................................................................ タブの使い方................................................................................ 印刷ジョブの停止 ........................................................................ 高度な印刷技法 ............................................................................ 677 677 679 679 680 681 682 第 34 章 初期設定ファイルと Windows レジストリの管理 ............. 環境設定とデフォルト設定について............................................ 初期設定ファイルでの情報の管理 ............................................... Windows レジストリでの情報の管理 .......................................... 685 685 686 687 第 35 章 InfoMaker の様式とアクションの作成 ....................... フォーム様式について ................................................................. フォーム様式でのデータウィンドウ コントロールの命名 .......... フォーム様式の作成および使用................................................... 既存の様式の修正 ........................................................................ 様式の基礎としてのウィンドウの識別 ................................. 最初からの様式の作成 ................................................................. 様式の完成 ................................................................................... セントラル データウィンドウ コントロールに対する作業 .. コントロールの追加 .............................................................. 689 689 693 694 694 696 697 698 698 699 xiv 657 657 658 658 659 664 PowerBuilder 目次 アクションの定義.................................................................. メニューの使い方.................................................................. スクリプトの記述.................................................................. その他の機能の追加 .............................................................. 様式の使い方................................................................................ カスタム フォーム様式を使用したフォームの作成 .............. フォーム様式の使用の管理 ................................................... 700 701 702 702 702 703 704 第9部 配布のテクニック 第 36 章 配布用アプリケーションのパッケージ化 .................... アプリケーションの配布について ............................................... アプリケーションの実行版の作成 ............................................... コンパイラの基本事項 .......................................................... パッケージに含まれる要素 ................................................... PowerBuilder リソース ファイルの作成................................ パッケージ化モデルの選択 ................................................... パッケージ化モデルの実装 ................................................... 実行アプリケーションのテスト ............................................ エンド ユーザへのアプリケーションの配布................................ インストール チェックリスト............................................... 配布済みアプリケーションの起動 ........................................ 第 37 章 アプリケーションとコンポーネントの配布 .................. 731 アプリケーション、コンポーネント、およびサポート ファイルの配布 732 PowerBuilder ランタイム パッケージャ ...................................... 737 サードパーティ製コンポーネントと配布 .................................... 742 Apache ファイル................................................................... 742 Microsoft ファイル ................................................................ 743 Sun Microsystems ファイル.................................................. 745 Web サービスの SOAP クライアントで使用するソフトウェア.. 745 Web フォーム アプリケーションの Telerik コントロール.... 746 PowerBuilder ランタイム ファイル ............................................. 746 データベース接続 ........................................................................ 749 ネイティブ データベース ドライバ ...................................... 750 ODBC データベース ドライバとサポート ファイル............. 751 OLE DB データベース プロバイダ........................................ 756 ADO.NET データベース インタフェース.............................. 757 JDBC データベース インタフェース .................................... 758 Java サポート .............................................................................. 759 アプリケーション テクニック 709 709 710 710 711 717 719 723 724 726 726 730 xv 目次 PowerBuilder エクステンション .................................................. PDF と XSL-FO のエクスポート ................................................. Ghostscript distiller の使い方................................................. Apache FO プロセッサの使い方........................................... データウィンドウ Web コントロール ActiveX ............................ EAServer 上の PowerBuilder コンポーネント ............................. EAServer 上の Web データウィンドウ ....................................... 761 762 762 765 765 766 769 索引 ............................................................................................................................................. 773 xvi PowerBuilder 本書について 対象とする読者 このマニュアルは、PowerBuilder® によるクライアント / サーバ ア プリケーション、分散アプリケーション、または Web アプリケー ション開発に従事している開発者を対象としています。 このマニュアルの使い方 このマニュアルでは、PowerBuilder アプリケーションとコンポー ネントを作成および配布する際に使用するプログラミング テク ニックを紹介します。ここでは、要件に最も適した方法を選択す るためのアドバイスとともに、様々な一般的なアプリケーション 機能を実装するための技術を紹介しています。 PowerBuilder には、このマニュアルで紹介する問題、機能、およ びテクニックを具体例で示すサンプル アプリケーションが付属し ています。PowerBuilder でサンプル アプリケーションのコンポー ネントを調べて、コードのコメントを読み、実践的な作業例を通 じて学習した内容を実際に試してください。 サンプル アプリケーションの使い方については、第 1 章「サンプ ル アプリケーションの使い方」を参照してください。 関連マニュアル PowerBuilder のすべてのマニュアル一覧については、PowerBuilder の『入門』マニュアルを参照してください。 そのほかの情報 製品に関するそのほかの詳細情報については、PowerBuilder DVD、 ND ソフトウェア Web サイト、および Sybase 製品マニュアル Web サイト(英語)を参照してください。 • PowerBuilder DVD には、製品マニュアルが収められています。 製品マニュアルは、PDF 形式で提供しています。PDF ファイ ルを読んだり、印刷したりするには、Adobe Acrobat Reader が 必要です。Adobe Acrobat Reader は、Adobe Web サイトから無 料でダウンロードすることができます。 • ND ソフトウェア Web サイトには、標準の Web ブラウザで アクセスすることができるオンライン版のマニュアルがあり ます。この Web サイトでは、PDF および HTML 形式でマニュ アルを見ることができます。 オ ン ラ イ ン 版 の マ ニ ュ ア ル に は、N D ソフトウェアの PowerBuilder のサイト http://www.powerbuilder.jp/ にある「技術情 報」からアクセスできます。 アプリケーション テクニック xvii Sybase 製品マニュアル Web サイト(英語)は、標準の Web ブラウ ザからアクセスでき、Sybase の製品マニュアルのほか、EBF/ メン テナンス、技術文書などへのリンクも含んでいます。 • Sybase 製品マニュアル Web サイトには、製品マニュアル のサイト http://www.sybase.com/support/manuals/ からアクセスできます。 表記規則 このマニュアルでは、以下の表記規則を使用します。 例 説明 Retrieve と Update 左記のフォントが説明文で使用されている場合、 以下を表す • コマンド名、関数名、メソッド名 • キーワード(true、false、null など) • データ型(integer、char など) • データベース カラム名(emp_id、f_name など) 変数(variable)または ファイル名(filename) • ユーザ定義オブジェクト(dw_emp、w_main など) 説明文と構文説明で使用された場合、斜体フォ ントは次のいずれかを表す • 変数(myCounter など) • 代入が必要な入力テキスト部分 (pblname.pbd など) [ファイル|上書き保存] dw_1.Update() • ファイル名とパス名 メニュー名とメニュー項目は単純なテキスト で表示される。 「|」は、選択の移動のしかた メニューを示す。たとえば、 [ファイル|上書 き保存]は、 「[ファイル]メニューから[上書 き保存]を選択する」と同義 左記のフォントは以下のいずれかを示す • ダイアログボックスまたはコマンド ライン に入力する情報 • サンプル スクリプトの一部 • サンプル出力の一部 サポートについて xviii 「サポート ハンドブック」を参照してください。 PowerBuilder 第 1 部 アプリケーション テクニック の学習 第 1 部では、PowerBuilder に添付しているサンプル アプ リケーションの概要と、これらのサンプルを使ってプロ グラミング テクニックを学習する方法について説明しま す。 第 1 章 サンプル アプリケーションの使い方 この章について この章では、PowerBuilder サンプル アプリケーションの使い方に ついて説明します。 内容 項目 サンプル アプリケーションについて サンプル アプリケーションのインストール サンプル アプリケーションを開く Code Examples アプリケーションの使い方 ページ 3 5 5 7 サンプル アプリケーションについて PowerBuilder には、サンプルで使用されているテクニックを学ん で活用できるように、ソース コード付きのサンプル アプリケー ションが用意されています。サンプルには、以下の 2 種類があり ます。 アプリケーション テクニック • Web サイトからダウンロードできるサンプル • DVD からインストールできるサンプル 3 サンプル アプリケーションについて Web サイトのサンプル PowerBuilder の最新のサンプル アプリケーションとユーティリティ は、Sybase CodeXchange Web サイト(PowerBuilder Samples and Utilities project のサイト http://powerbuilder.codeXchange.sybase.com/)で利用できま す。このページを開くには、Windows の[スタート|プログラム| Sybase | PowerBuilder 11.5 |コード サンプル| PB 11.5 コード サ ン プ ル]を 選 択 し ま す。MySybase に ロ グ イ ン し て い な い 場 合、 CodeXchange にアクセスするには[Sybase Account Login]ページで ログインする必要があります。MySybase のアカウントがない場合は、 このページ上のリンクを使ってサインアップできます。MySybase は、 Sybase Web サイトへのパーソナライズされたポータルを提供する無料 サービスです。 これらのサンプルは Sybase の社員とユーザが作成したものであり、頻 繁に更新されます。PowerBuilder の特定の機能を使うスタンドアロン アプリケーションがあり、PowerBuilder ネイティブ インタフェースを 使った Web サービスの使用、EJB クライアントの作成、ビジュアルお よび非ビジュアル エクステンションの記述などの機能も使われてい ます。ほとんどのサンプルには、そこで使われる機能とそのダウンロー ド方法および使い方について説明した readme 文書があります。 DVD 内のサンプル DVD 内には数種類のサンプルがあり、PowerBuilder のインストール時 にインストールできます。サンプルの一部では最新の PowerBuilder で 追加された機能を説明しています。各サンプルには Readme ファイル が含まれており、サンプルの概要とその使い方が記載されています。 DVD に付属しているサンプルは以下のとおりです。 Code Examples PowerBuilder Code Examples アプリケーションには、コーディング テク ニックの学習に活用できる多くのサンプルが含まれています。これら のサンプルは、PowerBuilder の新旧機能を駆使したさまざまなコー ティング テクニックの使い方を示す目的で特別に作成されています。 Web データウィンド ウ Web DataWindow® テクノロジを使用するアプリケーションを開発す るには、EAServer にプリインストールされている汎用サーバ コンポー ネントを使用できます。また、サンプルの Web データウィンドウ PBL をモデルとして、独自の HTML ジェネレータ コンポーネントを作成す ることもできます。 4 PowerBuilder 第1章 サンプル アプリケーションの使い方 Web データウィンドウの詳細については、『データウィンドウ プログ ラマーズ ガイド』マニュアルを参照してください。.NET アプリケー ションおよびコンポーネントの開発の詳細については、『アプリケー ションとコンポーネントの .NET への配布』マニュアルを参照してく ださい。 サンプル アプリケーションのインストール DVD からサンプルをインストールするには、コンポーネントのリスト から「Code Examples」を選択します。Code Examples アプリケーショ ンをインストールするには、 「Example アプリケーション」を選択しま す。Web データウィンドウ PBL をインストールするには、「Web デー タウィンドウ」を選択します。 すべてのサンプルは、Code Examples サブディレクトリにインストール されます。ほとんどの Code Examples アプリケーションでは、 EAS Demo DB というサンプルの SQL Anywhere® データベースを使用します。Code Examples サブディレクトリおよび EAS Demo DB データベースの格納 場所は、Windows XP と 2003 の場合は C:\Documents and Settings\All Users\Documents\Sybase\PowerBuilder 11.5 デ ィ レ ク ト リ、Windows Vista と 2008 の場合は C:\Users\Public\Documents\Sybase\PowerBuilder 11.5 ディレクトリです。 Code Examples ディレクトリまたは EASDEMO115.DB ファイルが見つ からない場合、サンプル アプリケーションとデータベースがインス トールされていないことがあります。 サンプル アプリケーションを開く サンプル アプリケーションを開くには、[スタート|プログラム| Sybase | PowerBuilder 11.5 |コード サンプル]を選択し、開きたい サンプル アプリケーションを選択します。 アプリケーション テクニック 5 サンプル アプリケーションを開く Web データウィンドウのサンプルにはワークスペースまたはターゲッ ト ファイルがなく、また[スタート]メニューからのリンクもありま せん。ただし、新規作成 ダイアログボックスの[ターゲット]タブか ら、既存のアプリケーション ウィザードを選択して、Web データウィ ンドウをワークスペースに追加できます。ウィザードに従い Code Examples\WebDW ディレクトリに移動し、ディレクトリを展開しま す。次にサンプル アプリケーションを格納する PBL を展開し、アプリ ケーションを選択します。 次節では、Code Examples アプリケーションの開き方と実行方法を段階 を追って説明します。 6 PowerBuilder 第1章 サンプル アプリケーションの使い方 Code Examples アプリケーションの使い方 Code Examples アプリケーションは開発環境から実行します。 v Code Example アプリケーションを実行するには 1 メニュー バーから[ファイル|新規作成]を選択し、[ワークス ペース]タブから[ワークスペース]を選択して、 [OK]をクリッ クします。 2 PowerBuilder 11.5\Code Examples\Example App フォルダに移動し、 ワークスペースの名前を入力して、[保存]をクリックします。 3 作成したワークスペースのポップアップ メニューから[ターゲッ トの追加]を選択し、PowerBuilder 11.5\Code Examples\Example App フォルダに移動し、ターゲット ファイル「PB Examples」を選択し て[開く]をクリックします。 ターゲットを展開すると、PBL にアプリケーションが含まれ、ア プリケーションがサポートする PBL がワークスペースに追加され ていることがわかります。 4 パワーバーの[実行]ボタンをクリックします。 サンプルの参照 Code Examples アプリケーションを開くと、左側のペインに、使用可能 なサンプル項目のツリー ビューが表示されます。このツリー ビュー は、さらに展開することもできます。中には、複数の項目に表示され るサンプルもあります。たとえばビジネス クラス サンプルは、継承と ユーザ オブジェクトの両方の項目にリスト表示されます。データスト アやデータウィンドウなど、特定の機能の使い方を知りたい場合は、 その項目を展開してサンプル名を調べてください。 アプリケーション テクニック 7 Code Examples アプリケーションの使い方 左側のペインでサンプルを選択すると、そのサンプルの説明と使い方 が右側に表示されます。 サンプルの検索 PowerBuilder の特定のオブジェクト クラスまたは機能の使い方を知り たい場合は、 [サンプル プログラム]ペインの項目とその説明によっ てサンプルを検索できます。特定のイベント、関数、またはユーザ定 義オブジェクトを使用するサンプルを検索するには、 [検索]ペインを 使用します。 v 関数、イベント、またはオブジェクトを検索するには 1 コード サンプルのメイン ウィンドウにある[検索]タブをクリッ クします。 2 [検索対象]グループボックスのラジオボタンを選択します。 3 8 ドロップダウン リストで目的の項目を選択し、 [検索開始]ボタン をクリックします。 PowerBuilder 第1章 サンプル アプリケーションの使い方 検索対象の関数、イベント、またはオブジェクトを使用している サンプルの名前がすべて表示されます。 サンプルの実行と調査 学習したい処理を実行するサンプルが見つかったら、そのサンプルを 実行して動作内容を調べ、コードを参照(必要であればコピーも)で きます。 サンプルの実行 ハイライト表示されたサンプルを実行するには、サンプルをダブルク リックするかまたは[実行]をクリックします。サンプルのメイン ウィ ンドウにある[ヘルプ|現在のサンプルのヘルプ]ボタンをクリック すると、そのサンプルの使い方と動作内容に関するヘルプが表示され ます。 アプリケーション テクニック 9 Code Examples アプリケーションの使い方 コードの調査 サンプルに使用されているすべてのオブジェクトを参照するには、右 側のペインにある[関連オブジェクト]タブをクリックし、プラス記 号をクリックしてさらに詳しい項目を表示します。 スクリプトまたは関数のアイコンをダブルクリックして、コードを参 照します。 開発環境でのサンプル の利用 Code Examples アプリケーションを実行したり、サンプルのコードを参 照したりすることによって、多くの情報を得ることができますが、開 発環境でサンプル内のオブジェクトを開けば、さらに詳しい情報を得 ることができます。 たとえば、ペインタでオブジェクトを開く、ブラウザで継承階層を調 べる、デバッガでサンプルをワンステップずつ実行することなどがで きます。さらに、ライブラリ ペインタ内の自分のアプリケーションに オブジェクトをコピーしたり、スクリプト ビューにコード フラグメン トをコピーしたりすることもできます。 Code Examples アプリケーションのライブラリは、オブジェクト型を基準 にして編成されています。たとえば、pbexamd1.pbl および pbexamd2.pbl はデータウィンドウ オブジェクトを含みます。これによって、このマ ニュアルの後半でサンプルとして紹介されているオブジェクトを容易 に見つけることができます。ライブラリ ペインタのリストビューのサ ンプル ライブラリを展開すると、各オブジェクトの用途が表示されま す。 10 PowerBuilder 第 2 部 言語テクニック 第 2 部では、PowerBuilder によるアプリケーション開発 でのオブジェクト指向プログラミングのテクニックと、 PowerScript® 言語の使用方法について説明します。 ClassDefinition オブジェクトについても説明します。 第 2 章 オブジェクト指向プログラミング この章について この章では、PowerBuilder におけるオブジェクト指向プログラミ ングのテクニックについて説明します。 内容 項目 用語の確認 PowerBuilder のテクニック その他のテクニック ページ 13 15 20 用語の確認 クラス、プロパティ、メ ソッド オブジェクト指向プログラミングでは、アプリケーション処理を 実行するための再利用可能なクラスを作成します。クラスには、ク ラスの動作を定義するプロパティとメソッドがあります。アプリ ケーション処理を実行するためには、クラスのインスタンスを作 成します。PowerBuilder では、以下のようなコンセプトを実装し ています。 • クラス PowerBuilder オブジェクト(ウィンドウ オブジェク ト、メニュー オブジェクト、ウィンドウ コントロール オブ ジェクト、ユーザ オブジェクトなど) • プロパティ • メソッド オブジェクト変数とインスタンス変数 イベントと関数 この章の後半で、これらの PowerBuilder の用語を使用します。 基本原則 オブジェクト指向のプログラミング ツールは、オブジェクト指向 の 3 つの基本原則である、継承、カプセル化、多相性(ポリモフィ ズム)をサポートします。 継承とは、オブジェクトを既存のオブジェクトから派生さ せ、既存オブジェクトのビジュアル コンポーネント、データ、コー ドにアクセスすることです。継承を使用すると、コーディング時 間を短縮し、コードの再利用性や一貫性を向上することができま す。子孫オブジェクトは、サブクラスとも呼ばれます。 継承 アプリケーション テクニック 13 用語の確認 カプセル化は、オブジェクトにデータとコードを格納し て、外部からのアクセスを必要であれば制限します。カプセル化は、 情報の隠ぺいとも呼ばれます。PowerBuilder は、アクセス レベルやス コープなどで、カプセル化を可能にしています。ただし、PowerBuilder 自身はカプセル化を要求したり、自動的に強化したりはしません。 カプセル化 多相性(ポリモフィズム) 同じ名前の関数は、その関数が定義されてい るオブジェクトによって、異なる動きをします。多相性は、アプリケー ション全体にわたって、またすべてのオブジェクト内において、一貫 性のあるインタフェースの提供を可能にします。 ビジュアル オブジェ クト 現在の多くのアプリケーションは、ウィンドウ、メニュー、ビジュア ル ユーザ オブジェクトなどのビジュアル オブジェクトのオブジェク ト指向の機能を頻繁に使用しています。これにより、アプリケーショ ンは一貫性があり、統一感のあるルック アンド フィールとなります。 非ビジュアル オブ ジェクト PowerBuilder のオブジェクト指向を十分に活用するためには、アプリ ケーションにクラス ユーザ オブジェクト(非ビジュアル ユーザ オブ ジェクト)を実装します。 PowerBuilder の組み込みシステム オブ ジェクト(Transaction オブジェクト、Message オブジェクト、Error オ ブジェクトなど)から、その定義を継承します。Code Examples のサン プル アプリケーションでの nvo_transaction のトランザクション オブ ジェクトは、サブクラス化された標準クラス ユーザ オブジェクトの例 です。カスタマイズされた標準クラス ユーザ オブジェクトを作成すれ ば、PowerBuilder の組み込みシステム オブジェクトを拡張できます。 標準クラス ユーザ オブジェクト カスタム クラス ユーザ オブジェクト PowerBuilder の NonVisualObject ク ラスから定義を継承したオブジェクトです。カスタム クラス ユーザ オ ブジェクトは、データとコードがカプセル化されています。このタイ プのクラス ユーザ オブジェクトは、何も定義されていない状態からオ ブジェクト クラスを定義することができます。Code Examples のサン プル アプリケーションでのユーザ オブジェクト u_business_object は、 カスタム クラス ユーザ オブジェクトの一例です。PowerBuilder のオブ ジェクト指向を最大限に活用するためには、カスタム クラス ユーザ オ ブジェクトを使用しなければなりません。典型的な用途としては、以 下のようなものがあります。 • 14 グローバル変数コンテナ カスタム クラス ユーザ オブジェクトに は、アプリケーションのすべてのオブジェクトで使用できる変数 と関数があります。アプリケーションで適切な場合に、直接また はオブジェクト関数によってアクセスできるように、これらの変 数をカプセル化します。 PowerBuilder 第2章 オブジェクト指向プログラミング カスタム クラス ユーザ オブジェクトには、 特定のコンテキスト(データウィンドウ オブジェクトなど)やグ ローバルなコンテキスト(文字列操作を行う関数のコレクション など)に役立つ関数や変数があります。 • サービス オブジェクト • ビジネス ルール カスタム クラス ユーザ オブジェクトには、ビジ ネス ルールを実装する関数や変数があります。すべてのビジネス ルールに対応した 1 つのオブジェクトを作成することができま す。または、ビジネス ルールの関連するグループに対応した複数 のオブジェクトを作成することもできます。 • 分散コンピューティング カスタム クラス ユーザ オブジェクトに は、サーバ上またはサーバのクラスタ上で実行する関数がありま す。 詳細については、第 6 部「分散処理アプリケーション テクニック」 を参照してください。 PowerBuilder のテクニック PowerBuilder は、ビジュアル オブジェクトとクラス オブジェクトの継 承、カプセル化、多相性を全面的にサポートしています。 再利用可能なオブジェクトの作成 ほとんどの場合、再利用可能なオブジェクトを開発する人と、アプリ ケーションで再利用可能なオブジェクトを使用する人は、同じ人では ありません。ここでは、再利用可能なオブジェクトの定義と作成の仕 方について説明します。使用法については説明しません。 継承の実装 PowerBuilder では、子孫オブジェクトを容易に作成することができま す。指定する先祖オブジェクトから継承するために、ウィンドウ ペイ ンタ、ユーザ オブジェクト ペインタ、メニュー ペインタを使用して、 PowerBuilder は継承を実装します。 ビジュアル オブジェクトの継承の例については、Code Examples サンプ ル アプリケーションでの w_employee ウィンドウと u_employee_object を参照してください。 アプリケーション テクニック 15 PowerBuilder のテクニック カスタム クラス ユーザ オブジェクト の継承を使用する 1 つの例としては、基本サービスを実行する先祖 サービス オブジェクトと、いくつかの子孫サービス オブジェクトを作 成するケースが挙げられます。子孫オブジェクトは、先祖のサービス にアクセスを持つとともに、子孫特有のサービスも実行します。 先祖サービス オブジェクトの例 図 2-1: 先祖サービス オブジェクト 先祖オブジェクトの仮想関数の例 カスタム クラス ユーザ オブジェクト の継承を使用する別の例としては、すべてのプラットフォーム用の関 数を持つクラスを先祖オブジェクトとして作成し、プラットフォーム 特定の関数を実行するクラスを子孫オブジェクトとして作成すること です。この場合、先祖オブジェクトをデータ型として子孫オブジェク トのインスタンスを作成できるように、先祖オブジェクトは仮想関数 (例では uf_change_dir)を持ちます。 図 2-2: 先祖オブジェクトの仮想関数 仮想関数の詳細については、20 ページの「その他のテクニック」を参 照してください。 カプセル化の実装 16 カプセル化は、プライベート(Private)またはプロテクト(Protected) としてインスタンス変数を宣言することによって、外部からのアクセ スを制限し、オブジェクトのデータを外部から隔離することができま す。次に、インスタンス変数への選択的なアクセスを提供するため、 オブジェクト関数を記述します。 PowerBuilder 第2章 オブジェクト指向プログラミング 処理とデータをカプセル化する 1 つのアプローチ は、以下のとおりです。 1 つのアプローチ • 外部へのアクセス程度により、パブリック(Public)、プライベー ト(Private)、またはプロテクト(Protected)としてインスタンス 変数を定義します。完全にカプセル化するには、プライベート (Private)またはプロテクト(Protected)としてインスタンス変数 を定義します。 • 処理の実行や、オブジェクトのデータへのアクセスを提供するに は、オブジェクト関数を定義します。 表 2-1: オブジェクト関数の定義 処理内容 処理の実行 インスタンス変数の 変更 インスタンス変数の 読み込み (オプション) Boolean 型のインスタ ンス変数の読み込み 関数 uf_do_operation uf_set_variablename uf_get_variablename uf_is_variablename 例 データベースから行を検索 する uf_do_retrieve 関数 String 型の変数 is_style の値 を変更する uf_set_style 関数 String 型の変数 is_style の値 を返す uf_get_style 関数 Boolean 型の変数 ib_protected の値を返す uf_is_protected 関数 処理とデータをカプセル化するための別のアプロー チは、実行するアクションを開発者が指定するための、単一のエント リ ポイントを用意することです。 別のアプローチ • 外部へのアクセス程度により、プライベート(Private)またはプロ テクト(Protected)としてインスタンス変数を定義します。 • 処理を実行するための、プライベート(Private)またはプロテクト (Protected)のオブジェクト関数を定義します。 • 実行する処理の種類を示す引数を持つ、1 つのパブリック関数を定 義します。 アプリケーション テクニック 17 PowerBuilder のテクニック 図 2-3: カプセル化のためのパブリック関数の定義 例については、Code Examples サンプル アプリケーションのユーザ オ ブジェクト u_sales_order を参照してください。 分散コンポーネント アプリケーション サーバ コンポーネントを生成すると、生成されたコ ンポーネントのインタフェースでパブリック関数を使用できるように なり、パブリック インスタンス変数を使用可能にするよう選択できま す。プライベートとプロテクトの関数と変数は、生成されたコンポー ネントのインタフェースで公開されません。 詳細については、第 6 部「分散処理アプリケーション テクニック」を 参照してください。 多相性の実装 多相性はプログラミング言語の機能です。この機能を使用すると、デー タ型やクラスに応じてオブジェクトを処理できます。多相性とは、同 じ名前の関数が、参照されているオブジェクトにより、異なる動作を することを意味します。多相性の正確な定義にはいろいろな議論があ りますが、以下のように考えるとわかりやすいでしょう。 独立したオブジェクト間の多相性(Operational polymorphism) 関連のな い別々のオブジェクトに、同じ名前の関数が定義されることがありま す。それぞれの関数は、そのオブジェクトの種類により適切な処理を 実行します。 18 PowerBuilder 第2章 オブジェクト指向プログラミング 図 2-4: 独立したオブジェクト間の多相性(Operational polymorphism) 例については、Code Example サンプル アプリケーションのユーザ オ ブジェクト u_external_functions とその子孫を参照してください。 継承したオブジェクト間の多相性(Inclusional polymorphism) 継承チェー ン内の個々のオブジェクトは、同じ名前の関数を定義できます。 継承したオブジェクト間の多相性によって、現行のオブジェクトが継 承階層のどこに適合するかに基づいて、どの継承チェーン内の関数を 実行するかが決定されます。子孫オブジェクトの関数は、先祖オブジェ クトの関数を上書きして実行します。 図 2-5: 継承したオブジェクト間の多相性(Inclusional polymorphism) 例については、Code Examples サンプル アプリケーションのユーザ オ ブジェクト u_employee_object を参照してください。 アプリケーション テクニック 19 その他のテクニック その他のテクニック PowerBuilder では、さまざまなオブジェクト指向のテクニックを実装 できます。この節では、PowerBuilder に関連するいくつかのテクニッ クについて説明します。 関数の多重定義の使い 方 関数の多重定義では、子孫関数(または同一オブジェクト内の同じ名 前の関数)に、引数の数や引数のデータ型が異なるものがあります。 PowerBuilder は、関数の呼び出しで指定された引数の数と引数のデー タ型を基に、どの子孫関数を実行するかを決定します。 図 2-6: 関数の多重定義 グローバル関数 グローバル関数は多重定義できません。 関数の動的呼び出しと 静的呼び出し 20 関数の動的呼び出し アプリケーションから、クロス プラットフォーム に依存する部分を取り除いた場合、特定のプラットフォームごとに、 別々の子孫オブジェクトを作成します。アプリケーションは、動的に プラットフォームに依存する子孫関数を呼び出します。 PowerBuilder 第2章 オブジェクト指向プログラミング 図 2-7: 関数の動的呼び出し 以下の例で示すように、実行時に適切なオブジェクトのインスタンス を作成します。 // 以下のスクリプトは、動的と静的な両方の // 関数の呼び出しに使用できます。 // 変数は、インスタンス変数とします。 u_platform iuo_platform Environment ienv_env ... GetEnvironment(ienv_env) choose case ienv_env.ostype case windows! iuo_platform = CREATE u_platform_win case windowsnt! iuo_platform = CREATE u_platform_win case else iuo_platform = CREATE u_platform_unix end choose 関数の動的呼び出しは柔軟性がありますが、パフォーマンスを悪くし ます。 パフォーマンスを良くするためには、関数の静的 呼び出しを用いることをお勧めします。ただし、CREATE 文で指定し たオブジェクト データ型と異なるデータ型の参照変数を使用して、オ ブジェクトにアクセスすることもできます。 関数の静的呼び出し アプリケーション テクニック 21 その他のテクニック 図 2-8: 関数の静的呼び出し 関数の静的呼び出しを使用するときは、先祖関数のデフォルトの処理 内容を定義しなければなりません。先祖関数は、エラー値(たとえば、 -1)を返して、少なくとも 1 つの子孫関数に上書きされます。 図 2-9: 子孫関数で上書きされる先祖関数 先祖オブジェクトの関数にデフォルトの処理を定義すれば、関数の静 的呼び出しのパフォーマンスが得られるとともに、プラットフォーム に依存しないで済むようになります。 処理の代行 (delegation)の使い 方 処理の代行は、オブジェクトがほかのオブジェクトのために処理を代 行するときに、発生します。 従属関係(aggregate relationship) 従属関係(一体関係と呼ばれること もある)では、 (オーナー オブジェクトと呼ばれる)オブジェクトは、 そのオブジェクトの種類のためにデザインされたサービス オブジェ クトに関連付けられます。 22 PowerBuilder 第2章 オブジェクト指向プログラミング たとえば、データウィンドウ オブジェクトで行の選択を行うサービス オブジェクトを作成できます。この場合、データウィンドウ オブジェ クトの Clicked イベントに、行選択オブジェクトを呼び出すスクリプト を記述します。 v オブジェクトを従属関係で使用するには 1 サービス オブジェクトを作成します(この例では u_sort_dw)。 2 オーナー(この例ではデータウィンドウ コントロール)にインス タンス変数(参照変数とも呼ばれる)を宣言します。 u_sort_dw iuo_sort 3 サービス オブジェクトのインスタンスを作成するため、オーナー オブジェクトにスクリプトを記述します。 iuo_sort = CREATE u_sort_dw 4 サービス オブジェクトのイベントや関数を呼び出すために、オー ナーのシステム イベントまたはユーザ イベントにスクリプトを 記述します。次の例は、データウィンドウ コントロールのユーザ イベント ue_sort に記述するスクリプトを示します。 IF IsValid(iuo_sort) THEN Return iuo_sort.uf_sort() ELSE Return -1 END IF 5 オーナー オブジェクトのユーザ イベントを呼び出すスクリプト を記述します。たとえば、データウィンドウ コントロールのユー ザ イベント ue_sort を呼び出す、コマンドボタンまたは[編集| ソート]などのメニュー項目を作成できます。 6 サービス オブジェクトのインスタンスを破棄するためのスクリプ トをオーナー オブジェクトの Destructor イベントに記述します。 IF IsValid(iuo_sort) THEN DESTROY iuo_sort END IF 独立関係(associative relationship) 独立関係では、オブジェクトは、 特定の種類の処理を実行するためのサービス オブジェクトを関連付 けます。 たとえば、どのアプリケーションのオブジェクトからでも使用できる ような、文字列操作を行うサービス オブジェクトを作成できます。 独立関係のオブジェクトを実装する操作手順は、従属関係と同じです。 アプリケーション テクニック 23 その他のテクニック ユーザ オブジェクトの AutoInstantiate プロパティを有効にした場合、 ユーザ オブジェクトのインスタンスのほかに、ユーザ オブジェクトが 宣言されているオブジェクト、イベント、または関数のインスタンス が生成されます。また、ユーザ オブジェクトのインスタンス変数を宣 言することもできます。これらの 2 つの機能を利用して、構造体とし て機能するユーザ オブジェクトを作成できます。このようなユーザ オ ブジェクトを構造体として使用する利点としては、以下のものがあり ます。 ユーザ オブジェクト の構造体としての使い 方 v • 子孫オブジェクトを作成して拡張できる • 一度にすべての構造体にアクセスする関数を作成できる • 特定のインスタンス変数へのアクセスを制限するためにアクセス 指定子を使用できる 構造体として使用されるカスタムクラス ユーザ オブジェクトを作成するには 1 インスタンス変数だけを定義したユーザ オブジェクトを作成しま す。 2 [全般]プロパティ ページの[インスタンスの自動生成]をオンに して、ユーザ オブジェクトの AutoInstantiate プロパティを有効に します。 3 オブジェクト、関数、またはイベントで、ユーザ オブジェクトを 宣言します。 PowerBuilder は、オブジェクト、イベント、または関数が作成され たときに、ユーザ オブジェクトを生成します。また、オブジェク トが破棄されるか、イベントや関数が終了すると、ユーザ オブジェ クトを破棄します。 データストア オブ ジェクトのサブクラス 化 多くのアプリケーションでは、標準のデータウィンドウ ウィンドウ コ ントロールではなく、データウィンドウのビジュアル ユーザ オブジェ クトを使用します。これを使用すると、エラー チェックやアプリケー ション固有のデータウィンドウの動作を標準化できます。チュートリ アル ライブラリ TUTOR_PB.PBL にある データウィンドウ 型のビジュ アル ユーザ オブジェクト u_dwstandard は、そのようなオブジェクトの 一例です。 データストア は、非表示のデータウィンドウ コントロールとして機能 します。同じアプリケーションや一貫性を必要とする多くのものは、 データウィンドウ コントロールと同様に データストア にも適用され ます。データストア に対するエラー チェックやアプリケーション特有 の動作形態を実装するときは、データストア の標準クラス ユーザ オ ブジェクトを作成することを考慮します。 24 PowerBuilder 第 3 章 PowerScript についての特別な トピック この章について この章では、PowerScript 言語要素のアプリケーションでの使い方 について説明します。 内容 項目 ドット表記 定数の宣言 インスタンス変数のアクセスの制御 名前の重複の解決 先祖スクリプトからの戻り値 関数とイベントの引数の型 先祖変数と子孫変数 データウィンドウと外部オブジェクトにおける式の最適化 PowerBuilder での例外処理 ガベージ コレクションとメモリ管理 効率的なコンパイルとパフォーマンス テキスト ファイルとバイナリ ファイルの読み書き ページ 25 30 30 31 33 35 36 38 39 49 53 53 ドット表記 ドット表記(.)を使用すると、参照先の項目(インスタンス変数、 プロパティ、イベント、関数)を、その項目を所有するオブジェ クトで修飾できます。 ドット表記はオブジェクトに使用します。グローバル変数や関数 はオブジェクトとは独立して存在するため、ドット表記を使用し ません。共有変数にもドット表記を使用することはありません。共 有変数は、オブジェクト インスタンスではなくオブジェクト クラ スに属するからです。 アプリケーション テクニック 25 ドット表記 参照の修飾 ドット表記では、使用する項目をオブジェクト変数名で修飾します。 objectvariable.item オブジェクト変数名は、プロパティまたはそのほかの項目の所有者を 識別する修飾子です。 親修飾子を追加する オブジェクトを完全に識別するには、ドット修飾 子を追加して、オブジェクトの親、そのまた親という具合に指定して いきます。 parent.objectvariable.item 親 オブジェクトは子オブジェクトを包含します。これは祖先と子孫の 関係ではありません。たとえば、ウィンドウはコントロールの親です。 タブ コントロールは、その中にあるタブ ページの親です。メニュー オ ブジェクトは、そのメニューの項目となっているメニュー オブジェク トの親です。 親修飾子はアプリケーション レベルまで指定できま す。ただし、通常はウィンドウ レベルまで指定すれば十分です。 複数の親レベル たとえば、あるタブ ページにあるデータウィンドウ コントロールの Retrieve 関数を呼び出すには、次のように関数名を修飾します。 w_choice.tab_alpha.tabpage_a.dw_names.Retrieve() メニュー オブジェクトには複数の修飾子が必要になることがよくあ り ま す。た と え ば、w_main ウ ィ ン ド ウ に メ ニ ュ ー オ ブ ジ ェ ク ト m_mymenu が含まれており、その中の[ファイル]メニューに[開く] という項目があるとします。この[開く]項目の Selected イベントを 起動するには、次のように指定します。 w_main.m_mymenu.m_file.m_open.EVENT Selected() このように、名前の修飾は、特にタブ コントロールに含まれるメ ニューやタブ ページでは、複雑になります。 修飾子の数 オブジェクト、関数、イベント、またはプロパティを識別 するのに必要なだけの修飾子を指定する必要があります。 親オブジェクトは、自分に含まれているオブジェクトを認識していま す。ウィンドウのスクリプト内では、そのウィンドウに含まれるコン トロールの名前を修飾する必要はありません。また、各コントロール のスクリプトでは、そのウィンドウ内のほかのコントロールを修飾子 なしで参照できます。 26 PowerBuilder 第3章 PowerScript についての特別なトピック たとえば、w_main ウィンドウに、データウィンドウ コントロール dw_data とコマンドボタン コントロール cb_close が含まれている場合、 このコマンドボタン コントロールのスクリプトは、データウィンドウ コントロールを次のように修飾子なしで参照できます。 dw_data.AcceptText() dw_data.Update() このデータウィンドウ コントロールを別のウィンドウまたはユーザ オブジェクト 内のスクリプトで参照する場合は、次のようにウィンド ウ名で修飾する必要があります。 w_main.dw_data.AcceptText() オブジェクトの参照 オブジェクト自身のスクリプト内でそのオブジェクトの要素を修飾す るには、次の 3 つの方法があります。 • 修飾しない li_index = SelectItem(5) 未修飾の名前は明確でないため、同名のローカルまたはグローバ ルの変数や関数が存在すると名前を一意に特定できないことがあ ります。 • オブジェクト名で修飾する li_index = lb_choices.SelectItem(5) オブジェクト自身のスクリプト内でそのオブジェクトの名前を指 定するのは不必要な指定です。 • オブジェクトへの汎用の参照で修飾する li_index = This.SelectItem(5) 代名詞 This は、その項目を所有するオブジェクトに属することを 示します。 オブジェクトのスクリプトでは、This を所有オブジェクト への汎用の参照として使用できます。 This 代名詞 This.property This.function プロパティや関数はスクリプト内で何の修飾子も付けずに使用できま すが、そうすると読む人によっては、そのプロパティまたは関数が特 定のオブジェクトに属していることに気づかないことがあります。This を使用したスクリプトは、オブジェクトの名前を変更してもそのまま 使えます。したがって、スクリプトを少ない編集作業で再利用できま す。 アプリケーション テクニック 27 ドット表記 This を単独で使用すると、現在のオブジェクトへの参照になります。た とえば、別のユーザ オブジェクト内の関数にデータウィンドウ コント ロールを渡したい場合は、次のように指定します。 uo_data.uf_retrieve(This) データウィンドウ コントロールのスクリプト内でデータウィンドウ 型のインスタンス変数を設定して、一番最近使用されたデータウィン ドウ コントロールがほかの関数に分かるようにするには、次のように 指定します。 idw_currentdw = This Parent 代名詞 Parent 代名詞は、オブジェクトの親を参照します。Parent を使用したスクリプトは、親オブジェクトの名前を変更してもそのま ま使えます。また、ほかのコンテキストでも再利用できます。 たとえば、データウィンドウ コントロールのスクリプトで、そのウィ ンドウの Resize 関数を呼び出すとします。この場合、データウィンド ウ コントロール自体にも Resize 関数が定義されているため、次のよう に修飾する必要があります。 // ウィンドウ関数を呼び出す 2 つの方法 w_main.Resize(400, 400) Parent.Resize(400, 400) // コントロールの関数を呼び出す 3 つの方法 Resize(400, 400) dw_data.Resize(400, 400) This.Resize(400, 400) GetParent 関数 Parent 代名詞が使えるのはドット表記内だけです。親 オブジェクトへの参照を取得したい場合は、GetParent 関数を使用しま す。これは、スクリプトの所有オブジェクト以外のオブジェクトの親 を参照したり、次のように親オブジェクトへの参照を変数に保存した りする場合に使用します。 window w_save w_save = dw_data.GetParent() たとえば、別のコマンドボタン コントロールの Clicked イベント スク リプトで、そのコマンドボタン コントロールの親ウィンドウへの参照 を、あるユーザ オブジェクトに定義されている関数に渡したいとしま す。この場合は、次のように、関数呼び出しの中で GetParent を使用し ます。 uo_winmgmt.uf_resize(This.GetParent(), 400, 600) ParentWindow プロパティと ParentWindow 関数 オ ブ ジ ェ ク ト の 親 を 取得する関数やプロパティはほかにもあります。 28 PowerBuilder 第3章 PowerScript についての特別なトピック • ParentWindow プロパティ – メニュー スクリプト内で、 そのメニュー の親ウィンドウを参照するために使用します。 • ParentWindow 関数 – 任意のスクリプト内で、特定のウィンドウの 親ウィンドウへの参照を取得するために使用します。 これらの代名詞および関数の詳細については、『PowerScript リファレ ンス』マニュアルを参照してください。 コンテナ オブジェク ト内のオブジェクト ドット表記を使用すると、オブジェクトの中のオブジェクトを参照す ることもできます。こうしたコンテナ内のオブジェクトを参照するに は、ドット表記内で Object プロパティを使用します。コンテナ内オブ ジェクトの構造によってアクセス可能なレベル数が決まります。 control.Object.objectname.property control.Object.objectname.Object.qualifier.qualifier.property Object プロパティによってアクセス可能なオブジェクトは次のとおり です。 • データウィンドウ コントロール内のデータウィンドウ オブジェ クト • OLE コントロール内の外部 OLE オブジェクト 次の式は、データウィンドウ コントロール内のデータウィンドウ オブ ジェクトのプロパティを参照しています。 dw_data.Object.emp_lname.Border dw_data.Object.nestedrpt[1].Object.salary.Border コンパイラによるチェックは行わない コンテナ内オブジェクトを含む ドット表記が正しいかどうかは、コンパイラには判断できません。た とえば、データウィンドウ オブジェクトは特定のコントロールにバイ ンドされておらず、いつでも変更できます。このため、Object プロパ ティの後の名前とプロパティが有効かどうかは、実行時に初めて チェックされます。参照名が間違っていると実行時エラーになります。 詳細情報 実行時エラー チェックの詳細については、38 ページの「デー タウィンドウと外部オブジェクトにおける式の最適化」を参照してく ださい。 データウィンドウ オブジェクトのプロパティとデータのドット表記 およびエラー処理についての詳細は、 『データウィンドウ リファレン ス』マニュアルを参照してください。 OLE オブジェクトおよび OLE オートメーションのドット表記の詳細 については、第 19 章「アプリケーションにおける OLE の使い方」を 参照してください。 アプリケーション テクニック 29 定数の宣言 定数の宣言 定数を宣言するには、標準の変数宣言に CONSTANT キーワードを追加 します。 CONSTANT { access } datatype constname = value 定数として宣言できるのは、宣言内に代入文を使用できるデータ型だ けです。このため、Blob 型は定数として宣言できません。 PowerScript の識別子は大文字と小文字を区別しませんが、ここでは命 名規約に従って定数名に大文字を使用します。 CONSTANT integer GI_CENTURY_YEARS = 100 CONSTANT string IS_ASCENDING = "a" 定数の利点 宣言文以外の箇所で定数に値を代入する文を書くと、コンパイル エ ラーになります。定数を宣言すると、宣言文で指定したとおりに定数 が使われるようになります。 また、定数を宣言することで効率も向上します。定数値はコンパイル 時に確定するため、マシン コードでは、その定数値を保持している変 数を参照するのではなく、定数値が直接使用されます。 インスタンス変数のアクセスの制御 インスタンス変数には、アクセス制御のための設定を行えます。この 設定により、ほかのオブジェクトのスクリプトがその変数にアクセス する方法を制御できます。 インスタンス変数のアクセス制御には次の 3 種類があります。 ほかのすべてのオブジェクトからアクセス可能です。 • パブリック • プロテクト そのオブジェクトおよびその子孫オブジェクトのス クリプト内でのみアクセス可能です。 • プライベート そのオブジェクトのスクリプト内だけでアクセス可 能です。 例 public integer ii_currentvalue CONSTANT public integer WARPFACTOR = 1.2 protected string is_starship // 内部計算に使用するプライベート値 30 PowerBuilder 第3章 PowerScript についての特別なトピック private integer ii_maxrpm private integer ii_minrpm パブリック変数とプロテクト変数へのアクセスは、修飾子 PRIVATEREAD、 PRIVATEWRITE、PROTECTEDREAD、または PROTECTEDWRITE を使っ てさらに制限できます。 public privatewrite ii_averagerpm カプセル化のためのプ ライベート変数 アクセス制御は、ほかのスクリプトによる変数の変更を禁止するとき によく使用します。PRIVATE または PUBLIC PRIVATEWRITE アクセスを 設定すると、ほかのスクリプトがその変数を直接変更できなくなりま す。これらの変数には、検証を行ってから変数の変更を許可するパブ リック関数を用意します。 プライベート変数を使用すると、オブジェクトの機能をカプセル化で きます。カプセル化とは、オブジェクトのデータとコードをそのオブ ジェクトの内部に隠ぺいし、外部に提供するインタフェースをオブ ジェクトが決定する手法のことです。 たとえば、カスタム クラス ユーザ オブジェクトから EAServer、COM+、 またはアプリケーション サーバなどのコンポーネントを生成する場 合、そのコンポーネントのインタフェースによってインスタンス変数 を公開することはできますが、プライベート型またはプロテクト型の インスタンス変数が公開されることは決してありません。 詳細情報 アクセス制御についての詳細は、『PowerScript リファレンス』マニュ アルの「宣言」の章を参照してください。 カプセル化についての詳細は、第 2 章「オブジェクト指向プログラミ ング」を参照してください。 名前の重複の解決 名前の重複が発生するケースとして次の 2 つがあります。 • 異なるスコープ内に定義された変数が同じ名前を持つ場合。たと えば、グローバル変数は、ローカル変数またはインスタンス変数 と同じ名前を持つことがあります。コンパイラはこうした重複す る名前があると警告を出しますが、変数名を変更する必要はあり ません。 • 子孫オブジェクトが先祖オブジェクトから関数やイベントを同じ 名前で継承している場合 アプリケーション テクニック 31 名前の重複の解決 隠された変数または先祖のイベントや関数を参照する必要がある場合 は、ドット表記修飾子またはスコープ演算子を使用します。 隠されたインスタンス 変数 インスタンス変数が、ローカル変数、共有変数、またはグローバル変 数と同じ名前を持つ場合は、そのインスタンス変数をオブジェクト名 で修飾します。 objectname.instancevariable あるウィンドウに birthdate という名前のローカル変数とインスタンス 変数が存在する場合は、インスタンス変数を次のように修飾します。 w_main.birthdate ウィンドウ スクリプトにローカル変数 x が定義されていると、同じ ウィンドウの X プロパティと名前が重複します。その場合は、X プロ パティに修飾子を付けます。次の文では、両者を比較しています。 IF x > w_main.X THEN 隠されたグローバル変 数 グローバル変数がローカル変数または共有変数と同じ名前を持つ場合 は、そのグローバル変数の前にスコープ演算子(::)を付けます。 ::globalvariable 次の式は、total という同じ名前を持つローカル変数とグローバル変数 を比較しています。 IF total < ::total THEN ... 接頭辞を使用して名前の重複を避ける 接頭辞を付けて変数のスコープを識別するという命名規約に従ってい る場合は、スコープの異なる変数は必ず名前も異なるため、変数名が 重複することはありません。 名前の重複を解決する方法を決定する検索順序についての詳細につい ては、『PowerScript リファレンス』マニュアルの「宣言」および「関 数とイベントの呼び出し」の章を参照してください。 上書きされた関数とイ ベント 継承した関数のスクリプトを変更する場合は、先祖オブジェクトの関 数を上書きします。イベントの場合は、ペインタ内で先祖オブジェク トのイベント スクリプトを上書きまたは拡張します。 スコープ演算子を使用すれば、上書きした関数またはイベントの先祖 オブジェクトを呼び出すことができます。それには次のように、スコー プ演算子を表す二重コロンの前に先祖クラス名(変数名ではない)を 指定します。 result = w_ancestor::FUNCTION of_func(arg1, arg2) 32 PowerBuilder 第3章 PowerScript についての特別なトピック 先祖クラスの名前を指定するかわりに、Super 代名詞を使用することも できます。Super は、すぐ上の先祖オブジェクトを参照します。 result = Super::EVENT ue_process() 優れたオブジェクト指向設計では、ほかのオブジェクトの先祖スクリ プトを呼び出すようなことはしません。こうした呼び出し方をするの は、Super を使って現在のオブジェクトのすぐ上の先祖を呼び出す場合 だけにしてください。 先祖スクリプトの戻り値を取得する方法についての詳細は、次の「先 祖スクリプトからの戻り値」を参照してください。 関数の多重定義 同じオブジェクトに同じ名前の関数を複数定義すると、関数名が多重 定義されたものとみなされます。PowerBuilder は、関数定義のシグネ チャ(形式)と関数呼び出しのシグネチャを比較することによって、 どの関数を呼び出すかを決定します。シグネチャには、関数名、引数 リスト、戻り値が含まれます。 多重定義 イベントおよびグローバル関数は多重定義できません。 先祖スクリプトからの戻り値 子孫オブジェクトのイベント スクリプト内で、先祖イベント スクリプ ト の 戻 り 値 に 依 存 し た 処 理 を 実 行 す る 場 合 は、ロ ー カ ル 変 数 AncestorReturnValue を使用します。このローカル変数は自動的に宣言 され、先祖イベントの戻り値が代入されます。 コンパイラは、スクリプト内で先祖イベントを呼び出す CALL 文に出 会うと、AncestorReturnValue 変数を宣言し、それに先祖イベントの戻 り値を代入するコードを暗黙に生成します。 AncestorReturnValue 変数のデータ型は常に、その先祖イベントの戻り 値に定義されているデータ型と同じです。先祖イベントの呼び出し時 には、子孫オブジェクトのイベントに渡された引数がそのまま渡され ます。 イベント スクリプト の拡張 AncestorReturnValue 変数は拡張イベント スクリプト内では常に使用で きます。イベント スクリプトを拡張すると、次の構文が生成され、ス クリプトの先頭に挿入されます。 CALL SUPER::event_name アプリケーション テクニック 33 先祖スクリプトからの戻り値 この文が表示されるのは、オブジェクトの構文を公開している場合だ けです。 イベント スクリプト の上書き イベント スクリプトを上書きした場合に AncestorReturnValue 変数が 使用可能になるのは、次のように CALL 構文を明示的に使用して先祖 イベントを呼び出したときだけです。 CALL SUPER::event_name または CALL ancestor_name::event_name コンパイラは、SUPER キーワードと先祖名を区別しません。SUPER キーワードは、スクリプトがコンパイルされる前に先祖名で置き換え られます。 AncestorReturnValue 変数が宣言され戻り値が代入されるのは、CALL イ ベント構文を使用した場合だけです。次のように新規イベント構文を 使用した場合、AncestorReturnValue 変数は宣言されません。 ancestor_name::EVENT event_name ( ) 例 拡張イベント スクリプトには次のようなコードを書くことができま す。 IF AncestorReturnValue = 1 THEN // 処理を実行する ELSE // 別の処理を実行する END IF 先祖イベント スクリプトを上書きするスクリプトにも上記の拡張イベ ント スクリプトと同じコードを書くことができますが、 AncestorReturnValue 変数を使用する前に CALL 文を挿入しなければな りません。 // 前処理を実行するコード CALL SUPER::ue_myevent IF AncestorReturnValue = 1 THEN … 34 PowerBuilder 第3章 PowerScript についての特別なトピック 関数とイベントの引数の型 関数またはユーザ イベントを定義するときは、引数、引数のデータ型、 および引数の渡し方を指定します。 引数の渡し方には、次の 3 つがあります。 • デフォルトの引数の渡し方です。 値渡し 引数値のコピーを渡します。呼び出し先で引数値を変更するとこ のコピーが変更されます。呼び出し元の引数値は変更されません。 • 参照渡し 引数が格納された変数へのポインタを渡します。 参照渡しの引数は呼び出し元の変数へのポインタなので、呼び出 し先の関数スクリプトからその値を変更できます。参照渡しの引 数には、値を変更できるように変数を指定する必要があります。リ テラルや定数を指定することはできません。 • 読み込み専用渡し 引数を値渡しで渡しますが、データのコピーを 作成しません。 読み込み専用渡しでは値渡しのようにデータのコピーを作成しな いため、データ型によってはパフォーマンスが向上します。String、 Blob、Date、Time、DateTime の各データ型は、読み込み専用渡しに するとパフォーマンスが向上します。 上記以外のデータ型の場合でも、読み込み専用渡しにすることで、 その引数の用途(読み込み専用であること)をほかの開発者に伝 えることができます。 関数を上書きするとき の引数型の照合 先祖関数を上書きする関数を子孫オブジェクトに定義する場合は、関 数のシグネチャ、すなわち関数名、戻り値、引数のデータ型、引数の 渡し方がすべて一致していなければなりません。 たとえば、次の関数宣言では、3 つの Long 型引数のうち、2 つを値渡 しで、1 つを参照渡しで渡しています。 uf_calc(long a_1, long a_2, ref long a_3) & returns integer 先祖関数を上書きした子孫関数のシグネチャが先祖関数のものと一致 しない場合は、関数が呼び出されたときに PowerBuilder はもっとも類 似している関数を捜し出して呼び出します。このため、予期せぬ結果 になることがあります。 アプリケーション テクニック 35 先祖変数と子孫変数 先祖変数と子孫変数 PowerBuilder のすべてのオブジェクトは、PowerBuilder システム オブ ジェクト(ブラウザの[システム]ページに一覧表示されるオブジェ クト)の子孫です。 したがって、オブジェクト インスタンスを宣言するときはいつも、子 孫オブジェクトを宣言していることになります。どの程度具体的な宣 言にするかは、開発者が決定します。 できるだけ具体的な宣 言にする場合 たとえば、uo_empdata という名前のユーザ オブジェクト クラスを定義 する場合に、uo_empdata という型の変数を宣言して、uo_empdata ユー ザ オブジェクトへの参照を格納することができます。 uo_empdata uo_emp1 uo_emp1 = CREATE uo_empdata uo_emp1 の型は uo_empdata なので、uo_empdata の定義に含まれる変数 や関数を参照することができます。 アプリケーションに柔 軟性が要求される場合 作成するユーザ オブジェクトがユーザの選択によって決まるとしま す。UserObject という型のユーザ オブジェクト変数を宣言するか、そ のユーザ オブジェクトの先祖クラスを宣言します。そして、インスタン ス化するオブジェクト クラスを文字列変数に格納し、 それを CREATE の 引数に指定してクラスをインスタンス化します。 uo_empdata uo_emp1 string ls_objname ls_objname = ...// 開くユーザ オブジェクトを確定する uo_emp1 = CREATE USING ls_objname この方法は汎用的ですが、オブジェクトの変数や関数へのアクセスが 制限されます。コンパイラは先祖クラス uo_empdata の(システム クラ ス UserObject を宣言した場合はその)プロパティや関数しか知りませ ん。実際に作成されるオブジェクトについては知らないため、その未知 のオブジェクトに定義されたプロパティへの参照を許可できません。 抽象先祖オブジェクト インスタンス化する子孫オブジェクトのプロパ ティや関数を特定するためには、子孫オブジェクトで実装するプロパ ティや関数を含む先祖オブジェクトを定義します。この先祖オブジェ クトの関数に戻り値以外のコードは不要です。この関数を定義する目 的は、コンパイラが関数名を認識できるようにすることだからです。 この先祖クラスの変数を宣言すると、関数を参照できるようになりま す。実行時に、特定の子孫で変数をインスタンス化します。この子孫 が必要な関数を実装しています。 uo_empdata uo_emp1 string ls_objname 36 PowerBuilder 第3章 PowerScript についての特別なトピック // 開く uo_empdata の子孫を確定する ls_objname = ... uo_emp1 = CREATE USING ls_objname // 先祖クラスで関数を宣言する result = uo_emp1.uf_special() この手法の詳細については、20 ページの「関数の動的呼び出しと静的 呼び出し」に記載されています。 宣言したクラスに定義されていない関数を扱うも う 1 つの方法として、動的関数呼び出しがあります。 動的関数呼び出し 関数呼び出しに DYNAMIC キーワードを指定すると、コンパイラはその 関数が有効かどうかをチェックしなくなります。このチェックは、実 行時に、変数が適切なオブジェクトでインスタンス化されたとき行わ れます。 // 子孫クラス内で宣言されていない関数 result = uo_emp1.DYNAMIC uf_special() パフォーマンスとエラー 動的関数呼び出し機能は、アプリケーションの設計によって要求され るとき以外は使用しないでください。実行時評価では、通常はコンパ イラが行う作業を実行時に行う必要があります。このため、動的呼び 出しを頻繁に、または大きなループ内で使用すると、アプリケーショ ンのパフォーマンスが低下します。また、コンパイラによるチェック が省略されるため、本来ならコンパイラが検出していたエラーが実行 時まで検出されません。 ウィンドウとビジュア ル ユーザ オブジェク トの動的オブジェクト 選択 ウィンドウとビジュアル ユーザ オブジェクトを開くには、CREATE 文 ではなく関数呼び出しを使用します。Open および OpenUserObject 関数 を使用すると、開くウィンドウまたはオブジェクトのクラスを指定で きるため、宣言のオブジェクト型とは異なる型の子孫を開けます。 次の例では、s_u_name 文字列に指定された型を持つユーザ オブジェク トを表示し、そのユーザ オブジェクトへの参照を u_to_open 変数に格 納しています。u_to_open 変数は DragObject 型、つまりすべてのユーザ オブジェクトの先祖です。このインスタンス変数は、すべてのユーザ オブジェクトへの参照を保持できます。 DragObject u_to_open string s_u_name s_u_name = sle_user.Text w_info.OpenUserObject(u_to_open, s_u_name, 100, 200) アプリケーション テクニック 37 データウィンドウと外部オブジェクトにおける式の最適化 ウィンドウについても同様のコードを書くと次のようになります。実 際に開かれるウィンドウの型は、w_data_entry クラス、またはその子孫 クラスになります。 w_data_entry w_data string s_window_name s_window_name = sle_win.Text Open(w_data, s_window_name) データウィンドウと外部オブジェクトにおける式の最適化 コンテナ オブジェク トに対するコンパイラ の妥当性チェックは行 われない ドット表記を使用して、データウィンドウ コントロール内のデータ ウィンドウ オブジェクトまたはデータストアを参照すると、コンパイ ラは次の式の妥当性チェックを行いません。 dw_data.Object.column.property Object プロパティ以降の部分はコンパイラによるチェックを受けず、 実行時にチェックされます。 これは、外部 OLE オブジェクトについても同じです。つまり、外部 OLE オブジェクトのチェックも実行時に行われます。 ole_1.Object.qualifier.qualifier.property.Value 部分参照の確定 多くの式を使用すると、実行時の構文チェックに時間がかかるためパ フォーマンスが低下します。同じデータウィンドウ コンポーネント オ ブジェクトまたは外部オブジェクトを繰り返し参照する場合に効率性 を高めるには、適切な型の変数を定義して、その変数に参照の一部を 割り当てます。これにより、参照の大部分を 1 回だけ評価し、以降は その評価結果を再利用できます。 データウィンドウ コンポーネント オブジェクトのデータ型は DWObject です。 DWObject dwo_column dwo_column = dw_data.Object.column dwo_column.SlideLeft = ... dwo_column.SlideUp = ... 部分的に解決されたオートメーション式のデータ型は OLEObject です。 OLEObject ole_wordbasic ole_wordbasic = ole_1.Object.application.wordbasic ole_wordbasic.propertyname1 = value ole_wordbasic.propertyname2 = value 38 PowerBuilder 第3章 PowerScript についての特別なトピック エラー処理 Error イベントと(オートメーション用の)ExternalException イベント は、データウィンドウおよび OLE 式を評価するときに発生します。こ れらのイベントを処理するスクリプトを書けば、SystemError イベント が起動される前にエラーを捕捉することができます。これらのイベン トを使用すると、エラーを無視したり、適切な値で置換したりできま す。ただし、それによって別のエラーを引き起こす条件を設定してし まわないように注意する必要があります。次の「PowerBuilder での例 外処理」で説明するように、try-catch ブロックを使用して例外を処理 することもできます。 詳細情報 データウィンドウのデータ式とプロパティ式、および DWObject 変数に ついての詳細は、『データウィンドウ リファレンス』マニュアルを参 照してください。オートメーションの OLEObject 変数の使い方につい ての詳細は、第 19 章「アプリケーションにおける OLE の使い方」を 参照してください。 PowerBuilder での例外処理 PowerBuilder アプリケーションで実行時エラーが発生した場合に、そ のエラーをトラップしないと、アプリケーション内でのエラー発生の 場所に関係なく、単一のアプリケーション イベント(SystemError)が 発生しエラーが処理されます。システム エラー イベントで処理できる エラーもありますが、発生箇所に近い位置でエラーを捕捉したほうが、 エラー状態から回復できる可能性が高くなります。 例外処理用のクラス構文を使用すれば、PowerBuilder アプリケーショ ンの状況依存エラーを処理できます。つまり、エラー処理用のコード をアプリケーション内に埋め込むことによって、エラー発生箇所に近 い位置でエラーを処理できます。例外処理コードをうまく設計すれば、 ユーザはエラー状態から回復できる可能性が高くなり、アプリケー ションによる作業を中断せずに済みます。 例外処理を行うことにより、例外状態から回復し処理を続行できるア プリケーションを設計できます。アプリケーションが捕捉しない例外 はすべてランタイム システムによって処理されます。その場合は、ア プリケーションが異常終了することがあります。 PowerBuilder クライアントは、アプリケーション サーバ コンポーネン トで送出された例外を捕捉し、例外状態から回復することができます。 PowerBuilder で開発したコンポーネントは、独自の例外の種類を定義 し送出できます。これにより、Java などほかのサーバ コンポーネント との一貫性を高めることができます。 アプリケーション テクニック 39 PowerBuilder での例外処理 例外処理は、Java や C++ などのオブジェクト指向言語でも使われます。 PowerBuilder の例外処理の実装は、Java の例外処理の実装に似ていま す。PowerBuilder の例外処 理では、TRY、CATCH、FINALLY、THROW、 THROWS などの予約語を使用します。Throwable オブジェクトから派 生した PowerBuilder オブジェクトもいくつかあります。 例外処理の基本 例外とは、何らかの例外的な(予想外の)状態やエラーのイベントで 送出されるオブジェクトであり、発生した条件やエラーを記述するも のです。Null オブジェクト参照やゼロによる除算などの標準エラーは 通常、ランタイム システムによって送出されます。この種のエラーは アプリケーション内のどこでも発生する可能性があり、任意の実行ス クリプトにはこれらのエラーから回復するための catch 句を指定でき ます。 ユーザ定義の例外 即座に実行時エラーとはならない例外条件もあります。これらの例外 は通常、関数またはユーザ イベント スクリプトの実行中に発生しま す。これらの例外を伝えるには、PowerScript の Exception クラスから 継承したユーザ オブジェクトを作成します。ユーザ定義の例外は、関 数、またはメソッド プロトタイプ内のユーザ イベントに関連付けるこ とができます。 たとえば、特定のファイルが見つからないことを知らせるためにユー ザ定義の例外を作成させるとします。この例外は、そのファイルを開 く関数のプロトタイプ内で宣言するとよいでしょう。この例外を捕捉 するには、ユーザ定義の例外オブジェクトをインスタンス化して、そ のメソッド スクリプト内で例外インスタンスを送出する必要があり ます。 例外処理用のオブジェクト PowerBuilder には、例外処理用のシステム オブジェクトがいくつかあ ります。 Throwable オブジェク ト型 40 Throwable オブジェクト型は、すべてのユーザ定義の例外およびシス テム エラー型の基本となるデータ型です。2 つのシステム オブジェク ト型 RuntimeError と Exception は、Throwable から派生したデータ型で す。 PowerBuilder 第3章 RuntimeError とその 子孫 PowerScript についての特別なトピック PowerBuilder の実行時エラーは、RuntimeError オブジェクト型で表さ れます。より堅牢なエラー処理機能を実現するために、RuntimeError 型には独自のシステム定義の子孫が定義されていますが、PowerBuilder の実行時エラーを処理するために必要な情報はすべて RuntimeError 型 に含まれています。 RuntimeError の子孫型の 1 つに NullObjectError 型があります。 NullObjectError 型の例外は、Null オブジェクト参照を検出するたびに システムによって送出されます。これにより、Null オブジェクト参照 エラーを、発生する可能性のあるほかの実行時エラーと区別せずに明 示的に処理できます。 RuntimeError から派生したエラー型は通常、実行時エラーを知らせる ためにシステムによって使用されます。RuntimeError は try-catch ブ ロックで捕捉できますが、このようなエラー条件が発生する場所を宣 言する必要はありません。これは PowerBuilder がかわりに行ってくれ ます。というのは、システム エラーはアプリケーション実行時にいつ でもどこでも発生する可能性があるからです。また、RuntimeError 型 のエラーを捕捉することは必須ではありません。 Exception オブジェク ト型 Exception システム オブジェクトも、Throwable から派生したオブジェ クトで、通常、ユーザ定義の例外型の先祖オブジェクトとして使用さ れます。例外のクラスは、すべての検査例外の基本となるクラスです。 検査例外 はユーザ定義の例外で、送出されたら必ず try-catch ブロック 内で捕捉しなければなりません。また、try-catch ブロックの外で送出 される場合は、メソッドのプロトタイプ内で宣言する必要があります。 PowerScript コンパイラは検査例外が送出されるローカルの構文を チェックして、検査例外が必ず宣言または捕捉されるようにします。 RuntimeError の子孫は、それがユーザ定義であっても、またランタイ ム システムによってではなくスクリプト内で送出されるものであっ ても、コンパイラによってチェックされることはありません。 例外の処理 例外は、ランタイム システムによって送出される場合でも、アプリ ケーション スクリプト内の THROW 文によって送出される場合でも、 例外を捕捉することによって処理します。例外を捕捉するには、例外 を送出させる一連のアプリケーション ロジックを、その例外の処理方 法を示すコードで囲みます。 アプリケーション テクニック 41 PowerBuilder での例外処理 TRY-CATCHFINALLY ブロック PowerScript で例外を処理するには、アプリケーション ロジックの一部 を try-catch ブロックで囲む必要があります。try-catch ブロックは、TRY 句で始まり、END TRY 文で終わります。また、ブロック内には、CATCH 句または FINALLY 句を含める必要があります。FINALLY 句は通常、エ ラー条件の後処理を記述するときに指定します。TRY 句と FINALLY 句 の間には、CATCH 句をいくつでも追加できます。 CATCH 句は必須ではありませんが、指定する場合は各 CATCH 文の後 に変数を宣言しなければなりません。この変数は、スクリプト内での ローカル変数宣言に関するすべての規則に従っているだけでなく、 Throwable から派生した型を持っていなければなりません。 TRY-CATCH-FINALLY、TRY-CATCH、TRY-FINALLY の各ブロックは、スク リプト ビューで PowerScript 文の[形式を指定して貼り付け]機能を 使用して追加できます。デザイン オプション ダイアログボックスの [オートスクリプト]タブにある[ステートメント テンプレート] チェックボックスをオンにすると、オートスクリプト機能を使用して 上記の各ブロック構文を挿入できます。 例 次の例は、アプリケーション ユーザに よって(シングルライン エディットに)入力された arccosine 引数の値 が、要求範囲外であることを示すシステム エラーを捕捉する TRYCATCH-FINALLY ブロックです。このエラーを捕捉しないと、システム エラー イベントが発生し、アプリケーションは最終的に異常終了しま す。 システム エラーを捕捉する例 Double ld_num ld_num = Double (sle_1.text) TRY sle_2.text = string (acos (ld_num)) CATCH (runtimeerror er) MessageBox(" 実行時エラー ", er.GetMessage()) FINALLY // クリーンアップ コードをここに追加 of_cleanup() Return END TRY MessageBox(" 完了 ", " 完了しました。") システム実行時のエラー メッセージはエンド ユーザには分かりにく いので、本稼働システムでは、ユーザ定義の例外を捕捉して(44 ペー ジの「ユーザ定義の例外型の作成」の例を参照)、分かりやすいメッ セージを設定するとよいでしょう。 42 PowerBuilder 第3章 PowerScript についての特別なトピック 予約語 TRY は、実行されるブロックの先頭を表します。ブロックには、 1 つまたは複数の CATCH 句を含めることができます。TRY ブロック内 のコードを実行中に例外が送出されると、最初の CATCH 句によって処 理されます。このとき、CATCH 句の変数に、送出された例外の値が代 入されます。CATCH 文の後の変数宣言は、処理される例外の型(この 例ではシステム実行時エラー)を表します。 CATCH 句の順序 1 つの CATCH 句がほかの CATCH 句を隠さないように CATCH 句を配 置することが必要です。先頭の CATCH 句で Exception 型の例外を捕捉 し、次の CATCH 句で Exception の子孫を捕捉するというような場合に、 この問題が発生します。指定した順に処理されるので、Exception の子 孫の例外は最初の CATCH 句で処理されて、2 番目の CATCH 句で処理 されることはありません。PowerScript コンパイラは、こうした状況を 検出すると、コンパイル エラーを発生させます。 どの CATCH 句によっても処理されなかった例外は、コールスタックの 上位に送出され、別の例外ハンドラ(try-catch ブロックの入れ子)、ま たはシステム エラー イベントによって処理されます。例外がコールス タックの上位に送出される前に、FINALLY 句が実行されます。 FINALLY 句 FINALLY 句では、一般的に、TRY 句または CATCH 句の実行後の後処理 を行います。FINALLY 句に指定されたコードは、try-catch ブロック内の いずれかの部分が実行されると、try-catch ブロックの終了状態に関係 なく必ず実行されます。 例外が発生しないと、TRY 句が終了した後、FINALLY 句に指定された文 が実行されます。そして、END TRY 文の次の行から処理が続行されま す。 CATCH 句が 1 つもなく、FINALLY 句だけが存在する場合は、FINALLY 句 に指定されたコードが実行されます。戻り値が検出された場合や TRY 句内で例外が送出された場合でも、FINALLY 句は必ず実行されます。 TRY 句のコンテキストで例外が発生した場合、その例外を処理できる 適切な CATCH 句があればその CATCH 句が実行され、その後、FINALLY 句が実行されます。送出された例外を処理できる適切な CATCH 句が存 在しない場合でも、FINALLY 句は必ず実行され、その後、コールスタッ クの上位に(未処理の)例外が送出されます。 CATCH 句内で例外が発生するか戻り値が検出された場合は、FINALLY 句が実行されてから、プログラム内の次の実行場所に制御が移ります。 アプリケーション テクニック 43 PowerBuilder での例外処理 ユーザ定義の例外型の作成 Exception または RuntimeError、あるいは Exception または RuntimeError から派生した既存のユーザ オブジェクトを継承する標準クラス ユー ザ オブジェクトから、ユーザ定義の固有の例外型を作成することがで きます。 Exception オブジェク ト型からの継承 通常、ユーザ定義の例外型は、Exception 型またはその子孫を継承する 必要があります。RuntimeError 型はシステム エラーを表すために使用 します。ユーザ定義のオブジェクトには、システム内のそのほかの非 ビジュアル ユーザ オブジェクトと同様、イベント、関数、インスタン ス変数を定義できます。 ユーザ定義の例外型は、たとえば、ビジネス ルール違反などの特定の 条件によってアプリケーション ロジックが異常終了する場合の処理 に使うと便利です。こうした条件を記述するユーザ定義の例外型を作 成し、例外を正しく捕捉して処理すれば、実行時エラーを回避できま す。 例外の送出 例外は、エラー条件を示すために、ランタイム エンジンによって送出 されます。潜在的な例外条件を手動で送出する場合は、THROW 文を使 用する必要があります。 THROW 文は通常、ユーザ定義の例外型と組み合わせて使用します。以 下に、THROW 文の使い方を簡単な例を用いて示します。 Exception le_ex le_ex = create Exception Throw le_ex MessageBox (" 注意 ", " 例外変数が " & + " インスタンス化されていなくてはなりません ") この例では、le_ex 例外のインスタンスを送出しています。予約語 THROW の後に続く変数は、Throwable から派生した型を持つ例外オブ ジェクトの有効なインスタンスへのポインタでなければなりません。 インスタンス化されていない Exception 変数を送出しようとすると、 ルーチン内に Null オブジェクト参照が存在することを示す NullObjectError が発生します。これは、アプリケーションのエラー処理を複雑にする だけです。 関数から送出される例 外の宣言 44 メソッド スクリプト内で THROW 文を使用して例外を送出する場合 に、その例外型を処理する try-catch ブロックで THROW 文を囲まない ときは、その例外をそのメソッドが送出可能な例外型(またはその子 孫)として宣言する必要があります。ただし、実行時エラーが送出可 能であることは PowerBuilder がかわりに宣言してくれるので、メソッ ドで宣言する必要はありません。 PowerBuilder 第3章 PowerScript についての特別なトピック ほとんどの PowerBuilder ペインタのスクリプト ビューにあるプロトタ イプ ウィンドウを使用すれば、関数またはユーザ定義のイベントが送 出可能なユーザ定義の例外を宣言できます。システム ツリーまたはラ イブラリ ペインタ ビューからプロトタイプ ウィンドウ内の[Throws] ボックスに例外型をドラッグ アンド ドロップするか、メソッドが送出 可能な例外型をコンマで区切られたリストとして入力します。 例 ユーザ定義の例外を捕捉する例 次 の コ ー ド で は、ア プ リ ケ ー シ ョ ン ユーザが入力した arccosine 引数が指定範囲外である場合にユーザ定義 のエラーを表示します。try-catch ブロック内で wf_acos メソッドを呼び 出します。このメソッドは、システム エラーを捕捉し、ユーザ定義の エラーを設定および送出します。 TRY wf_acos() CATCH (uo_exception u_ex) MessageBox(" 範囲外 ", u_ex.GetMessage()) END TRY wf_acos メソッドの中身は次のとおりです。 uo_exception lu_error Double ld_num ld_num = Double (sle_1.text) TRY sle_2.text = string (acos (ld_num)) CATCH (runtimeerror er) lu_error = Create uo_exception lu_error.SetMessage(" 値は -1 ~ " & + "1 の範囲になければなりません ") Throw lu_error END TRY EAServer との統合 ユーザ オブジェクトのメソッドで例外を宣言し、そのユーザ オブジェ クトを EAServer のコンポーネントとして配布すると、メソッド プロ トタイプの一部として例外が IDL(CORBA)に変換されます。つまり、 EAServer 内の PowerBuilder コンポーネントを、 任意のタイプの EAServer クライアント アプリケーションで処理可能な例外を送出するように 定義できます。 EAServer アプリケーションのそのほかの利点 コンポーネント開発の別 の利点は、コンポーネント内で実行時エラーを処理できることです。 未処理のエラーは自動的に例外に変換され、コンポーネントは実行を 中止します。 アプリケーション テクニック 45 PowerBuilder での例外処理 EAServer コンポーネントを使用した PowerBuilder クライアント アプ リケーションは、どのタイプの EAServer コンポーネントから送出され た例外も処理できます。例外を送出するように定義されたメソッドを 持つ Java EAServer コンポーネントがあり、そのコンポーネントを使用 して PowerBuilder プロキシを作成すると、PowerBuilder プロキシ上の メソッドもユーザ定義の例外を送出するように宣言されます。ユーザ 定義の例外に関する定義は、PowerBuilder プロキシの作成時に自動的 に作成されます。 EAServer のエラー処理についての詳細は、546 ページの「エラー処理」 を参照してください。 IDL の制限 EAServer のコンポーネントを配布する場合は、PowerBuilder 内での例外処理の使い方に制限が課されます。IDL に変換されるのは、 該当する例外型に定義されたパブリックなインスタンス変数だけで す。これは、IDL 例外を送出するようにメソッドを宣言することはで きないためです。したがって、特定の例外型が送出されるように定義 されたメソッドがある場合、それらのメソッドをコンポーネントの実 行中に呼び出すことはできますが、クライアント アプリケーションか らそれらのメソッドを呼び出して送出された例外を捕捉することはで きません。 分散アプリケーションでの例外オブジェクトを設計するときには、こ の制限を忘れないようにしなければなりません。すなわち、分散アプ リケーションでは、すべての例外情報を、例外オブジェクトのアクセ サ メソッドを介してではなく、パブリックなインスタンス変数として 公開する必要があります。 EAServer コンポーネントとして配布されるユーザ オブジェクトの例 外型に適用されるインタフェース上の制限があと 2 つあります。ユー ザ オブジェクト メソッドの例外を表すインスタンス変数は、オブジェ クト データ型を持つことができません。また、Null データは、単純な データ型を持つインスタンス変数の場合だけサポートされています。 インスタンス変数が構造体または配列の場合、各要素の Null 値は維持 されません。 柔軟性の向上とオブジェクトの再利用の促進 例外処理を使用すると、PowerBuilder アプリケーションの柔軟性を高 め、ビジネス ルールをプレゼンテーション ロジックから切り離すこと ができます。たとえば、ビジネス ルールを、以下の非ビジュアル オブ ジェクト(nvo)に格納できます。 46 PowerBuilder 第3章 • PowerScript についての特別なトピック プレゼンテーション オブジェクトへの参照を保持するインスタン ス変数 powerobject my_presenter • プレゼンテーション オブジェクトを登録する関数 登録用関数には次の構文を使用します。 SetObject (string my_purpose, powerobject myobject) • プレゼンテーション オブジェクトによって実装された動的関数を 呼び出すコード(データの表示方法については最小限の機能のみ をサポート) 動的関数呼び出しは、次のように try-catch ブロックで囲む必要が あります。 TRY my_presenter.Dynamic nf_displayScreen(" ") CATCH (Throwable lth_exception) Throw lth_exception END TRY この try-catch ブロックは、プレゼンテーション オブジェクトで発 生するシステム エラーとユーザ定義のエラーをすべて捕捉し、呼 び出し元(この nvo を呼び出したオブジェクト)に送出します。上 の例では、CATCH 文で送出されるオブジェクトの型が Throwable になっていますが、次のようにユーザ定義の例外オブジェクトを インスタンス化および送出することもできます。 uo_exception luo_exception TRY my_presenter.Dynamic nf_displayScreen(" ") CATCH (Throwable lth_exception) luo_exception = Create uo_exception luo_exception.SetMessage & + (lth_exception.GetMessage()) Throw luo_exception END TRY データ処理用のコードは、プレゼンテーション オブジェクト、ビジネ ス ルール nvo、または nvo によって呼び出されるデータ処理用オブ ジェクトに追加できます。具体的にどのような設計にするかはビジネ スの目的によって異なりますが、このデータ処理用のコードも trycatch ブロックで囲む必要があります。実行するアクションと(処理失 敗時に)報告するエラー メッセージは、処理用コードを囲む try-catch ブロック内でできる限り具体的に指定します。 アプリケーション テクニック 47 PowerBuilder での例外処理 この手法には大きな利点がいくつかあります。まず、ビジネス nvo を 非常に簡単に再利用できるようになります。これにより、同じビジネ ス データをさまざまな方法で表示するオブジェクトからビジネス nvo を使用できます。また、例外処理を追加したことにより堅牢性が大幅 に向上し、アプリケーション ユーザがエラー条件から回復できる可能 性が高くなります。 SystemError イベントと Error イベントの使い方 Error イベント 実行時エラーが発生すると、そのエラーを記述するエラー構造体が作 成されます。リモート サーバ(EAServer など)との接続のコンテキス トでエラーが発生すると、接続、JaguarORB、データウィンドウ、OLE などのコントロール オブジェクトの Error イベントが起動されます。 このとき、エラー構造体の情報が引数として渡されます。 この Error イベント内でエラーを処理するには、特殊な参照引数を使用 してエラーを無視できるようにします。上記のコンテキストでエラー が発生しないか、または上記のコンテキストで発生したエラーが処理 されないと、エラー構造体情報がグローバル エラー変数に格納され、 アプリケーション オブジェクトの SystemError イベントが起動されます。 SystemError イベント SystemError イベントでは、予期せぬエラー条件を制限された方法で処 理できます。一般に、SystemError イベントが起動された後も処理を継 続するのはよくありません。しかし、SystemError イベントにはエラー 処理用のコードを追加できるようになっており、また追加するべきで す。SystemError イベントは通常、アプリケーションを終了する前に データを保存したり、 (ファイルやデータベース接続を閉じるなど)最 後の後処理を実行したりするために使用します。 例外ハンドラおよびイ ベントの優先順位 Error イベント内にコードを書くと、例外発生時にまずそのコードが実 行されます。 上記のどのコンテキストでも例外を送出しないか、オブジェクトの Error イベントによって例外が処理されないか、または Error イベント をコーディングしないと、その例外型を処理できる任意のアクティブ な例外ハンドラ(CATCH 句)によって例外が処理されます。例外を処 理する例外ハンドラが存在しない場合に限って、例外クラスの情報が グローバルなエラー変数にコピーされ、アプリケーション オブジェク トの SystemError イベントが起動されます。 48 PowerBuilder 第3章 新規アプリケーション のエラー処理 PowerScript についての特別なトピック 新規の PowerBuilder アプリケーションでは、接続、データウィンドウ、 OLE などのコントロール オブジェクトの Error イベントをコーディン グするのではなく、try-catch ブロックを使用してエラーを処理するこ とをお勧めします。ただし、捕捉されない例外を処理するために、ア プリケーション オブジェクトには SystemError イベントを設定してお く必要があります。SystemError イベントは本質的に、PowerBuilder ア プリケーションのグローバルな例外ハンドラになります。 ガベージ コレクションとメモリ管理 PowerBuilder のガベージ コレクション機能は、未参照の孤立したオブ ジェクトがないかどうかメモリを自動的にチェックし、もしあればそ れを削除します。これにより、大半のメモリ リークを防ぐことができ ます。ガベージ コレクションを使用すると、DESTROY 文で明示的に指 示することなくオブジェクトを破壊できます。これにより、ほかのプ ロセスで使用中のオブジェクト、ポストされたイベント、および関数 に参照渡しされたオブジェクトを間違って破壊してしまうことによっ て起こる実行時エラーを防ぐことができます。 オブジェクトへの参照とは、値が object 型であるすべての変数のことで す。これらの変数がスコープの外に出るか object 型以外の値が代入さ れると、PowerBuilder はそのオブジェクトへの参照を削除し、残りの 参照数を数えて、参照数がゼロならガベージ コレクション プロセスは そのオブジェクトを破棄します。 ガベージ コレクションが発生するタイミングは、次のとおりです。 • 設定されたガベージ コレクション実行間隔を超え、 PowerBuilder アプリケーションがアイドル状態になったとき • GarbageCollect 関数を明示的に呼び出したとき PowerBuilder はシステムによって起動されたイベントの処理が終了し たとき、前回のガベージ コレクションからの経過時間が、設定された 実行間隔を超えている場合は、ガベージ コレクション操作を実行しま す。デフォルトの実行間隔は 0.5 秒です。このシステムによって起動 されるガベージ コレクションは、PowerBuilder アプリケーションがア イドル状態のときにのみ発生します。そのため、実行間隔を超えたと きに時間のかかる計算や処理を実行している場合、ガベージ コレク ションはすぐには発生しないため、注意が必要です。 アプリケーション テクニック 49 ガベージ コレクションとメモリ管理 GarbageCollect 関数を呼び出して、ガベージ コレクションを強制的に実 行できます。ドット表記および OLEObjects を使用すると、一時変数が 作成されます。これらの一時変数は、ガベージ コレクションが処理さ れている間だけ解放されます。そのため、メモリ リークの原因となっ ている可能性のあるループ内で GarbageCollect を呼び出すことをお勧 めします。 ガベージ コレクション操作では、参照できないオブジェクトとクラス がすべて削除されます。これには循環参照(相互に参照し合うが、ほ かからは一切参照されていないオブジェクト)も含まれます。 イベントと関数のポスト イベントまたは関数をポストしてオブジェクトへの参照を渡すと、 PowerBuilder はそのオブジェクトへの内部参照を追加します。これに より、ポストしてからそのイベントまたは関数が終了するまでの間に、 そのオブジェクトが占有しているメモリがガベージ コレクションに よって収集されなくなります。追加された参照は、そのイベントまた は関数の実行が終了すると削除されます。 ガベージ コレクショ ンの対象にならないオ ブジェクト ガベージ コレクショ ンの発生の制御 50 次のオブジェクトはガベージ コレクションの対象から除外されます。 • ビジュアル オブジェクト 画面に表示されるオブジェクトは、画面 で作成され表示されるときに内部参照が追加されるため、ガベー ジ コレクションは行われません。ビジュアル オブジェクトは、閉 じるときに明示的に破棄します。 • タイミング オブジェクト • 共有オブジェクト SharedObjectRegister 関数は内部参照を追加する ため、登録された共有オブジェクトにはガベージ コレクションは 行われません。SharedObjectUnregister 関数を呼び出すと、追加され た内部参照が削除されます。 タイミング オブジェクトの Start 関数は そのオブジェクトの内部参照を追加するため、現在実行中のタイ ミング オブジェクトにはガベージ コレクションは行われません。 Stop 関数を呼び出すと追加された参照が削除されます。 ガベージ コレクションは PowerBuilder 内で自動的に行われますが、関 数を呼び出して、ガベージ コレクションを強制実行したり、参照カウ ントをチェックする間隔を変更したりすることもできます。ガベージ コレクション発生を制御する関数として、GarbageCollect、 GarbageCollectGetTimeLimit、および GarbageCollectSetTimeLimit の 3 つが 用意されています。 PowerBuilder 第3章 PowerScript についての特別なトピック これらの関数についての詳細は、『PowerScript リファレンス』マニュ アルを参照してください。これらの関数の使用例については、第 1 章 「サンプル アプリケーションの使い方」の Code Examples サンプル ア プリケーションを参照してください。 パフォーマンスに関す る考慮点 トレースとプロファイルを使用すると、ガベージ コレクションの実行 間隔を変更することによるパフォーマンスへの影響を調べることがで きます。 トレースとプロファイルの詳細については、PowerBuilder の『ユーザー ズ ガイド』マニュアルを参照してください。 メモリ管理の設定 PowerBuilder メモリ マネージャが別のメモリ割り当て方法に切り替え るときの閾値を指定するには、PB_POOL_THRESHOLD 環境変数を設 定します。 ほとんどのウィンドウ、データウィンドウ、データストア、またはそ のほかの PowerBuilder オブジェクトがガベージ コレクタによって破棄 または解放されると、PowerBuilder ヒープ マネージャは、そのオブジェ クトに割り当てられていたメモリをグローバル メモリ プールに戻し、 それを利用可能なメモリとしてグローバル フリー リストに記録しま す。解放されたメモリは、オペレーティング システムには戻されませ ん。新規オブジェクトが作成されるときに、PowerBuilder は、グロー バル フリー リストに十分な利用可能メモリがある場合はグローバル メモリ プールのメモリ ブロック、ない場合はオペレーティング シス テムのメモリ ブロックをオブジェクトのメモリ プールに割り当てま す。 オブジェクトに必要なメモリが 256 KB を超える場合、PowerBuilder は 別の方法でメモリを割り当てます。メモリが要求されるとオペレー ティング システムから大きいブロックで以降のメモリを割り当て、オ ブジェクトが破棄されると物理メモリをオペレーティング システム に戻します。また、仮想アドレス空間のフラグメンテーションを抑え るために仮想メモリを保持します。 ほとんどのアプリケーションとコンポーネントでは、必要なメモリが 256 KB の閾値に達したときに、PowerBuilder は「大きいブロック」の 方法に切り替えます。これにより、メモリは適切に割り当てられ、ア プリケーションがピーク時に必要とするメモリも少なくなります。た だし、アプリケーションが使用する全体の物理メモリをできるだけ少 なくする必要がある場合は、この閾値をもっと低く設定できます。 アプリケーション テクニック 51 ガベージ コレクションとメモリ管理 低い閾値を設定すると、グローバル メモリ プールのサイズが縮小され るという利点があります。アプリケーションは、動作していないとき はメモリの大部分を保持しません。ただし、欠点として、設定した閾 値より多くのメモリを必要とするオブジェクトに大きいメモリ ブ ロックが割り当てられた場合、アプリケーションがピーク時に使用す る仮想メモリ量がデフォルトの閾値の場合よりも多くなる可能性があ ります。 低い閾値を設定するのは、長時間動作するクライアント アプリケー ションが動作時間の短いオブジェクトを多数使用する場合に適してい ます。このようなアプリケーションでは、メモリ使用量が少なくなっ たり(アイドル時)多くなったり(動作時)するからです。サーバな どのマルチスレッド アプリケーションの場合は、高い閾値を設定する と、通常は仮想メモリの使用量が少なくなります。 ヒープ マネージャ出 力のログへの記録 PowerBuilder ヒープ マネージャの診断出力をファイルに記録できます。 この情報は、アプリケーションにおけるメモリ割り当ての問題を解決す る際に役立ちます。ファイルの名前と場所は PB_HEAP_LOGFILENAME 環境変数で設定します。 ディレクトリではなくファイル名を指定すると、 ファイルは PowerBuilder の実行ファイルと同じディレクトリに保存されます。または、EAServer で動作している PowerBuilder コンポーネントの場合は、EAServer の bin ディレクトリに保存されます。 存在しないディレクトリを指定した場合、ファイルは作成されません。 または、EAServer で動作している PowerBuilder コンポーネントの場合 は、EAServer のログ ファイル(Jaguar.log)に出力が書き込まれます。 デフォルトでは、ログ ファイルは、PowerBuilder または EAServer を再 起動するたびに上書きされます。診断出力をファイルの最後に追加す るには、PB_HEAP_LOGFILE_OVERWRITE に false を設定します。 環境変数は、アプリケーションを起動するバッチ ファイルで設定する か、アプリケーションまたはコンポーネントを実行するコンピュータ やサーバ上でシステム環境変数またはユーザ環境変数として設定でき ます。 PowerBuilder および EAServer でメモリ管理をチューニングする方法に ついては、テクニカル ドキュメント EAServer/PowerBuilder Memory Tuning and Troubleshooting のサイト http://www.sybase.com/detail?id=1027319 を参照してください。 52 PowerBuilder 第3章 PowerScript についての特別なトピック 効率的なコンパイルとパフォーマンス 関数の記述や変数の定義のしかたは、開発の生産性とアプリケーショ ンのパフォーマンスに影響を与えます。 スクリプトを短くして コンパイル時間を短縮 する 配布アプリケーション用の動的ライブラリを構築する場合は、関数と イベントのスクリプトを短くするようにしてください。スクリプトが 長いとコンパイルに時間がかかります。1 つの長いスクリプトを書く かわりに、ほかの複数の関数を呼び出すスクリプトを作成できるよう に、スクリプトを分割してください。ユーザ オブジェクト内の関数を、 ほかのオブジェクトからも呼び出せるように定義することを考慮して ください。 ローカル変数を使用し てパフォーマンスを向 上 変数のスコープはパフォーマンスに影響を与えます。できるだけロー カル変数を使うようにしてください。そうすれば、パフォーマンスが 向上します。グローバル変数を使うと、パフォーマンスが大幅に低下 します。 テキスト ファイルとバイナリ ファイルの読み書き ライン モードまたはテキスト モードでテキストを読み書きしたり、ス トリーム モードでバイナリ ファイルを読み書きしたりするには、 PowerScript のテキスト ファイル関数を使用します。 • ライン モードでは、キャリッジ リターンか改行(CR/LF)または ファイルの終わり(EOF)が現れるまで、一度に 1 行ずつファイ ルを読み込みます。ファイルに書き込むときは、指定された文字 列を書き込んだ後、CR/LF を追加します。 • ストリーム モードでは、ファイルの中身を、CR/LF も含めてすべ て読み込むことができます。ファイルに書き込むときは、指定さ れた Blob データを書き込みます(ただし、 CR/LF は追加しません)。 • テキスト モードでは、ファイルの中身を、CR/LF も含めてすべて 読み込むことができます。ファイルに書き込むときは、指定され た文字列を書き込みます(ただし、CR/LF は追加しません)。 マルチラインエディットにファイルを読み込む ストリーム モードを使用すると、ファイル全体をマルチラインエ ディットに読み込み、修正した後に書き出すことができます。 アプリケーション テクニック 53 テキスト ファイルとバイナリ ファイルの読み書き 位置ポインタ PowerBuilder は、ファイルを開くと、そのファイルに一意な整数を割 り当て、ファイルの位置ポインタを指定された位置、つまりファイル の先頭(バイト オーダー マーク(BOM: Byte-Order Mark)がある場合 はその後)または末尾に設定します。ファイルを読み書きしたり閉じ たりするときに、この一意な整数を使用してファイルを特定します。 位置ポインタは、次の読み書きの開始位置を指します。読み書きを実 行するたびに、位置ポインタが自動的に進められます。 位置ポインタは、FileSeek または FileSeek64 関数を使用して設定するこ ともできます。 ファイル操作関数 PowerScript には、次のファイル操作用組み込み関数が用意されていま す。 表 3-1: PowerScript のファイル操作用関数 関数 戻りデータ型 FileClose Integer FileDelete FileEncoding FileExists FileLength FileLength64 FileOpen FileRead FileReadEx FileSeek FileSeek64 FileWrite FileWriteEx エンコーディング 54 動作内容 指定されたファイルを閉じる Boolean 指定されたファイルを削除する Encoding カタロ ファイルで使用されているエンコーディン グを返す グ データ型 Boolean 指定されたファイルが存在するかどうかを 判定する Long サイズが 2 GB 以下のファイルの長さを取 得する LongLong 任意のサイズのファイルの長さを取得する Integer 指定されたファイルを開く Integer 指定されたファイルを読み込む(非推奨) Long 指定されたファイルを読み込む Long サイズが 2 GB 以下のファイル内の特定位 置に位置ポインタを設定する LongLong 任意のサイズのファイル内の特定位置に位 置ポインタを設定する Integer 指定されたファイルに書き込む(非推奨) Long 指定されたファイルに書き込む FileOpen 関数の最後の引数を指定すると、ANSI、UTF-8、UTF-16LE (リトル エンディアン)、または UTF16-BE(ビッグ エンディアン)ファ イルを作成できます。 PowerBuilder 第3章 PowerScript についての特別なトピック encoding 引数は、FileOpen 関数のファイル名以外のすべての引数と同様 にオプションです。Unicode エンコーディングの新規テキスト ファイ ルを作成する場合のみ必須です。filename 引数に存在しないファイル を指定すると、FileOpen 関数によってファイルが作成され、encoding 引 数に指定された文字エンコーディングが設定されます。 デフォルトでは、存在しないファイルを指定して encoding 引数を指定 しなければ、ファイルは ANSI エンコーディングで開かれます。これ により、PowerBuilder の旧バージョンとの互換性が維持されます。 FileRead 関数と FileWrite 関数は、一度に 32,766 バイトを超えるデータ を読み込むことができません。かわりに FileReadEx 関数と FileWriteEx 関数を使用すると、一度に大量のデータを読み書きできます。 アプリケーション テクニック 55 テキスト ファイルとバイナリ ファイルの読み書き 56 PowerBuilder 第 4 章 PowerBuilder のクラス定義に関する 情報の取得 この章について この章では、クラス定義情報の概要、その使い方、およびサンプ ル コードについて説明します。ツールとオブジェクト フレーム ワークの開発者は、似たような特性を持つオブジェクトの定義や レポートの作成などの作業に関して、クラス定義情報を使用でき ます。一般的なビジネス アプリケーションを構築する場合には、 クラス定義情報を使用する必要はありません。 内容 項目 クラス定義情報の概要 クラス定義の調査 ページ 57 61 クラス定義情報の概要 ClassDefinition オブジェクトは、PowerBuilder オブジェクトの 1 つ であり、別の PowerBuilder オブジェクトのクラスに関する情報を 提供します。PowerBuilder ライブラリ内のクラス、またはインス タンス化されたオブジェクトのクラスを調べることができます。 クラスの ClassDefinition オブジェクトのプロパティを調べること によって、クラスが PowerBuilder のオブジェクト階層構造にどう 収まるかを詳細に知ることができます。 ClassDefinition オブジェクトからは、以下の項目を知ることができ ます。 アプリケーション テクニック • そのクラスに定義された変数、関数、およびイベント • そのクラスの先祖 • そのクラスの親 • そのクラスの子(ネスティッド クラス) 57 クラス定義情報の概要 関連するオブジェクト ClassDefinition オブジェクトは、データ型に関する情報を提供したり、 クラス定義に関連付けられた変数、プロパティ、関数、およびイベント スクリプトに関する情報を提供したりするオブジェクト(TypeDefinition、 VariableDefinition、および ScriptDefinition などのオブジェクト)の階層 構造のメンバーです。 詳細については、ブラウザまたは『オブジェクトとコントロール』マ ニュアルを参照してください。 インスタンス化されたオブジェクトの定義 ClassDefinition プ ロ パテ ィ を 使うと、ClassDefinition オブジェクトを使って、各オブジェクトのイン スタンスから、オブジェクトの記述を取得できます。ClassDefinition オ ブジェクトは、変数の値などのオブジェクト インスタンスに関する情 報を提供しません。このような情報は、インスタンスから直接取得す る必要があります。 ライブラリでのオブジェクトの定義 クラス情報を取得するには、必ずし も オ ブ ジ ェ ク ト が イ ン ス タ ン ス 化 さ れ て い る 必 要 は あ り ま せ ん。 PowerBuilder ライブラリ内のオブジェクトの場合には、FindClassDefinition 関数を呼び出して、その ClassDefinition オブジェクトを取得できます。 クラス定義オブジェクトを使用するとオーバーヘッ ドが大きくなるように思われますが、オーバーヘッドが生じるのは ClassDefinition オブジェクトを参照するときだけです。ClassDefinition オブジェクトがインスタンス化されるのは、FindClassDefinition を呼び 出すとき、および PowerBuilder オブジェクトの ClassDefinition プロパ ティにアクセスするときに限られます。同様に、ClassDefinition オブ ジェクトのプロパティ自身が ClassDefinition または VariableDefinition オブジェクトである場合には、オブジェクトがインスタンス化される のは、それらのプロパティを参照するときだけです。 パフォーマンス 用語 クラス情報には、オブジェクト間の関係についての情報が含まれます。 これらの定義は、情報の意味を理解するときに役立ちます。 オブジェクト インス タンス 58 オブジェクトを具現化したものです。インスタンスはメモリ内に存在 し、そのプロパティと変数には値が割り当てられています。オブジェ クト インスタンスが存在するのは、アプリケーションを実行するとき だけです。 PowerBuilder 第4章 PowerBuilder のクラス定義に関する情報の取得 クラス オブジェクトの定義であり、オブジェクト インスタンスを作成するた めのソース コードを含んでいます。PowerBuilder ペインタを使用して、 オブジェクトを PBL に保存するときには、オブジェクトのクラス定義 を作成していることになります。アプリケーションを実行する場合に は、クラスは、そのクラスに基づくオブジェクト インスタンスのデー タ型となります。PowerBuilder では、 「オブジェクト」という用語は一 般にオブジェクトのインスタンスを表します。場合によっては、オブ ジェクトのクラスを表すこともあります。 システム クラス PowerBuilder によって定義されるクラスです。ペインタで定義するオ ブジェクトは、たとえ定義するオブジェクトの継承を使用するよう明 示的に選択しない場合でも、システム クラスの子孫となります。 親 現行のオブジェクトを含むオブジェクト、または継承以外の方法でオ ブジェクトに接続されているオブジェクトです。次の表に、オブジェ クトのクラスと、そのオブジェクトの親になれるクラスを示します。 表 4-1: オブジェクトのクラスとその親 オブジェクト ウィンドウ 親 そのウィンドウを開いたウィンドウ メニュー項目 ウィンドウは親を持たないこともある。親は実行 時に決定され、クラス定義の一部ではない メニューにおける前のレベルのメニュー項目 ウィンドウ上のコント ロール ユーザ オブジェクト 上のコントロール タブ ページ リストビュー項目また はツリービュー項目 ビジュアル ユーザ オ ブジェクト メニュー バー上の項目は、関連するドロップダウ ン メニュー上のすべての項目の親となる ウィンドウ ユーザ オブジェクト タブ ページが定義されているか、または開かれた タブ コントロール リストビューまたはツリービュー コントロール ユーザ オブジェクトが置かれているウィンドウま たはユーザ オブジェクト 子 別の親クラスに含まれているクラスです。ネスティッド クラスとも呼 ばれます。親と子の関係を持つオブジェクトのタイプに関しては、 「親」 を参照してください。 先祖 その定義から別のオブジェクトが継承されるクラスです。 「子孫」も参 照してください。 アプリケーション テクニック 59 クラス定義情報の概要 子孫 別のオブジェクトから継承され、そのオブジェクトの特質(プロパ ティ、関数、イベント、および変数)を内蔵するオブジェクトです。 子孫は、これらの値を使用したり、新しい定義でこれらの値に上書き したりすることができます。ペインタで定義してライブラリに格納す るオブジェクトは、すべて PowerBuilder システム クラスの子孫です。 継承階層 オブジェクトおよびそのすべての先祖です。 折りたたまれた階層 オブジェクト クラス定義のビューであり、現行レベルの継承で定義さ れている項目に加えて、オブジェクトの継承ツリー内のすべての先祖 からの情報も含んでいます。 スカラ オブジェクトでも配列でもない、単純なデータ型です。たとえば、Integer、 Boolean、Date、Any、および String です。 インスタンス変数とプ ロパティ PowerBuilder システム オブジェクトに組み込まれた属性はプロパティ と呼ばれますが、クラス定義情報ではインスタンス変数として扱われ ます。 PowerBuilder クラス定義の使用について 多くのビジネス アプリケーションでは、クラス定義情報を使用する必 要はありません。クラス定義情報を使用するコードは、クラス ライブ ラリ、アプリケーション フレームワーク、および開発支援ツールを記 述するグループによって記述されます。 アプリケーションにはクラス定義情報を使用するコードが含まれてい ないかもしれませんが、デザイン、ドキュメンテーション、およびク ラス ライブラリに使用するツールには含まれている可能性がありま す。これらのツールは、アプリケーションの解析とフィードバックの 提供ができるよう、オブジェクトのクラス定義を調べます。 シナリオ 以下の開発を行う場合には、クラス情報を使用することがあ ります。 • カスタム オブジェクト ブラウザ • アプリケーションのオブジェクトとそれらの関係を知る必要のあ るツール 目的としては、アプリケーションを文書化したり、オブジェクト を選択および操作するための論理的な方法を提供したりすること が挙げられます。 • 60 PowerBuilder オブジェクトを分解し、ユーザによるデザイン変更と 再構築を可能にする CASE ツール PowerBuilder 第4章 PowerBuilder のクラス定義に関する情報の取得 再構築を行うために、CASE ツールは、PowerBuilder オブジェクト のソース コード構文の知識とクラス定義情報を必要とします。 • オブジェクトで、インスタンス化されたオブジェクトに関連付け られたクラスを決定する必要があるクラス ライブラリ。または、 スクリプトで、使用可能なメソッドと変数を想定するためにオブ ジェクトの先祖を知る必要があるクラス ライブラリ クラス定義の調査 この節では、クラス定義オブジェクトへのアクセス方法を説明します。 さらに、クラス定義オブジェクトのプロパティを調べて、クラス、そ のスクリプト、およびその変数に関する情報を取得する方法について も説明します。 クラス定義オブジェクトの取得 クラス情報を取り扱うには、クラス定義オブジェクトが必要となりま す。クラス定義情報を含む ClassDefinition オブジェクトを取得するに は、2 つの方法があります。 アプリケーション内で インスタンス化された オブジェクトの場合 オブジェクトの ClassDefinition プロパティを使用します。 たとえば、ボタン用のスクリプトでは、次のコードは、親ウィンドウ のクラス定義を取得します。 ClassDefinition cd_windef cd_windef = Parent.ClassDefinition PBL に格納されたオ ブジェクトの場合 FindClassDefinition を呼び出します。 たとえば、ボタン用のスクリプトでは、次のコードは、アプリケーショ ンのライブラリ リスト上のライブラリから w_genapp_frame ウィンド ウのクラス定義を取得します。 ClassDefinition cd_windef cd_windef = FindClassDefinition("w_genapp_frame") アプリケーション テクニック 61 クラス定義の調査 クラスに関する詳細情報の取得 この節に含まれるコード フラグメントでは、cd_windef という ClassDefinition オブジェクトから情報を取得する方法を説明します。 cd_windef に値を割り当てる例については、 「クラス定義オブジェクト の取得」を参照してください。 ライブラリ LibraryName プロパティは、クラスのロード元となったライブラリの名 前をレポートします。 s = cd_windef.LibraryName 先祖 Ancestor プロパティは、このクラスの継承元となったクラスの名前を レポートします。すべてのオブジェクトは PowerBuilder システム オブ ジェクトから継承されるので、Ancestor プロパティは、PowerBuilder ク ラスの ClassDefinition オブジェクトを保持できます。ClassDefinition が (継承階層の最上位にある)PowerObject 用である場合には、Ancestor プロパティには NULL オブジェクト参照があります。 次の例では、cd_windef によって表されるクラスの先祖の ClassDefinition オブジェクトを取得します。 ClassDefinition cd_ancestorwindef cd_ancestorwindef = cd_windef.Ancestor 次の例では先祖の名前を取得します。なお、cd_windef に PowerObject の定義が含まれている場合には、Ancestor プロパティが NULL となる ため、このコードを実行するとエラーになります。 ls_name = cd_windef.Ancestor.Name オブジェクトが NULL でないことをテストするには、IsValid 関数を使 用します。 次の例では、w_genapp_frame ウィンドウの継承階層を逆向きにたどっ て、その先祖のリストをマルチライン エディットに表示します。 string s, lineend ClassDefinition cd lineend = "~r~n" cd = cd_windef s = "Ancestor tree:"+ lineend DO WHILE IsValid(cd) s = s + cd.Name + lineend cd = cd.Ancestor LOOP 62 PowerBuilder 第4章 PowerBuilder のクラス定義に関する情報の取得 mle_1.Text = s 次のようなリストになります。 Ancestor tree: w_genapp_frame window graphicobject powerobject 親 ClassDefinition オブジェクトの ParentClass プロパティは、オブジェク トの定義に指定された親(コンテナ)をレポートします。 ClassDefinition cd_parentwindef cd_parentwindef = cd_windef.ParentClass クラスに親がない場合には、ParentClass は NULL オブジェクト参照と なります。次の例では、ParentClass が有効なオブジェクトであること をテストしてから、その Name プロパティをチェックします。 IF IsValid(cd_windef.ParentClass) THEN ls_name = cd_windef.ParentClass.Name END IF ネスティッド クラス または子クラス ClassDefinition オブジェクトの NestedClassList 配列には、そのオブジェ クトが含んでいるクラスがあります。 NestedClassList 配列には先祖と子孫があります。 NestedClassList 配列は先祖オブジェクトのクラスを含むことができま す。たとえば、先祖ウィンドウで定義され、子孫ウィンドウで修正さ れたコマンドボタンは、子孫ウィンドウの配列に 2 度現われます(つ まり、ウィンドウとその先祖に現われます)。 次のスクリプトでは、cd_windef で表されるウィンドウに定義されたコ ントロールと構造体のリストを作成します。 string s, lineend integer li lineend = "~r~n" s = s + "Nested classes:"+ lineend FOR li = 1 to UpperBound(cd_windef.NestedClassList) s = s + cd_windef.NestedClassList[li].Name & + lineend NEXT mle_1.Text = s アプリケーション テクニック 63 クラス定義の調査 次のスクリプトでは、ClassDefinition オブジェクト cd_windef にある NestedClassList 配列を検索して、入れ子のドロップダウン リストボッ クス コントロールを見つけ出します。 integer li ClassDefinition nested_cd FOR li = 1 to UpperBound(cd_windef.NestedClassList) IF cd_windef.NestedClassList[li].DataTypeOf & = "dropdownlistbox" THEN nested_cd = cd_windef.NestedClassList[li] EXIT END IF NEXT オブジェクト参照とは異なるオブジェクト インスタンスのクラス定義 先祖やネスティッド オブジェクトなど、インスタンス化されたオブ ジェクトの ClassDefinition オブジェクトを取得しても、親クラスまた は子クラスのインスタンスへの参照は行われません。インスタンス化 されたオブジェクトへの参照を取得および格納するには、標準の PowerBuilder プログラミング テクニックを使用します。 クラスのスクリプトに関する情報の取得 この節に含まれるコード フラグメントでは、cd_windef という ClassDefinition オブジェクトからスクリプト情報を取得する方法を説明 します。 cd_windef に値を割り当てる例については、61 ページの「クラス定義オ ブジェクトの取得」を参照してください。 スクリプトのリスト ScriptList 配列には、あるクラスに定義されているすべての関数とイベ ントの ScriptDefinition オブジェクトがあります。関数が多重定義され た場合には、その関数は異なる引数リストを付けて配列内に 1 回以上 現われます。関数またはイベントが階層構造内の複数のレベルにコー ドを持っている場合には、その関数またはイベントは、コーディング されたバージョンごとに配列に現れます。 次の例では、ScriptList 配列をループして、スクリプト名のリストを作 成します。すべてのオブジェクトが PowerObject から継承されるため、 すべてのオブジェクトには、ClassName や PostEvent など、いくつかの 標準関数があります。 64 PowerBuilder 第4章 PowerBuilder のクラス定義に関する情報の取得 string s, lineend integer li ScriptDefinition sd lineend = "~r~n" FOR li = 1 to UpperBound(cd_windef.ScriptList) sd = cd_windef.ScriptList[li] s = s + sd.Name + " " + lineend NEXT mle_1.Text = s 次の例では、前の例を拡張して、ScriptDefinition オブジェクト内のさ まざまなプロパティにアクセスします。この例では、スクリプトが関 数であるかイベントであるか、ローカルでスクリプト作成されたかど うか、戻りデータ型と引数の種類、および引数の渡し方をレポートし ます。 string s, lineend integer li, lis, li_bound ScriptDefinition sd lineend = "~r~n" FOR li = 1 to UpperBound(cd_windef.ScriptList) sd = cd_windef.ScriptList[li] s = s + sd.Name + " " CHOOSE CASE sd.Kind CASE ScriptEvent! // イベントには、コードの定義場所について // 関連するプロパティが 3 つあります。 s = s + "Event, " IF sd.IsScripted = TRUE then s = s + "scripted, " END If IF sd.IsLocallyScripted = TRUE THEN s = s + "local, " END IF IF sd.IsLocallyDefined = TRUE THEN s = s + "local def," END IF CASE ScriptFunction! // 関数には、コードの定義場所について // 関連するプロパティが 1 つあります。 s = s + "Function, " IF sd.IsLocallyScripted = TRUE THEN s = s + "local, " アプリケーション テクニック 65 クラス定義の調査 END IF END CHOOSE s = s + "returns " + & sd.ReturnType.DataTypeOf + "; " s = s + "Args: " li_bound = UpperBound(sd.ArgumentList) IF li_bound = 0 THEN s = s + "None" FOR lis = 1 to li_bound CHOOSE CASE sd.ArgumentList[lis]. & CallingConvention CASE ByReferenceArgument! s = s + "REF " CASE ByValueArgument! s = s + "VAL " CASE ReadOnlyArgument! s = s + "READONLY " CASE ELSE s = s + "BUILTIN " END CHOOSE s = s + sd.ArgumentList[lis].Name + ", " NEXT s = s + lineend NEXT mle_1.text = s 継承階層内のコードの位置 IsLocallyScripted プロパティをチェックすれ ば、スクリプトが継承階層内のクラス独自のレベルにコードを持って いるかどうかを確認できます。Ancestor プロパティを介して継承階層 を逆向きにたどると、スクリプトのコードがどこにあるかを見つける ことができます。 次の例では、まず ClassDefinition cd_windef に関連付けられたクラスの スクリプトを調べます。スクリプトのコードがこのレベルに定義され ていることがわかると、そのスクリプト名はドロップダウン リスト ボックスに追加されます。また、ScriptList 配列におけるスクリプトの 位置は、インスタンス変数 ii_localscript_idx に保存されます。ドロップ ダウン リストボックスはソートされないため、リスト内の位置と配列 内の位置は同期しています。 integer li_pos, li FOR li = 1 to UpperBound(cd_windef.ScriptList) 66 PowerBuilder 第4章 PowerBuilder のクラス定義に関する情報の取得 IF cd_windef.ScriptList[li].IsLocallyScripted & = TRUE THEN li_pos = ddlb_localscripts.AddItem( & cd_windef.ScriptList[li].Name) ii_localscript_idx[li_pos] = li END IF NEXT 関数シグネチャの照合 クラスに多重定義された関数がある場合には、FindMatchingFunction を 呼び出すことによって、特定の引数リストに対して呼び出される関数 を調べることができます。 一例として、『PowerScript リファレンス』マニュアルの FindMatchingFunction を参照してください。 変数に関する情報の取得 この節に含まれるコード フラグメントでは、cd_windef という ClassDefinition オブジェクトから変数に関する情報を取得する方法を説 明します。cd_windef に値を割り当てる例については、61 ページの「ク ラス定義オブジェクトの取得」を参照してください。 クラスに関連付けられた変数は、ClassDefinition オブ ジェクトの VariableList 配列に登録されます。この配列を調べると、明 示的に定義した変数に加えて、インスタンス変数である PowerBuilder オブジェクト プロパティとネスティッド オブジェクトも見つかりま す。 変数のリスト 次の例では、VariableList 配列をループして、変数名のリストを作成し ます。最初に PowerBuilder プロパティが現われ、続いてネスティッド オブジェクト、独自のインスタンス、および共有変数が現われます。 string s, lineend integer li VariableDefinition vard lineend = "~r~n" FOR li = 1 to UpperBound(cd_windef.VariableList) vard = cd_windef.VariableList[li] s = s + vard.Name + lineend NEXT mle_1.Text = s アプリケーション テクニック 67 クラス定義の調査 変数に関する詳細 次の例では、VariableList 配列に含まれる各変数のプロパティを調べ て、そのデータ型、基数、およびグローバル、共有、またはインスタ ンスの区別をレポートします。また、インスタンス変数が先祖宣言を 上書きするかどうかもチェックします。 string s integer li VariableDefinition vard lineend = "~r~n" FOR li = 1 to UpperBound(cd_windef.VariableList) vard = cd_windef.VariableList[li] s = s + vard.Name + ", " s = s + vard.TypeInfo.DataTypeOf CHOOSE CASE vard.Cardinality.Cardinality CASE ScalarType! s = s + ", scalar" CASE UnboundedArray!, BoundedArray! s = s + ", array" END CHOOSE CHOOSE CASE vard.Kind CASE VariableGlobal! s = s + ", global" CASE VariableShared! s = s + ", shared" CASE VariableInstance! s = s + ", instance" IF vard.OverridesAncestorValue = TRUE THEN s = s + ", override" END IF END CHOOSE s = s + lineend NEXT mle_1.text = s 68 PowerBuilder 第 3 部 ユーザ インタフェース テクニック 第 3 部では、PowerBuilder によるアプリケーション開発 において、ユーザ インタフェース機能を実現するための テクニックについて説明します。MDI アプリケーション の構築、ドラッグ アンド ドロップ機能の使い方、オンラ イン ヘルプ機能などについて説明します。 第 5 章 MDI アプリケーションの構築 この章について この章では、PowerBuilder におけるマルチ ドキュメント インタ フェース(MDI)アプリケーションの構築方法について説明しま す。 内容 項目 MDI について MDI フレーム ウィンドウの作成 シートの使い方 マイクロヘルプの提供 MDI アプリケーションにおけるツールバーの使い方 クライアント領域のサイズ設定 MDI アプリケーションにおけるキーボード操作について ページ 71 74 75 77 78 84 87 MDI について マルチ ドキュメント インタフェース(MDI)は、1 つのウィンド ウ内で複数の(シートと呼ばれる)ウィンドウを開いたり、シー ト間を自由に移動したりすることができるアプリケーション形式 です。MDI アプリケーションを構築する場合は、MDI フレームと いう種類のウィンドウを定義し、そのフレーム内でほかのウィン ドウをシートとして開きます。 大規模な Windows アプリケーションのほとんどは MDI 形式で作 成されています。たとえば、PowerBuilder も MDI アプリケーショ ンです。PowerBuilder ウィンドウがフレーム、ペインタがシート です。 エンド ユーザに複数のウィンドウを開かせたり、ウィンドウ間を 簡単に移動させたりしたい場合には、MDI 形式でアプリケーショ ンを構築します。 アプリケーション テクニック 71 MDI について テンプレート アプリケーション機能の使い方 新規のアプリケーションを作成した場合には、アプリケーション ウィ ザードを選択してから、SDI または MDI アプリケーションを作成する よう選択できます。MDI アプリケーションを選択した場合には、シー トを開くまたは閉じるなどのウィンドウ操作を行う関数をすべて備え た MDI フレーム、シート マネージャ オブジェクトといくつかのシー ト、バージョン情報ダイアログボックス、メニュー、ツールバー、お よびスクリプトを含む MDI アプリケーションのシェルが生成されま す。 MDI フレーム ウィン ドウ MDI フレーム ウィンドウは、メニュー バー、フレーム、クライアン ト領域、シートなどの複数の要素から構成されるウィンドウです。通 常、MDI フレーム ウィンドウの構成要素には上記のほかにステータス バーが含まれ、この領域にはマイクロヘルプ(現在選択しているメ ニュー項目や操作についての簡単な説明)が表示されます。 フレーム MDI フレームは、MDI ウィンドウの外枠領域で、クライアント領域を 含みます。MDI フレームには、以下の 2 種類があります。 72 • 標準フレーム • カスタム フレーム PowerBuilder 第5章 MDI アプリケーションの構築 標準 MDI フレーム ウィンドウには、メニュー バーと、 通常は、マイクロヘルプが表示されるステータス バーがあります。 シートが開かれていないときは、クライアント領域は空白になります。 シートは、独自のメニュー、または MDI フレームから継承したメ ニューを持つことができます。MDI アプリケーションのメニュー バー は、常にフレーム上に表示され、シート上に表示されることはありま せん。通常、メニュー バーには、現在開かれているすべてのウィンド ウをリスト表示するメニュー項目があり、それらのウィンドウを並べ て表示、カスケード表示、または重ねて表示できます。 標準フレーム カスタム フレーム 標準フレームと同様に、カスタム フレーム ウィン ドウにも、通常、メニュー バーとステータス バーがあります。標準フ レームとカスタム フレームの違いはクライアント領域にあります。標 準フレームの場合は、クライアント領域には開いているシートだけが 表示されますが、カスタム フレームの場合は、シートだけではなくボ タンやスタティック テキストなど、ほかのオブジェクトも表示できま す。たとえば、テキストが表示されたボタンをクライアント領域に配 置できます。 クライアント領域 標準フレーム ウィンドウでは、PowerBuilder が自動的にクライアント 領域のサイズを設定し、クライアント領域内でシートが開かれ表示さ れるようになっています。クライアント領域にオブジェクトがあるカ スタム フレーム ウィンドウでは、開発者自身がクライアント領域のサ イズを設定しなければなりません。クライアント領域のサイズが正し く設定されなかった場合、シートを開いても表示されないことがあり ます。 MDI_1 コントロール 開発者が MDI フレーム ウィンドウを作成する と、フレーム ウィンドウのクライアント領域を識別するために、MDI_1 という名前のコントロールが PowerBuilder によって作成されます。標 準フレームでは PowerBuilder が自動的に MDI_1 を管理します。カスタ ム フレームでは、開発者がフレームの Resize イベントに対してスクリ プトを記述し MDI_1 のサイズを設定します。 MDI_1 に関する情報の表示 MDI_1 のプロパティと関数をブラウザで参照できます。MDI 型のウィ ンドウを作成し、ブラウザで[ウィンドウ]タブを選択します。MDI フレーム ウィンドウを選択し、ポップアップ メニューから[この下を すべて表示]を選択します。すると、MDI_1 がウィンドウ コントロー ルとして表示されるため、そのプロパティや関数などをブラウザの右 側ペインで調べることができます。 アプリケーション テクニック 73 MDI フレーム ウィンドウの作成 MDI シート シートは、MDI フレームのクライアント領域で開くことができるウィ ンドウです。MDI フレーム以外のあらゆる種類のウィンドウが MDI ア プリケーションのシートとして使用できます。シートを開くには OpenSheet 関数か OpenSheetWithParm 関数を使用します。 ツールバー MDI アプリケーションにおいて、エンド ユーザにツールバーを提供し たいことがあります。PowerBuilder では、現行メニューを基にしたツー ルバーを自動的に作成し、管理できます。また、 (通常は、ユーザ オ ブジェクトとして)独自のカスタム ツールバーを作成し、クライアン ト領域のサイズを再設定することもできます。 ツールバーの提供については、 『ユーザーズ ガイド』マニュアルの「メ ニューとツールバーでの作業」の章を参照してください。クライアン ト領域のサイズ設定の詳細については、84 ページの「クライアント領 域のサイズ設定」を参照してください。 MDI フレーム ウィンドウの作成 PowerBuilder で新規のウィンドウを作成するとき、そのデフォルトの ウィンドウの種類はメインです。 [全般]プロパティ ページで、 [mdi!] または[mdihelp!]を選択して、ウィンドウを MDI フレーム ウィンド ウに変更します。 メニューの使い方 ウィンドウの種類を MDI に変更した場合には、メニューとフレームを 関連付ける必要があります。一般に、メニューを使用すれば、フレー ム内のシートを開いたり、すべてのシートが閉じられている場合には フレームを閉じたりすることができます。 メニューとシートについて シートごとに独自のメニューを持つことができますが、必ずしもそう する必要はありません。メニューを持たないシートが開かれると、フ レームのメニューが使用されます。 74 PowerBuilder 第5章 MDI アプリケーションの構築 シートの使い方 MDI フレーム ウィンドウでは、ユーザは複数のウィンドウ(または シート)を開いて作業を行うことができます。たとえば、電子メール システムの場合、MDI フレームは複数のシートを持ち、それぞれの シートにおいて、メッセージを作成して送信したり、メッセージを読 んで返答したりすることができます。すべてのシートを同時に開くこ とができ、ユーザはシート間を移動して各シートで異なる作業を行う ことができます。 メニューとシートについて シートごとに独自のメニューを持つことができますが、必ずしもそう する必要はありません。メニューを持たないシートが開かれると、フ レームのメニューが使用されます。 シートを開く MDI フレームのクライアント領域でシートを開くには、OpenSheet 関 数を使用します。OpenSheet 関数は、メニュー項目、別のシート、また はフレーム内の任意のオブジェクトのイベントに対するスクリプトで 呼び出します。 OpenSheet 関数の詳細については、 『PowerScript リファレンス』マニュ アルを参照してください。 ウィンドウのインスタンスを開く MDI アプリケーションでは、エンド ユーザは特定の Window 型のイン スタンスを複数開くことができます。たとえば、受発注情報を管理す るアプリケーションでは、複数の異なる受注情報を同時に見ることが できます。個々の受注情報は、それぞれ個別のウィンドウ(シート) に表示されます。 アプリケーション テクニック 75 シートの使い方 クライアント領域でシートを開くと、ドロップダウン メニューの一番 下にそのウィンドウ(シート)のタイトルを表示できます。以下の図 のメニューでは、開いている 2 つのシート名が表示されています。 開いているシートの一 覧表示 v ドロップダウン メニューに開いているシート名を表示するには • 関数を呼び出した時に開いているシートを一覧したい メニュー バー項目の番号を指定します。通常、[ウィンドウ]メ ニューに開いているシート名を表示します。ファイル、編集、ウィ ンドウ、ヘルプの順番に 4 つの項目を持つメニュー バーでは、番 号 3 で[ウィンドウ]メニューを指定します。 OpenSheet 一度に 9 つ以上のシートが開いている場合、最初の 9 シートの名前は 表示されますが、10 番目以降は[その他のウィンドウ]と表示されま す。10 番目以降のシートを表示するには、 [その他のウィンドウ]を 選択します。 シートの整列 76 ArrangeSheets 関数を使用して、MDI フレーム内で開いてるシートの並 べ方を変更することができます。 PowerBuilder 第5章 MDI アプリケーションの構築 シートの並び方の変更 エンド ユーザがシートの並べ方を変更できるように、メニュー項目 (通常は[ウィンドウ]メニューのドロップダウンメニュー項目)を作 成します。エンド ユーザがメニュー項目を選択した時に、ArrangeSheets 関数を使用してシートを並べ替えます。 シートの最大表示 シートを閉じる MDI ウィンドウに開かれているシートがコントロール メニューを持 つ場合、エンド ユーザはそのシートを最大表示することができます。 アクティブなシートが最大表示された場合の動作は以下のようになり ます。 • ほかのシートがアクティブになると、そのアクティブになった シートが最大表示される。アクティブになったシートは、直前の シートの状態を継承する • 新しいシートを開くと、現行シートは直前のサイズに戻り、新し いシートはオリジナルのサイズのまま表示される アクティブなシート 〔Ctrl〕+〔F4〕を押すと、アクティブなウィンド ウ(シート)が閉じます。メニューの親ウィンドウ(シート)を閉じ るスクリプトをメニュー項目に記述することもできます。この場合、 メニューはフレームではなくシートに関連付けます。たとえば、次の ようにスクリプトを記述します。 Close(ParentWindow) すべてのシート 〔Alt〕+〔F4〕を押すと、すべてのシートを閉じてアプ リケーションを終了することができます。開いているシートを配列に 保持しておいて、ループによってすべてのシートを閉じるようにスク リプトを記述することもできます。 マイクロヘルプの提供 MDI では、フレームの底辺に位置するステータス バーにマイクロヘル プを用意して、エンド ユーザに対して情報を提供することができま す。たとえば、エンド ユーザがメニュー項目を選択するときに、ス テータス バーに選択されたメニュー項目の説明が表示されます。 開発者は、メニュー項目とカスタム フレーム ウィンドウ内のコント ロールに対してマイクロヘルプを定義できます。 アプリケーション テクニック 77 MDI アプリケーションにおけるツールバーの使い方 メニュー項目に対する マイクロヘルプ メニュー項目に関連付けるマイクロヘルプのテキストは、メニュー ペ インタの[マイクロヘルプ]テキストボックスで指定します。メニュー 項 目 の ス ク リ プ ト で マ イ ク ロ ヘ ル プ の テ キ ス ト を 変 更 す る に は、 SetMicroHelp 関数を使用します。 コントロールに対する マイクロヘルプ コントロールの Tag プロパティを使用して、カスタム フレーム ウィン ドウのコントロールにマイクロヘルプを関連付けることができます。 たとえば、クライアント領域に[印刷]ボタンを配置したとします。 こ の ボ タ ン に 対 す る マ イ ク ロ ヘ ル プ を 表 示 す る に は、ボ タ ン の GetFocus イベントに対してスクリプトを記述します。GetFocus イベン トにおいて、Tag プロパティにマイクロヘルプで表示したいテキスト を設定し、SetMicroHelp 関数を使用してそのテキストをマイクロヘルプ に表示します。たとえば、次のようになります。 cb_print.Tag=" 現行ジョブの情報を印刷します " w_genapp_frame.SetMicroHelp(This.Tag) コントロールのプロパティ シートでコントロールの Tag プロパティを 設定することもできます。 LoseFocus イベントで、マイクロヘルプの表示を元に戻します。 w_genapp_frame.SetMicroHelp("Ready") MDI アプリケーションにおけるツールバーの使い方 この節では、ツールバーの動作のカスタマイズ、ツールバーの設定の 保存と復元を行うためのテクニックについて説明します。メニューと ツールバー を定義して使用する方法については、 『ユーザーズ ガイド』 マニュアルを参照してください。 ツールバーの動作のカスタマイズ ツールバー ボタンの 使用不可 ツールバー ボタンを使用不可にするには、そのボタンに関連付けられ ているメニュー項目を使用不可にする必要があります。メニュー項目 を使用不可にすると、自動的にツールバー ボタンも使用不可になりま す。 メニュー項目を使用不可にするには、メニュー項目の Enabled プロパ ティに FALSE を設定します。 m_test.m_file.m_new.Enabled = FALSE 78 PowerBuilder 第5章 ツールバー ボタンの 非表示 MDI アプリケーションの構築 メニュー項目を非表示にするには、メニュー項目の Visible プロパティ に FALSE を設定します。 m_test.m_file.m_open.Visible = FALSE メニュー項目を非表示にしても、そのツールバー ボタンは非表示また は使用不可になりません。ツールバー ボタンを非表示にするには、メ ニュー項目の ToolbarItemVisible プロパティに FALSE を設定する必要 があります。 m_test.m_file.m_open.ToolBarItemVisible = FALSE ツールバー ボタンを非表示にしても、ドロップダウンまたはカスケー ドのメニュー項目における下位レベルのツールバー ボタンは、非表示 または使用不可にはなりません。下位レベルのボタンは、個別に非表 示または使用不可にする必要があります。 ドロップダウン ツー ルバーにおける現行の ボタンの設定 エンド ユーザがドロップダウン ツールバーのツールバー ボタンをク リックすると、PowerBuilder は選択されたボタンを現行のボタンとし ます。このようにすれば、エンド ユーザが繰り返しそのボタンを使用 す る の が 容 易 に な り ま す。さ ら に、MenuCascade オ ブ ジ ェ ク ト の CurrentItem プロパティを設定することによって、スクリプトで特定の ボタンを現行のボタンとすることができます。たとえば、[ファイル] メニューの[新規作成]メニュー項目に対応するツールバー ボタンを 現行のボタンとして設定するには、以下のスクリプトを実行します。 m_test.m_file.currentitem = m_test.m_file.m_new このスクリプトを正常に実行するためには、メニュー ペインタで、 [ファイル]メニューのオブジェクト データ型として MenuCascade を 指定する必要があります。 ツールバーの移動の確 認 ツールバーが MDI フレーム ウィンドウで移動すると、ウィンドウの ToolBarMoved イベントが起動されます。このイベントに対するスクリ プトでは、どのツールバーが移動したかを確認して、処理を実行する こ と が で き ま す。フ レ ー ム バ ー ま た は シ ー ト バ ー を 移 動 す る と、 ToolbarMoved イベントが起動されて、Message.WordParm プロパティと Message.LongParm プロパティにどのツールバーが移動したかを示す値 が設定されます。 アプリケーション テクニック 79 MDI アプリケーションにおけるツールバーの使い方 表 5-1: Message.WordParm プロパティと Message.LongParm プロパ ティの値 プロパティ Message.WordParm Message.LongParm 値 0 1 0 1 2 3 4 意味 フレームバーが移動された シートバーが移動された 左へ移動された 上へ移動された 右へ移動された 下へ移動された 浮動に設定された ツールバー設定の保存と復元 ツールバーの設定に関する情報を検索したり更新したりする関数を使 用すれば、現行のツールバーの設定の保存と復元ができます。 GetToolbar 関数と GetToolbarPos 関数を使用すれば、現行のツールバー の設定を取得できます。SetToolbar 関数と SetToolbarPos 関数を使用す れば、ツールバーの設定を変更できます。ツールバーの表示位置が浮 動か固定かによって、GetToolbarPos 関数と SetToolbarPos 関数は、使用 する構文が異なります。 浮動ツールバー 浮動ツールバーの表示位置は、その x 座標と y 座標によって決まりま す。浮動ツールバーのサイズは、その幅と高さによって決まります。 GetToolbarPos 関数と SetToolbarPos 関数を使用して、浮動ツールバーの 位置の取得と設定を行う場合は、x 座標、y 座標、幅、高さの引数が必 要です。 固定ツールバー 固定ツールバーの表示位置は、配置された行とその行の開始位置から のオフセットによって決まります。上端または下端に配置されたツー ルバーの場合、オフセットは左端から算出されます。左端または右端 に配置されたツールバーの場合、オフセットは上端から算出されます。 デフォルトでは、ツールバーが配置される行は、ツールバーのインデッ クスと同じ位置になります。ウィンドウと異なる枠線でツールバーを 配置する場合、その配置する位置によって、行は変更されることがあ ります。 GetToolbarPos 関数と SetToolbarPos 関数を使用して、固定ツールバーの 位置の取得と設定を行う場合は、行とオフセットの引数が必要です。 80 PowerBuilder 第5章 例 MDI アプリケーションの構築 以下の例では、ツールバーの設定を管理するカスタム ユーザ オブジェ クトの使用方法を示します。ユーザ オブジェクトには、2 つの関数が あります。1 つは現行の設定を保存するための関数、もう 1 つは後で 設定を復元するための関数です。ツールバーの設定の保存と復元をす るための処理は、ウィンドウではなくユーザ オブジェクトで行うの で、このユーザ オブジェクトを使用すればどのウィンドウにおいても 簡単にツールバーの設定の保存と復元ができます。 例では、固定ツールバーと浮動ツールバーの両方をサポートします。 ウィンドウの Open イベントに対するスクリプト ウィンドウが開かれる と、初期設定ファイル toolbar.ini からツールバーの設定を復元します。 設定を復元するため、カスタム ユーザ オブジェクト u_toolbar のインス タンスを作成し、ユーザ定義関数 Restore を呼び出します。 // ツールバー NVO を作成します。 u_toolbar = create u_toolbar // ツールバーの表示位置を復元します。 u_toolbar.Restore(this,"toolbar.ini", this.ClassName()) ウィンドウの Close イベントに対するスクリプト ウ ィ ン ド ウ が 閉 じ る と、ユーザ定義関数 Save を呼び出して、ツールバーの設定を保存しま す。設定を保存した後は、ユーザ オブジェクトのインスタンスを破棄 します。 // ツールバーの設定を保存します。 stateu_toolbar.Save(this, "toolbar.ini", ClassName()) // NVOdestroy u_toolber ツールバーを破棄します。 Save 関数のスクリプト Save 関数には、3 つの引数があります。 • Win – ウィンドウの参照 • File – 設定を保存するファイルの名前 • Section – 設定を保存するファイル内のセクション名 Save 関数では、GetToolbar 関数と GetToolbarPos 関数を使用して、現行 のツールバーの設定を取得します。初期設定ファイルに設定を記述す るには SetProfileString 関数を使用します。 Save 関数は、1 つのメニューにおける複数のツールバーを処理できま す。そのため、ツールバーのインデックスを使用して、各ツールバー の情報を管理します。 // ウィンドウのツールバーの設定を保存します。 integer index, row, offset, x, y, w, h boolean visible string visstring, alignstring, title toolbaralignment alignmentFOR index = 1 to 16 アプリケーション テクニック 81 MDI アプリケーションにおけるツールバーの使い方 // ツールバーの属性を取得します。 IF win.GetToolbar(index, visible, alignment, & title)= 1 THEN // 変数 visible の値を String 型に変換します。 CHOOSE CASE visible CASE true visstring = "true" CASE false visstring = "false" END CHOOSE // 変数 alignment の値を String 型に変換します。 CHOOSE CASE alignment CASE AlignAtLeft! alignstring = "left" CASE AlignAtTop! alignstring = "top" CASE AlignAtRight! alignstring = "right" CASE AlignAtBottom! alignstring = "bottom" CASE Floating! alignstring = "floating" END CHOOSE // 基本的な属性を保存します。 SetProfileString(file, section + & String(index), "visible", visstring) SetProfileString(file, section + & String(index), "alignment", alignstring) SetProfileString(file, section + & String(index), "title", title) // 固定ツールバーの表示位置を保存します。 win.GetToolbarPos(index, row, offset) SetProfileString(file, section + & String(index), "row", String(row)) SetProfileString(file, section + & String(index), "offset", String(offset)) // 浮動ツールバーの表示位置を保存します。 win.GetToolbarPos(index, x, y, w, h) SetProfileString(file, section + & String(index), "x", String(x)) SetProfileString(file, section + & String(index), "y", String(y)) SetProfileString(file, section + & 82 PowerBuilder 第5章 MDI アプリケーションの構築 String(index), "w", String(w)) SetProfileString(file, section + & String(index), "h", String(h)) END IF NEXT Restore 関数のスクリプト Restore 関数にも、Save 関数と同じ 3 つの引 数があります。Restore 関数は、初期設定ファイルからツールバーの設 定を取得するため、ProfileString 関数を使用します。設定を取得したら、 SetToolbar 関数と SetToolbarPos 関数を使用して、ツールバーの設定を 復元します。 Save 関数と同じように、Restore 関数も 1 つのメニューにおける複数の ツールバーを処理できます。そのため、ツールバーのインデックスを 使用して、各ツールバーの情報を管理します。 // ウィンドウのツールバーの設定を復元します。 integer index, row, offset, x, y, w, h boolean visible string visstring, alignstring, title toolbaralignment alignment FOR index = 1 to 16 // ツールバーの属性を取得します。 IF win.GetToolbar(index, visible, alignment, & title)= 1 THEN // .ini ファイルから // ツールバーの設定情報を取得します。 visstring = ProfileString(file, section + & String(index), "visible", "") IF visstring > "" THEN // ツールバーのすべての設定情報を取得します。 alignstring = ProfileString(file, section + & String(index), "alignment", "left") title = ProfileString(file, section + & String(index), "title", "(Untitled)") row = Integer(ProfileString(file, section + & String(index), "row", "1")) offset = Integer(ProfileString(file, & section + String(index), "offset", "0")) x = Integer(ProfileString(file, section + & String(index), "x", "0")) y = Integer(ProfileString(file, section + & String(index), "y", "0")) w = Integer(ProfileString(file, section + & String(index), "w", "0")) アプリケーション テクニック 83 クライアント領域のサイズ設定 h = Integer(ProfileString(file, section + String(index), "h", "0")) & // 変数 visstring の値を Boolean 型に変換します。 CHOOSE CASE visstring CASE "true" visible = true CASE "false" visible = false END CHOOSE // 変数 Alignstring の値を // toolbaralignment カタログ データ型に変換します。 CHOOSE CASE alignstring CASE "left" alignment = AlignAtLeft! CASE "top" alignment = AlignAtTop! CASE "right" alignment = AlignAtRight! CASE "bottom" alignment = AlignAtBottom! CASE "floating" alignment = Floating! END CHOOSE // 新しい表示位置を設定します。 win.SetToolbar(index, visible, alignment, title) win.SetToolbarPos(index, row, offset, false) win.SetToolbarPos(index, x, y, w, h) END IF END IF NEXT クライアント領域のサイズ設定 PowerBuilder は、自動的に標準 MDI フレーム ウィンドウのクライアン ト領域のサイズを設定し、クライアント領域内にシートを開いて表示 します。また、前節でも説明したように、メニュー項目に対してツー ルバーを定義した場合も、クライアント領域のサイズは自動的に再設 定されます。 84 PowerBuilder 第5章 MDI アプリケーションの構築 カスタム MDI フレーム ウィンドウでは、クライアント領域にはシー トが開かれるほかにコントロールが配置されますが、PowerBuilder は クライアント領域のサイズを設定しないので、開発者がサイズ設定を 行わなければなりません。クライアント領域のサイズが適切に設定さ れていないと、シートが開いても表示されなかったり、クライアント 領域からはみ出した部分が切り取られて表示されたりします。 カスタム MDI フレーム ウィンドウでツールバーを使用する場合は、ク ライアント領域に配置したコントロールが、クライアント領域の境界 から十分に離れていることを確認してください。ウィンドウを表示し たときに、ツールバーがコントロールの上に表示されないようにして ください。 表示されないシートがある場合に現われるスクロールバー ウィンドウを定義する際に HScrollBar プロパティと VScrollBar プロパ ティを設定すると、表示されないシートがある場合にスクロールバー が現れます。これはシート内のすべての情報が表示されるという意味 ではありません。エンド ユーザは、スクロールバーをスクロールして 情報を表示できます。 カスタム MDI フレーム ウィンドウを作成すると、MDI_1 という名前の コントロールが作成され、フレームのクライアント領域を識別するた めに使用されます。AutoScript を有効にした場合には、フレームのスク リプトを作成すると、オートスクリプト ポップアップ ウィンドウのオ ブジェクト リストに MDI_1 が表示されます。 v フレームが開かれるとき、またはフレームのサイズが変更されるときに、ク ライアント領域のサイズを設定または変更するには • アプリケーション テクニック フレームの Open または Resize イベントに対してスクリプトを記 述します。 • フレームのサイズを決定する • クライアント領域(MDI_1)のサイズを適切に設定する 85 クライアント領域のサイズ設定 たとえば、以下のスクリプトは、フレーム w_genapp_frame のクライア ント領域のサイズを設定します。このフレームでは、メニューのすぐ 下にボタンが配置され、フレームの一番下にはマイクロヘルプが表示 されるものとします。 int li_width, li_height // フレームにおけるワークスペースの幅と高さを取得します。 // // MDI ツールバーを表示する場合は、 // WorkSpaceWidth 関数と WorkSpaceHeight 関数が返した // ワークスペースのサイズからツールバーの // サイズ分を差し引くことに注意してください。 // この調整方法については、後で説明します。 // li_width = w_genapp_frame.WorkSpaceWidth() li_height = w_genapp_frame.WorkSpaceHeight() // 次に、以下の処理を行うことによって、 // クライアント領域の高さを決めます。 // // 1) WorkSpaceHeight 値からコントロールの高さと // コントロールの y 座標を減算します。 // つまり、この値は、ツールバーがない場合の // フレームにおけるワークスペースの上端と // コントロールの上端との距離 // になります。 86 PowerBuilder 第5章 MDI アプリケーションの構築 // // 2) 次の減算を行います。 フレームのマイクロヘルプ バーが // ある場合は、その高さを減算します。 // // 3) 次の加算を行います。表示するツールバーの高さを加算します。 // 最初に WorkSpaceHeight 関数が返した値からは、 // ツールバーの高さが差し引かれているからです。 // 最終的にツールバーの高さは、WorkspaceY 関数が返す // Y 座標と同じになります。 li_height = li_height - (cb_print.y + cb_print.height) li_height = li_height - MDI_1.MicroHelpHeight li_height = li_height + WorkspaceY() // 次に、ワーク スペースのコントロールの真下からクライアント領 // 域が始まるように移動します。 mdi_1.Move (WorkspaceX (), cb_print.y + cb_print.height) & // 最後に、以前に計算した幅と高さに基づいて、 // クライアント領域のサイズを変更します。 mdi_1.Resize (li_width, li_height) MicroHelpHeight プロパティについて MicroHelpHeight プロパティは MDI_1 のプロパティで、ウィンドウの種 類に MDI フレームを選択したときに設定されます。MDI フレームを選 択した場合、マイクロヘルプは表示されず MicroHelpHeight プロパティ は 0 になります。マイクロヘルプ付き MDI フレームを選択した場合、 MicroHelpHeight プロパティの値はマイクロヘルプの高さになります。 MDI アプリケーションにおけるキーボード操作について PowerBuilder MDI アプリケーションでは、矢印キーとショートカット キーが自動的にサポートされます。 アプリケーション テクニック 87 MDI アプリケーションにおけるキーボード操作について 矢印キー MDI フレームでは、エンド ユーザが矢印キーを押したときのポインタ の動きは、キーが押されたときにフォーカスされていた場所によって 異なります。 表 5-2: 矢印キーによるフォーカスの移動 キー 〔←〕 フォーカスの位置 メニュー バー 〔→〕 最初(左端)のメニュー バー 項目 アクティブ シートのコント ロール メニュー フレームのコントロール メ ニュー メニュー バー 最後(右端)のメニュー バー 〔↓〕 〔↑〕 88 フレームのコントロール メ ニュー アクティブ シートのコント ロール メニュー ドロップダウン メニューまた はカスケード メニュー ドロップダウン メニューやカ スケード メニューの最後のメ ニュー項目 ドロップダウン メニューまた はカスケード メニュー ドロップダウン メニューやカ スケード メニューの最初のメ ニュー項目 フォーカスの移動先 フォーカスがあるメニュー項目 の左側のメニュー項目 アクティブ シートのコントロー ル メニュー フレームのコントロール メ ニュー 最後(右端)のメニュー バー フォーカスがあるメニュー項目 の右側のメニュー項目 フレームのコントロール メ ニュー アクティブ シートのコントロー ル メニュー メニュー バーの最初(左端)の 項目 現行の項目の下位のメニュー項 目 そのメニューの最初の項目 現行の項目の上位のメニュー項 目 そのメニューの最後の項目 PowerBuilder 第5章 ショートカット キー MDI アプリケーションの構築 PowerBuilder では、すべての MDI フレームに対して以下の 2 つの ショートカット キーが割り当てられています。 表 5-3: MDI フレームのショートカット キー キー 〔Ctrl〕+〔F4〕 〔Ctrl〕+〔F6〕 アプリケーション テクニック 機能 アクティブなシートを閉じ、次のシートをアクティブにし ます。次にアクティブになるのは、閉じられたシートの直 前にアクティブになっていたシートです。 直前にアクティブになっていたシートをアクティブにし ます。 89 MDI アプリケーションにおけるキーボード操作について 90 PowerBuilder 第 6 章 ウィンドウ インスタンスの管理 この章について この章では、同じウィンドウの複数のウィンドウ インスタンスを 管理する方法について説明します。 内容 項目 ウィンドウ インスタンスについて ウィンドウ インスタンスの宣言 ウィンドウ配列の使い方 子孫オブジェクトのエンティティの参照 ページ 91 93 94 97 ウィンドウ インスタンスについて アプリケーションを構築するとき、構造は同じで、データ値が異 なるウィンドウをいくつか表示したいことがあります。 たとえば、ウィンドウ w_employee の複数のコピー(インスタンス) を開いて、同時に複数の従業員情報を表示するという場合です。 これには、まず、PowerBuilder がどのようにウィンドウ定義を格 納するかを理解する必要があります。 PowerBuilder によるウィ ンドウ定義の格納方法 ウィンドウを保存するとき、PowerBuilder は、以下の 2 つのエン ティティをライブラリに生成します。 • 新しいデータ型 データ型名はウィンドウ名と同じ たとえば、w_employee という名前のウィンドウを保存すると、 PowerBuilder は内部的に w_employee という名前のデータ型を 作成します。 • 新しいデータ型のグローバル変数 グローバル変数名はウィンド ウ名と同じ たとえば、ウィンドウ w_employee を保存すると、w_employee 型 で w_employee という名前のグローバル変数も暗黙的に定義さ れます。 アプリケーション テクニック 91 ウィンドウ インスタンスについて 次のように宣言するのと同じです。 図 6-1: 変数宣言 データ型や変数の名前を複製することにより、PowerBuilder の新規 ユーザは、データ型のコンセプトを気にせずに、変数を使用してウィ ンドウに簡単にアクセスできます。 ウィンドウを開くとき に行われる処理 ウィンドウを開くには、次のように Open 関数を使用します。 Open(w_employee) これによって実際は、データ型 w_employee のインスタンスが作成さ れ、グローバル変数 w_employee への参照が割り当てられます。 すでに開いているウィンドウを開くと、PowerBuilder は単に既存の ウィンドウをアクティブにするだけで、新たにウィンドウを開きませ ん。たとえば、次のスクリプトをコマンドボタン コントロールの Clicked イベントに記述したとします。 Open(w_employee) このボタンを何回クリックしても、ウィンドウ w_employee は 1 つしか 開きません。このウィンドウは、グローバル変数 w_employee にポイン トされます。 ウィンドウの複数のインスタンスを開くには、そのウィンドウの種類 をデータ型として変数を宣言します。 92 PowerBuilder 第6章 ウィンドウ インスタンスの管理 ウィンドウ インスタンスの宣言 ウィンドウは、実際はデータ型であるため、Integer 型や String 型など の変数を宣言するのと同様に、ウィンドウの種類をデータ型として変 数を宣言できます。そうすれば、スクリプトでそれらの変数を参照で きます。 例 w_employee mywin w_employee 型の変数 mywin を宣言します。 変数の制限 ウィンドウ インスタンスを宣言すると、ほかのウィンドウから参照で きません。たとえば、3 つのウィンドウが開いている場合、2 番目と 3 番目のウィンドウから 1 番目のウィンドウを明示的に参照することが できません。参照変数を使用して開いたウィンドウのグローバル ハン ドルがありません。スクリプトを使用してウィンドウ インスタンスへ の参照を維持する方法については、94 ページの「ウィンドウ配列の使 い方」を参照してください。 インスタンスを開く ウィンドウ インスタンスを開くには、次のように、Open 関数でウィン ドウ変数を参照します。 w_employee mywin Open(mywin) この場合、Open 関数は、変数 mywin のデータ型を w_employee として ウィンドウ w_employee のインスタンスを作成し、変数 mywin への参照 を割り当てます。 このスクリプトをコマンドボタンの Clicked イベントに記述すると、ボ タンがクリックされるたびに、ウィンドウ w_employee の新しいインス タンスが作成されます。つまり、ボタンがクリックされるたびに、新 しいウィンドウが開きます。 したがって、ウィンドウ名をデータ型として変数を作成することで、 複数のウィンドウ インスタンスを開くことができます。これは簡単な 方法です。PowerBuilder は、ウィンドウを自動的に管理します。たと えば、開発者がウィンドウを閉じると、自動的にメモリを解放します。 インスタンスを閉じる 一般的に、ウィンドウのインスタンスを閉じるには、コマンドボタン の Clicked イベントに次のスクリプトを記述してウィンドウ内に配置 します。 Close(Parent) アプリケーション テクニック 93 ウィンドウ配列の使い方 このスクリプトは、コマンドボタンの親、つまりコマンドボタンが配 置されているウィンドウを閉じます。したがって、このスクリプトを 記 述 し た コ マ ン ド ボ タ ン を ウ ィ ン ド ウ w_employee に 配 置 す れ ば、 w_employee の 現 行 の ウ ィ ン ド ウ イ ン ス タ ン ス が 閉 じ ら れ ま す。 w_employee の mywin インスタンスにある CommandButton をクリック すると、mywin が閉じられます。 ウィンドウ配列の使い方 ウィンドウ配列を作成するには、ウィンドウのデータ型で配列を宣言 します。たとえば、次のステートメントでは、ウィンドウ w_employee のインスタンスを 5 つ含んだ配列 myarray を宣言します。 w_employee myarray[5] ウィンドウをいくつ開くのかコンパイル時にわからない場合は、可変 長のウィンドウ配列を作成できます。 配列を使用してインス タンスを開く 配列内のウィンドウのインスタンスを開くには、Open 関数に引数とし て配列のインデックスを渡します。上記の宣言に続き、以下のステー トメントでは、ウィンドウ w_employee の 1 番目と 2 番目のインスタン スを開きます。 Open(myarray[1]) Open(myarray[2]) // ウィンドウ w_employee の // 1 番目のインスタンスを開きます。 // 2 番目のインスタンスを開きます。 最初に開いたインスタンスの移動 上記のステートメントでは、1 番目のインスタンスと同じ位置に 2 番 目のインスタンスが開きます。2 番目の Open 関数を呼び出す前にスク リプトで Move 関数を呼び出して、最初に開いたインスタンスを別の位 置に移動する必要があります。 配列の操作 ウィンドウ配列を使用すると、配列のインデックスを指定して特定の ウィンドウ インスタンスを操作できます。たとえば、次のステートメ ントは、配列内の 2 番目のウィンドウを非表示にします。 myarray[2].Hide() また、次のように、配列のインデックスを使用してウィンドウ内のコ ントロールを参照できます。 myarray[2].st_count.text = "2" 94 PowerBuilder 第6章 ウィンドウ インスタンスの管理 複数のウィンドウを開く 多数のウィンドウ インスタンスを開いたり、閉じたりする場合は、メ イン ウィンドウのスクリプトに FOR...NEXT 文を記述してウィンドウ インスタンスを開いたり、閉じたりできます。たとえば、次のように スクリプトを記述します。 w_employee myarray[5] for i = 1 to 5 Open(myarray[i]) next 型が混在する配列の作 成 前述の例では、配列内のウィンドウはすべて同じ型でしたが、型が混 在する配列を作成することもできます。この方法を習得する前に、ま ず、ウィンドウの継承機能について詳しく知っておく必要があります。 定義するウィンドウは、実際はすべて、組み込みデータ型 window の 子孫ウィンドウです。 ゼロから定義されたウィンドウ w_employee と、w_employee から継承さ れたウィンドウ w_customer がある場合、継承階層は次のようになりま す。 図 6-2: ウィンドウの継承階層 window という名前のシステム定義オブジェクトは、PowerBuilder で定 義されるすべてのウィンドウの先祖オブジェクトです。組み込みオブ ジェクト window には、すべてのウィンドウで使用される、X、Y、タ イトルなどのプロパティが定義されています。 ユーザ定義ウィンドウはすべて window の子孫ウィンドウなので、 window 型の変数を定義すればアプリケーション内でどのような種類 のウィンドウでも参照できます。 次のスクリプトでは、3 つのウィンドウを含む配列 newarray を定義し ます。ユーザ定義ウィンドウはすべてデータ型 window から派生して いるので、配列はどのようなウィンドウでも参照できます。 アプリケーション テクニック 95 ウィンドウ配列の使い方 window newarray[3] string win[3] int iwin[1] = "w_employee" win[2] = "w_customer" win[3] = "w_sales" for i = 1 to 3 Open(newarray[i], win[i]) next このコードでは、次に示す書式の Open 関数を使用します。 Open ( windowVariable, windowType ) windowVariable は window 型の変数(子孫ウィンドウ)、windowType は ウィンドウの種類を指定する文字列です。 上記のスクリプトでは、ウィンドウ w_employee、w_customer、および w_sales のウィンドウ インスタンスを開きます。 配列の使い方と参照変 数の使い方 表 6-1 に、ウィンドウ インスタンスを操作するために参照変数を使用 する場合と配列を使用する場合を示します。 表 6-1: 配列と参照変数 項目 配列 長所 特定のウィンドウ イ ンスタンスが参照で きる 参照変数 使い方が簡単。 PowerBuilder が自動 的に処理を行う 短所 使い方が複雑。たとえば、配列内の 2 番 目のウィンドウを閉じた後で新しいウィ ンドウを開こうとする場合、 (必要以上に メモリを使用するが)配列の最後にウィ ンドウを追加するか、または既存の配列 内に新しいウィンドウ用の空スロットを 探すかどうかのスクリプトを記述する必 要がある 参照変数を使用して作成したウィンドウ の特定のインスタンスを操作できない w_employee を使用して、個々の従業員のデータを提供または修正する ものと仮定します。w_employee の 2 番目のインスタンスが同じ従業員 を開くことを禁止したり、w_employee のインスタンスをどの従業員に 対して開くかを決定したりすることもできます。このような管理を行 うには、配列を使用する必要があります。特定のウィンドウ インスタ ンスを管理する必要がない場合には、かわりに使いやすい参照変数を 使用してください。 96 PowerBuilder 第6章 ウィンドウ インスタンスの管理 子孫オブジェクトのエンティティの参照 データ型が window などオブジェクトの一種である変数を宣言すると、 その変数を使用して、子孫オブジェクトではなく先祖オブジェクトに 定義されているエンティティを参照できます。しかし、次の場合を考 えてみましょう。 w_customer mycust Open(mycust) // 次のステートメントは、ウィンドウ w_customer に // コントロール st_name があれば有効です。 mycust.st_name.text = "Joe" mycust は w_customer 型の変数として宣言されています。つまり、mycust はウィンドウ w_customer です。ウィンドウ w_customer に st_name とい う名前のスタティック テキスト コントロールが存在すれば、上記の最 後のステートメントは有効です。 しかし、次の場合を考えてみましょう。 window newwin string winname = "w_customer" Open(newwin, winname) // window 型のオブジェクトにスタティック テキスト コントロール // st_name がないので無効です。 newwin.st_name.text = "Joe" こ の 場 合、newwin は window 型 の 変 数 と し て 定 義 さ れ て い ま す。 PowerBuilder は、コンパイル時に厳密なデータ型チェックを行うため、 上記のステートメントは拒否されます。つまり、変数のコンパイル時 データ型に明示的に含まれていないオブジェクトのエンティティを参 照することはできません。 window 型のオブジェクトには st_name というコントロールは含まれて いないので、このステートメントは無効になります。下記のいずれか を行う必要があります。 • 次のように、newwin の宣言を、w_customer に、またはコントロー ル st_name を含む先祖ウィンドウに変更します。 w_customer newwin string winname = "w_customer" Open(newwin, winname) // 今度は有効です。 newwin.st_name.text = "Joe" アプリケーション テクニック 97 子孫オブジェクトのエンティティの参照 • 次のように、w_customer 型の別の変数を定義し、その変数を newwin に代入します。 window newwin w_customer custwin string winname = "w_customer" Open(newwin, winname) custwin = newwin // 今度は有効です。 custwin.st_name.text = "Joe" 98 PowerBuilder 第 7 章 ウィンドウにおけるタブ コント ロールの使い方 この章について この章では、アプリケーションでのタブ コントロールの使い方に ついて説明します。 内容 項目 タブ コントロールについて タブ ページの定義と管理 タブ コントロールのカスタマイズ スクリプトにおけるタブ コントロールの使い方 ページ 99 100 104 107 タブ コントロールについて タブ コントロールとは、ほかのコントロールを表示するタブ ペー ジのコンテナです。1 つのタブ ページは、タブ コントロールの表 示域を満たします。また、タブ ページには、インデックス カード を分割するようなタブがあります。ページを移動するには、タブ をクリックします。 アプリケーション テクニック 99 タブ ページの定義と管理 タブ コントロールを使用すれば、たくさんの情報を整理して、表示で きるようになります。ほかのコントロールと同様に、タブ コントロー ルの追加、サイズの変更、移動ができます。PowerBuilder の『ユーザー ズ ガイド』マニュアルでは、ウィンドウやカスタム ビジュアル ユー ザ オブジェクトにコントロールを追加する方法について説明してい ます。 タブ関連の用語 次の定義を知っておく必要があります。 タブ コントロール ウィンドウまたはユーザ オブジェクトの中に配置 する、タブ ページを持つコントロールです。タブ コントロールは、タ ブとタブ ページで構成されます。残りのスペースはタブ ページそのも のが占めています。 タブ ページはユーザ オブジェクトです。タブ ページ内 に、ほかのコントロールを配置することができます。タブ コントロー ルの中にあるすべてのタブ ページは、タブ コントロールと同じエリア を占めます。したがって、タブ ページは一度に 1 つのタブ ページしか 表示できません。アクティブなタブ ページが、ほかのタブ ページを覆 い隠してしまいます。 タブ ページ ペインタまたは実行時に、タブ コントロールの中にタブ ページを定義 できます。また、タブ ページをユーザ オブジェクトの中に定義して、 ペインタで、あるいは実行中にそのユーザ オブジェクトをタブ コント ロールに挿入することもできます。 タブ タブ ページのビジュアルなハンドルです。タブは、タブ ページ のラベルを表示します。タブ ページが表示されていない場合は、タブ をクリックして、そのタブ ページを前面に持ってきてアクティブにし ます。 タブ ページの定義と管理 タブ ページは、ユーザ オブジェクトです。 2 つの方法 タブ ページを定義するには、いくつかの方法があります。定義は、以 下のように行います。 • 100 埋め込みタブ ページ ペインタで、タブ コントロールにタブ ページ を挿入して、そのページにコントロールを追加します。埋め込み タブ ページは、UserObject クラスですが、再利用できません。 PowerBuilder 第7章 • ウィンドウにおけるタブ コントロールの使い方 ユーザ オブジェクト ペインタで、カ スタム ビジュアル ユーザ オブジェクトを作成して、タブ ページ に表示されるコントロールを追加します。ユーザ オブジェクト ペ インタかスクリプトの中で OpenTab 関数を呼び出して、タブ コン トロール内のタブ ページとしてユーザ オブジェクトを使用でき ます。独立したユーザ オブジェクトとして定義されたタブ ページ は、再利用できます。 独立したユーザ オブジェクト これら 2 つの方法は、同時に使用できます。つまり、1 つのタブ コン トロールに、埋め込みタブ ページと独立したユーザ オブジェクトの両 方を挿入できます。 新しいタブ コントロールを作成すると、埋め込みタブ ページが自動的 に 1 つ作成されます。そのタブ ページを使用することも、削除するこ ともできます。 タブ ページの作成方 法 v v v タブ コントロール内に新しいタブ ページを作成するには 1 タブ コントロール内のタブエリアを右クリックします。タブ ペー ジをクリックしてはいけません。 2 ポップアップ メニューから[タブ ページの挿入]を選択します。 3 新しいタブ ページにコントロールを追加します。 タブ コントロールの独立したタブ ページを定義するには 1 新規作成 ダイアログボックスで、[PB オブジェクト]タブの[カ スタム ビジュアル]を選択します。 2 ユーザ オブジェクト ペインタで、使用するタブ コントロールの表 示領域のサイズに合わせて、ユーザ オブジェクトのサイズを設定 します。 3 タブ ページに表示されるコントロールをユーザ オブジェクトに 追加して、イベントに対するスクリプトを記述します。 4 ユーザ オブジェクトのプロパティ シートで、[タブ ページ]タブ をクリックして、タブ ページで使用される情報を設定します。 タブ コントロールに、タブ ページとしてユーザ オブジェクトを追加するには 1 タブ コントロール内のタブエリアを右クリックします。タブ ペー ジをクリックしてはいけません。 2 ポップアップ メニューから[ユーザ オブジェクトの挿入]を選択 します。 3 ユーザ オブジェクトを選択します。 アプリケーション テクニック 101 タブ ページの定義と管理 タブ ページは、選択したユーザ オブジェクトから継承されます。 タブ コントロール内のタブ ページを定義するのと同じように、継 承されたユーザ オブジェクトのタブ ページにプロパティを設定 し、スクリプトを記述できます。 タブ コントロール内のユーザ オブジェクトに配置されたコントロールの 編集 タブ コントロール内にあるユーザ オブジェクトの内容は編集で きません。ユーザ オブジェクト上のコントロールを編集したり、 スクリプトを記述したりする場合は、ウィンドウまたはタブ コン トロールがあるユーザ オブジェクトを閉じてから、ユーザ オブ ジェクト ペインタに戻って変更を行います 。 タブ ページの管理 タブ コントロール上で、タブ ページの表示、表示順序の変更、削除が できます。 v 別のタブ ページを表示するには • タブ ページのタブをクリックします。 タブ ページは前面に表示され、アクティブなタブ ページとなりま す。タブは、設定したタブ順序に応じて再配置されます。 v v 102 タブ コントロール内のタブの表示順序を変更するには 1 タブ コントロールのプロパティ シートの[タブ順序]タブをクリッ クします。 2 表示したい位置にタブ ページの名前をドラッグします。 タブ コントロールからタブ ページを削除するには 1 タブ ページのタブをクリックします。 2 タブ ページを右クリックし、ポップアップ メニューから[切り取 り]または[削除]を選択します。 PowerBuilder 第7章 ウィンドウにおけるタブ コントロールの使い方 タブ コントロールとタブ ページの選択 タブ コントロール内のさまざまな領域をクリックしてみると、プロパ ティ ビューが変化して、タブ コントロール自身のプロパティ、タブ ページ、またはタブ ページ上のコントロールが表示されることがわか ります。ポップアップ メニューから[切り取り]などの項目を選択す る前に、正しいオブジェクトが選択されていることを確認してくださ い。 タブ コントロールのタブ領域のどこかをクリックすると、そのタブ コ ントロールが選択されます。特定ページのタブをクリックすると、そ のタブ ページはアクティブになりますが、選択されるオブジェクトは 依然としてタブ コントロールです。タブ ページを選択するには、その タブをクリックしてアクティブにしてから、タブ自身を除く、ページ の背景のどこかをクリックします。 タブ コントロールの本来の目的は、タブ ページにほかのコントロール を表示させることです。タブ ページをウィンドウのミニチュア版とし て考えることができます。ウィンドウに対して行うように、タブ ペー ジにコントロールを追加します。 タブ ページ上のコン トロール タブ コントロールで作業しているときは、タブ コントロール内に作成 されたタブ ページにしかコントロールを追加することができません。 タブ コントロール内のユーザ オブジェクトへのコントロールの追加 タブ コントロール内のユーザ オブジェクトにコントロールを追加す るには、ユーザ オブジェクト ペインタでそのユーザ オブジェクトを 開きます。 v 埋め込みタブ ページにコントロールを追加するには • ウィンドウにコントロールを追加する場合と同様に、ツールバー または[挿入]メニューからコントロールを選択して、タブ ペー ジをクリックします。 タブ ページをクリックすると、そのタブ ページがコントロールの 親になります。 v 1 つのタブ ページから別のタブ ページにコントロールを移動するには • アプリケーション テクニック コントロールを切り取るかコピーして、目的のタブ ページに貼り 付けます。 103 タブ コントロールのカスタマイズ 移動元のタブ ページと移動先のタブ ページは、両方とも埋め込みタブ ページでなければなりません。独立したユーザ オブジェクトであって はなりません。 v タブ ページとそのタブ コントロールがあるウィンドウの間でコントロールを 移動するには • コントロールを切り取るかコピーして、目的のウィンドウかタブ ページに貼り付けます。 タブ コントロールの外のウィンドウに、コントロールをドラッグ することはできません。 タブ ページとウィンドウの間でコントロールを移動することは、コン トロールの親を変更することになります。したがって、コントロール を参照するスクリプトに影響を与えます。 タブ コントロールのカスタマイズ タブ コントロールには、タブの表示位置と表示形態を制御する設定が あります。それぞれのタブには、タブ自身のラベル、ピクチャ、背景 色があります。 すべてのタブは、タブのプロパティ シートの[フォント]タブ ページ で設定された、同じフォント設定を共有します。 タブ コントロールと タブ ページのための、 ポップアップ メ ニューとプロパティ シート タブ コントロールにはいくつかの要素があり、それぞれにポップアッ プ メニューとプロパティ シートがあります。プロパティ シートを開 くためには、ポップアップ メニュー上で[プロパティ]を選択します。 アクセスしたい要素の箇所でクリックします。 表 7-1: タブ コントロール要素へのアクセス 構成要素 タブ コントロール 方法 タブ コントロールのタブエリア内を右ク リックするか、ダブルクリックする タブ ページ タブ ページをアクティブにするためにタブ をクリックしてから、タブ ページ内でコント ロールがない部分をどこか右クリックする か、ダブルクリックする タブ ページ内のコントロー タブ ページをアクティブにするためにタブ ル をクリックしてから、コントロールを右ク リックするか、ダブルクリックする 104 PowerBuilder 第7章 タブの表示位置とサイ ズ ウィンドウにおけるタブ コントロールの使い方 タブのプロパティ シートの[全般]タブ ページには、タブの表示位置 とサイズを制御するための、いくつかの設定があります。 表 7-2: タブのサイズと表示位置の制御 変更内容 変更する値 タブ コントロールのタブを表示する位置 [タブの位置] タブ コントロールの大きさに連動したタブの [幅合わせをしない]、 [複数 サイズ変更 行]、[均等なタブ幅] タブ コントロールの左右に連動したテキスト [テキストをタブに対して の向き。垂直テキストをサポートするのは 垂直に表示] True Type フォントのみであるため、この設定 には注意が必要 [均等なタブ幅]と[幅合わせをしない]チェックボックス [均等なタブ幅]をオンにすると、タブ幅は同じになります。[均等な タブ幅]をオンにすることと、 [幅合わせをしない]をオフにすること とは違います。 [幅合わせをしない]をオフにすると、タブ コントロー ルの縁にあわせて、タブが引き延ばされます。すべてのタブ ラベルの 長さが同じ場合はタブ幅も同じになりますが、長いラベルと短いラベ ルが混ざっている場合は、 [均等なタブ幅]をオンにしない限り、タブ 幅は、タブ ラベルの長さに応じて異なります。 以下のタブ コントロールは、いくつかの設定を組み合わせた結果を表 します。タブの位置は上端に設定してあります。 アプリケーション テクニック 105 タブ コントロールのカスタマイズ 次の例では、タブ コントロールは、住所録のように、タブが左側と右 側を行き来します。 [選択したテキストを太字]チェックボックスをオ ンにして、タブ位置を変更すれば、選択されたタブを見つけることが 容易になります。 タブ ラベル タブ コントロールとタブ シートの両方のプロパティ シートを使用し て、タブの外観を変更できます。 表 7-3: タブの外観の変更 プロパティ プロパティ シート ページ タブ コント [全般] ロール タブ ページ [全般] 設定 [ピクチャを右側に表 示]、 [ピクチャの表 示]、 [テキストの表示] [テキスト] [背景色] 、 タブ ページ [タブページ] [ピクチャ名] [タブの 、 文字の色]、 [タブの背 景色]、 [ピクチャのマ スク色] 作用対象 コントロール内の すべてのタブ タブ上のラベルとタ ブ ページの背景色 テキストの色、タブ 上のピクチャ、 (タ ブ ページではなく) タブ自身の背景色 タブ ページとして使用するユーザ オブジェクトをユーザ オブジェク ト ペインタで作成している場合、タブ ページのプロパティ シートで 作成できる、ユーザ オブジェクトのプロパティ シートの[タブ ペー ジ]で同じ設定ができます。 106 PowerBuilder 第7章 ウィンドウにおけるタブ コントロールの使い方 以下の例では、ピクチャとテキストがそれぞれのタブ ページに設定さ れています。タブは、それぞれ異なる背景色が設定されています。 [ピ クチャの表示]と[テキストの表示]の両チェックボックスの設定は、 どちらもオンです。 スクリプトでタブの表 示形態を変更 ペインタで行った、これらのプロパティの設定は、スクリプトでもで きます。スクリプトでプロパティを設定すれば、実行時に動的にタブ コントロールの表示形態を変更できます。 スクリプトにおけるタブ コントロールの使い方 この節では、以下のようなスクリプトにおけるタブの例について説明 します。 • スクリプトでのタブ ページの参照 • タブ ページにあるコントロールの参照 • タブ ページを開く、閉じる、非表示にする • タブ ページの履歴 • 必要なときだけタブ ページを生成 • タブ コントロールの各部分におけるイベント スクリプトでのタブ ページの参照 ドット(.)表記を使用して、個々のタブ ページとそのタブ ページに あるコントロールを参照できます。 • ウィンドウやユーザ オブジェクトは、その中にあるタブ コントロー ルの親です。 window.tabcontrol • タブ コントロールは、その中にあるタブ ページの親です。 window.tabcontrol.tabpageuo • タブ ページは、その中にあるコントロールの親です。 window.tabcontrol.tabpageuo.controlonpage アプリケーション テクニック 107 スクリプトにおけるタブ コントロールの使い方 たとえば、以下のステートメントは、ウィンドウ w_display 内のタブ コ ントロール tab_1 の PowerTips プロパティを設定します。 w_display.tab_1.PowerTips = TRUE 次の例では、タブ ページ tabpage_1 の PowerTipText プロパティを設定 します。 w_display.tab_1.tabpage_1.PowerTipText = & "Font settings" 以下の例では、タブ ページ tabpage_doit にあるコマンドボタン cb_OK を使用可能にします。 w_display.tab_1.tabpage_doit.cb_OK.Enabled = TRUE 汎用的なプログラミン グ スクリプトを汎用的に作成するには、Parent 代名詞と GetParent 関数を 使用します。 Parent 代名詞 どんなタブ ページのスクリプトにおいてもタブ コント ロールを参照するために、Parent 代名詞を使用できます。 Parent.SelectTab(This) GetParent 関数 タブ ページのイベントに対するスクリプトでは、タブ ページの親であるタブ コントロールを参照するために GetParent 関数 を呼び出すことができます。この関数を使用して、Tab データ型の変 数に親への参照を代入できます。 タブ ページとして使用されている、ユーザ オブジェクトのイベントに 対するスクリプトで、インスタンス変数にタブ ページの親であるタブ コントロールへの参照を代入するために、以下のスクリプトが使用で きます。 以下は、インスタンス変数の宣言です。このインスタンス変数は、ど んなタブ コントロールへの参照も代入できます。 tab itab_settings 以下は、インスタンス変数にタブ ページの親への参照を代入します。 // タブ コントロールへの参照を取得します。 // This 代名詞は、タブ ページのユーザ オブジェクトを参照します。 itab_settings = This.GetParent() タブ ページにあるコントロールのイベントに対するスクリプトでは、 タブ ページのユーザ オブジェクトとその親のタブ コントロールを参 照するために、GetParent 関数を 2 回呼び出します。 tab tab_mytab userobject tabpage_generic 108 PowerBuilder 第7章 ウィンドウにおけるタブ コントロールの使い方 tabpage_generic = This.GetParent() tab_mytab = tabpage_generic.GetParent() tabpage_generic.PowerTipText = & "Important property page" tab_mytab.PowerTips = TRUE tab_mytab.SelectTab(tabpage_generic) PowerBuilder のシステム オブジェクト データ型である Tab 型の変数は、タブ コントロールにあるタブ ページ を認識できません。また、UserObject 型の変数は、タブ ページにある コントロールを認識できません。 Tab データ型の変数の制限事項 以下のタブ ページのイベントに対するスクリプトで記述したローカ ル変数は、親であるタブ コントロールへの参照が代入されています。 Tab 型の変数 tab_settings はタブ コントロール内のページについて認識 できないので、特定なページを参照できません。ただし、タブ コント ロールの関数を呼び出して、タブ コントロールのプロパティを参照す ることはできます。 tab tab_settings tab_settings = This.GetParent() tab_settings.SelectTab(This) ユーザ オブジェクト変数 タブ ページが独立したユーザ オブジェクト の場合は、そのユーザ オブジェクトをデータ型として、タブ ページの 変数を定義できます。ユーザ オブジェクトは、挿入したタブ ページの 先祖です。宣言した変数は、ユーザ オブジェクトにあるコントロール が参照できます。 以下のタブ コントロールのイベントに対するスクリプトでは、引数 index は、タブ ページを参照して、Control プロパティ配列からユーザ オブジェクトへの参照を取得するために使用されます。例では、すべ てのタブ ページが同じユーザ オブジェクト uo_emprpt_page を使用し ているものとします。 uo_emprpt_page tabpage_current tabpage_current = This.Control[index] tabpage_current.dw_emp.Retrieve & (tabpage_current.st_name.Text) アプリケーション テクニック 109 スクリプトにおけるタブ コントロールの使い方 タブ コントロールの Control プロパティ配列 Control プロパティ配列には、埋め込みユーザ オブジェクトや独立した ユーザ オブジェクトなど、コントロール内のすべてのタブ ページへの 参照が含まれます。新しいタブ ページをペインタで挿入したり、スクリ プトで開いたりすると、それらのタブ ページが配列に追加されます。 タブ ページにあるコントロールの参照 別のウィンドウのタブ ページにあるコントロールを参照する場合は、 ウィンドウ レベルまでコントロールの名前を修飾しなければなりま せん。 次の例では、完全修飾してスタティック テキスト コントロールを参照 します。 w_activity_manager.tab_fyi.tabpage_today. & st_currlogon_time.Text = ls_current_logon_time PowerBuilder の Code Examples の以下の例は、ウィンドウにあるデータ ウィンドウ コントロールのサイズとタブ ページにあるデータウィン ドウ コントロールのサイズが一致するように設定します。すべてのタ ブ ページはペインタで挿入されているので、Control プロパティ配列は タブ ページのインデックス順に、タブ ページへの参照が保持されてい ます。すべてのタブ ページは、同じユーザ オブジェクト u_tab_dir が挿 入されたものです。 u_tab_dir luo_Tab luo_Tab = This.Control[newindex] luo_Tab.dw_dir.Height = dw_list.Height luo_Tab.dw_dir.Width = dw_list.Width タブ ページとして使用されるユーザ オブジェクトのスクリプトと関 数は、ユーザ オブジェクトにあるコントロールを認識します。した がって、コントロールへの参照を修飾する必要はありません。ユーザ オブジェクト u_tab_dir の関数である以下の例は、データウィンドウ コ ントロール dw_dir にデータを取得します。 IF NOT ib_Retrieved THEN dw_dir.SetTransObject(SQLCA) dw_dir.Retrieve(as_Parm) ib_Retrieved = TRUE END IF 110 PowerBuilder 第7章 ウィンドウにおけるタブ コントロールの使い方 RETURN dw_dir.RowCount() タブ ページを開く、閉じる、非表示にする スクリプトでタブ ページを開くことができます。スクリプトで開いた タブ ページを閉じることはできますが、ペインタで挿入したタブ ペー ジを閉じることはできません。ただし、どんなタブ ページも非表示に することはできます。 以下の例は、ユーザ オブジェクト tabpage_listbox をタブ ページとして 開いて、インスタンス変数 i_tabpage にユーザ オブジェクトへの参照 を代入します。OpenTab 関数の引数 0 は、そのタブ ページがタブ コン トロールで最後のページになることを指定します。後からタブ ページ を閉じるには、ユーザ オブジェクトへの参照を保持する必要がありま す。 以下は、タブ ページのユーザ オブジェクトへの参照のためのインスタ ンス変数宣言です。 userobject i_tabpage 以下のステートメントは、ユーザ オブジェクトをタブ ページとして開 きます。 li_rtn = tab_1.OpenTab & (i_tabpage, "tabpage_listbox", 0) 以下のステートメントは、タブ ページを閉じます。 tab_1.CloseTab(i_tabpage) タブ ページの履歴 タブ ページにあるコントロールを参照するには、タブ ページのイン デックスやユーザ オブジェクトへの参照が必要です。タブ ページの Control プロパティ配列を使用すると、すべてのタブ ページへの参照を 取得できます。 タブ ページの Control プロパティ配列 タブ コントロールの Control プロパティ配列は、ペインタで定義した タブ ページとスクリプトで追加したタブ ページへの参照を保持する 配列です。イベントに渡されるインデックスの値は、Control プロパ ティ配列の配列要素と一致します。 SelectedTab プロパティを使用して、選択したタブ ページのユーザ オ ブジェクトへの参照を取得できます。 アプリケーション テクニック 111 スクリプトにおけるタブ コントロールの使い方 userobject luo_tabpage luo_tabpage = tab_1.Control[tab_1.SelectedTab] タブ コントロールのイベントでは、SelectionChanged イベントのよう に、イベントに渡されたタブ ページのインデックスの値を使用して、 Control プロパティ配列からタブ ページへの参照を取得できます。 userobject tabpage_generic tabpage_generic = This.Control[newindex] 新しいタブ ページの 追加 OpenTab 関数を呼び出すと、Control プロパティ配列の要素が 1 つ増え ます。新しい要素は、新しく開いたタブ ページへの参照を保持します。 次のステートメントでは、タブ コントロールの 2 番目の位置に新しい タブを追加します。 tab_1.OpenTab(uo_newtab, 2) tab_1 の Control 配列内の 2 番目の要素が uo_newtab への参照を保持す るので、それ以降のタブ ページの Control 配列のインデックスが 1 つ ずつ加算されます。 タブ ページを閉じる CloseTab 関数を呼び出すと、配列のサイズが 1 つ減少し、ユーザ オブ ジェクトまたはページへの参照が破棄されます。配列の最後の要素以 外のタブを閉じた場合は、それ以降のタブ ページのインデックスが 1 つずつ減少します。 タブ ページの移動 MoveTab 関数は、タブ コントール内のページの順序を変更し、その順 序に合わせて Control 配列の要素の順序も変更します。 ユーザ オブジェクトの Control プロパティ配列 ユーザ オブジェクトの Control プロパティ配列の場合も同様に行いま す。 必要なときだけタブ ページを生成 エンド ユーザは、タブ コントロール内のすべてのタブ ページを参照 するとは限りません。タブ コントロールの[全般]プロパティ ページ で[現行タブ上のコントロールのみ生成]をチェックしておくか、 CreateOnDemand プロパティを TRUE に設定しておけば、すべてのタブ ページのコントロールのグラフィック表現を作成するオーバーヘッド を回避できます。 112 PowerBuilder 第7章 ウィンドウにおけるタブ コントロールの使い方 タブ コントロールを作成すると、タブ コントロール内のすべてのタブ ページのコントロールのインスタンスがいつも作成されます。ただし、 [現行タブ上のコントロールのみ生成]がチェックしてあれば、タブ ページのコントロールの Constructor イベントは発生せず、ユーザがそ のタブ ページを参照しない限り、コントロールのグラフィック表現は 作成されません。 選択したタブ ページの Constructor イベント タブ コントロールを作成すると、選択したタブ ページにあるコント ロールの Constructor イベントが常に発生します。 [現行タブ上のコント ロールのみ生成]オプ ションのトレードオフ タブ ページの生成 チェック コントロールが多くあるタブ ページのグラフィック表現の作成を遅 らせると、ウィンドウがよりすばやく開きます。しかし、タブ ページ の Constructor イベントが起動されてコントロールのグラフィック表現 が作成されるまでは、スクリプトでタブ ページのコントロールを参照 することはできません。[現行タブ上のコントロールのみ生成]が チェックされている場合は、表示されていないタブ ページのコント ロールをスクリプトで参照することはできません。 PageCreated 関数を使用して、 タブ ページが作成されたかどうかを確認 できます。作成されていない場合は、CreatePage 関数を使用してその タブ ページの Constructor イベントを発生させることができます。 IF tab_1.tabpage_3.PageCreated() = FALSE THEN tab_1.tabpage_3.CreatePage() END IF タブ ページにあるコントロールのハンドルがゼロでないかをチェッ クして、タブ ページのインスタンスが生成されたかを確認できます。 ハンドルがゼロでない場合は、コントロールのインスタンスは生成さ れています。 IF Handle(tab_1.tabpage_3.dw_list) > 0 THEN ... 実行時での CreateOnDemand プ ロパティの変更 スクリプトで CreateOnDemand プロパティを FALSE に設定すると、グ ラフィック表現が作成されていなかったタブ ページのグラフィック 表現がすぐに作成されます。 すべてのタブ ページのグラフィック表現が作成されている場合は、実 行時に CreateOnDemand プロパティを TRUE に変更しても、何も変わり ません。 アプリケーション テクニック 113 スクリプトにおけるタブ コントロールの使い方 タブ ページの動的な 作成 CreateOnDemand が FALSE である場合には、メッセージ オブジェクト に渡された OpenTabWithParm への引数を使用して、Constructor イベン トにおいて動的に作成されたタブ ページのラベルを設定できます。 CreateOnDemand が TRUE で ある 場 合 には、タブ が 選 択 され る ま で Constructor イベントは発生しないため、タブ ページがインスタンス化 されるときにラベルを設定する必要があります。ウィンドウの Open イ ベントからポストされたユーザ イベントに以下のスクリプトが含ま れる場合には、5 つのタブ ページが開かれ、インスタンス化されると きにタブごとのラベルが設定されます。 int li_ctr string is_title THIS.setredraw(false) FOR li_ctr = 1 to 5 is_title = "Tab#" + string(li_ctr) tab_test.opentabwithparm(iuo_tabpage[li_ctr], & is_title, 0) iuo_tabpage[li_ctr].text = is_title // タブ ラベルを設定 NEXT THIS.setredraw(true) RETURN 1 タブ コントロールの各部分におけるイベント タブ コントロールの各部分(タブ、タブ ページ、タブ ページにある コントロール)は、重なるエリアが多いため、イベントに対するスク リプトをどこに記述するかを知っておく必要があります。 表 7-4: タブ コントロール イベントに対するスクリプトの記述 イベントの起動対象となる箇所 タブに対するクリックやドラッグ を含む、タブ コントロールのタ ブ エリア タブ ページ(タブではない) タブ ページ内のコントロール 114 イベントに対するスクリプトの所属 タブ コントロール タブ ページ(埋め込みタブ ページの場 合)またはユーザ オブジェクト(独立 したタブ ページの場合) タブ ページ上のコントロール自身 PowerBuilder 第7章 ウィンドウにおけるタブ コントロールの使い方 たとえば、エンド ユーザがタブへドラッグして、タブに関連付けられ ているタブ ページに何かを行いたい場合、タブ ページではなくタブ コ ントロールの DragDrop イベントにスクリプトを記述する必要があり ます。 例 タブ コントロール tab_1 の DragDrop イベントの以下のスクリプトは、 エンド ユーザがタブの上に何かをドロップしたときに、ドロップ先の タブ ページを選択します。ドロップされたタブのインデックスが、 DragDrop イベントの引数となります。 This.SelectTab( index ) 次のスクリプトは、タブ コントロールの DragDrop イベントのもので す。エンド ユーザがデータウィンドウのデータをタブにドラッグする と、そのタブに関連付けられているタブ ページのリストに、そのデー タが挿入されます。 ListBox コントロール lb_list がある tabpage_listbox 型のユーザ オブジェ クトは、ユーザ オブジェクト ペインタで定義されています。タブ コン トロールには、tabpage_listbox 型の独立したタブ ページが複数ありま す。 Control プロパティ配列からタブ ページへの参照を取得するには、 DragDrop イベントの引数 index を使用します。ユーザ オブジェクトへ の参照により、スクリプトでタブ ページのコントロールにアクセスで きます。 タブ コントロールの以下のスクリプトの Parent 代名詞は、ウィンドウ を参照しています。 long ll_row string ls_name tabpage_listbox luo_tabpage IF TypeOf(source) = DataWindow!THEN l_row = Parent.dw_2.GetRow() ls_name = Parent.dw_2.Object.lname.Primary[ll_row] // Control プロパティ配列から参照を取得します。 luo_tabpage = This.Control[index] // タブ ページを選択します。 This.SelectTab(index) // ドラッグされたデータを挿入します。 luo_tabpage.lb_list.InsertItem(ls_name, 0) END IF アプリケーション テクニック 115 スクリプトにおけるタブ コントロールの使い方 タブ ページが作成されていない場合 タブ コントロールの CreateOnDemand プロパティが TRUE になってい る場合、タブ ページが選択されるまでは、タブ ページやそのコント ロールの Constructor イベントは発生しません。上記の例では、タブ ページを選択したことによって、Constructor イベントが発生していま す。CreatePage 関数を使用して、Constructor イベントを発生させるこ ともできます。 IF luo_tabpage.PageCreated() = FALSE THEN & luo_tabpage.CreatePage() 116 PowerBuilder 第 8 章 ツリービュー コントロールの使い方 この章について この章では、ツリービュー コントロールを使用して階層構造(分 岐型)のリストを表示する方法について説明します。 内容 項目 ツリービュー コントロールについて ツリービューの表示 ツリービューの項目の管理 ツリービュー ピクチャの管理 データウィンドウのデータのツリービューへの表示 ページ 117 121 127 136 139 ツリービュー コントロールについて ツリービュー コントロールによって、階層構造のリストを表示す ることができます。ツリービューは、階層を開いたり閉じたりす る標準インタフェースを提供します。 アプリケーション テクニック 117 ツリービュー コントロールについて ツリービューの用途 ツリービューは、ウィンドウとカスタム ビジュアル ユーザ オブジェ クトで使用します。同レベルの項目だけでなく、さまざまな項目で構 成された、より複雑なリストや、1 つの項目から多数の項目が分岐す るリストを表示する場合に、リストボックスやリストビューのかわり にツリービューを使用します。エンド ユーザが標準ツリービュー イン タフェースを使用してリストの分岐を表示する場合にも、データウィ ンドウ コントロールではなくツリービューを使用します。 階層構造のリスト リストビューのレポート ビューのような単一階層のリストでツリー ビューを使用してもかまいませんが、1 つの項目から多数の項目が分 岐し、複数の階層で構成されるリストでツリービューは威力を発揮し ます。たとえば、1 つまたは複数の親項目の下にそれぞれいくつかの 子項目が属するようなリストでツリービューを利用するとよいでしょ う。また、複数のレベルで段階的に分類されているリストにも有効で す。 ルート 項目 1 二次項目 1a 詳細項目 詳細項目 二次項目 1b 詳細項目 詳細項目 項目 2 二次項目 2a 詳細項目 レベルの数 分岐によって必要な階層の深さが異なる場合、分岐ごとのレベルの数 が一致しなくてもかまいません。ただし、同じレベルの項目が、ある 分岐では二次項目であり、ほかの分岐では詳細項目であるというよう にバラバラであるよりは、同じ種類の項目である方が、プログラミン グは容易になります。 たとえば、項目のレベルをテストして、適切なアクションを決めるス クリプトを考えてみましょう。この場合、SetLevelPictures 関数を呼び 出して、特定のレベルのすべての項目にピクチャを設定することがで きます。 ツリービューのデータ ソース 118 PowerBuilder のほとんどのリストでは、ペインタまたはスクリプトを 使用して項目を追加できますが、ツリービューではスクリプトを作成 しなければなりません。通常、ウィンドウを開くと、ツリービューの 第 1 レベル(ルート レベル)が表示されます。エンド ユーザが分岐を 表示したときに、ツリービューの ItemPopulate イベントに対するスク リプトによって、次のレベルの項目を追加できます。 PowerBuilder 第8章 ツリービュー コントロールの使い方 項目のデータはスクリプトでハードコード化できますが、エンド ユー ザの入力や、ツリービューの内容が登録されているデータベースを使 用する方が効率的です。1 つの項目から複数の子項目が分岐するので、 データベース内の複数のテーブルを使用してツリービューを表示でき ます。 データストアの使用例については、139 ページの「データウィンドウ のデータのツリービューへの表示」を参照してください。 項目のピクチャ ツリービューでは、各項目にピクチャが関連付けられています。コン トロールのピクチャ リストで使用するピクチャを選択してから、その ピクチャのインデックスを項目に関連付けます。一般的に、ピクチャ は各項目に固有のものではありません。ピクチャは、そのレベル内で 項目を分類したり識別したりするためのものです。以下のような方法 でピクチャを使用すると、エンド ユーザがデータを識別しやすくなり ます。 • 各レベルで異なるピクチャを使用する • 同一レベルで、項目の種類ごとに異なるピクチャを使用する • 特定のレベルのみピクチャを使用する • エンド ユーザが項目をクリックしたらピクチャを変更する ピクチャによってエンド ユーザに情報 を提示する必要がない場合は、ピクチャを使用しなくてもかまいませ ん。項目のラベルと階層のレベルだけで十分な場合もあります。 ピクチャを使用しなくてもよい ツリービューの外観 プロパティを使用してツリービューの外観を制御できます。全体的な 外観を変更するプロパティは表 8-1 のとおりです。 アプリケーション テクニック 119 ツリービュー コントロールについて 表 8-1: ツリービューのプロパティ プロパティ HasButtons HasLines と LinesAtRoot Checkboxes TrackSelect FullRowSelect SingleExpand Indent フォント プロパ ティ 各種ピクチャ プ ロパティ LayoutRTL と RightToLeft 効果 項目の前にプラス(+)やマイナス(-)ボタンがある場 合は子項目があり、そのボタンをクリックすることに よって分岐を開閉できることを示す 分岐内の項目や、ルート レベルの項目を接続する線を表 示する 状態ピクチャをチェック済みチェックボックスおよび 未チェック チェックボックスに置き換える マウスが上に移動したときに項目の外観を変更する 選択した項目の行全体をハイライト表示する 選択した項目を展開し、前に選択した項目を自動的に折 りたたむ 項目をインデントする量を指定する すべてのラベルのフォントを指定する ピクチャとそのサイズを制御する コントロール内の要素と文字を右から左に表示する これらのプロパティの詳細については、『オブジェクトとコントロー ル』マニュアルを参照してください。 ユーザ操作 開発者が特にスクリプトを作成しなくても、ツリービューの基本機能 を利用して、エンド ユーザがラベルの編集、項目の削除、分岐の開閉、 およびアルファベット順のソートを行うことができます。たとえば、 エンド ユーザが選択した項目をもう一度クリックすると、ラベルは編 集状態になります。また、〔Delete〕を押すと項目が削除されます。プ ロパティを設定して、このような操作を実行できないようにすること も可能です。 スクリプトを作成して、このような基本操作をカスタマイズすること ができます。基本操作にイベントを関連付けることにより、操作を実 行可能または実行不可にします。また、項目の追加、項目のドラッグ、 ソート指定のカスタマイズなど、そのほかの機能を実装することもで きます。 カスタム イベントの 使い方 120 PowerBuilder バージョン 7 以降では、リストビュー コントロールとツ リービュー コントロールに Microsoft のコントロールが使用されてい ます。右クリックしたときに呼び出されるイベントが、以前のリリー スとは異なります。 PowerBuilder 第8章 ツリービュー コントロールの使い方 マウスの右ボタンを放したときに、pbm_rbuttonup イベントは発生しま せん。このボタンが放されると、ツリービュー コントロールの組み込 み RightClicked! イベント pbm_tvnrclickedevent が発生します。 選択されていないツリービュー項目を右クリックした場合、その右ボ タンを放すと、以前選択されていた項目にフォーカスが戻ります。新 しい項目を選択するには、次のコードを pbm_tvnrclickedevent スクリプ トに挿入します。その後で、その項目に対する処理スクリプトを記述 します。 this.SelectItem(handle) マウスの右ボタンでダブルクリックすると、pbm_rbuttondblclk イベント のみ発生します。以前のリリースでは pbm_rbuttondblclk と pbm_tvnrdoubleclick の両方のイベントが発生していました。 ツリービューの表示 ツリービューに項目を追加するには、スクリプトを作成する必要があ ります。ほかのリスト コントロールのように、ペインタでアイテムを 追加することはできません。ツリービューのすべてのレベルを一度に 表示することもできますが、ツリービューのイベントを使用してエン ド ユーザが必要な分岐のみを表示した方が、不要な手間を省くことが できます。 通常、コントロールを表示したときに、ツリービューの第 1 レベルが 表示されます。このコードは、ウィンドウの Open イベント、Open イ ベ ン ト か ら 起 動 さ れ る ユ ー ザ イ ベ ン ト、ま た は ツ リ ー ビ ュ ー の Constructor イベントにあります。その後で、コントロールの ItemPopulate イベントに対するスクリプトによって、エンド ユーザが分岐を開いた ときに、その項目の子項目が挿入されます。 エンド ユーザが項目のプラス ボタンをクリックするか、項目をダブル クリックすると、その項目の Children プロパティが TRUE の場合のみ、 ItemPopulate イベントが起動されます。このため、子項目がある項目を 挿入する場合、Children プロパティを TRUE にして、エンド ユーザが 分岐を開いたときに子項目が表示されるようにしておかなければなり ません。 ItemPopulate イベント以外にも項目を追加する方法はあります。たとえ ば、エンド ユーザがリストボックスから項目をドラッグしたり、テキ ストボックスに入力することによって追加したりすることもできま す。 アプリケーション テクニック 121 ツリービューの表示 項目挿入関数 表 8-2 に、ツリービュー コントロールに項目を追加する関数を示しま す。 表 8-2: ツリービュー コントロールに項目を追加する関数 関数 InsertItem 挿入位置 指定した親項目の兄弟項目の後 兄弟項目がない場合は、別の挿入関数を使用しなければな らない InsertItemFirst InsertItemLast InsertItemSort 親項目の最初の子項目になる 親項目の最後の子項目になる 可能な場合は、子項目のアルファベット順で適切な位置に 挿入 すべての InsertItem 関数で、SortType プロパティを使用して項目を追加 する位置を指定できます。 追加した項目に関する情報を表示するには、プロパティを使用した以 下の 2 つの方法があります。 方法 1 : ラベルとピク チャ インデックスの み指定する 項目にピクチャ インデックスとラベルを付けて挿入します。そのほか のプロパティはすべて、デフォルト値を使用します。ハンドルを使用 して、必要であれば、後でそのほかのプロパティを設定できます。 以下の例は、現在選択されている項目の後に、同レベルの新規項 目を追加する場合です。最初に、現在選択されている項目とその親項 目のハンドルを取得し、その後現在選択されている項目の後に Hindemith というラベルの項目を挿入します。この項目のピクチャ インデックス は 2 です。 例 long ll_tvi, ll_tvparent ll_tvi = tv_list.FindItem(CurrentTreeItem!, 0) ll_tvparent = tv_list.FindItem(ParentTreeItem!, & ll_tvi) tv_list.InsertItem(ll_tvparent, ll_tvi, & "Hindemith", 2) 方法 2 :TreeViewItem 構造体で項目のプロパ ティを設定する 122 特定の値にプロパティを設定した TreeViewItem 構造体を使用して項 目を追加します。必要なプロパティはラベルだけです。表 8-3 に示さ れているプロパティを設定できます。 PowerBuilder 第8章 ツリービュー コントロールの使い方 表 8-3: TreeViewItem プロパティ プロパティ Label PictureIndex SelectedPictureIndex StatePictureIndex Children Data 値 項目名を示すテキスト 標準ピクチャ リストの値 標準ピクチャ リストの値。その項目が選択されたとき のみ表示されるピクチャ。この値が 0 の場合、その項 目を選択してもピクチャは表示されない 状態ピクチャ リストの値。標準ピクチャの左側にその 状態ピクチャが表示される ダブルクリックによって ItemPopulate イベントを起動 する場合、この値が TRUE でなければならない。この イベント スクリプトによって子項目を挿入できる 項目に関連付けるデータ型の値(オプション)。ソー トの制御やデータベースのクエリで使用できる 以下の例では、ツリービュー コントロールに項目を追加する前に、 TreeViewItem 構造体ですべてのプロパティを設定します。この項目は、 現在の項目の子項目として追加されます。 例 treeviewitem tvi long h_item = 0, h_parent = 0 h_parent = tv_1.FindItem(CurrentTreeItem!, 0) tvi.Label = "Choral" tvi.PictureIndex = 1 tvi.SelectedPictureIndex = 2 tvi.Children = true tvi.StatePictureIndex = 0 h_item = tv_1.InsertItemSort(h_parent, tvi) ツリービュー コントロールに項目を挿入する方法の詳細については、 『PowerScript リファレンス』マニュアルを参照してください。 ルート レベルへの項目の挿入 最初に挿入した項目には兄弟項目がないので、InsertItem 関数を使用で きません。この場合、InsertItemFirst 関数か InsertItemLast 関数を使用す る必要があります。ルート レベルに項目を挿入する場合、親は 0 にな ります。 以下のサンプル コードは、ツリービューを表示するウィンドウの Open イベントから起動されたユーザ イベントのものです。ここでは、以下 に示す 2 つのインスタンス変数配列があるものとします。 アプリケーション テクニック 123 ツリービューの表示 • item_label という名前の文字列配列。ルート レベルに挿入されるす べての項目のラベル(ここでは作曲家名) • Data プロパティの値(ここでは作曲家の世紀)になる整数配列。 この数値を使用してユーザ定義のソートを行う int ct long h_item = 0 treeviewitem tvi FOR ct = 1 TO UpperBound(item_label) tvi.Label = item_label[ct] tvi.Data = item_data[ct] tvi.PictureIndex = 1 tvi.SelectedPictureIndex = 2 tvi.Children = TRUE tvi.StatePictureIndex = 0 tvi.DropHighlighted = TRUE h_item = tv_1.InsertItemSort(0, tvi) NEXT すべての項目を挿入した後で、以下のコードによってツリービューを 最初の項目までスクロールして戻し、最初の項目を現在の項目にしま す。 // 最初の項目までスクロール h_item = tv_1.FindItem(RootTreeItem!, 0) tv_1.SetFirstVisible(h_item) tv_1.SelectItem(h_item) ルート レベルの下への項目の挿入 エンド ユーザが子項目を表示するために最初に分岐を開いたときに、 その項目の Children プロパティが TRUE の場合のみ、ItemPopulate イベ ントが起動されます。ItemPopulate イベントで、現在開いているレベル に子項目を追加できます。 親項目の Children プロパティ 最初に分岐を開いたときに ItemPopulate イベントが起動されなかった 場合、その項目の Children プロパティが TRUE になっているかどうか を確認してください。子項目がある項目の Children プロパティはすべ て TRUE になっていなければなりません。 124 PowerBuilder 第8章 ツリービュー コントロールの使い方 ItemPopulate イベント以外の方法による挿入 ItemPopulate イベントを使 用すると、エンド ユーザが必要な項目のみを表示すればよいので、効 率的にプログラムを作成できますが、エンド ユーザが分岐を開くまで 待たなければなりません。ItemPopulate イベントが起動される前に挿入 したい場合は、ルート レベルに項目を挿入するように、スクリプトに よって子項目を追加することもできます。 たとえば、小さなツリービューの場合、ウィンドウを開いたときに全 体を表示し、ExpandAll 関数を使用して分岐がすべて開いた状態で項目 を表示することができます。 子項目を表示したかどうかの確認 その項目の ExpandedOnce プロパティ をチェックすることにより、エンド ユーザがその子項目を表示したか どうかを確認することができます。エンド ユーザが子項目を表示して いる場合、Expanded プロパティも TRUE になります。 以下のツリービューは、作曲家とその楽曲を分類したものです。 ItemPopulate イベントに対するスクリプトによって、現在開いている項 目が、レベル 1(作曲家)またはレベル 2(分類)のいずれに属するか をチェックします。レベル 3 の項目は開いていません。 例 レベル 1 の項目の下に、スクリプトによって 3 つの標準分類を追加し ます。レベル 2 の項目の下に、その分類に属する楽曲を追加します。 この場合、以下のような構造になります。 モーツァルト 管弦楽 交響曲第 33 番 魔笛への序曲 室内楽 ホルン五重奏曲 変ホ長調 アイネ クライネ ナハトムジーク 声楽 ドン ジョバンニ イドメネオ ItemPopulate イベントに対するスクリプトは以下のとおりです。 TreeViewItem tvi_current, tvi_child, tvi_root long hdl_root Integer ct string categ[] // 現在の項目は、新規項目の親項目です。 This.GetItem(handle, tvi_current) IF tvi_current.Level = 1 THEN // レベル 2 の標準分類を表示します。 アプリケーション テクニック 125 ツリービューの表示 categ[1] = " 管弦楽 " categ[2] = " 室内楽 " categ[3] = " 声楽 " tvi_child.StatePictureIndex = 0 tvi_child.PictureIndex = 3 tvi_child.SelectedPictureIndex = 4 tvi_child.OverlayPictureIndex = 0 tvi_child.Children = TRUE FOR ct = 1 to UpperBound(categ) tvi_child.Label = categ[ct] This.InsertItemLast(handle, tvi_child) NEXT END IF // レベル 3 の楽曲名を表示します。 IF tvi_current.Level = 2 THEN // 現在の項目の親項目を表示します。 // 現在の分岐のルートであり、 // 子項目を選択するキーの 1 つになります。 hdl_root = This.FindItem(ParentTreeItem!, handle) This.GetItem(hdl_root, tvi_root) FOR ct = 1 to 4 // このステートメントはラベルを構成します。テーブルや // データベースでデータを検索する場合や、エンド ユーザの // 入力を受け付ける際にラベルを使用すると便利です。 This.InsertItemLast(handle, & tvi_root.Label + " 音楽 " & + tvi_current.Label + String(ct), 3) NEXT END IF 126 PowerBuilder 第8章 ツリービュー コントロールの使い方 ツリービューの項目の管理 ツリービューの各項目が TreeViewItem 構造体になります。この構造体 で項目のプロパティを設定し、ツリービューに項目を挿入する方法に ついては、前節を参照してください。 以下のコードは、TreeViewItem 構造体を宣言し、一部のプロパティを 設定します。 TreeViewItem tvi_defined tvi_defined.Label = "Symphony No. 3 Eroica" tvi_defined.StatePictureIndex = 0 tvi_defined.PictureIndex = 3 tvi_defined.SelectedPictureIndex = 4 tvi_defined.OverlayPictureIndex = 0 tvi_defined.Children = TRUE ピクチャ プロパティについては、136 ページの「ツリービュー ピク チャの管理」を参照してください。 項目を挿入すると、挿入関数によってその項目に対するハンドルが戻 されます。TreeViewItem 構造体がツリービュー コントロールにコピー されるので、その項目のプロパティにアクセスする必要はありません。 itemhandle = This.InsertItemLast(parenthandle, & tvi_defined) 項目の取得、変更、設 定 ツリービュー項目のプロパティを変更したい場合には、以下の操作を 実行します。 1 その項目を取得し、TreeViewItem 構造体に割り当てます。 2 TreeViewItem プロパティを設定して変更します。 3 項目を設定し、ツリービューにコピーして戻します。 ツリービューに挿入された項目を処理する場合、そのハンドルを操作 します。大部分のツリービュー イベントでは、引数として 1 つまたは 2 つのハンドルを渡します。このハンドルによって、エンド ユーザが 処理している項目を識別します。 Clicked イベントに対する以下のコードは、エンド ユーザがクリックした 項目のハンドルを使用して、開発者がプロパティを変更した TreeViewItem 構造体にその項目をコピーして戻します。 treeviewitem tvi This.GetItem(handle, tvi) tvi.OverlayPictureIndex = 1 This.SetItem(handle, tvi) アプリケーション テクニック 127 ツリービューの項目の管理 重要 項目のプロパティを変更した後は、必ず SetItem 関数を呼び出してくだ さい。SetItem 関数を呼び出さないと、ツリービューの表示が変更され ません。 項目と階層 FindItem 関数と項目のハンドルを使用して、 ツリービューで構造体を調 べることができます。項目のプロパティでレベルはわかりますが、親 項目はわかりません。FindItem 関数によって、その項目がどの親項目の 下にあるかがわかります。 long h_parent h_parent = This.FindItem(ParentTreeItem!, handle) FindItem 関数を使用して子項目を探したり、 レベルに関係なく現在表示 されている項目の中から検索したりすることができます。 詳細については、 『PowerScript リファレンス』マニュアルの FindItem 関 数に関する節を参照してください。 スクリプトによるツ リービュー機能の制御 スクリプトを作成しなくても、ツリービューのプロパティを設定して、 項目の削除や名前の変更などのユーザ操作を使用可能 / 使用禁止にで きますが、関数を呼び出すことによってこれらのユーザ操作を制御す ることもできます。以下のことを行うことができます。 • 項目の削除 • 項目の名前の変更 • ドラッグ アンド ドロップによる項目の移動 • 項目のソート 項目の削除 エンド ユーザが項目を削除できるようにするためには、ツリービューの DeleteItems プロパティを使用可能にします。エンド ユーザが〔Delete〕 を押すと、選択した項目が削除され、DeleteItem イベントが起動され ます。子項目もすべて削除されます。 詳細項目のみ削除するなど、削除対象をより細かく指定したい場合は、 プ ロ パ テ ィ を 設 定 す る か わ り に DeleteItem 関 数 を 呼 び 出 し ま す。 DeleteItem 関数を呼び出した場合も、DeleteItem イベントが起動されま す。 128 PowerBuilder 第8章 例 ツリービュー コントロールの使い方 TreeView ユーザ イベントに対するスクリプトを以下に示します。イベ ント ID は pbm_keydown で、ツリービューにフォーカスがある場合に キーを押すと起動されます。このスクリプトによって、〔Delete〕が押 されたかどうか、また、選択された項目が詳細項目かどうかをチェッ クします。両方とも TRUE だった場合にその項目を削除します。 ツリービューの DeleteItems プロパティの値は FALSE にします。TRUE になっていると、コードの内容にかかわらず、エンド ユーザが任意の 項目を削除できます。 TreeViewItem tvi long h_item IF KeyDown(KeyDelete!)= TRUE THEN h_item = This.FindItem(CurrentTreeItem!, 0) This.GetItem(h_item, tvi) IF tvi.Level = 3 THEN This.DeleteItem(h_item) END IF END IF RETURN 0 項目の名前の変更 ツリービューの EditLabels プロパティが使用可能な場合、エンド ユー ザが項目のラベルを 2 回クリックすると、ラベルの編集状態になりま す。 イベント ラベルの編集には以下の 2 つのイベントが関連付けられています。 BeginLabelEdit イベントは、EditLabels プロパティが設定されている場 合、または EditLabel 関数を呼び出したときに、2 回目のクリックの後 で起動されます。戻り値が 1 の場合は編集できないようにすることが できます。 BeginLabelEdit イベントに対する以下のスクリプトでは、レベル 2 の項 目のラベルは変更できません。 TreeViewItem tvi This.GetItem(handle, tvi) IF tvi.Level = 2 THEN RETURN 1 ELSE RETURN 0 END IF アプリケーション テクニック 129 ツリービューの項目の管理 EndLabelEdit イベントは、エンド ユーザが、〔Enter〕を押す、別の項 目をクリックする、別のコントロールのテキスト入力エリアをクリッ クする、のいずれかによって編集を終了したときに起動されます。 EndLabelEdit イベントに対するスクリプトを作成することにより、ユー ザの変更が適切かどうかを確認できます(たとえば、スペル チェッカー を起動できます)。 EditLabel 関数 エンド ユーザによるラベルの編集を制限するために、上記のような方 法で、BeginLabelEdit イベントを使用してラベルの編集を禁止すること ができます。ラベルを編集可能にしたい場合は、EditLabels プロパティ を FALSE に設定し、EditLabel 関数を呼び出します。 EditLabel 関数を呼び出すと、 編集を開始したときには BeginLabelEdit イ ベントが、エンド ユーザが〔Enter〕を押したとき、あるいは別の項目 をクリックしたときには EndLabelEdit イベントが起動されます。 CommandButton イベントに対する以下のコードによって、現在の項目 が編集モードになります。 long h_tvi h_tvi = tv_1.findItem(CurrentTreeItem!, 0) tv_1.EditLabel(h_tvi) ドラッグ アンド ドロップによる項目の移動 PowerBuilder では、ウィンドウ レベルでコントロールをほかのコント ロールにドラッグするための関数とプロパティが用意されています。 ツリービュー内でエンド ユーザが項目をほかの項目にドラッグでき るようにすることもできます。エンド ユーザは、項目をソートする、 別の分岐に移動する、親項目の下に子項目を配置する、などの場合に ドラッグを利用できます。 項目の移動方法としてドラッグ アンド ドロップを実装した場合、ド ラッグされた項目が兄弟項目になるのか子項目になるのか、移動する のかコピーするのか、また、子項目も一緒に移動するのかを指定しま す。 表 8-4 に、ドラッグ アンド ドロップを実装する際に指定するプロパ ティとイベントを示します。 130 PowerBuilder 第8章 ツリービュー コントロールの使い方 表 8-4: ドラッグ アンド ドロップのプロパティとイベント プロパティまたは イベント DragAuto プロパティ 設定と目的 TRUE または FALSE FALSE の場合、BeginDrag イベントで Drag 関数を呼 び出さなければならない DisableDragDrop プロ パティ DragIcon プロパティ BeginDrag イベント DragWithin イベント DragDrop イベント 例 FALSE 適切なアイコン または None!(ユーザがアイテムの画像をドラッグする) ドラッグされた項目のハンドルを保存し、オプショ ンで特定の項目をドラッグできないようにするスク リプト ドロップ先をハイライト表示するスクリプト ドラッグ操作の結果を実装するスクリプト ドラッグ アンド ドロップの実装が成功する鍵は、詳細項目にありま す。この節では、項目を移動する方法について説明します。以下の例 では、ドラッグされた項目はドロップ先の兄弟項目になり、ドロップ 先の項目の後に挿入されます。子項目も一緒に移動され、元の項目は 削除されます。 関数を繰り返し呼び出すことにより、レベルの数にかかわらず、すべ てのレベルの子項目が移動されます。無限ループを避けるため、項目 が自分自身の子項目になることはできません。すなわち、ドラッグす る項目の子項目にドロップすることはできません。 BeginDrag イベント 以下のスクリプトは、ドラッグする項目のハンド ルをインスタンス変数に保存します。 ll_dragged_tvi_handle = handle 特定のレベルの項目のような一部の項目をドラッグできないようにし たい場合、以下のようなコードを作成します。 TreeViewItem tvi This.GetItem(handle, tvi) IF tvi.Level = 3 THEN This.Drag(Cancel!) DragWithin イベント 以下のスクリプトは、エンド ユーザがドロップ 先を確認できるように、カーソル位置の項目をハイライト表示します。 ドロップ先の項目が制限される場合には、その項目がドロップ先とし て適切かどうかをチェックしてからハイライト表示します。以下の例 では、ドラッグする項目の親項目かどうかをチェックし、親項目でな い場合のみハイライト表示します。 アプリケーション テクニック 131 ツリービューの項目の管理 TreeViewItem tvi This.GetItem(handle, tvi) tvi.DropHighlighted = TRUE This.SetItem(handle, tvi) 以下のスクリプトによって移動処理を実行しま す。選択した位置にその項目を挿入できるかどうかをチェックして、 新しい位置に(ドロップ先の兄弟項目として)ドラッグされた項目を 挿入します。その後で、ドラッグされた項目の子項目も移動する関数 を呼び出します。 DragDrop イベント TreeViewItem tvi_src, tvi_child long h_parent, h_gparent, h_moved, h_child integer rtn // ドラッグされた項目の TreeViewItem を取得します。 This.GetItem(ll_dragged_tvi_handle, tvi_src) // その項目の分岐先には移動できません。 // すなわち、その項目の子項目にはなれません。 h_gparent = This.FindItem(ParentTreeItem!, handle) DO WHILE h_gparent <> -1 IF h_gparent = ll_dragged_tvi_handle THEN MessageBox(" ドラッグできません ", & " 子項目にすることはできません ") RETURN 0 END IF h_gparent=This.FindItem(ParentTreeItem!, h_gparent) LOOP // 挿入先の親項目を取得します。 h_parent = This.FindItem(ParentTreeItem!, handle) // ドロップ先がレベル 1 のため親項目がない場合は 0 を使用します。 IF h_parent = -1 THEN h_parent = 0 // ドロップ先の後に項目を挿入します。 h_moved = This.InsertItem(h_parent, handle, tvi_src) IF h_moved = -1 THEN MessageBox(" ドラッグできません ", " 項目は移動できません ") RETURN 0 ELSE // 引数 :old parent、new parent rtn = uf_movechildren(ll_dragged_tvi_handle, & h_moved) 132 PowerBuilder 第8章 ツリービュー コントロールの使い方 // すべての子項目の移動が完了したら、 // 元の項目を削除します。 IF rtn = 0 THEN This.DeleteItem(ll_dragged_tvi_handle) END IF END IF 上記の DragDrop イベントのスクリプトでは、uf_movechildren 関数を呼 び出します。この関数は、ドラッグされた項目のすべてのレベルの子 項目が移動されるまで、繰り返しその関数自身を呼び出します。 // // // // // // // // // 関数 :uf_movechildren 引数 : oldparent - 子項目が移動された 項目のハンドル。最初は、別の位置にある 項目(ドラッグされる項目) newparent - 子項目の移動先 項目のハンドル。最初は、別の位置にある 項目(ドラッグされる項目) long h_child, h_movedchild TreeViewItem tvi // 挿入が失敗した場合は戻り値 -1 // 子項目があるか? h_child = tv_2.FindItem(ChildTreeItem!, oldparent) IF h_child <> -1 THEN tv_2.GetItem(h_child, tvi) h_movedchild = tv_2.InsertItemLast(newparent, tvi) IF h_movedchild = -1 THEN RETURN -1 // 子項目の子がある場合は移動します。 uf_movechildren(h_child, h_movedchild) // 元のレベルで、ほかに子項目がないかどうかをチェックします。 h_child = tv_2.FindItem(NextTreeItem!, h_child) DO WHILE h_child <> -1 tv_2.GetItem(h_child, tvi) h_movedchild= tv_2.InsertItemLast(newparent,tvi) IF h_movedchild = -1 THEN RETURN -1 uf_movechildren(h_child, h_movedchild) // 元のレベルに子項目が残っているか ? h_child = tv_2.FindItem(NextTreeItem!, h_child) アプリケーション テクニック 133 ツリービューの項目の管理 LOOP END IF RETURN 0 // すべての子項目の移動完了 項目のソート ツリービューの機能を使用して自動的にソートするか、開発者が手動 でソートを制御することができます。手動ソートでは、ラベルをアル ファベット順にソートできるほか、ソート条件を定義してユーザ定義 のソートを実装することもできます。SortType プロパティでソート方 法を制御します。このプロパティの値は、カタログ データ型 grSortType です。 自動アルファベット順ソート テキスト ラベルをソートするには、SortType プロパティを Ascending! または Descending! に設定します。挿入された 項目が自動的にソートされます。 手動アルファベット順ソート ソート条件をより細かく指定するには、 SortType を Unsorted! に設定し、表 8-5 の関数を呼び出してソートを実 行します。 表 8-5: ツリービューのソート関数 使用する関数 InsertItemSort Sort SortAll 処理内容 可能な場合には、アルファベット順で適切な位置に項 目を挿入する その項目のすぐ下の子項目をソートする その項目の分岐をすべてソートする ユーザが項目をドラッグしてリストを作成した場合、ソートは使用禁 止にしておく必要があります。 ラベル以外によるソート ラベル以外で項目をソートするには、 UserDefinedSort! に SortType プロパティを設定して Sort イベントに対す るスクリプトを作成し、ユーザ定義のソートを実装します。そのスク リプトでソートする方法を指定します。 並べ替えを試みるたびに Sort イベントが起動されます。Sort スクリプ トは、どの項目がほかの項目より大きいかを示す値を戻します。この スクリプトによって、項目の種類ごとに異なる基準でソートすること ができます。たとえば、レベル 2 の項目を、レベル 3 の項目とは異な る基準でソートできます。項目を挿入すると常にツリービューがソー トされます。 134 PowerBuilder 第8章 Sort イベントの例 ツリービュー コントロールの使い方 以下のサンプル スクリプトでは、第 1 レベルを Data プロパティの値 で、それ以外のレベルをラベルのアルファベット順にソートします。 Data プロパティにはその作曲家の世紀が登録されているので、第 1 レ ベルでは作曲家が年代順に並べられます。 // 戻り値 //-1 handle 1 は handle 2 より古い // 0 handle 1 と handle 2 は同じ // 1 handle 1 は handle 2 より新しい TreeViewItem tvi1, tvi2 This.GetItem(handle1, tvi1) This.GetItem(handle2, tvi2) IF tvi1.Level = 1 THEN // Data プロパティに登録されている世紀を比較 IF tvi1.data > tvi2.Data THEN RETURN 1 ELSEIF tvi1.data = tvi2.Data THEN RETURN 0 ELSE RETURN -1 END IF ELSE // ほかのレベルをアルファベット順にソート IF tvi1.Label > tvi2.Label THEN RETURN 1 ELSEIF tvi1.Label = tvi2.Label THEN RETURN 0 ELSE RETURN -1 END IF END IF アプリケーション テクニック 135 ツリービュー ピクチャの管理 ツリービュー ピクチャの管理 ツリービューの画像は、以下の 3 つの画像リストに保存されます。 • ピクチャ リスト(ここでは標準ピクチャ リストと呼びます) • 状態ピクチャ リスト • オーバーレイ ピクチャ リスト これらのリストにピクチャを追加して、ツリービューの項目と関連付 けます。 項目のピクチャ ツリービューでピクチャを使用するにはいくつかの方法があります。 表 8-6 に示されている項目のピクチャ プロパティを設定することによ り、ピクチャ リストにあるピクチャを項目と関連付けます。 表 8-6: ツリービュー ピクチャ プロパティ プロパティ PictureIndex StatePictureIndex 目的 その項目に関連付けられている主ピクチャ。ラベルの 左横に表示される 標準ピクチャの左側に表示される状態ピクチャ。状態 ピクチャを表示するスペースだけ項目が右に移動さ れる。Checkboxes プロパティが TRUE である場合は、 状態ピクチャは一組のチェックボックスに置き換え られる 状態ピクチャによって項目の位置がずれるので、状態 ピクチャがある項目とない項目では位置が揃わない。 すべての項目を揃えるには、空白の状態ピクチャを使 用するとよい OverlayPictureIndex エンド ユーザが選択した項目の横にチェックマーク を付ける場合などに状態ピクチャを使用する 標準ピクチャの上に表示されるオーバーレイ ピク チャ オーバーレイ ピクチャ リストに標準ピクチャ リスト のピクチャを割り当てるスクリプトによってオー バーレイ ピクチャを設定する オーバーレイ ピクチャは標準ピクチャと同じサイズ だが、標準ピクチャ全体に重ならないように、一部を 使用する場合が多い。Windows のエクスプローラで ショートカット アイテムを示す矢印などがオーバー レイ ピクチャである 136 PowerBuilder 第8章 プロパティ SelectedPictureIndex ツリービュー コントロールの使い方 目的 標準ピクチャ リストから選択したピクチャ。その項 目が現在の項目であるときに、標準ピクチャのかわり に表示される。エンド ユーザが別の項目を選択する と、最初の項目にその標準ピクチャが割り当てられ、 新しい項目に選択したピクチャが表示される 現在の項目であるときにも異なるピクチャを使用する 必要がない場合は、SelectedPictureIndex を PictureIndex と同じ値に設定する ピクチャの設定方法 . SetLevelPictures 関数を使用して、特定のレベルに属 するすべての項目のピクチャを変更することができます。あるいは、 項目ごとにピクチャ プロパティを設定できます。 ピクチャが必要ない場合 ツリービューの項目に必ずピクチャを付ける 必要はありません。その項目のピクチャ インデックスが 0 の場合、ピ クチャは表示されません。ただし、ツリービューでは常に、標準ピク チャ用のスペースが用意されています。PictureWidth プロパティを 0 に 設定すると、このスペースが削除されます。 tv_2.DeletePictures() tv_2.PictureWidth = 0 ピクチャ リストの設定 ペインタを使用して、あるいは実行時に、標準ピクチャ リストと状態 ピクチャ リストにピクチャを追加できます。実行時には、標準ピク チャ リストのピクチャをオーバーレイ リストに割り当てることがで きます。 マスクの色 マスクの色とは、ピクチャで使用される色の 1 つで、ツリービューに ピクチャが表示されるときには透明になります。通常は、ピクチャを ツリービューの色と合成できるように、ピクチャの背景色を使用しま す。 ペインタまたはスクリプトでピクチャを追加する前に、そのピクチャ に合わせてマスクの色を設定できます。以下のステートメントでは、 ピクチャの背景色が白なので、マスクの色を白に設定します。 tv_1.PictureMaskColor = RGB(255, 255, 255) ピクチャにはそれぞれ独自のマスクの色があります。ピクチャを挿入 するときに、この色が表示されます。ピクチャのマスクの色を変更す るには、そのピクチャを削除して追加し直さなければなりません。 アプリケーション テクニック 137 ツリービュー ピクチャの管理 画像サイズ ペインタで、各ピクチャ タブの Height と Width プロパティを設定する ことにより、随時画像サイズを変更できます。リスト内のピクチャは すべて、指定したサイズに拡大されます。 実行時には、リストが空の場合のみ、ピクチャ リストの画像サイズを 変更できます。DeletePictures 関数と DeleteStatePictures 関数でリストを 消去できます。 例 以下のサンプル コードは、実行時にプロパティを変更して標準ピク チャ リストにピクチャを追加する方法を示すものです。状況ピクチャ の場合もこのコードを応用してください。 tv_list.DeletePictures() tv_list.PictureHeight = 32 tv_list.PictureWidth = 32 tv_list.PictureMaskColor = RGB(255.255.255) tv_list.AddPicture("c:\apps_pb\kelly.bmp") tv_list.PictureMaskColor = RGB(255,0,0) tv_list.AddPicture("Custom078!") tv_list.PictureMaskColor = RGB(128,128,128) tv_list.AddPicture("Custom044!") ピクチャの削除による 既存の項目への影響 ピクチャ リストからピクチャを削除したときに、表示されている項目 のピクチャに予期せぬ変化が起こる場合があります。ピクチャを削除 すると、リストの空白を埋めるために、リスト内の残りのピクチャが 移動されます。これにより、それらのピクチャには異なるインデック ス値が割り当てられます。つまり、これらのインデックスを使用する 項目に、従来とは異なる画像が関連付けられるということです。 オーバーレイ リストは独立したリストではなく、標準ピクチャをポイ ントしているだけなので、標準ピクチャ リストからピクチャを削除す ると、オーバーレイ リストにも影響があります。 このように項目のピクチャが変更されるのを防ぐには、その項目のピ クチャ インデックスを使用した後はピクチャを削除しない方がよい でしょう。 オーバーレイ ピクチャの使い方 オーバーレイ リストのピクチャは、標準ピクチャ リストに対応してい ます。まず、ペインタを使用して、または実行時に、標準リストにピ クチャを追加しなければなりません。次に、実行時にオーバーレイ ピ クチャ リストにピクチャを指定します。その後で、SetLevelPictures 関 数を使うか、個別にピクチャを項目に割り当てます。 138 PowerBuilder 第8章 ツリービュー コントロールの使い方 以下のコードでは、標準ピクチャ リストにピクチャを追加してから、 そのピクチャをオーバーレイ リストに割り当てます。 integer idx idx = tv_1.AddPicture("Custom085!") IF tv_1.SetOverlayPicture(1, idx) <> 1 THEN sle_get.Text = "Setting overlay picture failed" END IF Clicked イベントに対する以下のコードは、エンド ユーザがその項目を クリックするごとにオーバーレイ ピクチャの表示 / 非表示を切り替え ます。 treeviewitem tvi This.GetItem(handle, tvi) IF tvi.OverlayPictureIndex = 0 THEN tvi.OverlayPictureIndex = 1 ELSE tvi.OverlayPictureIndex = 0 END IF This.SetItem(handle, tvi) データウィンドウのデータのツリービューへの表示 データウィンドウから取り出したデータを使用して、ツリービュー コ ントロールを表示するのもよい方法です。このためには、アプリケー ションで以下の操作を実行しなければなりません。 • データストアを宣言してインスタンスを作成し、データウィンド ウ オブジェクトを割り当てる • 必要に応じてデータを取り出す • 取り出されたデータを使用してツリービューを表示する • 処理が完了したらデータストアのインスタンスを破棄する ツリービューでは異なるレベルで異なる種類のデータを表示できるの で、レベルごとに追加のデータウィンドウを定義できます。これらの データウィンドウは、通常異なるテーブル(関連するテーブル)を参 照します。分岐を開くと、その項目は子項目を取得するための検索引 数になります。 アプリケーション テクニック 139 データウィンドウのデータのツリービューへの表示 第 1 レベルの表示 以下の例では、作曲家リストのツリービューを表示します。ツリー ビューの第 2 レベルには、その作曲家の楽曲が表示されます。データ ベースには、作曲家名と、 (作曲家名を外部キーとする)楽曲名の 2 つ のテーブルがあります。 この例では、ツリービュー コントロールを表示するウィンドウ用に、 以下の 2 つのデータストア インスタンス変数を宣言します。 datastore ids_data, ids_info この例では、ツリービュー コントロールの Constructor イベントを使用 して以下の処理を行います。 • データストアのインスタンスを作成する • 作成したインスタンスをデータウィンドウに関連付け、データを 取り出す • 取り出されたデータを使用してツリービューのルート レベルを表 示する // tv_1 に対する Constructor イベント treeviewitem tvi1, tvi2 long ll_lev1, ll_lev2, ll_rowcount, ll_row // データストアのインスタンス変数を作成します。 ids_data = CREATE datastore ids_data.DataObject = "d_composers" ids_data.SetTransObject(SQLCA) ll_rowcount = ids_data.Retrieve() // ツリービューの第 1 レベルを作成します。 tvi1.PictureIndex = 1 tvi1.Children = TRUE // データストアから取り出されたデータで // ツリービューを表示します。 FOR ll_row = 1 to ll_rowcount tvi1.Label = ids_data.GetItemString(ll_row, & 'name') This.InsertItemLast(0, tvi1) NEXT 140 PowerBuilder 第8章 第 2 レベルの表示 ツリービュー コントロールの使い方 エンド ユーザがルート レベルの項目を開くと、ItemPopulate イベント が起動されます。このイベントに対するスクリプトで、以下の処理を 行います。 • 2 番目のデータストアのインスタンスを作成する そのデータウィンドウで、作曲家名を楽曲名テーブルの検索引数 として使用します。 • 選択した作曲家に楽曲名を子項目として挿入する ItemPopulate のハンドル引数は、新しい項目の親項目になります。 // tv_1 に対する ItemPopulate イベント TreeViewItem tvi1, tvi2 long ll_row, ll_rowcount // データストアのインスタンス変数を作成します。 ids_info = CREATE datastore ids_info.DataObject = "d_music" ids_info.SetTransObject(SQLCA) // 表示されている項目のラベルを // 検索引数として使用します。 This.GetItem(handle, tvi1) ll_rowcount = ids_info.Retrieve(tvi1.Label) // データベースから取り出されたデータを使用して // 開かれた項目を表示します。 FOR ll_row = 1 to ll_rowcount This.InsertItemLast(handle, & ids_info.GetItemString(ll_row, & music_title'), 2) NEXT データストア インス タンスの破棄 ツリービュー コントロールが表示されているウィンドウを閉じると きに、以下のコードでデータストアのインスタンスを破棄します。 // w_treeview に対する Close イベント DESTROY ids_data DESTROY ids_info アプリケーション テクニック 141 データウィンドウのデータのツリービューへの表示 142 PowerBuilder 第 9 章 ウィンドウでのリストの使い方 この章について この章では、アプリケーションにおいて情報を提示するリストの 使い方について説明します。 内容 項目 リストの提示について リストの使い方 ドロップダウン リストの使い方 リストビュー コントロールの使い方 ページ 143 144 149 152 リストの提示について アプリケーションでリストを提示する複数の方法があります。 アプリケーション テクニック • リストボックスとピクチャ リストボックスは、テキストの表 示とアクションの起動ができます。選択肢を表示して、エン ド ユーザに選択させます。 • ドロップダウン リストボックスとドロップダウン ピクチャ リ ストボックスも、選択肢を表示します。また、エンド ユーザ に表示しているテキストを編集させることもできます。ド ロップダウン リストボックスはテキストだけのリストです。 ドロップダウン ピクチャ リストボックスはテキストとピク チャを一緒に表示します。 • リストビュー コントロールは、ピクチャとテキストの両方を 一 緒 にリ ス ト に し て 提 示し ま す。エ ン ド ユ ー ザ に リス ト ビューの項目を追加、削除、編集、および再配置させること ができます。また、リストビューの項目を使用してアクショ ンを起動させることもできます。 143 リストの使い方 ツリービュー コントロール ツリービュー コントロールも、ピクチャとテキストを一緒にリストに 提示します。リストビュー コントロールとの違いは、ツリービュー コ ントロールは、ツリービュー項目間の階層的な関係を表示することで す。リストビュー コントロールと同じように、エンド ユーザにツリー ビュー項目を追加、削除、編集、および再配置させることができます。 また、アクションを起動させることもできます。 ツリービューの詳細については、第 8 章「ツリービュー コントロール の使い方」を参照してください。 リストの使い方 リストを使用して、エンド ユーザに、スクロールできる簡単なリスト で情報を提示できます。ピクチャ リストボックスは、テキストとピク チャの情報を提示できます。また、リストボックスは、テキストの情 報だけを提示できます。 アプリケーションの設計にもよりますが、エンド ユーザは、1 つまた はそれ以上のリスト項目を選択して、その選択に基づいたアクション を実行できます。 ウィンドウにリストボックス コントロールまたはピクチャ リスト ボックス コントロールを追加するには、ほかのコントロールを追加す るのと同様の方法で行います。つまり、 [挿入|コントロール]メニュー から[リストボックス]または[ピクチャ リストボックス]を選択し て、ウィンドウ上の配置したい位置でクリックします。 新規項目を追加するには、コントロールの[項目]プ ロパティ ページを使用します。 リスト コントロール への項目の追加 ペインタで追加 v リストボックスまたはピクチャ リストボックスに項目を追加するには 1 コントロールのプロパティ ビューで[項目]タブを選択します。 2 リストボックスの項目名を入力します。さらに、ピクチャ リスト ボックスの場合は、項目にピクチャを関連付けるため、ピクチャ インデックスを[ピクチャ インデックス]ボックスに入力します。 ピクチャ リストボックスにピクチャを追加する方法については、 145 ページの「ピクチャ リストボックス コントロールへのピク チャの追加」を参照してください。 144 PowerBuilder 第9章 ウィンドウでのリストの使い方 スクリプトで追加 実行時に、リストボックスまたはピクチャ リスト ボックスに項目を動的に追加するには、AddItem 関数と InsertItem 関数 を使用します。AddItem 関数は、リストの最後に項目を追加します。し かし、リストがソートされると、その項目はソート順の該当する位置 に移動されます。リスト中で項目が挿入される位置を指定したい場合 は、InsertItem 関数を使用します。 表 9-1: InsertItem 関数と AddItem 関数の使用 関数 InsertItem 指定する内容 項目名 項目の挿入位置 (ピクチャ リストボックスの場合)ピクチャ インデックス AddItem 項目名 (ピクチャ リストボックスの場合)ピクチャ インデックス たとえば、以下のスクリプトでは、リストボックスに項目を追加します。 This.AddItem (" 小物 ") This.InsertItem (" ソフトウェア ",2) This.InsertItem (" ハードウェア ",2) This.InsertItem (" ドキュメント ",2) 以下のスクリプトでは、ピクチャ リストボックスに項目とピクチャを 追加します。 This.AddItem (" モニタ ",2) This.AddItem (" モデム ", 3) This.AddItem (" プリンタ ",4) This.InsertItem (" スキャナ ",5,1) Sort プロパティの使い方 リスト項目が常にアルファベットの昇順に並ぶようにするには、コン トロールの Sort プロパティに TRUE を設定するか、 [全般]プロパティ ページで[ソート]チェックボックスをオンにします。 ペインタで追加 ピクチャを追加するには、コントロールの[ピクチャ] プロパティ ページと[項目]プロパティ ページを使用します。 ピクチャ リストボッ クス コントロールへ のピクチャの追加 v ピクチャ リストボックスにピクチャを追加するには 1 2 アプリケーション テクニック コントロールのプロパティ ビューで[ピクチャ]タブを選択します。 ドロップダウン リストボックスからピクチャを選択するか、参照 ([...])ボタンをクリックして、ビットマップ、ポインタ、または アイコン ピクチャを選択します。 145 リストの使い方 3 [ピクチャのマスク色]ドロップダウン リストボックスからピクチャ の色を選択します。 ピクチャ マスクに選択した色は、ピクチャ リストボックスでは透 明に見えます。 4 ピクチャの高さと幅を選択します。 これで、ピクチャ リストボックスのピクチャのサイズを調整します。 動的にピクチャ サイズを変更する スクリプトで、実行時にピクチャのサイズを変更できます。ピク チャ リストボックスにピクチャが 1 つも追加されていない場合だ け、PictureHeight プロパティと PictureWidth プロパティを設定でき ます。 PictureHeight プロパティと PictureWidth プロパティの詳細につい ては、 『PowerScript リファレンス』マニュアルを参照してください。 5 ピクチャ リストボックスで使用する各ピクチャに対して処理を繰 り返します。 6 [項目]タブを選択し、各項目の[ピクチャ インデックス]を適切 な数字に変更します。 スクリプトで追加 実行時に、ピクチャ リストボックスにピクチャを動 的に追加するには、AddPicture 関数を使用します。以下の例では、ピク チャのサイズを設定し、ピクチャ リストボックスにビットマップ ファ イルを追加して、ピクチャ リストボックスに項目を追加します。 This.PictureHeight = 75 This.PictureWidth = 75 This.AddPicture ("c:\ArtGal\bmps\butterfly.bmp") This.AddItem("Aine Minogue",8) ピクチャ リスト コン トロールからのピク チャの削除 ピクチャ リストボックスまたはドロップダウン ピクチャ リストボッ クスのいずれかからピクチャを削除するには、DeletePicture 関数と DeletePictures 関数を使用します。 DeletePicture 関数を使用する場合、削除したいピクチャのピクチャ イ ンデックスを指定する必要があります。 例 This.DeletePicture (1) コントロールから最初のピクチャを削除します。次に、 This.DeletePictures () 146 PowerBuilder 第9章 ウィンドウでのリストの使い方 コントロールからすべてのピクチャを削除します。 以下のウィンドウには、リストボックスとピクチャ リストボック スがあります。リストボックスの項目は 4 つあり、ピクチャ リスト ボックスの項目は 1 つあります。 例 エンド ユーザがリストボックスの項目をダブルクリックすると、スク リプトは以下を実行します。 • ピクチャ リストボックスからすべての項目を削除する • ダブルクリックされたリストボックスの項目に関連する項目を、 ピクチャ リストボックスに新しく追加する 以下は、リストボックスの DoubleClicked イベントに対するスクリプト です。 int li_count // ピクチャ リストボックスの // 項目数を取得します。 li_count = plb_1.totalItems() // // // // // アプリケーション テクニック どの項目がダブルクリックされたかを判別します。 次に * ピクチャ リストボックスからすべての項目を削除します。 * ダブルクリックされた項目に 関連する項目を追加します。 147 リストの使い方 CHOOSE CASE index CASE 1 DO WHILE plb_1.totalitems() > 0 plb_1.DeleteItem(plb_1.totalitems()) LOOP plb_1.AddItem(" モニタ ",2) plb_1.AddItem(" モデム ",3) plb_1.AddItem(" プリンタ ",4) plb_1.InsertItem(" スキャナ ",5,1) CASE 2 DO WHILE plb_1.totalitems() > 0 plb_1.DeleteItem(plb_1.totalitems()) LOOP plb_1.InsertItem(" グリーンバー ",6,1) plb_1.InsertItem(" レターヘッド ",7,1) plb_1.InsertItem(" コピー ",8,1) plb_1.InsertItem("50 lb.",9,1) CASE 3 DO WHILE plb_1.totalitems() > 0 plb_1.DeleteItem(plb_1.totalitems()) LOOP plb_1.InsertItem("SpreadIt!",10,1) plb_1.InsertItem("WriteOn!",11,1) plb_1.InsertItem("WebMaker!",12,1) plb_1.InsertItem("Chessaholic",13,1) CASE 4 DO WHILE plb_1.totalitems() > 0 plb_1.DeleteItem(plb_1.totalitems()) LOOP plb_1.InsertItem("AlnaWarehouse",14,1) plb_1.InsertItem("AlnaInfo",15,1) plb_1.InsertItem("Info9000",16,1) plb_1.InsertItem("AlnaThink",17,1) END CHOOSE 148 PowerBuilder 第9章 ウィンドウでのリストの使い方 ドロップダウン リストの使い方 ドロップダウン リストは、エンド ユーザに簡単なリストで情報を提示 できるもう 1 つの方法です。ドロップダウン リストボックスではテキ ストだけを提示したり、ドロップダウン ピクチャ リストボックスでは テキストとピクチャを提示したりできます。ドロップダウン リスト ボックスおよびドロップダウン ピクチャ リストボックス コントロー ルをウィンドウに追加する方法は、ほかのコントロールを追加する方 法と同じです。つまり、 [挿入|コントロール]メニューから[ドロッ プダウン リストボックス]または[ドロップダウン ピクチャ リスト ボックス]を選択して、ウィンドウ上の配置したい位置でクリックし ます。 項目を追加するには、コントロールの[項目]プロパ ティ ページを使用します。 ドロップダウン リス ト コントロールへの 項目の追加 ペインタで追加 v ドロップダウン リストボックスまたはドロップダウン ピクチャ リストボッ クスに項目を追加するには 1 コントロールのプロパティ ビューで[項目]タブを選択します。 2 リストボックスの項目名を入力します。さらに、ピクチャ リスト ボックスの場合は、項目にピクチャを関連付けるため、ピクチャ インデックスを[ピクチャ インデックス]ボックスに入力します。 ドロップダウン ピクチャ リストボックスへのピクチャの追加方 法については、150 ページの「ドロップダウン ピクチャ リストボッ クス コントロールへのピクチャの追加」を参照してください。 実行時に、ドロップダウン リストボックスやドロップ ダウン ピクチャ リストボックスに動的に項目を追加するには、AddItem 関数や InsertItem 関数を使用します。 スクリプトで追加 AddItem 関数は、リストの最後に項目を追加します。しかし、リストが ソートされると、その項目はソート順の該当する位置に移動されます。 リスト中で項目が挿入される位置を指定したい場合は、InsertItem 関数 を使用します。 アプリケーション テクニック 149 ドロップダウン リストの使い方 表 9-2: InsertItem 関数と AddItem 関数の使用 関数 InsertItem AddItem 指定する内容 項目名 (ドロップダウン ピクチャ リストボックスの場合)ピクチャ インデックス 項目の挿入位置 項目名 (ドロップダウン ピクチャ リストボックスの場合)ピクチャ インデックス 以下の例では、ドロップダウン ピクチャ リストボックスの 1 番目、2 番 目、3 番目のそれぞれの位置に、項目を挿入します。 This.InsertItem ("Atropos", 2, 1) This.InsertItem ("Clotho", 2, 2) This.InsertItem ("Lachesis", 2, 3) 以下の例では、ドロップダウン ピクチャ リストボックスに 2 つの項目 を追加します。 this.AddItem ("Plasma", 2) this.AddItem ("Platelet", 2) Sort プロパティの使い方 リストの項目を常に昇順にソートするには、コントロールの Sort プロ パティに TRUE を設定します。 ピクチャを追加するには、リストビュー コントロール の[ピクチャ]と[項目]プロパティ ページを使用します。 ドロップダウン ピク チャ リストボックス コントロールへのピク チャの追加 ペインタで追加 v ドロップダウン ピクチャ リストボックスにピクチャを追加するには 1 コントロールのプロパティ ビューで[ピクチャ]タブを選択しま す。 2 ドロップダウン リストボックスからピクチャを選択するか、参照 ([...])ボタンをクリックして、ビットマップ、ポインタ、または アイコン ピクチャを選択します。 3 [ピクチャのマスク色]ドロップダウン リストボックスからピクチャ の色を選択します。 ピクチャ マスクに選択した色は、ドロップダウン ピクチャ リスト ボックスでは透明に見えます。 150 PowerBuilder 第9章 4 ウィンドウでのリストの使い方 ピクチャの高さと幅をそれぞれ選択します。 これで、ドロップダウン ピクチャ リストボックスのピクチャのサ イズを調整します。 動的にピクチャ サイズを変更する ピクチャ サイズの変更を実行時に行うには、ドロップダウン ピク チ ャ リ ス ト ボ ッ ク ス の 作 成 時 に、PictureHeight プ ロ パ テ ィ と PictureWidth プロパティを設定してからピクチャを追加します。 PictureHeight プロパティと PictureWidth プロパティの詳細につい ては、 『PowerScript リファレンス』マニュアルを参照してください。 5 ドロップダウン ピクチャ リストボックスで使用する各ピクチャに対 して処理を繰り返します。 6 [項目]タブを選択し、各項目の[ピクチャ インデックス]を適切 な数字に変更します。 実行時に、ピクチャ リストボックスにピクチャを動 的に追加するには、AddPicture 関数を使用します。たとえば、以下の例 では、ピクチャ リストボックスに 2 つのビットマップ ファイルを追加 します。 スクリプトで追加 This.AddPicture ("c:\images\justify.bmp") This.AddPicture ("c:\images\center.bmp") ドロップダウン ピク チャ リストボックス コントロールからのピ クチャの削除 ドロップダウン ピクチャ リストボックス コントロールからのピクチャ の削除方法については、146 ページの「ピクチャ リスト コントロール からのピクチャの削除」を参照してください。 アプリケーション テクニック 151 リストビュー コントロールの使い方 リストビュー コントロールの使い方 リストビュー コントロールでは、いろいろな組み合わせでテキストと アイコンを表示できます。大きいアイコンや小さいアイコンをフリー フォーム形式で表示したり、一覧形式でリストを表示したりできます。 また、各リスト項目についての詳細情報を、リスト項目に関連する追 加カラムとしていっしょに表示できます。 リストビュー コントロールは、リストビュー項目で構成されます。そ れぞれのリストビュー項目は配列に格納されています。リストビュー 項目は、以下で構成されます。 リストビュー項目の名前 • ラベル • インデックス コントロールにおけるリストビュー項目の表示位置 • ピクチャ インデックス リストビュー項目に関連するピクチャの番 号 提示されるスタイルにもよりますが、大きいピクチャまたは小さ いピクチャは、リストビュー項目に関連付けることもできます。 • オーバーレイ ピクチャ インデックス リストビュー項目に関連付け るオーバーレイ ピクチャの番号 • 状態ピクチャ インデックス リストビュー項目に関連付ける状態ピ クチャの番号 リストビュー項目、ピクチャ インデックス、提示様式の詳細について は、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してくだ さい。 152 PowerBuilder 第9章 ウィンドウでのリストの使い方 リストビュー コント ロールの作成 ウィンドウにリストビュー コントロールを追加するには、ほかのコン トロールを追加するのと同様の方法で行います。つまり、 [挿入|コン トロール]メニューから[リストビュー]を選択して、ウィンドウ上 の配置したい位置でクリックします。 リストビュー項目の追 加 ペインタで追加 項目を追加するには、コントロールの[項目]プロパ ティ ページを使用します。 v リストビューに項目を追加するには 1 コントロールのプロパティ ビューで[項目]タブを選択します。 2 リストビューに追加する項目のラベルとピクチャ インデックスを 入力します。 [項目]タブ ページのすべてのエントリを消去する 最初の項目のピクチャ インデックスをゼロに設定すると、タブ ページ上のすべての設定が消去されます。 リストビュー コントロールにピクチャを追加する方法の詳細につ いては、154 ページの「リストビュー コントロールへのピクチャ の追加」を参照してください。 スクリプトで追加 実行時に、リストビューに項目を動的に追加するに は、AddItem 関数と InsertItem 関数を使用します。リストビューに項目 を追加するために、AddItem 関数または InsertItem 関数を使用する場合 は、2 つの方法があります。 以下の例が示すように、ピクチャ インデックスとラベルを指定して、 項目を追加できます。 lv_1.AddItem("Item 1", 1) または、リストビュー、ラベル、およびピクチャ インデックスの項目 の表示位置を指定して、項目を挿入できます。 lv_1.InsertItem (1,"Item 2", 2) リストビュー項目を直接指定して追加することもできます。リスト ビューの DragDrop イベントに対する以下のスクリプトの例では、リス トビューにドラッグされたリストビュー項目を挿入します。 listviewitem lvi This.GetItem(index, lvi) lvi.label = "Test" lvi.pictureindex = 1 This.AddItem (lvi) アプリケーション テクニック 153 リストビュー コントロールの使い方 または、リストビューの表示位置とリストビュー項目を指定して、項 目を挿入できます。 listviewitem l_lvi //2 番目のリストビュー項目の情報を // 取得します。 lv_list.GetItem(2, l_lvi) // 項目のラベルを Entropy に変更します。 //5 番目の表示位置に 2 番目の項目を挿入します。 lv_list.InsertItem (5, l_lvi) lv_list.DeleteItem(2) リストビュー コント ロールへのピクチャの 追加 PowerBuilder は 4 つのピクチャ リストに、リストビューのピクチャを 保持します。 • 小さいピクチャ インデックス • 大きいピクチャ インデックス • 状態ピクチャ インデックス • オーバーレイ ピクチャ インデックス ペインタを使用するか、または実行時に AddItem 関数と InsertItem 関数 を使用してリストビューを作成した場合、上記のピクチャをリスト ビュー項目に関連付けることができます。 しかし、リストビュー項目にピクチャを関連付けるには、リストビュー コントロールにリストビュー項目が追加されていなければなりませ ん。 ピクチャを追加するには、リストビュー コントロール の[ピクチャ]と[項目]プロパティ ページを使用します。 ペインタで追加 v リストビュー コントロールにピクチャを追加するには 1 コントロールのプロパティ ビューで、 [大きいピクチャ]、 [小さい ピクチャ]、または [状態]タブのいずれかを選択します。 オーバーレイ ピクチャ スクリプトでのみ、リストビュー コントロールにオーバーレイ ピ クチャを追加できます。 2 ドロップダウン リストボックスからピクチャを選択するか、参照 ([...])ボタンをクリックして、ビットマップ、ポインタ、または アイコン ピクチャを選択します。 3 [ピクチャのマスク色]ドロップダウン リストボックスからピクチャ の色を選択します。 154 PowerBuilder 第9章 ウィンドウでのリストの使い方 ピクチャ マスクに選択した色は、リストビューでは透明に見えま す。 ピクチャの高さと幅をそれぞれ選択します。 4 これで、リストビューのピクチャのサイズを調整します。 動的にピクチャ サイズを変更する ピクチャ サイズの変更を実行時に行うには、リストビューの作成 時に、PictureHeight プロパティと PictureWidth プロパティを設定 してからピクチャを追加します。PictureHeight プロパティと PictureWidth プロパティの詳細については、『PowerScript リファレ ンス』マニュアルを参照してください。 以下に対して処理を繰り返します。 5 • リストビューで使用するピクチャの種類(大きい、小さい、状 態)の数 • リストビューで使用する各ピクチャの種類に対応したピク チャの数 リストビューのピクチャリストにピクチャを追加す るには、表 9-3 に示されている関数を使用します。 スクリプトで追加 表 9-3: リストビュー ピクチャリストにピクチャを追加する関数 関数 ピクチャリストに追加するピクチャ AddLargePicture 大きいピクチャ 小さいピクチャ 状態ピクチャ AddSmallPicture AddStatePicture 大きいピクチャと小さいピクチャの追加 以下の例では、大きいピクチャ と小さいピクチャの高さと幅を設定して、大きいピクチャのピクチャ リストと小さいピクチャのピクチャ リストに 3 つのピクチャを追加し ます。 // 大きいピクチャの高さと幅を設定します。 lv_1.LargePictureHeight=32 lv_1.LargePictureWidth=32 // 大きいピクチャを追加します。 lv_1.AddLargePicture("c:\ArtGal\bmps\celtic.bmp") lv_1.AddLargePicture("c:\ArtGal\bmps\list.ico") lv_1.AddLargePicture("Custom044!") // 小さいピクチャの高さと幅を設定します。 アプリケーション テクニック 155 リストビュー コントロールの使い方 lv_1.SmallPictureHeight=16 lv_1.SmallPictureWidth=16 // 小さいピクチャを追加します。 lv_1.AddSmallPicture("c:\ArtGal\bmps\celtic.bmp") lv_1.AddSmallPicture("c:\ArtGal\bmps\list.ico") lv_1.AddSmallPicture("Custom044!") // リストビューに項目を追加します。 lv_1.AddItem("Item 1", 1) lv_1.AddItem("Item 2", 1) lv_1.AddItem("Item 3", 1) 項目のオーバーレイとして、大きいピク チャや小さいピクチャを使用するには、SetOverLayPicture 関数を使用し ます。以下の例では、リストビューに大きいピクチャを追加して、リ ストビュー項目のオーバーレイ ピクチャとして、大きいピクチャを使 用します。 オーバーレイ ピクチャの追加 listviewitem lvi_1 int li_index // リストビューに大きいピクチャを追加します。 li_index = lv_list.AddLargePicture & ("c:\ArtGal\bmps\dil2.ico") // 追加した大きいピクチャを // オーバーレイ ピクチャとして設定します。 lv_list.SetOverlayPicture (3, li_index) // リストビュー項目とともにオーバーレイ ピクチャを使用します。 lv_list.GetItem(lv_list.SelectedIndex (), lvi_1) lvi_1.OverlayPictureIndex = 3 lv_list.SetItem(lv_list.SelectedIndex (), lvi_1) 状態ピクチャの追加 以下の例では、選択されたリストビュー項目に状 態ピクチャを設定するために、項目の StatePictureIndex プロパティを使 用します。 listviewitem lvi_1 lv_list.GetItem(lv_list.SelectedIndex (), lvi_1) lvi_1.StatePictureIndex = 2 lv_list.SetItem(lv_list.SelectedIndex (), lvi_1) 156 PowerBuilder 第9章 リストビューの項目と ピクチャの削除 ウィンドウでのリストの使い方 DeleteItem 関数で、リストビューから項目を 1 つずつ削除できます。 DeleteItems 関数は、リストビューからすべての項目を削除します。同 様に、DeleteLargePicture 関数、DeleteSmallPicture 関数、DeleteStatePicture 関数で、特定の種類のピクチャを 1 つずつ削除できます。 DeleteLargePictures 関数、DeleteSmallPictures 関数、DeleteStatePictures 関 数は、特定の種類のピクチャをすべて削除します。 以下の例では、リストビューから、1 つの項目とすべての小さいピク チャを削除します。 int li_index li_index = This.SelectedIndex() This.DeleteItem (li_index) This.DeleteSmallPictures () ホット トラッキング とシングルまたはダブ ル クリックによるア クティブ化 ホット トラッキングでは、リストビュー コントロール内の項目の上に マウスが移動するとその項目の外観が変化し、マウスが一時停止する と、カーソルの下にある項目が自動選択されます。ホット トラッキン グを有効にするには、TrackSelect プロパティに TRUE を設定します。 また、OneClickActivate または TwoClickActivate に TRUE を設定しても、 ホット トラッキングが有効になります。OneClickActivate が TRUE の場 合には、UnderlineHot プロパティまたは UnderlineCold プロパティを設 定することによって、選択した項目または選択しない項目に下線を付 けるよう指定できます。これらすべてのプロパティは、コントロール の[全般]プロパティ ページまたはスクリプトで設定できます。 表 9-4 に示されている OneClickActivate と TwoClickActivate の設定は、 ItemActivate イベントが発生したときに作用します。 表 9-4: OneClickActivate と TwoClickActivate の設定 カスタム イベントの 使い方 ItemActivate が発生する タイミング OneClickActivate TwoClickActivate TRUE TRUE または FALSE 任意の項目をクリック FALSE TRUE FALSE FALSE 選択した項目をクリック 任意の項目をダブルクリック PowerBuilder バージョン 7 以降のリリースでは、リストビュー コント ロールとツリービュー コントロールに Microsoft のコントロールが使 用されており、右クリックしたときに発生するイベントが以前のバー ジョンとは異なります。以下に、リストビュー コントロール内で右ク リックしたときに発生するイベントを示します。 アプリケーション テクニック 157 リストビュー コントロールの使い方 表 9-5: 右クリックで発生するリストビュー コントロールのイベント 場所 リストビュー 項目 リストビュー 内の空白領域 動作内容 マウスの右ボタ ンを押す マウスの右ボタ ンを放す マウスの右ボタ ンを押す マウスの右ボタ ンを放す 発生するイベント pbm_rbuttondown pbm_lvnrclicked(組み込み RightClicked! イベント) pbm_contextmenu pbm_rbuttondown pbm_lvnrclicked(組み込み RightClicked! イベント) pbm_contextmenu pbm_rbuttonup pbm_contextmenu 詳細表示の使い方 リストビューの詳細表示は、大きいアイコン表示、小さいアイコン表 示、そして一覧表示より多くの情報を必要とします。リストビュー コ ントロールで詳細表示するには、AddColumn 関数と SetColumn 関数でカ ラムを設定するスクリプトを記述し、SetItem 関数を使用してカラムの 値を設定します。 カラム値の設定 リストビューでカラムを作成するには、AddColumn 関数を使用します。 AddColumn 関数を使用するときは、以下の指定をします。 カラム ヘッダで表示される名前 • カラム ラベル • カラム配置 • カラムのサイズ PowerBuilder 単位系でのカラムの幅 テキストの左詰め、右詰め、または中央揃え 以下の例では、リストビューに 3 つのカラムを作成します。 This.AddColumn("Name", Left!, 1000) This.AddColumn("Size", Left!, 400) This.AddColumn("Date", Left!, 300) カラムの設定 カラム番号、名前、配置、サイズを設定するには、SetColumn 関数を使 用します。 This.SetColumn (1, "Composition", Left!, 860) This.SetColumn (2, "Album", Left!, 610) This.SetColumn (3, "Artist", Left!, 710") 158 PowerBuilder 第9章 カラム項目の設定 ウィンドウでのリストの使い方 リストビューのカラムに値を設定するには SetItem 関数を使用します。 This.SetItem This.SetItem This.SetItem This.SetItem This.SetItem This.SetItem This.SetItem This.SetItem This.SetItem (1, (1, (1, (2, (2, (2, (3, (3, (3, 1, 2, 3, 1, 2, 3, 1, 2, 3, "St.Thomas") "Saxophone Colossus") "Sonny Rollins") "So What") "Kind of Blue") "Miles Davis") "Good-bye, Porkpie Hat") "Mingus-ah-um") "Charles Mingus") リストビュー コントロールへのカラムの追加の詳細については、 『PowerScript リファレンス』マニュアルを参照してください。 アプリケーション テクニック 159 リストビュー コントロールの使い方 160 PowerBuilder 第 1 0 章 ドラッグ アンド ドロップ機能の 使い方 この章について この章では、ドラッグ アンド ドロップ機能を使用して、アプリ ケーションをグラフィカルに操作する方法について説明します。 内容 項目 ドラッグ アンド ドロップ機能について ドラッグ アンド ドロップのプロパティ、イベント、および関 数 ドラッグされたコントロールの識別 ページ 161 162 164 ドラッグ アンド ドロップ機能について ドラッグ アンド ドロップ機能とは、コントロールをドラッグし、 ほかのコントロール上にドロップすることで、アクションを起動 する機能のことです。この機能を用いると、アプリケーションが グラフィカルで操作しやすくなります。たとえば、製造用のアプ リケーションで、部品のピクチャをドラッグし、完成した組み立 て品のピクチャにドロップすることで、組み立て作業を行えるよ うにできます。 ドラッグ アンド ドロップ操作には、ドラッグされるコントロール (ドラッグ コントロール)とドラッグ先のコントロール(ターゲッ ト)の少なくとも 2 つのコントロールが必要となります。 PowerBuilder では、描画オブジェクト(線、楕円、長方形、丸長方形)を除く すべてのコントロールをドラッグすることができます。 自動ドラッグ モード アプリケーション テクニック コントロールは、ドラッグされるとドラッグ モードになります。 コントロールに Clicked イベントが発生したときに自動的にド ラッグ モードになるように、コントロールを定義することができ ます。また、ウィンドウやアプリケーションで、あるイベントが 発生したときにコントロールがドラッグ モードになるようにスク リプトを記述することもできます。 161 ドラッグ アンド ドロップのプロパティ、イベント、および関数 ドラッグ アイコン ドラッグ可能なコントロールのスタイルをウィンドウ ペインタで定 義する際に、ドラッグ アイコンを指定することができます。ドラッグ アイコンは、そのコントロールが有効なドロップ領域(コントロール をドロップできる領域)上にドラッグされると表示されます。ドラッ グ アイコンを指定していない場合は、そのコントロールのサイズの長 方形が表示されます。 ドラッグ イベント 描画オブジェクトを除くすべてのコントロールとウィンドウ オブ ジェクトは、ドラッグ ターゲットになったときに特別なイベントを持 つことができます。ドラッグされたコントロールがターゲット内に 入ったりターゲット上にドロップされたりすると、該当するイベント のスクリプトが実行されます。ドラッグ コントロールがターゲットに 入るとき、ターゲット内にドラッグされているとき、ターゲットから 離れるとき、ターゲット上にドロップされるとき、それぞれのタイミ ングでどのような処理を行うかをスクリプトで指定します。 ドラッグ アンド ドロップのプロパティ、イベント、および 関数 ドラッグ アンド ド ロップのプロパティ PowerBuilder の各コントロールは、以下の 2 つのドラッグ アンド ド ロップのプロパティを持ちます。 • DragAuto • DragIcon DragAuto プロパティ DragAuto は、Boolean 型のプロパティです。 表 10-1: DragAuto プロパティ値 値 TRUE FALSE v 意味 オブジェクトがクリックされると、コントロールは自動的にド ラッグ モードになる オブジェクトがクリックされても、コントロールは自動的には ドラッグ モードにならない。ドラッグ モードにするには、スク リプトで Drag 関数を使用しなければならない ウィンドウ ペインタでコントロールに対する自動ドラッグ モードを指定する には 1 コントロールのプロパティ ビューで[その他]プロパティ ページ を選択します。 2 [自動ドラッグモード]チェックボックスをオンにします。 162 PowerBuilder 第 10 章 ドラッグ アンド ドロップ機能の使い方 DragIcon プロパティ DragIcon プロパティを使用して、コントロールが ドラッグ モードになったときのアイコンを指定します。DragIcon プロ パティは、組み込みアイコン名か、アイコン ファイル(ICO ファイル) 名です。デフォルトのドラッグ アイコンは、コントロールと同じサイ ズの長方形です。 コントロールをドラッグすると、そのコントロールがドロップできる 領域(有効ドロップ領域)上にあるときに、ドラッグ アイコンが表示 されます。コントロールをドロップできない領域(たとえば、ウィン ドウのスクロールバー)ではドロップ禁止アイコンが表示されます。 v ドラッグ アイコンを指定するには 1 コントロールのプロパティ ビューで[その他]プロパティ ページ を選択します。 2 組み込みアイコンのリストから使用するアイコンを選択するか、 参照( [...] )ボタンをクリックして ICO ファイルを選択し、 [OK] ボタンをクリックします。 アイコンの作成 アイコンは、Microsoft Windows の ICO ファイル形式で保存可能な描画 アプリケーションを利用して作成します。 ドラッグ アンド ド ロップのイベント ドラッグ アンド ドロップのイベントには、以下の 6 種類があります。 表 10-2: ドラッグ アンド ドロップのイベント イベント BeginDrag BeginRightDrag DragDrop DragEnter DragLeave DragWithin アプリケーション テクニック 発生する状況 リストビューまたはツリービュー コントロール上で、マ ウスの左ボタンを押してドラッグを開始するとき リストビューまたはツリービュー コントロール上で、マ ウスの右ボタンを押してドラッグを開始するとき ドラッグ アイコンのホット スポット(通常は中央)が ターゲット(ドラッグ先の PowerBuilder コントロールや ウィンドウ)上にあり、マウス ボタンが放されたとき ドラッグ アイコンのホット スポットがターゲットの境 界内に入るとき ドラッグ アイコンのホット スポットがターゲットの境 界外に出るとき ドラッグ アイコンのホット スポットがターゲットの境 界内で移動するとき 163 ドラッグされたコントロールの識別 ドラッグ アンド ド ロップの関数 PowerBuilder の各コントロールでは、ドラッグ アンド ドロップのイベ ントに対するスクリプトを記述するために、以下の 2 種類の関数が用 意されています。 表 10-3: ドラッグ アンド ドロップ イベントの関数 関数 Drag DraggedObject 動作内容 コントロールのドラッグを開始または終了する 現在ドラッグされているコントロールを取得する これらのイベントおよび関数の詳細については、 『PowerScript リファ レンス』マニュアルを参照してください。 ドラッグされたコントロールの識別 ドロップされたコントロールの種類を識別するには、DragDrop イベン トの source 引数を使用します。 以下のスクリプトは、ピクチャ内の DragDrop イベントに対するスクリ プトです。ここでは 2 種類の変数を宣言してから、ドロップされたオ ブジェクトの種類を特定しています。 CommandButton lcb_button StaticText lst_info IF source.TypeOf() = CommandButton!THEN lcb_button = source lcb_button.Text = "You dropped a Button!" ELSEIF source.TypeOf() = StaticText!THEN lst_info = source lst_info.Text = "You dropped the text!" END IF CHOOSE CASE 文の使用 ウィンドウにドロップ可能なコントロールが数多くあるときは、 CHOOSE CASE 文を使用します。 164 PowerBuilder 第 11 章 オンライン ヘルプの提供 この章について この章では、Windows 上でほかの開発者およびエンド ユーザに対 してオンライン ヘルプを提供する方法について説明します。 内容 項目 ヘルプ ファイルの作成 開発者に対するオンライン ヘルプの提供 エンド ユーザに対するオンライン ヘルプの提供 ページ 165 167 169 ヘルプ ファイルの作成 ヘルプ オーサリング ツー ルについて Windows でオンライン ヘルプ ファイルを作成する際には、多数の オーサリング ツールと関連製品を使用できます。RTF ベースのヘ ルプ ファイルを作成するすべてのオーサリング ツールは、Microsoft ヘルプ コンパイラを使用して、一連のソース ファイルを完成した ヘルプ ファイルにコンパイルします。 組み込まれる内容 一般に、ヘルプ システム用のソース ファイルには以下の要素が組 み込まれています。 アプリケーション テクニック • トピック ファイル(RTF): トピックの識別に役立ち、ナビ ゲーションなどの機能を提供するコマンドと脚注コードに加 えて、ヘルプ システムのテキストも含む • グラフィック ファイル : 一般的にはビットマップ(BMP)で、 特定のトピックに関連付けられている • プロジェクト ファイル(HPJ): 完成したヘルプ システムには 組み込まれないが、コンパイラ用の命令が含まれており、そ のうちのいくつかは、指定したヘルプ ウィンドウの外観と機 能に影響を与える • コンテンツ ファイル(CNT): 完成したヘルプ ファイルには 組み込まれないが、ヘルプ システム全体の一部としてヘルプ ファイルとともに配布される 165 ヘルプ ファイルの作成 コンテンツ ファイルは、ヘルプ トピック ダイアログボックスの [目次]タブに表示するエントリを提供する。また、ヘルプ システ ムの動作全体に影響を及ぼすことのあるそのほかの情報も提供す る 処理方法 多機能なヘルプ オーサリング ツールを使用している場合には、その指 示に従って、必要なソース ファイルを作成し、コンパイルすることが できます。 Microsoft SDK に添付の Microsoft ヘルプ ワークショップを使用してい る場合には、このツールを使用してプロジェクト ファイルとコンテン ツ ファイルを作成し、完成したヘルプ ファイルをコンパイルすること ができます。しかし、Microsoft Word で直接ヘルプ トピックを記述す る必要があります。Microsoft ヘルプ ワークショップ用のオンライン ヘ ルプでは、ヘルプ コンパイラ、WinHelp マクロ、および WinHelp API によって識別されるさまざまな脚注コードの使い方に関する指示をは じめとして、ヘルプ作成に関する多くの情報を提供しています。 サンプル プロジェク ト ファイル 参考用にサンプルのプロジェクト ファイルが、PowerBuilder とともに インストールされる PBUSR115.HLP ファイルのトピックにあります。 テキストの取り出し方法を以下に示します。 1 PowerBuilder ヘルプを開いて、 [ユーザ]ボタンをクリックします。 2 ユーザ定義ヘルプの下で、トピックの検索 ダイアログボックスの [目次]タブから「ヘルプ プロジェクト ファイルのサンプル」項 目に移動します。 3 ヘルプ トピックを Windows のクリップボードにコピーします。 4 メモ帳などのテキスト エディタを開いて、クリップボードのテキ ストを空のドキュメントに貼り付けます。 5 そのドキュメントを PBUSR115.HPJ としてテキスト形式で保存し ます。 ソース ファイル名やディレクトリ パス名など、ヘルプ開発環境の細部 を反映させるには、プロジェクト ファイルを編集する必要がありま す。そのためには、テキスト エディタを使用したり、ヘルプ ワーク ショップまたはそのほかのヘルプ オーサリング ツールでプロジェク ト ファイルを開いて編集したりすることができます。 166 PowerBuilder 第 11 章 オンライン ヘルプの提供 開発者に対するオンライン ヘルプの提供 ヘルプを提供する 2 つの方法 ユーザ定義関数、ユーザ イベント、およびユーザ オブジェクトのオン ライン ヘルプを PowerBuilder の開発環境に統合するには、2 つの方法 があります。 • • ユーザ定義関数の状況 依存ヘルプの機能 PowerBuilder メイン ヘルプ ウィンドウの[ユー ザ]ボタンをハードコード化して、PBUSR115.HLP というファイ ルを起動します。 [ユーザ]ボタン 状況依存ヘルプ スクリプト ビューで関数名を選択して(または カーソルを関数名に置いて) 〔Shift〕+〔F1〕を押すと、ユーザ定 義関数の状況依存ヘルプを表示できます。 スクリプト ビューで関数の名前を選択するか関数名にカーソルを置 いて、 〔Shift〕+〔F1〕を押すと、以下の動作が行われます。 1 PowerBuilder は、関数名の中から標準の接頭辞(デフォルトは uf_) を探します。 2 標準の接頭辞が見つかった場合には、PowerBuilder は(自身のメイ ン ヘルプ ファイルである PBUSR115.HLP を調べるかわりに)ユー ザ定義関数のヘルプ トピックを含んでいるヘルプ ファイルから ヘルプ トピックを探します。ユーザ定義関数のヘルプのデフォル ト ファイル名は PBUSR115.HLP です。 PowerBuilder は、PB.INI 内の UserHelpFile 変数を読み取ることに よって、調べるヘルプ ファイルの名前を判別します。この変数の 値を変更する方法については、168 ページの「高度な手順」を参照 してください。 3 最も簡単な方法 PowerBuilder が変数を見つけ出した場合には、指定したヘルプ ファ イルから選択した関数の名前を探します。PB.INI に UserHelpFile 変 数が存在しない場合には、PowerBuilder は、PowerBuilder Help ディ レクトリの PBUSR115.HLP ファイルからキーワードを探します。 PowerBuilder のデフォルトを使用する場合には、以下の操作が必要に なります。 • アプリケーション テクニック ユーザ定義関数、ユーザ イベント、およびユーザ オブジェクトの すべてのオンライン ヘルプを、PBUSR115.HLP という 1 つのファ イルにコンパイルします。 167 開発者に対するオンライン ヘルプの提供 オプションでコンテンツ ファイルを提供できます。その名前は PBUSR115.CNT とする必要があります。 • 作成する各ユーザ定義関数の名前の前に uf_ を付けます(たとえ ば、uf_calculate) 。 次に、オンライン ヘルプを PowerBuilder 環境に組み込む方法について 説明します。 基本的な手順 v [ユーザ]ボタンから PowerBuilder 開発者用のオンライン ヘルプを起動す るには 1 Microsoft Word および Microsoft ヘルプ ワークショップまたはその ほかのヘルプ オーサリング ツールを使用して、オンライン ヘルプ ファイルを作成します。 2 PowerBuilder とともにインストールされた PBUSR115.HLP と PBUSR115.CNT のファイル名を変更します。独自のコンテンツ ファイルを提供しない場合でも、オリジナルの PBUSR115.CNT ファイルの名前は変更してください。 3 コンパイルしたヘルプ ファイルとオプションのコンテンツ ファ イルを、PowerBuilder の Help ディレクトリに保存します。ヘルプ ファイルの名前は PBUSR115.HLP、コンテンツ ファイルの名前は PBUSR115.CNT とします。 [ユーザ]ボタンをクリックすると、ヘルプ ファイルが表示されま す。 v ユーザ定義関数の状況依存ヘルプを作成するには 1 ユーザ定義関数を作成した場合には、関数の名前には標準の接頭辞 を付けます。 デフォルトの接頭辞は uf_ です(たとえば、uf_calculate)。 2 ユーザ定義関数のヘルプ トピックごとに、関数名と同じ検索キー ワード(脚注として K を使用)を割り当てます。 たとえば、ユーザ定義関数 uf_CutBait のヘルプ項目には、検索キー ワード uf_CutBait を設定します。PowerBuilder は、このキーワード を使用して、ヘルプ ウィンドウに適切なトピックを呼び出します。 3 高度な手順 168 ヘルプ ファイルをコンパイルし、PowerBuilder Help ディレクトリ に保存します。 状況依存ヘルプに別のファイル名を指定するには、PB.INI ファイルの UserHelpFile 変数の値を変更します。この変数を使用するには、ヘル プ ファイルが PowerBuilder Help ディレクトリに存在する必要があり ます。 PowerBuilder 第 11 章 v オンライン ヘルプの提供 状況依存ヘルプに別のファイル名を指定するには 1 テキスト エディタで PB.INI ファイルを開きます。 2 [PB]セクションで、UserHelpFile 変数を追加して、状況依存トピッ クを含むヘルプ ファイルの名前を指定します。変数の書式は次の とおりです。 UserHelpFile = helpfile.hlp ファイル名だけを指定します。絶対パスで指定しても認識されま せん。 ユーザ定義関数には、デフォルトの uf_ 接頭辞以外の標準の接頭辞を 付けることができます。使用したい接頭辞を定義するには、PB.INI ファ イルに UserHelpPrefix 変数を記述します。 v ユーザ定義関数に別の接頭辞を使用するには 1 テキスト エディタで PB.INI ファイルを開きます。 2 [PB]セクションで、UserHelpPrefix 変数を追加して、接頭辞の値 を指定します。次の書式を使用します。 UserHelpPrefix = yourprefix_ 指定する接頭辞の最後は、アンダースコア文字にする必要があり ます。 エンド ユーザに対するオンライン ヘルプの提供 アプリケーションから ヘルプを呼び出す 2 つの方法 ShowHelp の使い方 PowerBuilder は、PowerBuilder アプリケーションからオンライン ヘル プ ファイルを呼び出すために 2 つの方法を提供しています。 • アプリケーション スクリプトで ShowHelp および ShowPopupHelp 関数を使用して、ヘルプ トピックを呼び出す • WinHelp API を外部関数として宣言し、アプリケーション スクリ プトで WinHelp 関数を使用してヘルプ トピックを呼び出す ShowHelp の実装は、WinHelp API の場合よりも簡単です。ShowHelp 関 数を使用すれば、ヘルプ コンテキスト ID またはキーワードによって、 あるいはヘルプ ファイルのコンテンツ トピック(プロジェクト ファ イルにヘルプ コンテンツ トピックとして定義されたトピック)にアク セスすることによって、ヘルプ トピックを検索できます。ShowHelp 関 数は、コンパイル済みの HTML(.chm)ファイルでも使用できます。 アプリケーション テクニック 169 エンド ユーザに対するオンライン ヘルプの提供 ShowPopupHelp 関数は、コントロールのポップアップ ヘルプを表示し ます。通常、ShowPopupHelp 関数は、Context Help プロパティを有効に した状態で、レスポンス ウィンドウの Help イベントで使用します。ま た、コントロール上でのカーソルの動きに応じて発生するイベントや、 コントロールまたはオブジェクトをドラッグしたときに発生するイベ ントは、ShowPopupHelp によって呼び出されます。 ShowHelp 関数、ShowPopupHelp 関数、および Help イベントの詳細につ いては、 『PowerScript リファレンス』マニュアルを参照してください。 WinHelp API を使用すると、WinHelp 関数の全域に渡るアクセスが可 能となります。これらの関数の多くは、ShowHelp では使用できません。 たとえば、WinHelp 関数を使用すれば、ヘルプ トピックを提示するウィ ンドウの種類またはウィンドウ名を簡単に指定できます。 WinHelp API の使い方 v 外部関数として WinHelp API を宣言するには 1 2 スクリプト ペインタの最初のドロップダウン リストボックスから [(Declare)] を、2 番目のドロップダウン リストボックスから[Global External Functions]を選択します。 関数宣言をスクリプト ビューに入力します。 次の例では、WinHelp API を宣言します。 FUNCTION boolean WinHelpW(long hWndMain, & string lpszHelp, long uCommand, & long dwData) & LIBRARY "USER32.DLL" WinHelp API の詳細については、Microsoft ヘルプ ワークショップのオ ンライン ヘルプまたはご使用のヘルプ オーサリング ツールの資料を 参照してください。グローバル外部関数の宣言と使用の詳細について は、 『PowerScript リファレンス』マニュアルおよび 421 ページの「外 部関数の使い方」を参照してください。 170 PowerBuilder 第 4 部 データ アクセス テクニック 第 4 部では、PowerBuilder によるアプリケーション開発 において、データ アクセス機能を実現するためのテク ニックについて説明します。トランザクション オブジェ クトの使い方、XML の処理、グラフの操作、リッチテキ ストの作成方法、データ ソース間のデータ転送などにつ いて説明します。データウィンドウ オブジェクトおよび データストアでのデータ アクセスの使い方については 『データウィンドウ プログラマーズ ガイド』マニュアル を参照してください。 第 1 2 章 トランザクション オブジェクトの 使い方 この章について この章では、トランザクション オブジェクトと PowerBuilder アプ リケーションにおけるそれらの使い方について説明します。 内容 項目 トランザクション オブジェクトについて トランザクション オブジェクトの使い方 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 ストアド プロシージャを呼び出すときサポートされている DBMS の機能 ページ 173 178 190 199 トランザクション オブジェクトについて PowerBuilder で行うデータベース接続は、トランザクション オブ ジェクトと呼ばれる、PowerBuilder アプリケーションとデータベー スとの通信領域として機能する非ビジュアル オブジェクトを使用し ます。PowerBuilder がデータベースに接続するためには、トランザ クション オブジェクトにパラメータを指定します。なお、トラン ザクション オブジェクトは、図 12-1 に示すように、アプリケー ションからデータベースにアクセスする前に、あらかじめ設定し なければなりません。 図 12-1: データベースにアクセスするためのトランザクション オブジェクト アプリケーション テクニック 173 トランザクション オブジェクトについて PowerBuilder アプリケーションにおいて、データを表示したり、操作 したりするためには、データベースと通信する必要があります。 データベースとの通信 v PowerBuilder アプリケーションからデータベースと通信するには 1 トランザクション オブジェクトに適切な値を設定します。 2 データベースに接続します。 3 トランザクション オブジェクトをデータウィンドウ コントロー ルに関連付けます。 4 データベース処理を行います。 5 データベースとの接続を解除します。 データウィンドウ コントロール用のトランザクション オブジェクト の設定方法、およびデータウィンドウを使用して検索と更新を行う方 法についての詳細は、『データウィンドウ プログラマーズ ガイド』マ ニュアルを参照してください。 デフォルト トランザ クション オブジェク ト アプリケーションの実行を開始するときに、PowerBuilder は SQLCA (SQL Communications Area)という名前のグローバルなデフォルト ト ランザクション オブジェクトのインスタンスを作成します。アプリ ケーションでは、このデフォルト トランザクション オブジェクトを使 用できます。また、アプリケーションが複数のデータベースに接続す る場合は、ほかのトランザクション オブジェクトを作成して使用でき ます。 トランザクション オ ブジェクトのプロパ ティ トランザクション オブジェクトには、以下の 15 種類のプロパティが あります。 • 10 種類のプロパティは、データベースに接続するために使用され ます。 • 5 種類のプロパティは、実行された SQL 文の成否についてのステー タス情報をデータベースから受け取るために使用されます。これ らのエラーをチェックするプロパティ名は、5 種類ともすべて SQL から始まります。 トランザクション オブジェクトのプロパティ 表 12-1 に、トランザクション オブジェクトのプロパティを示します。 接続のための 10 種類のプロパティには、それぞれのプロパティに対応 する DB プロファイル設定 ダイアログボックスのフィールドを示しま す。DB プロファイル設定 ダイアログボックスは、PowerBuilder の開 発環境でデータベース プロファイルを作成します。 174 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 PoweBuilder データベース インタフェースにおけるトランザクション オブ ジェクトのプロパティ PowerBuilder データベース インタフェースで使用できるトランザク ション オブジェクトのプロパティについては、177 ページの「トラン ザクション オブジェクトのプロパティと PowerBuilder データベース インタフェースのサポート」を参照してください。 接続のための 10 種類のプロパティに設定する値については、『データ ベースとの接続』マニュアルの該当する PowerBuilder データベース イ ンタフェースの節を参照してください。 表 12-1: トランザクション オブジェクトのプロパティ プロパティ DBMS データ型 String Database String UserID DBPass Lock String String String LogID String LogPass String ServerName String アプリケーション テクニック DB プロファイ ル設定の フィールド DBMS 説明 接続のための PowerBuilder の DBMS 識別子。サポート されているデータベース インタフェースの識別子の一 覧については、オンライン ヘルプを参照 接続するデータベースの名前 [データソー ス] データベースに接続するユーザの名前または ID [ユーザ ID] データベースに接続するときに使用するパスワード [パスワード] Lock の値と分離レベルの使用をサポートする DBMS の [分離レベル] 場合、データベースに接続するときの分離レベル。ご使 用の DBMS に設定できる Lock の値については、オンラ イン ヘルプの Lock DBParm パラメータの記述を参照 データベース サーバにログインするユーザの名前また [ログイン ID] は ID データベース サーバにログインするときに使用するパ [パスワード] スワード データベースが常駐するサーバの名前 [サーバ」 175 トランザクション オブジェクトについて プロパティ AutoCommit データ型 Boolean DBParm String SQLReturnData String SQLCode Long SQLNRows Long SQLDBCode Long SQLErrText String 176 DB プロファイ ル設定の 説明 フィールド AutoCommit をサポートする DBMS のために、 PowerBuilder [自動コミット が SQL 文をトランザクションのスコープ外またはス モード] コープ内のどちらで発行するかを指定する。設定できる 値は、以下のとおり • True SQL 文は、トランザクションのスコープ外で 発行される。つまり、ステートメントは、論理的な作 業単位(LUW)の一部ではない。SQL 文の実行が成 功した場合、DBMS は、COMMIT 文が発行されたかの ように、データベースをただちに更新する • False (デフォルト)SQL 文は、トランザクションの スコープ内で発行される。PowerBuilder は、接続を開 始するときに BEGIN TRANSACTION 文を発行する。さ らに、COMMIT 文や ROLLBACK 文が発行された後に、 BEGIN TRANSACTION 文を発行する 詳細については、オンライン ヘルプの AutoCommit に関 する記述を参照 DBMS 固有の接続パラメータ。特定の DBMS 機能をサ [ドライバ固有 ポート。PowerBuilder がサポートする各 DBParm パラ のパラメータ] メータの記述については、『データベースとの接続』マ ニュアルの追加の「接続パラメータの設定」についての 章を参照 DBMS 固有の情報。たとえば、Informix データベースに — 接続し、埋め込み SQL の INSERT 文を実行すると、 SQLReturnData プロパティには、テーブルに挿入した行 のシリアル番号が入る 直前に実行した SQL 文の成否コード。詳細については、 — 188 ページの「SQL 文実行後のエラー処理」を参照 直前に実行した SQL 文によって影響を受けた行の数。こ — の行数はデータベースが返すので、その意味は DBMS に よって異なる データベース ベンダのエラーコード。詳細については、 — 188 ページの「SQL 文実行後のエラー処理」を参照 データベース ベンダのエラー コードに対応するエラー — メッセージのテキスト。詳細については、188 ページの 「SQL 文実行後のエラー処理」を参照 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 トランザクション オブジェクトのプロパティと PowerBuilder データ ベース インタフェースのサポート データベースに接続するために必要なトランザクション オブジェク トのプロパティは、PowerBuilder データベース インタフェースによっ て異なります。SQLReturnData プロパティを除き、SQL 文の成否につ いてのステータス情報を返すプロパティは、すべての PowerBuilder データベース インタフェースに適用します。 サポートする PowerBuilder データベース インタフェースとトランザク ション オブジェクトのプロパティを、表 12-2 に示します。 表 12-2: PowerBuilder データベース インタフェース データベース インタフェース Informix トランザクション オブジェクト のプロパティ DBMS UserID DBPass Database ServerName DBParm Lock AutoCommit SQLReturnData SQLCode SQLNRows SQLDBCode SQLErrText JDBC DBMS LogID LogPass DBParm Lock AutoCommit SQLCode SQLNRows SQLDBCode SQLErrText Microsoft SQL Server DBMS Database ServerName LogID LogPass DBParm Lock AutoCommit SQLCode SQLNRows SQLDBCode SQLErrText ODBC DBMS UserID* LogID# LogPass# DBParm Lock DBMS LogID LogPass DBParm AutoCommit SQLReturnData SQLCode SQLNRows SQLDBCode SQLErrText AutoCommit SQLCode SQLNRows SQLDBCode SQLErrText OLE DB アプリケーション テクニック 177 トランザクション オブジェクトの使い方 データベース インタフェース Oracle Sybase Adaptive Server Enterprise * # トランザクション オブジェクト のプロパティ DBMS ServerName LogID LogPass DBParm DBMS Database ServerName LogID LogPass DBParm Lock SQLReturnData SQLCode SQLNRows SQLDBCode SQLErrText AutoCommit SQLCode SQLNRows SQLDBCode SQLErrText ODBC に対するオプション(UserID プロパティを指定するときは、ODBC の SQLGetInfo 関数呼び出しによって返される UserName プロパティを上書きするので、 注意してください)。 ご使用の ODBC ドライバが ODBC SQL ドライバの Connect 関数呼び出しをサポート していない場合に限り、PowerBuilder は LogID プロパティと LogPass プロパティを使 用します。 トランザクション オブジェクトの使い方 PowerBuilder は、論理的な作業単位(LUW)と呼ばれるデータベース トランザクション処理の基本的なコンセプトを使用しています。LUW は、トランザクションの同意語です。トランザクションは、LUW を形 成する 1 つまたは複数の SQL 文のセットです。トランザクション内の すべての SQL 文は、1 つの論理的な単位として処理されます。 PowerScript のトランザクション管理文には、以下の 4 つのステートメ ントがあります。 178 • COMMIT • CONNECT • DISCONNECT • ROLLBACK PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 トランザクションの基礎 CONNECT 文と DISCONNECT 文 CONNECT 文が正常に実行されるとトランザクションが開始され、 DISCONNECT 文によってそのトランザクションが終了します。CONNECT 文と DISCONNECT 文の間で実行される SQL 文はすべて、そのトランザ クションに属します。 CONNECT 文を実行する前に、トランザクション オブジェクトは存在 しなければなりません。また、DBMS に接続するためには、トランザ クション オブジェクトの必要なプロパティに値を設定しなければな りません。 COMMIT 文と ROLLBACK 文 COMMIT 文が実行されると、現行のトランザクションが開始(または、 最後に実行された COMMIT 文や ROLLBACK 文)後にデータベースに対 して行われたすべての変更が確定され、新しいトランザクションが開 始されます。ROLLBACK 文が実行されると、現行のトランザクション が開始以降のすべての変更は取り消され、新しいトランザクションが 開始されます。 トランザクション型コンポーネントが EAServer、COM+、または別の アプリケーション サーバに配布された場合、TransactionServer コンテ キスト オブジェクトを使用して、トランザクションをコントロールで きます。180 ページの「トランザクション サーバの配布」を参照して ください。 AutoCommit プロパ ティの設定 COMMIT 文と ROLLBACK 文が実行できるのは、トランザクション オブ ジェクトの AutoCommit プロパティの値が False(デフォルト)で、埋 め込み SQL を使用したトランザクションをまだ開始していないとき だけです。 AutoCommit プロパティについての詳細は、174 ページの「トランザク ション オブジェクトのプロパティ」を参照してください。 接続が解除されたときの自動コミット トランザクションの接続が解除されたときに、COMMIT 文が発行され ます。 アプリケーション テクニック 179 トランザクション オブジェクトの使い方 トランザクション プール トランザクション プールを使用して、データベースの処理を最適化で きます。 詳細については、189 ページの「データベース トランザクションのプー ル」を参照してください。 トランザクション サーバの配布 PowerBuilder で開発したコンポーネントは、EAServer、COM+、または 別のアプリケーション サーバのトランザクションに関与できます。コ ンポーネントにマークを付けることによって、トランザクション サ ポートを提供するコンポーネントを判別できます。コンポーネントが トランザクション サポートを提供する場合、トランザクション サーバ は、コンポーネントのデータベース操作がトランザクションの一部と して実行され、しかも関与しているコンポーネントによって行われた データベース変更はすべてコミットまたはロールバックされるように します。トランザクションを使用するコンポーネントを定義すれば、 トランザクションに関与するコンポーネントによって実行されるすべ ての作業は意図したとおりに行われることを保証できます。 PowerBuilder は、TransactionServer というトランザクション サービス コンテキスト オブジェクトを提供します。このオブジェクトは、トラ ンザクション サーバが現行のトランザクションをコミットするか中 止するかの判断に影響を与える、トランザクション状態プリミティブ へのアクセス権を与えます。COM+ クライアントは、OleTxnObject オ ブジェクトを使用して、トランザクションを制御することもできます。 TransactionServer コンテキスト オブジェクトを使用し、 UseContextObject DBParm パラメータに Yes を設定した場合、トランザクション オブ ジェクト内で COMMIT 文と ROLLBACK 文を呼び出すとデータベース エ ラーになります。 デフォルトでは、TransactionServer コンテキスト オブジェクトは使用 されません。そのかわりに、COMMIT 文と ROLLBACK 文を使用してト ランザクションを管理できます。この場合には、COMMIT は SetComplete 関数と解釈され、ROLLBACK は SetAbort 関数と解釈されます。 詳細については、467 ページの「トランザクションのサポート」を参 照してください。 デフォルト トランザクション オブジェクト SQLCA 180 たいていのアプリケーションは 1 つのデータベースにだけアクセスす るので、PowerBuilder は、SQLCA と呼ばれるグローバルなデフォルト トランザクション オブジェクトを用意しています。SQLCA は、SQL 通信領域(SQL Communication Area)を意味します。 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 PowerBuilder は、アプリケーションの Open イベントに対するスクリプ トを実行する前に、SQLCA オブジェクトを作成します。SQLCA とそ の プ ロ パ テ ィ は、ア プ リ ケ ー シ ョ ン 内 の ど の ス ク リ プ ト か ら も、 PowerScript のドット(.)表記によって参照できます。 トランザクション オブジェクトは、 (一度に複数のデータベースに接 続する場合などに)必要であれば独自に作成できます。ただし、通常 は必要となるトランザクション オブジェクトは SQLCA だけで済みま す。 例 デフォルト ト ランザクショ ン オブジェク ト SQLCA を使用して、 Sample という名前の ODBC データ ソースに接続し、さらにその接続 を解除する簡単な例を以下に示します。 // デフォルト トランザクション オブジェクトのプロパティを設定しま す。 SQLCA.DBMS="ODBC" SQLCA.DBParm="ConnectString='DSN=Sample'" // データベースに接続します。 CONNECT USING SQLCA; IF SQLCA.SQLCode < 0 THEN & MessageBox(" 接続エラー ", SQLCA.SQLErrText,& Exclamation!) ... // データベースとの接続を解除します。 DISCONNECT USING SQLCA; IF SQLCA.SQLCode < 0 THEN & MessageBox(" 接続解除エラー ", SQLCA.SQLErrText,& Exclamation!) SQL 文の区切り子はセミコロン PowerBuilder のスクリプト内で埋め込み SQL を使用する場合、SQL 文 は必ずセミコロン(;)で終了しなければなりません。なお、複数行に わたる SQL 文に対して、継続行文字を使用する必要はありません。 トランザクション オブジェクトのプロパティ値の設定 デフォルト トランザクション オブジェクト(SQLCA)や独自に作成 したトランザクション オブジェクトを使用する前に、トランザクショ ン オブジェクトのプロパティに値を設定する必要があります。値を設 定するには、PowerScript のドット(.)表記を使用します。 アプリケーション テクニック 181 トランザクション オブジェクトの使い方 例 以下の PowerScript 文では、SQLCA のプロパティに値を割り当てます。 これは、PowerBuilder Adaptive Server Enterprise データベース インタ フェースを通じて Sybase Adaptive Server Enterprise データベースに接続 するために必要です。 sqlca.DBMS="SYC" sqlca.database="testdb" sqlca.LogId="CKent" sqlca.LogPass="superman" sqlca.ServerName="Dill" 外部ファイルからの値の読み込み 外部ファイルの使い方 トランザクション オブジェクトのプロパティの値は、外部ファイルか ら読み込んで設定できます。トランザクション オブジェクトの設定に 使用する外部ファイルには、アプリケーションの開発時に使用する PowerBuilder の初期設定ファイルや、アプリケーションを配布する際 に指定する初期設定ファイルなどがあります。 ProfileString 関数 設定する値は、PowerScript の ProfileString 関数を使用して、初期設定 ファイルから読み込むことができます。初期設定ファイルは、Windows の INI ファイルと同様に、変数値の代入式が集まった複数のセクショ ンで構成されています。PowerBuilder の初期設定(INI)ファイルも初 期設定ファイルの 1 つであり、PB、Application、Database などのセク ションから構成されています。 [PB] 変数とその変数値 ... [Application] 変数とその変数値 ... [Database] 変数とその変数値 ... ProfileString 関数の構文は以下のとおりです。 ProfileString ( file, section, key, default) 例 182 次のスクリプトでは、初期設定ファイルから値を読み取って、トラン ザクション オブジェクトをデータベースに接続するよう設定します。 条件付きコードでは、プラットフォームごとに適切な値を変数 startupfile に設定します。 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 sqlca.DBMS = ProfileString(startupfile, "database",& "dbms", "") sqlca.database = ProfileString(startupfile,& "database", "database", "") sqlca.userid = ProfileString(startupfile, "database",& "userid", "") sqlca.dbpass = ProfileString(startupfile, "database",& "dbpass", "") sqlca.logid = ProfileString(startupfile, "database",& "logid", "") sqlca.logpass = ProfileString(startupfile, "database",& "LogPassWord","") sqlca.servername = ProfileString(startupfile,& "database", "servername","") sqlca.dbparm = ProfileString(startupfile, "database",& "dbparm", "") データベースへの接続 トランザクション オブジェクトのプロパティに値を設定したら、SQL の CONNECT 文を使用して、データベースに接続できます。 // トランザクション オブジェクトの値は設定されています。 CONNECT; CONNECT 文は、PowerScript 文ではなく SQL 文なので、文の末尾にセ ミコロン(;)が必要です。 SQLCA 以外のトランザクション オブジェクトを使用している場合は、 SQL 構文に USING TransactionObject 句が必要です。 CONNECT USING TransactionObject; 例 CONNECT USING ASETrans; PowerBuilder アプリケーションで接続するための[プレビュー]タブ の使い方 DB プロファイル設定 ダイアログボックスの[プレビュー]タブを使っ て、開発時に PowerBuilder アプリケーションのスクリプトで使用する PowerScript 接続構文を、正確かつ簡単に作成できます。 アプリケーション テクニック 183 トランザクション オブジェクトの使い方 DB プロファイル設定 ダイアログボックスで必要な項目を指定する と、[プレビュー]タブに、選択したオプションに対応する正しい PowerScript 接続構文が表示されます。対応する DBParm パラメータ、 または SQLCA プロパティ名が各オプションに割り当てられ、必要に 応じて、引用符、カンマ、セミコロンなどの文字が挿入されます。こ の構文は、[プレビュー]タブからスクリプトに直接コピーできます。 v PowerBuilder アプリケーションで接続するための[プレビュー]タブを使 用するには 1 接続用の DB プロファイル設定 ダイアログボックスで、データベー ス インタフェースの指示に従って、[接続]タブの基本オプショ ン、ほかのタブの DBParm パラメータと SQLCA プロパティに値を 代入します。 インタフェースの接続パラメータと指定する値については、ヘル プを参照してください。 2 [更新]を選択して、DB プロファイル設定ダイアログボックスを 閉じないで、設定を保存します。 3 [プレビュー]タブを選択します。 選択したオプションに対する適切な PowerScript 接続構文が、 [プ レビュー]タブの[DB 接続構文]ボックスに表示されます。 4 [DB 接続構文]ボックスで 1 行以上のテキスト行を選択し、[コ ピー]を選択します。 選択したテキストがクリップボードにコピーされます。次に、こ の構文をスクリプトに貼り付け、必要であれば、デフォルトのト ランザクション オブジェクト名(SQLCA)を修正します。 5 [OK]をクリックします。 データベースとの接続の解除 データベースの処理が終了したら、SQL の DISCONNECT 文を使用し て、データベースとの接続を解除します。 DISCONNECT; SQLCA 以外のトランザクション オブジェクトを使用している場合は、 SQL 構文に USING TransactionObject 句が必要です。 DISCONNECT USING TransactionObject; 184 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 例 DISCONNECT USING ASETrans; 接続が解除されたときの自動コミット デフォルトでは、トランザクションの接続が解除されたときに、COMMIT 文が実行されます。 複数のデータベース接続におけるトランザクション オブジェクトの定義 接続ごとに 1 つのト ランザクション オブ ジェクトを使用する 同時に複数のデータベースに対する処理を行うときは、複数のトラン ザクション オブジェクトをデータベースの接続ごとに 1 つずつ使用し ます。独自に定義するトランザクション オブジェクトを参照するとき には、その前にオブジェクトを宣言して作成する必要があります。ま た、そのオブジェクトが不要になったら破棄するようにします。 注意 PowerBuilder は、SQLCA を自動的に作成し、破棄します。したがって、 スクリプトで SQLCA の作成や破棄は行わないでください。 SQLCA 以外のトラン ザクション オブジェ クトの作成 SQLCA 以外のトランザクション オブジェクトを作成するには、 Transaction 型の変数を宣言します。 transaction TransactionObjectName 次に、トランザクション オブジェクトのインスタンスを作成します。 TransactionObjectName = CREATE transaction たとえば、DBTrans という名前のトランザクション オブジェクトを作 成する場合は、以下のように記述します。 transaction DBTrans DBTrans = CREATE transaction // これで、DBTrans のプロパティに値を設定できます。 DBTrans.DBMS = "ODBC" ... プロパティ値の設定 スクリプトで宣言して作成したトランザクション オブジェクトのプ ロパティに値を設定するときは、以下のように、プロパティの値を一 度に 1 つずつ設定しなければなりません。 // 以下の記述は、正しい結果となります。 transaction ASETrans アプリケーション テクニック 185 トランザクション オブジェクトの使い方 ASETrans = CREATE TRANSACTION ASETrans.DBMS = "SYC" ASETrans.Database = "Personnel" 次のように、デフォルト以外のトランザクション オブジェクトで SQLCA と同じオブジェクトを設定して、値を代入することはできませ ん。 // 以下の記述は正しい結果になりません。 transaction ASETrans ASETrans = CREATE TRANSACTION ASETrans = SQLCA // エラー ! SQL 文の実行にトランザクション オブジェクトが必要となる場合は、 特に指定しない限り、デフォルト トランザクション オブジェクト SQLCA が使用されます。したがって、以下の 2 つの CONNECT 文は同 一です。 SQL 文に対するトラ ンザクション オブ ジェクトの指定 CONNECT; CONNECT USING SQLCA; SQLCA 以外のトランザクション オブジェクトを使用する場合は、表 12-3 の SQL 文において、USING TransactionObject 句を使用して、トラ ンザクション オブジェクトを指定する必要があります。 表 12-3: USING TransactionObject 句を必要とする SQL 文 v COMMIT INSERT CONNECT PREPARE(動的 SQL) DELETE ROLLBACK DECLARE Cursor SELECT DECLARE Procedure SELECTBLOB DISCONNECT UPDATEBLOB EXECUTE(動的 SQL) UPDATE SQL 文にユーザ定義のトランザクション オブジェクトを指定するには • SQL 文の終わりに以下の句を追加します。 USING TransactionObject たとえば、以下のステートメントでは、ASETrans という名前のト ランザクション オブジェクトを使用して、データベースに接続し ます。 CONNECT USING ASETrans; 186 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 トランザクション オブジェクトのスクリプト記述の推奨 SQL 文における USING TransactionObject 句の指定は、SQLCA を使用す るときはオプションで、独自のトランザクション オブジェクトを使用 するときは必須です。しかし、SQLCA を含むすべてのトランザクショ ン オブジェクトに対して、USING TransactionObject 句を記述しておけ ば、複数のトランザクション オブジェクトを使用する場合などは、SQL 文で使用するトランザクション オブジェクトが明確になります。ま た、USING TransactionObject 句が必要な場合に必ず指定することができ ます。 例 以下のステートメントでは、デフォルト トランザクション オブジェク ト(SQLCA)を使用して SQL Anywhere データベースに接続します。 また、ASETrans という独自に作成したトランザクション オブジェクト を使用して、Adaptive Server Enterprise データベースに接続します。 // デフォルト トランザクション オブジェクトのプロパティを設定します。 SQLCA.DBMS = "ODBC" SQLCA.DBParm = "ConnectString='DSN=Sample'" // SQL Anywhere データベースに接続します。 CONNECT USING SQLCA; // ASE トランザクション オブジェクトを宣言します。 transaction ASETrans // ASE トランザクション オブジェクトを作成します。 ASETrans = CREATE TRANSACTION // ASE トランザクション オブジェクトのプロパティを設定します。 ASETrans.DBMS = "SYC" ASETrans.Database = "Personnel" ASETrans.LogID = "JPL" ASETrans.LogPass = "JPLPASS" ASETrans.ServerName = "SERVER2" // ASE データベースに接続します。 CONNECT USING ASETrans; // SQL Anywhere データベースに行を挿入します。 INSERT INTO CUSTOMER VALUES ( 'CUST789', 'BOSTON' ) USING SQLCA; // ASE データベースに行を挿入します。 INSERT INTO EMPLOYEE VALUES ( "Peter Smith", "New York" ) USING ASETrans; // SQL Anywhere データベースとの接続を解除します。 アプリケーション テクニック 187 トランザクション オブジェクトの使い方 DISCONNECT USING SQLCA; // ASE データベースとの接続を解除します。 DISCONNECT USING ASETrans; // ASE トランザクション オブジェクトを破棄します。 DESTROY ASETrans エラー チェックの使い方 実際のスクリプトでは、CONNECT 文、INSERT 文、DISCONNECT 文の 後にエラー チェックのスクリプトを記述します。 詳細については、次の「SQL 文実行後のエラー処理」を参照してくだ さい。 SQL 文実行後のエラー処理 エラー チェックのタ イミング スクリプトで以下のステートメントを実行した後は、その成否コード (トランザクション オブジェクトの SQLCode プロパティ)を確認する 必要があります。 • トランザクション管理文(CONNECT 文、COMMIT 文、DISCONNECT 文など) • 埋め込み SQL 文や動的 SQL データウィンドウでのエラー チェック このようなエラー チェックは、データウィンドウで検索や更新を行っ た後には使用しないでください。 データウィンドウでのエラー処理についての詳細は、 『データウィンド ウ プログラマーズガイド』マニュアルを参照してください。 SQLCode の戻り値 表 12-4 に SQLCode の戻り値を示します。 表 12-4: SQLCode の戻り値 値 0 100 -1 意味 正常終了 取得しようとした行が見つからない エラー(ステートメントの実行に失敗) SQLErrText プロパティや SQLDBCode プロパティの値を使用し て詳細を参照。 188 PowerBuilder 第 12 章 SQLErrText プロパ ティと SQLDBCode プロパティの使い方 トランザクション オブジェクトの使い方 トランザクション オブジェクトの String 型の SQLErrText プロパティ には、データベースから提供されるエラーメッセージが保持されてい ます。トランザクション オブジェクトの Long 型の SQLDBCode プロ パティには、データベースから提供されるステータス コードが保持さ れています。これらの変数は、スクリプトで参照できます。 例 接続が失敗した場合に、メッセージボックスで DBMS のエラー番 号とメッセージを表示するには、以下のように記述します。 CONNECT USING SQLCA; IF SQLCA.SQLCode = -1 THEN MessageBox("SQL error " + String(SQLCA.SQLDBCode),& SQLCA.SQLErrText ) END IF データベース トランザクションのプール トランザクション プール アプリケーションは、データベース トランザクションをプールするこ とによって、データベースの処理を最適化できます。トランザクショ ンをプールすると、データベースに接続できる数を制御しながら、デー タベースの処理のスループットを上げることができます。トランザク ション プールを設定する場合は、アプリケーションは、同じデータ ベースに対する接続を再利用できます。 動作 トランザクション プールを使用しないでアプリケーションがデータ ベースに接続する場合、PowerBuilder は DISCONNECT 文が実行された データベース トランザクションを物理的に終了させます。 トランザクション プールが有効な場合、PowerBuilder は論理的にデー タベースとの接続を解除して、データベースに対する変更をコミット します。しかし、データベースとの接続は物理的に解除されません。 そのかわり、データベースへの接続はトランザクション プールで開い たまま保たれ、ほかのデータベース操作のために再利用することがで きます。 効果 同じデータベースに対して短いトランザクションを数多く処理するア プリケーションは、トランザクション プールを使用して、パフォーマ ンスを向上させることができます。 使い方 トランザクション プールを設定するには、SetTransPool 関数を使用し ま す。ア プ リ ケ ー シ ョ ン が デ ー タ ベ ー ス に 接 続 す る 前 な ら ば、 SetTransPool 関数はアプリケーションのスクリプトのどこにでも記述 できます。SetTransPool 関数は通常、アプリケーション オブジェクト の Open イベントで呼び出します。 アプリケーション テクニック 189 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 例 以下のステートメントは、SetTransPool 関数を使用して、データベース に接続できるトランザクションの数に 16 を指定します。また、一度 データベースに接続したら、DISCONNECT 文を実行してもデータベー スとの接続を物理的に解除しないトランザクションの数に 12 を指定 します。接続の数が最大数に到達した場合は、次からの接続要求は、 トランザクション プールに接続が保持できるようになるまで 10 秒間 待ちます。10 秒間経過すると、アプリケーションはエラーを返します。 myapp.SetTransPool (12,16,10) 詳細情報 SetTransPool 関数についての詳細は、 『PowerScript リファレンス』マ ニュアルを参照してください。 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 SQLCA は、すべての PowerBuilder アプリケーションで使用される Transaction 型の組み込みグローバル変数です。アプリケーションに よっては、データに特定の処理や計算を行わせるために、SQLCA をカ スタマイズして使用したいことがあります。 ご使用のデータベースがストアド プロシージャをサポートしている 場合は、ストアド プロシージャを処理するためのリモート ストアド プ ロシージャがすでに定義されていることがあります。アプリケーショ ンにおいて、データベースのストアド プロシージャを呼び出すため に、トランザクション オブジェクトをカスタマイズして、リモート プ ロシージャ コール(RPC)を使用することができます。 結果集合 RPC テクニックを使用して、ストアド プロシージャが返す結果集合に アクセスすることはできません。ストアド プロシージャが 1 つまたは 複数の結果集合を返す場合は、PowerBuilder は結果集合を無視して、出 力パラメータと戻り値を返します。ストアド プロシージャが結果集合 を返す場合は、埋め込み SQL の DECLARE Procedure 文を使用します。 DECLARE Procedure 文についての詳細は、 『PowerScript リファレンス』 マニュアルの「SQL 文」を参照してください。 190 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 PowerBuilder アプリケーションからデータベースのストアド プロシー ジャを呼び出すには、そのストアド プロシージャを呼び出すようにト ランザクション オブジェクトをカスタマイズして、PowerScript のドッ ト表記(object.function)を使用します。 RPC プロシージャの 概要 v アプリケーションにおいてデータベースのストアド プロシージャを呼び出す には 1 新規作成 ダイアログボックスの[PB オブジェクト]タブにおい て、組み込みトランザクション オブジェクトから継承した標準ク ラス ユーザ オブジェクトを定義します。 2 ユーザ オブジェクト ペインタのスクリプト ビューで、RPCFUNC キーワードを使用して、ストアド プロシージャをユーザ オブジェ クトの外部関数またはサブルーチンとして宣言します。 3 ユーザ オブジェクトを保存します。 4 アプリケーション ペインタで、定義済みのユーザ オブジェクトを SQLCA のかわりにデフォルト グローバル変数として指定します。 5 PowerBuilder アプリケーションでそのユーザ オブジェクトを使用 します。 PowerBuilder におけるユーザ オブジェクト、アプリケーション ペイン タ、およびスクリプト ビューの使い方についての詳細は、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 カスタム トランザク ション オブジェクト の例 u_trans_database ユーザ オブジェクト この節では、アプリケーション でストアド プロシージャを呼び出すために、カスタム トランザクショ ン オブジェクトの使い方を解説します。例では、u_trans_database とい う、標準クラス ユーザ オブジェクトの定義と使い方を示します。 u_trans_database ユーザ オブジェクトは、 組み込みトランザクション オ ブジェクト SQLCA から継承した子孫オブジェクトです。子孫オブジェ クトとは、先祖オブジェクトのプロパティ、変数、関数、イベントに 対するスクリプトを継承しているオブジェクトです。子孫オブジェク トは、サブクラスとも呼ばれます。 GIVE_RAISE ストアド プロシージャ u_trans_database ユーザ オブジェク トは、GIVE_RAISE という Oracle データベースのストアド プロシージャ を使用して、現行の給料の 5 % の昇給を計算するのに使用します。以 下に、GIVE_RAISE ストアド プロシージャを作成するための Oracle の 構文を示します。 アプリケーション テクニック 191 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 SQL 文の区切り子 Oracle のストアド プロシージャを作成するための構文では、バック クォーテーション(`)記号を SQL 文の区切り子として使っています。 // Oracle の GIVE_RAISE 関数を作成します。 // SQL 文の区切り子は、`(バッククォーテーション)です。 CREATE OR REPLACE FUNCTION give_raise (salary IN OUT NUMBER) return NUMBER IS rv NUMBER; BEGIN salary := salary * 1.05; rv := salary; return rv; END; ` // 変更内容を保存します。 COMMIT WORK` // エラーをチェックします。 SELECT * FROM all_errors` ステップ 1: 標準クラス ユーザ オブジェクトの定義 v 標準クラス ユーザ オブジェクトを定義するには 1 PowerBuilder を起動します。 2 ストアド プロシージャをサポートするデータベースに接続します。 この例では、データベース サーバ上にリモート ストアド プロシー ジャを持っている Oracle データベースに接続するものとします。 PowerBuilder における Oracle データベースとの接続および Oracle のストアド プロシージャの使い方についての詳細は、 『データベー スとの接続』マニュアルを参照してください。 3 パワーバーの[新規作成]ボタンをクリックするか、メニューバー から[ファイル|新規作成]を選択します。 新規作成 ダイアログボックスが表示されます。 4 [PB オブジェクト]タブで、[標準クラス]アイコンを選択し、 [OK]ボタンをクリックして新規の標準クラス ユーザ オブジェク トを定義します。 192 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 標準クラス データ型の選択 ダイアログボックスが表示されます。 5 ユーザ オブジェクトを継承したい組み込みシステムのデータ型と して、 [データ型]ボックスから[transaction]を選択し、 [OK]ボ タンをクリックします。 ユーザ オブジェクト ペインタのワークスペースが表示され、ユー ザ オブジェクトにプロパティ(インスタンス変数)と関数を設定 することができます。 ステップ 2: 外部関数としてのストアド プロシージャの宣言 FUNCTION または SUBROUTINE 宣言 PowerBuilder アプリケーションで、外部関数または外部サブルーチン として結果集合のないデータベースのストアド プロシージャを宣言 できます。ストアド プロシージャに戻り値がある場合は、 (FUNCTION キーワードを使用して)関数として宣言します。ストアド プロシー ジャに戻り値がないか VOID を返す場合は、(SUBROUTINE キーワード を使用して)サブルーチンとして宣言します。 RPCFUNC と ALIAS FOR キーワード 外部関数が DLL ではなく、データベースのストアド プロシージャの ためにリモート プロシージャ コール(RPC)であることを示す、外部 関数や外部サブルーチンの宣言で RPCFUNC キーワードを必ず使用し なければなりません。データベースのストアド プロシージャの名前と 異なる名前をスクリプトで使用したい場合は、ALIAS FOR "spname" 句 を使用して、ストアド プロシージャに名前を与えることができます。 ストアド プロシージャをリモート プロシージャ コールとして宣言す るための構文についての詳細は、『PowerScript リファレンス』マニュ アルの「関数とイベントの呼び出し」の章を参照してください。 アプリケーション テクニック 193 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 v ストアド プロシージャをユーザ オブジェクトの外部関数として宣言するには 1 ユーザ オブジェクト ペインタのスクリプト ビューで、最初のリス トから「Declare」を選択し、2 番目のリストから「Local External Funcions」を選択します。 2 カーソルをローカル外部関数の宣言ビューに置きます。ポップ アップ メニューまたは[編集]メニューから、 [形式を指定して貼 り付け| SQL |リモート ストアド プロシージャ]を選択します。 データベースからストアド プロシージャがロードされ、リモート ストアド プロシージャ ダイアログボックスが表示されます。ダイ アログボックスには、現行のデータベースにあるストアド プロ シージャ名のリストが表示されます。 3 ユーザ オブジェクトの関数として宣言するストアド プロシージャ を 1 つまたは複数選択し、[OK]ボタンをクリックします。 PowerBuilder は、データベースからストアド プロシージャの宣言 を取り出し、各宣言をビューに貼り付けます。 たとえば、sp_addlanguage を選択した場合には、1 行に表示される 宣言は次のようになります。 function long sp_addlanguage() RPCFUNC ALIAS FOR "dbo.sp_addlanguage" 4 必要であれば、アプリケーションに対するストアド プロシージャ の宣言を編集することができます。 外部関数または外部サブルーチンとして、データベースのリモー ト プロシージャ コール(RPC)を宣言する場合は、以下の構文の いずれかを使用します(構文についての詳細は、『PowerScript リ ファレンス』マニュアルを参照してください)。 194 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 FUNCTION rtndatatype functionname ( { { REF } datatype1 arg1, ..., { REF } datatypen argn } ) RPCFUNC { ALIAS FOR "spname" } SUBROUTINE functionname ( { { REF } datatype1 arg1 , ..., { REF } datatypen argn } ) RPCFUNC { ALIAS FOR "spname" } 以下に、sp_addlanguage に対する RPC 関数の宣言を編集したもの を示します。 FUNCTION long sp_addlanguage() RPCFUNC ALIAS FOR "addlanguage_proc" ステップ 3: ユーザ オブジェクトの保存 v ユーザ オブジェクトを保存するには 1 ユーザ オブジェクト ペインタで、[保存]ボタンをクリックする か、メニューバーから [ファイル|名前を付けて保存]を選択し ます。 ユーザ オブジェクトの保存 ダイアログボックスが表示されます。 2 ユーザ オブジェクトの名前を指定し、そのユーザ オブジェクトに ついてのコメントを記述し、ユーザ オブジェクトを保存するライ ブラリを指定します。 3 [OK]ボタンをクリックして、ユーザ オブジェクトを保存します。 ユーザ オブジェクトは、指定した名前で選択したライブラリに保 存されます。 ステップ 4: SQLCA に対するデフォルトのグローバル変数の型の指定 ア プ リ ケ ー シ ョ ン ペ イ ン タ で、定 義 し た ユ ー ザ オ ブ ジ ェ ク ト を SQLCA に対するデフォルト グローバル変数の型として指定しなけれ ばなりません。これにより、アプリケーションを実行すると、組み込 みシステム トランザクション オブジェクトのかわりにその標準クラ ス ユーザ オブジェクトがデフォルト トランザクション オブジェクト として使用されます。 アプリケーション テクニック 195 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 SQLCA のかわりに独自のトランザクション オブジェクトを使用 このプロシージャでは、アプリケーションでデフォルト トランザク ション オブジェクト SQLCA を使用するものとしていますが、独自の トランザクション オブジェクトのインスタンスを宣言して作成し、そ の後、ユーザ オブジェクトをトランザクション オブジェクトのプロパ ティとして呼び出すことも可能です。詳細については、PowerBuilder の『ユーザーズ ガイド』マニュアルの「ユーザ オブジェクト」の章を 参照してください。 v SQLCA に対するデフォルト グローバル変数の型を指定するには 1 パワーバーの[開く]ボタンをクリックするか、メニューバーか ら[ファイル|開く]を選択します。 開く ダイアログボックスが表示されます。 2 [オブジェクトの種類]ドロップダウン リストボックスから[アプ リケーション]を選択します。新規のユーザ オブジェクトを使用 したいアプリケーションを選択して、 [OK]ボタンをクリックし ます。 アプリケーション ペインタ ワークスペースが表示されます。 3 プロパティ ビューで[全般]タブを選択します。 [付加的なプロパ ティ]ボタンをクリックします。 アプリケーション ダイアログボックスが表示されます。 4 [変数の型]タブを選択して、[変数の型]プロパティ ページを表 示します。 196 PowerBuilder 第 12 章 5 トランザクション オブジェクトの使い方 テキストボックスに、ステップ 1 から 3 までで定義した標準クラ ス ユーザ オブジェクトの名前を指定します。 6 [OK]ボタンか、[更新]ボタンをクリックします。 アプリケーションを実行すると、組み込みシステム オブジェクト のかわりに、そのシステム オブジェクトを継承した標準クラス ユーザ オブジェクトが使用されます。 ステップ 5: アプリケーションでユーザ オブジェクトを使用する これまでに行ったこと 先の操作手順では、標準クラス ユーザ オブジェ クト u_trans_database の外部関数としてリモート ストアド プロシー ジャ GIVE_RAISE を定義しました。次に、SQLCA に対するデフォルト グローバル変数の型として、u_trans_database を指定しました。これで、 PowerBuilder アプリケーションは、ユーザ オブジェクト内にカプセル 化されたプロパティと関数にアクセスできます。 次は、このユーザ オブジェクトにストアド プロシー ジャを実行させるスクリプトを記述する必要があります。 この後に行うこと アプリケーション テクニック 197 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 アプリケーションのスクリプトで、ユーザ オブジェクトで定義したス トアド プロシージャ関数を呼び出すには、ほかの PowerBuilder オブ ジェクトと同様に SQLCA に対して、PowerScript のドット(.)表記を 使用します。ドット(.)表記の構文は以下のとおりです。 object.function ( arguments ) たとえば、以下の記述で、GIVE_RAISE ストアド プロシージャを呼び出 すことができます。 SQLCA.give_raise(salary) v アプリケーションでユーザ オブジェクトを使用するには 1 スクリプトを記述するオブジェクトまたはコントロールを選択し ます。 2 スクリプトを記述したいイベントを選択します。 スクリプト ビューの使い方については、PowerBuilder の『ユーザー ズ ガイド』マニュアルを参照してください。 3 アプリケーションでストアド プロシージャによる処理を行うため に、ユーザ オブジェクトを用いたスクリプトを記述します。 以下の例は、Oracle データベースに接続し、GIVE_RAISE ストアド プロシージャを呼び出して、昇給額を計算し、昇給後の給料をメッ セージボックスに表示してから、データベースとの接続を解除し ます。 // トランザクション オブジェクトのプロパティを設定します。 SQLCA.DBMS="OR7" SQLCA.LogID="scott" SQLCA.LogPass="xxyyzz" SQLCA.ServerName="@t:oracle:testdb" SQLCA.DBParm="sqlcache=24,pbdbms=1" // Oracle データベースに接続します。 CONNECT USING SQLCA; // エラーをチェックします。 IF SQLCA.sqlcode <> 0 THEN MessageBox (" 接続エラー ",SQLCA.SQLErrText) return END IF // 現在の給料として 2,000,000 を設定します。 DOUBLE val = 2000000 DOUBLE rv 198 PowerBuilder 第 12 章 // // // // rv トランザクション オブジェクトの使い方 GIVE_RAISE ストアド プロシージャを 呼び出し、昇給額を計算します。 ストアド プロシージャを呼び出すのにドット(.)表記を 使用します。 = SQLCA.give_raise(val) // メッセージボックスに昇給後の給料を表示します。 MessageBox(" 新しい給与額は ",string(rv)) // Oracle データベースとの接続を解除します。 DISCONNECT USING SQLCA; 4 スクリプトをコンパイルして、変更内容を保存します。 エラー チェックの使い方 実際のスクリプトでは、CONNECT 文や DISCONNECT 文の実行後と GIVE_RAISE プロシージャを呼び出した後に、エラーのチェックをする べきです。詳細については、188 ページの「SQL 文実行後のエラー処 理」を参照してください。 ストアド プロシージャを呼び出すときサポートされている DBMS の機能 アプリケーションで、リモート ストアド プロシージャを呼び出すため に、カスタム トランザクション オブジェクトを定義して使用する場 合、アプリケーションが接続する DBMS によってサポートされる機能 が異なります。 この節では、PowerBuilder からアクセスできる DBMS に応じてサポー トされている機能の違いを解説します。PowerBuilder アプリケーショ ンで RPC テクニックを使用する場合は、使用している DBMS に関す る項目を参照して、できることとできないことを確認してください。 アプリケーション テクニック 199 ストアド プロシージャを呼び出すときサポートされている DBMS の機能 結果集合 リモート ストアド プロシージャを呼び出して、ストアド プロシージャ が返す結果集合にアクセスすることはできません。ストアド プロシー ジャが 1 つ以上の結果集合を返す場合、PowerBuilder は結果集合を無 視して、出力パラメータと戻り値を返します。 ストアド プロシージャが結果集合を返す場合は、埋め込み SQL の DECLARE Procedure 文を使用します。DECLARE Procedure 文についての 詳細は、『PowerScript リファレンス』マニュアルの「SQL 文」を参照 してください。 Informix ODBC アプリケーションが Informix データベースに接続する場合は、配列以 外のデータ型が使用できます。なお、Blob(Binary Large Object)型は 使用できません。 アプリケーションが ODBC データ ソースに接続する場合は、ODBC ド ライバがサポートしていれば、以下の ODBC の機能が使用できます (詳細については、使用している ODBC ドライバのマニュアルを参照 してください)。 • 表 12-5 に IN、OUT、IN OUT の各パラメータを示します。 表 12-5: ODBC の IN、OUT、IN OUT の各パラメータ パラメータ IN(入力) 結果 IN 変数は値によって渡される。プロシージャには値が 渡される OUT(出力) OUT 変数は参照によって渡される。プロシージャは、 渡された PowerScript 変数の内容を変更できる。このパ ラメータには、PowerScript の REF キーワードを指定す る IN OUT IN OUT 変数は参照によって渡される。プロシージャは (入力 / 出力) 渡された値の参照と、PowerScript 変数の内容の変更が できる。このパラメータには、PowerScript の REF キー ワードを指定する Oracle • パラメータとしての Blob データ。Blob データは、32,512 バイトま で使用できます。 • Integer 型のリターン コード アプリケーションが Oracle データベースに接続する場合は、以下の Oracle PL/SQL の機能が使用できます。 • 200 表 12-6 に IN、OUT、IN OUT の各パラメータを示します。 PowerBuilder 第 12 章 トランザクション オブジェクトの使い方 表 12-6: Oracle の IN、OUT、IN OUT の各パラメータ パラメータ IN(入力) 結果 IN 変数は値によって渡される。プロシージャには値が 渡される OUT(出力) OUT 変数は参照によって渡される。プロシージャは、 渡された PowerScript 変数の内容を変更できる。このパ ラメータには、PowerScript の REF キーワードを指定す る IN OUT IN OUT 変数は参照によって渡される。プロシージャは (入力 / 出力) 渡された値の参照と、PowerScript 変数の内容の変更が できる。このパラメータには、PowerScript の REF キー ワードを指定する Microsoft SQL Server または Sybase Adaptive Server Enterprise • パラメータとしての Blob データ。Blob データは、32,512 バイトま で使用できます。 • パラメータとしての PL/SQL テーブル。PowerScript の配列が使用 できます。 • 関数のリターン コード アプリケーションが Microsoft SQL Server または Sybase Adaptive Server Enterprise のデータベースに接続された場合には、以下の Transact-SQL 機能を使用できます。 表 12-7 に IN、OUT、IN OUT の各パラメータを示します。 • 表 12-7: Adaptive Server Enterprise および Microsoft SQL Server の IN、 OUT、IN OUT の各パラメータ パラメータ IN(入力) 結果 IN 変数は値によって渡される。プロシージャには値が 渡される OUT(出力) OUT 変数は参照によって渡される。プロシージャは、 渡された PowerScript 変数の内容を変更できる。このパ ラメータには、PowerScript の REF キーワードを指定す る IN OUT IN OUT 変数は参照によって渡される。プロシージャは (入力 / 出力) 渡された値の参照と、PowerScript 変数の内容の変更が できる。このパラメータには、PowerScript の REF キー ワードを指定する • パラメータとしての Blob データ。Blob データは、32,512 バイトま で使用できます。 • Integer 型のリターン コード アプリケーション テクニック 201 ストアド プロシージャを呼び出すときサポートされている DBMS の機能 SQL Anywhere アプリケーションが SQL Anywhere のデータベースに接続された場合 には、以下の SQL Anywhere 機能を使用できます。 • 表 12-8 に IN、OUT、IN OUT の各パラメータを示します。 表 12-8: SQL Anywhere の IN、OUT、IN OUT の各パラメータ パラメータ IN(入力) 結果 IN 変数は値によって渡される。プロシージャには値が 渡される OUT(出力) OUT 変数は参照によって渡される。プロシージャは、 渡された PowerScript 変数の内容を変更できる。このパ ラメータには、PowerScript の REF キーワードを指定す る IN OUT IN OUT 変数は参照によって渡される。プロシージャは (入力 / 出力) 渡された値の参照と、PowerScript 変数の内容の変更が できる。このパラメータには、PowerScript の REF キー ワードを指定する • 202 パラメータとしての Blob データ。Blob データは、32,512 バイトま で使用できます。 PowerBuilder 第 1 3 章 MobiLink 同期の使い方 この章について この章では、 『ユーザーズ ガイド』マニュアルの「データベース管 理」の章で説明した、MobiLink 同期の概要を補足します。同期プ ロセスの詳細なバックグラウンド、MobiLink 同期ウィザードで生 成されたオブジェクトの使用方法について説明します。さらに、 ウィザードを使用しないで同期オブジェクトを作成する方法につ いても説明します。 内容 項目 MobiLink 同期について 同期の動作方法 PowerBuilder 同期オブジェクトの使い方 統合データベースの準備 リモート データベースの作成 同期のテクニック ページ 203 208 210 222 231 237 MobiLink 同期について MobiLink は、統合データベースと呼ばれるメイン データベースと 多数のリモート データベース間の双方向の同期を実現できる、 セッションベースの同期システムです。 この節では、MobiLink の用語およびコンセプトの一部について説 明します。 参照先 MobiLink 同期の詳細については、『MobiLink - クイック・スター ト』、 『MobiLink - クライアント管理』、 『Mobilink - サーバ管理』の 各マニュアルを参照してください。 これらのマニュアルは、SQL Anywhere 製品マニュアル のサイト http://www.ianywhere.com/developer/product_manuals/sqlanywhere/ で入 手できます。 アプリケーション テクニック 203 MobiLink 同期について すでに MobiLink について理解している場合は、210 ページの 「PowerBuilder 同期オブジェクトの使い方」の PowerBuilder と MobiLink との統合についての説明に進んでください。 データの移動と同期 データの移動が行われるのは、共有データが複数のノードにある複数 のデータベース上に分散している場合に、あるデータベースのデータ に行われた変更が別のデータベースの対応するデータに適用されると きです。データは、複製または同期によって移動できます。 データの複製では、すべてのトランザクションが一方のデータベース から他方のデータベースに移動されます。データの同期では、トラン ザクションの最終結果だけが移動されます。どちらの方法も、トラン ザクション ログ ファイルをスキャンすることで情報を取得しますが、 同期の場合はログ ファイル全体ではなく、更新されたログ ファイル セ グメントだけを使用するので、データをより高速かつ効率的に移動で きます。 同期の場合は、データをローカルで利用でき、サーバに接続しなくて も変更できます。MobiLink 同期は、ゆるやかな一貫性方式を使用しま す。このモデルは、すべての変更が一貫した方法で徐々に各サイトと 同期を取りますが、特定のタイミングで別のサイトが異なるコピーを 保持している可能性があることを意味します。同期が取られるのは、 成功したトランザクションだけです。 統合データベースとリ モート データベース 統合データベースは、SQL Anywhere、Sybase Adaptive Server Enterprise、 Oracle、 IBM DB2 UDB、または Microsoft SQL Server などのような ODBC 準拠のデータベースであり、すべてのデータのマスタ コピーを保持し ます。 リモート データベースには、統合データのサブセットが含まれていま す。MobiLink は、SQL Anywhere および UltraLite データベースと同期 を取ることができますが、PowerBuilder アプリケーションの場合、リ モート データベースは SQL Anywhere データベースでなければなりま せん。 MobiLink 同期サーバ MobiLink 同期サーバ mlsrv11 は、同期プロセスを管理し、リモート デー タベースと統合データベース サーバ間のインタフェースを提供しま す。MobiLink 同期サーバと統合データベース間の通信はすべて ODBC 接続を介して行われます。統合データベースと同期サーバは、一般に 同一マシン上は配置されますが、別のマシン上でもかまいません。 同期プロセスを開始する前に、MobiLink サーバを起動しておく必要が あります。データベース ペインタのオブジェクト ビューの[Utilities] フォルダから MobiLink 同期サーバを起動できます。 204 PowerBuilder 第 13 章 MobiLink 同期の使い方 コマンド ラインからサーバを起動する方法については、オンラインの 『MobiLink - サーバ管理』マニュアルの「Mobile Link サーバの実行」を 参照してください。 MobiLink 階層構造 MobiLink は、一般に階層構造の設定を使用します。階層構造内のノー ドは、サーバ、デスクトップ コンピュータ、およびハンドヘルド デバ イスまたは埋め込みデバイスに配置できます。単純な階層構造は、サー バ上の統合データベースと、モバイル デバイス上の複数のリモート データベースで構成できます。もう少し複雑な階層構造には、複数の レベルがあり、各レベルでいくつかのサイトがリモート データベース と統合データベースの両方として機能します。PowerBuilder アプリ ケーションでは、リモート データベースとしても機能する統合データ ベースは、SQL Anywhere データベースでなければなりません。 たとえば、リモート サイト A1、A2、A3 がローカル サーバ上の統合 データベース A と同期を取り、リモート サイト B1、B2、B3 が別の ローカル サーバ上の統合データベース B と同期を取るとします。A と B は順番にリモート サイトとして機能して、マスタ サーバ上の統合 データベース C と同期を取ります。データベース C には 任意の ODBC 準拠のデータベースを利用できますが、A と B は SQL Anywhere デー タベースでなければなりません。 アプリケーション テクニック 205 MobiLink 同期について 図 13-1: MobiLink 階層構造 同期スクリプト MobiLink 同期は、イベント駆動型のプロセスです。MobiLink クライア ントが同期を開始すると、MobiLink サーバ内で多数の同期イベントが 発生します。イベントが発生すると、MobiLink はその同期イベントと 一致するスクリプトを探します。MobiLink サーバで何らかの動作を実 行させるには、イベントに対応するスクリプトを提供する必要があり ます。 接続レベルのイベント、およびリモート データベースの各テーブル レ ベルのイベントに対応する同期スクリプトを記述できます。これらの スクリプトは統合データベースに保存します。 SQL、Java、または .NET を使用してスクリプトを記述できます。イベ ント スクリプト、および Sybase Central での MobiLink 同期プラグイン でのイベント スクリプトの記述についての詳細は、222 ページの「統 合データベースの準備」を参照してください。 206 PowerBuilder 第 13 章 MobiLink 同期クライ アント MobiLink 同期の使い方 リモート サイト上の SQL Anywhere クライアントは、コマンド ライン ユーティリティ dbmlsync を実行して同期を開始します。このユーティ リティは、リモート データベース上の 1 つまたは複数のサブスクリプ ションと MobiLink 同期サーバとの同期を取ります。サブスクリプショ ンについては、次の「パブリケーション、アーティクル、ユーザ、サ ブスクリプション」で説明します。dbmlsync ユーティリティとそのオ プションについての詳細は、SQL Anywhere オンライン ブックのイン デックスで「dbmlsync ユーティリティ」を参照してください。 PowerBuilder では、ASA MobiLink 同期ウィザードで作成される同期オ ブジェクトが dbmlsync プロセスを管理します。詳細については、210 ページの「PowerBuilder 同期オブジェクトの使い方」を参照してくだ さい。 パブリケーション、 アーティクル、ユー ザ、サブスクリプショ ン パブリケーションは、リモート データベース上のデータベース オブ ジェクトであり、同期を取るテーブルとカラムを識別します。各パブ リケーションには、1 つまたは複数のアーティクルを含めることがで きます。アーティクルはデータベース オブジェクトであり、テーブル 全体、またはテーブル内のカラムと行のサブセットを示します。 ユーザは、リモート データベース上のデータベース オブジェクトであ り、固有の同期クライアントを記述します。MobilLink システムのリ モート データベースごとに 1 つの MobiLink ユーザ名があります。統 合データベース上の ml_user という MobiLink システム テーブルは、 MobiLink ユーザ名のリストを保持します。これらの名前は認証に使用 されます。 サブスクリプションは、ユーザを 1 つまたは複数のパブリケーションに 関連付けます。また、同期プロトコル(TCP/IP、HTTP、または HTTPS)、 アドレス(myserver.acmetools.com など)、その他の任意の接続および 拡張オプションを指定します。 ユーザ、パブリケーション、サブスクリプションは、リモート データ ベースで作成されます。これらは、Sybase Central で SQL Anywhere プ ラグイン(MobiLink 同期プラグインではありません)を使用して作成 できます。ユーザ、パブリケーション、サブスクリプションの作成に ついては、231 ページの「リモート データベースの作成」を参照して ください。 アプリケーション テクニック 207 同期の動作方法 同期プロセス dbmlsync は、TCP/IP、HTTP、または HTTPS を使用してリモート デー タベースに接続し、統合データベースにアップロードするデータのス トリーム(アップロード ストリーム)を準備します。dbmlsync は、リ モート データベースのトランザクション ログ内の情報を使用して、 アップロード ストリームを作成します。アップロード ストリームに は、MobiLink ユーザ名とパスワード、使用する同期スクリプトのバー ジョン、前回の同期のタイムスタンプ、パブリケーション内のテーブ ルとカラムのスキーマ、および前回の同期以降のすべての挿入、更新、 削除の最終結果が含まれます。 アップロード ストリームを作成した後、dbmlsync は、指定されたパブ リケーションとサブスクリプションに格納された情報を使用して、 MobiLink 同期サーバに接続し、データを交換します。 MobiLink 同期サーバは、データを受信すると、統合データベースを更 新し、関連する変更をすべて含むダウンロード ストリームを作成し て、それをリモート サイトに戻します。それぞれの同期が正常に終了 した時点で、統合データベースとリモート データベースの一貫性が維 持されています。同期は、トランザクション全体について実行される か全く実行されないかのどちらかです。これで、各データベースでト ランザクションの整合性が維持されます。 同期の動作方法 MLSync イベントの実 装方法 図 13-2 に示すように、PowerBuilder アプリケーションの MLSync オブ ジェクトと dbmlsync プロセスは、2 つのウィンドウ間でメッセージを 送信して互いに通信します。MLSync オブジェクトが作成するウィン ドウは内部関数 MlSyncControlWindowProc を使用して、これらのメッ セージを処理します。 Synchronize 関数は、dbmlsync を起動するコマンド ライン文字列の最後 に、 「-wh window_handle」引数を追加します。これにより、dbmlsync は WM_COPYDATA メッセージをこのウィンドウ ハンドルに送信し ます。MlSyncControlWindowProc は次に、MLSync オブジェクトの対象 イベントを起動させます。 208 PowerBuilder 第 13 章 MobiLink 同期の使い方 図 13-2: 同期プロセスの動作方法 進行状態ウィンドウ イベントの起動方法 MobiLink 同期ウィザードは、イベントごとに PowerScript コードを含 む MLSync オブジェクトのインスタンスを生成します。生成されたイ ンスタンスが適切である場合、このコードは進行状態ウィンドウで同 じ名前のイベントを起動します。この進行状態ウィンドウは、ウィザー ドが生成したウィンドウ、またはアプリケーション用にカスタマイズ されたウィンドウのいずれかです。 CancelSync 関数の実 装方法 dbmlsync コマンド文字列には「-wc window_class」引数があります。こ の引数には、dbmlsync が登録して作成するコミュニケーション ウィン ドウのクラス名を指定します。PowerBuilder アプリケーションで、任 意のイベント処理ロジックを実行中に同期プロセスをキャンセルする 必要がある場合は、CancelSync を呼び出します。この関数は、-wc ウィ ンドウ クラスに関連付けられたウィンドウ ハンドルを見つけて、 WM_CLOSE メッセージを送信します。 アプリケーション テクニック 209 PowerBuilder 同期オブジェクトの使い方 PowerBuilder 同期オブジェクトの使い方 新規作成 ダイアログボックスの[データベース]ページから ASA MobiLink 同期ウィザードを実行すると、ウィザードによってオブジェ クトが生成されます。これを PowerBuilder アプリケーションからの MobiLink 同期リクエストの開始と制御に使用できます。これらのオブ ジェクトを使用して、同期プロセス中にフィードバックを取得したり、 同期中の特定の時点での PowerScript イベントのコードを作成したり、 プロセスをプログラムによってキャンセルしたりできます。 MobiLink 同期ウィザードの詳細については、『ユーザーズ ガイド』マ ニュアルの「データベースの管理」を参照してください。 ウィザードを使用する準備 本稼動アプリケーションでウィザードを使用する前に、次の作業を行 う必要があります。 • 222 ページの「統合データベースの準備」に従って、統合データ ベースをセットアップし、同期スクリプトを記述します。 • 231 ページの「リモート データベースの作成」に従って、デスク トップにリモート データベースを作成し、1 つまたは複数のパブ リケーション、ユーザ、サブスクリプションをセットアップしま す。 • PowerBuilder オンライン ヘルプにある『データベースとの接続』マ ニュアルと 221 ページの「ファイル DSN によるレジストリ DSN の代用方法」に従って、すべてのリモート マシンで ODBC マネー ジャにデータベースを登録するか、リモート データベース用の ファイル DSN を作成します。 • 219 ページの「リモート マシンでの同期の実行時要件」に従って、 すべてのリモート マシンに必要なサポート ファイルがあること を確認します。 • (オプション)PowerBuilder オンライン ヘルプにある『データベー スとの接続』マニュアルに従って、リモート データベースのデー タベース接続プロファイルを作成します。プロファイルを作成す ると、ウィザードが、MobiLink サブスクリプションが入力されて いるリモート データベースから、パブリケーションのリストを取 り出すことができます。 210 PowerBuilder 第 13 章 MobiLink 同期の使い方 生成されるもの ウィザードは、2 つのオブジェクト セットを生成します。 同期を開始およびモニ タするオブジェクト 1 つ目のオブジェクト セットは、エンド ユーザによる同期の開始およ びモニタに使用できます。 • nvo_appname_mlsync – MobiLink クライアントを制御するカスタム クラス ユーザ オブジェクト(appname はアプリケーションの名前) • gf_appname_sync – ユーザ オブジェクトをインスタンス化し、同期 リクエストを開始する関数を呼び出すグローバル関数 • w_appname_syncprogress – 同期プロセスの進行をレポートする、省 略可能なステータス ウィンドウ ウィザードでは、アプリケーションでステータス ウィンドウを使用す るかどうかを選択できます。生成されるステータス ウィンドウには、 ウィンドウを閉じる前にユーザがステータスを確認できる[OK]ボタ ンと、完了前の同期をユーザがキャンセルできる[キャンセル]ボタ ンがあります。アプリケーションのニーズに合わせてウィンドウをカ スタマイズすることもできます。 同期オプションを変更 するオブジェクト 2 つ目のオブジェクト セットは、ウィザードで[ユーザのパスワード と実行オプションの入力]を選択している場合にだけ生成されます。 これを使用すると、エンド ユーザは同期を開始する前に同期オプショ ンを変更できます。 • w_appname_sync_options – MobiLink ユーザ名とパスワード、 MobiLink サーバのホスト名とポート、および dbmlsync のその他の オプションの変更、およびステータスの表示方法の選択をエンド ユーザが行うことができるオプション ウィンドウ。 • gf_appname_configure_sync – オプション ウィンドウを開くグローバ ル関数。ユーザが[OK]をクリックした場合は、gf_appname_sync を呼び出して同期を開始します。 オプション ウィンドウを使用するほとんどのアプリケーションは、同 期を開始するための 2 つのメニュー項目またはコマンド ボタンを提供 します。1 つは、ユーザが同期をリクエストする前に dbmlsync オプショ ンをセットアップまたは変更できるオプション ウィンドウを開きま す。もう 1 つは、現在のオプションで同期をリクエストします。 アプリケーション テクニック 211 PowerBuilder 同期オブジェクトの使い方 MLSync のインスタンスの作成 Dbmlsync.exe を起動する非ビジュアル オブジェクトの作成に、MobiLink 同期ウィザードを使用する必要はありません。次の方法で、MLSync シ ステム オブジェクトをアプリケーションに組み込むことができます。 プログラミングによる MLSync オブジェクト の追加 • PowerScript を使用してプログラムで作成 • 新規作成 ダイアログボックスから選択 次に示すコード フラグメントは、MLSync オブジェクトのインスタン スを作成し、システムの SyncParm 構造体のインスタンスを使用して、 オプションのプロパティと必要なプロパティすべてをプログラムで設 定します。次に、Synchronize 関数を呼び出してデータベースの同期を 開始します。 SyncParm MLSync Long Parms mySync rc mySync = CREATE MLSync mySync.MLServerVersion = 11// 必須 mySync.Publication = 'salesapi'// 必須 mySync.UseLogFile = TRUE// オプション mySync.LogFileName = "C:\temp\sync.log"// オプション mySync.Datasource = 'salesdb_remote'// 必須 Parms.MLUser = '50'// 必須 Parms.MLPass = 'xyz123'// 必須 // 以下の値は DSN で設定されない場合に // 必要な値 Parms.DBUser = 'dba' Parms.DBPass = 'sql' // プロパティ値を sync オブジェクトに適用 mySync.SetParm(Parms) // 同期プロセスの起動 rc = mySync.Synchronize() destroy mySync 新規作成 ダイアログ ボックスからの MLSync オブジェクト の追加 212 新規作成 ダイアログボックスを使用して、MLSync オブジェクトを対 象 PBL に追加できます。PowerBuilder のメニューから[ファイル|新 規作成]を選択して[PB オブジェクト]タブに移動し、 [標準クラス] を選択して、次に[MLSync]を選択します。これで、ユーザ オブジェ クト ペインタに新しい MLSync オブジェクトが開かれます。ここで、 すべてまたは一部のプロパティを初期化できます。すべての設定が終 了したら、対象 PBL に新しいオブジェクトとして保存できます。 PowerBuilder 第 13 章 MobiLink 同期の使い方 すべてのプロパティは、ユーザ ID とパスワードを含めてすでに初期化 されているため、すぐに使用できます。同期を取るには、次の例に示 すような多少のコーディングが必要です。この例の MLsync オブジェ クトは、「nvo_my_mlsync」として保存したオブジェクトです。 nvo_my_mlsync mySync Long rc mySync = CREATE nvo_my_mlsync mySync.Synchronize() destroy mySync これらのコードは、通常、アプリケーション ウィンドウの 1 つで、メ ニュー項目やコマンド ボタンの Clicked イベントに追加します。 詳細情報 同期に関連するシステム オブジェクト、および、システム オブジェク トの関数、イベント、プロパティの詳細については、オンライン ヘル プの MLSynchronization、MLSync、および SyncParm を参照してくださ い。 MobiLink 同期の補助オブジェクト PowerScript コードまたは新規作成 ダイアログボックスで MLSync の インスタンスを作成する場合は、補助オブジェクトの使用を検討して ください。この補助オブジェクトはウィザードで自動的に生成され、 PowerBuilder のウィンドウ ペインタでカスタマイズできます。 既存の同期進行状態 ウィンドウの使い方 MLSync オブジェクトをインスタンス化し、SetParm を呼び出して、エ ンド ユーザが実行時に認証プロパティを設定できるようにすると、デー タベース同期の進行状況を確認する Response! 型のウィンドウを呼び 出すことができます。進行状態ウィンドウを表示するには、ウィンド ウ名と MLSync オブジェクト名を引数として指定し、OpenWithParm を 呼び出します。デフォルトでは、ウィザードは w_appname_syncprogress という名前の進行状態ウィンドウを生成し、OpenWithParm の呼び出し を追加します。 MLSync オブジェクトのプロパティ ビューでは、同期呼び出しの進行 状況を確認する、カスタマイズされた進行状態ウィンドウを選択でき ます。ウィザードで生成された進行状態ウィンドウは、通常、タブ ページの一部のフィールドが非表示になっていたり、1 ~ 2 個のタブ ページが非表示になっていたりします。このウィンドウをカスタマイ ズする場合は、すべての MobiLink アプリケーションに対して、カス タマイズされた進行状態ウィンドウを選択できます。 アプリケーション テクニック 213 PowerBuilder 同期オブジェクトの使い方 実行時における接続引 数の変更 ユーザが実行時に認証パラメータを上書きできるようにするには、カ スタマイズされたオプション ウィンドウ、または、ウィザードで生成 された同期オプション ウィンドウを呼び出します。このオプション ウィンドウでは、SyncParm オブジェクトのインスタンスを順番に呼び 出すことができます。このインスタンスは、リモート データベース テーブルなどの、より高レベルのセキュリティ保護された永続的な保 存場所から、認証値を初期化できます。一部またはすべての認証値を 書き込み可能に設定すると、エンド ユーザが実行時に上書きできるよ うになります。 MLSync オブジェクトのプロパティ設定の管理 通常、MLSync オブジェクトから SetParm (SyncParm) を呼び出す場合、 MLSync オブジェクトのプロパティに対して設定した認証値 (AuthenticationParms、DBUser、DBPass、EncryptionKey、MLUser、お よび MLPass)を、特定の SyncParm プロパティの値が空の文字列で あっても、自動的に上書きします。ただし、SetParm を呼び出す前に、 SetNull を呼び出して SyncParm オブジェクトの特定のプロパティを NULL に設定した場合は、かわりに、MLSync オブジェクトのプロパ ティ値が使用されます。 デフォルトの同期オプション ウィンドウ w_appname_sync_options は、 Message オブジェクトの PowerObjectParm プロパティを使用して、呼び 出し側に SyncParm 構造体を返します。これによって呼び出し側は、よ り機密性の高い認証プロパティ値を安全な場所に保存できます。また、 実際の同期処理を続行するかどうかを指定する整数値を持つ SyncParm ReturnCode プロパティも設定できます。 オプション ウィンド ウのデフォルトのタブ ページ デフォルトの同期オプション ウィンドウには、[サブスクリプショ ン]、 [SQL Anywhere]、 [ML サーバ]、 [設定]の 4 つのタブ ページが あります。 [サブスクリプション]ページ MobiLink ウィザードを使用したときに、 利用可能なパブリケーションのリストから 1 つまたは複数のパブリ ケーションを選択しています。選択したパブリケーションは、 [サブス クリプション]ページに表示されますが、実行時に編集することはで きません。 各リモート ユーザは、このページで MobiLink 同期ユーザ名を入力す ることができます。この名前は、サブスクリプションでそのページに 表示されているパブリケーションと関連付けられている必要がありま す。アプリケーションを使用する MobiLink ユーザがいつも同じである 場合は、この情報を再入力する必要はありません。名前は、レジスト リに保存され、このデバイスのアプリケーションから同期処理が起動 されるたびにデフォルトで使用されます。 214 PowerBuilder 第 13 章 MobiLink 同期の使い方 MobiLink のパスワードと認証パラメータは、ユーザのレジストリには 保存されません。どちらも、毎回、ユーザが入力するか、安全なデー タベースから提供されます。 リモート ユーザは、このページで DSN ファ イル名を入力して、リモート データベースとの接続に必要なすべての 引数を渡すことができます。 [SQL Anywhere]ページ DSN ファイルが使用されない場合、または DSN ファイルにユーザ名 およびパスワードが記述されていない場合は、各リモート ユーザがリ モート データベースのユーザ名を入力できます。名前はレジストリに 保存され、このデバイスのアプリケーションから同期処理が起動され るたびにデフォルトで使用されます。 図 13-3 に、オプション ウィンドウの[SQL Anywhere]タブ ページを 示します。このタブ ページのフィールドは、 [DSN] 、 [ユーザ ID]、 [パ スワード]、および[暗号化キー]です。データベース パスワードと 暗号化キーはレジストリには保存されません。 図 13-3: 同期オプション ウィンドウ サブスクリプションを作成するときは、プロトコ ル、ホスト、ポート、そのほかの接続オプションを指定します。テス トを簡単にするために、デフォルト プロトコルを TCP/IP、デフォルト ホストを localhost にします。デフォルト ポートは、TCP/IP の場合は 2439、HTTP の場合は 80、HTTPS の場合は 443 です。 [ML サーバ]ページ アプリケーション テクニック 215 PowerBuilder 同期オブジェクトの使い方 テスト中にこれらのデフォルト値の変更が必要になる場合がありま す。また、サーバが別のホストに移動された場合やポートが変更され た場合は、アプリケーションの使用中にユーザがデフォルト値を変更 する必要があります。設計時にホストおよびポートの値を入力しな かった場合、および、ユーザがこのページで何も変更をしない場合、 dbmlsync はサブスクリプション内の値を使用します。 サブスクリプションの詳細については、236 ページの「サブスクリプ ションの追加」を参照してください。 [設定]ページ [設定]ページには、ログ オプションと、設計時に指定 したそのほかの dbmlsync オプションが表示され、ユーザはこれらのオ プションを実行時に変更できます。また、このページを使用して、同 期進行状態ウィンドウを表示するかどうかを選択できます。 拡張オプション 拡張オプションを追加するには、dbmlsync コマンド ラインで -e スイッ チを指定します。テキストボックスに -e スイッチを入力する必要はあ りません。 アプリケーションでの同期オブジェクトの使い方 生成されたオブジェクトを使用する前に、PowerBuilder のペインタを 使ってオブジェクトの操作方法を理解しておいてください。多数の関 数およびイベント スクリプトに、その用途を説明するコメントが含ま れています。 アプリケーションによる同期の管理を全面的に制御できるように、す べてのソース コードが提供されています。オブジェクトは、そのまま でも、変更しても、または独自オブジェクトのテンプレートとしても 使用できます。 ユーザ オブジェクト のプロパティ 216 nvo_appname_mlsync ユーザ オブジェクトには、パブリケーション名、 MobiLink サーバのホスト名とポート、リモート データベースに接続す るためのユーザ名とパスワードなどの特定の dbmlsync 引数を示すプロ パティが含まれています。 PowerBuilder 第 13 章 MobiLink 同期の使い方 ウィザードを実行すると、これらのプロパティで指定した値が、ユー ザ オブジェクトの constructor イベントのスクリプトにデフォルト値と して設定されます。また、これらの値は、開発コンピュータの Windows レジストリ HKEY_CURRENT_USER\Software\Sybase\PowerBuilder\11.5\appname \MobiLink にも設定されます。ここで appname はアプリケーションの 名前です。 実行時に、constructor イベントのスクリプトは、リモート マシンのレ ジストリからプロパティの値を取得します。レジストリから取得でき ない場合、またはレジストリ設定を上書きしている場合は、かわりに、 スクリプトで提供されているデフォルト値が使用され、レジストリに 書き込まれます。 イベント スクリプトのデフォルト値は変更できます。また、 w_appname_sync_options ウィンドウを開くメニュー項目を提供するこ とによって、実行時にユーザがレジストリ値を変更できるようにする こともできます。 dbmlsync の開始 ユーザが同期プロセスを開始できるようにするには、gf_appname_sync グローバル関数を呼び出すボタンまたはメニューのイベントスクリプ トを記述します。この関数は、nvo_appname_mlsync ユーザ オブジェク トのインスタンスを作成します。ユーザ オブジェクトの constructor イベ ント スクリプトは、リモート マシンのレジストリの appname\MobiLink キーを設定します。 ウィザードで進行状態ウィンドウを表示するように指定した場合、グロー バル関数は進行状態ウィンドウを開き、このウィンドウの ue_postopen イ ベントがユーザ オブジェクトの同期関数 nvo_appname_mlsync を呼び 出します。それ以外の場合、グローバル関数は同期関数を呼び出しま す。同期関数は dbmlsync を外部プロセスとして起動します。 MobiLink ユーザ名お よびパスワードの入力 グローバル関数は、唯一の引数として構造体を受け取ります。ここで は、インスタンス化したシステムの SyncParm 構造体を渡すことができ ます。この構造体には、String データ型の 6 つの変数(MobiLink とリ モート データベースそれぞれのユーザ名とパスワード、認証パラメー タと暗号化キーの変数)と、リターン コード用に Long データ型の別 の変数が含まれています。 引数として渡す構造体に有効な値を割り当てる場合、グローバル関数 は、MobiLink サーバとリモート データベースの接続を可能にするユー ザ オブジェクトに、これらの値を渡します。 アプリケーション テクニック 217 PowerBuilder 同期オブジェクトの使い方 オプション ウィンドウ(214 ページの「オプション ウィンドウのデ フォルトのタブ ページ」を参照)は、ユーザが初めて同期を開始する ときにこれらの値をレジストリに確実に格納するメカニズムを提供し ています。機密性の高いパスワードと暗号化情報は、レジストリには 保存されません。初回以降の同期は、ユーザが情報を再入力しなくて も開始できますが、オプション ウィンドウを使用してレジストリ値を 上書きしたり再設定したりすることもできます。 同期後のデータの取り 出し 同期の後は、一般に同期エラーについてテストし、新しく同期された データベースからデータを取り出します。たとえば、次のようになり ます。 if gf_myapp_sync(s_opt) <> 0 then MessageBox(" エラー ", "MobiLink エラー ") else dw_1.Retrieve() end if dbmlsync メッセージ の取得 PowerBuilder VM は、同期プロセスの実行中に、dbmlsync プロセスから のメッセージをトラップし、ユーザ オブジェクトのイベントを発生さ せます。 次のイベントは、同期開始前のアップロード ストリームを準備すると きに発生します。 ue_begin_logscan ( long rescan_log ) ue_progress_info ( long progress_index, long progress_max ) ue_end_logscan ( ) 次のイベントは、223 ページの「接続イベント」で説明する同期サー バでのイベントに対応しています。 ue_begin_sync ( string user_name, string pub_names) ue_connect_MobiLink ( ) ue_begin_upload ( ) ue_end_upload ( ) ue_begin_download ( ) ue_end_download ( long upsert_rows, long delete_rows ) ue_disconnect_MobiLink( ) ue_end_sync ( long status_code ) 次のイベントは、ue_end_upload の後、ue_begin_download の前に発生し ます。 ue_wait_for_upload_ack ( ) ue_upload_ack ( long upload_status ) 218 PowerBuilder 第 13 章 MobiLink 同期の使い方 次のイベントは、各種のメッセージがサーバから送信されるときに発 生します。 ue_error_msg ( string error_msg ) ue_warning_msg ( string warning_msg ) ue_file_msg ( string file_msg ) ue_display_msg ( string display_msg ) ウィザードが作成するデフォルト イベント スクリプトは、オプション の進行状態ウィンドウがある場合はそこで対応するイベントを発生さ せます。ウィンドウ イベントは、進行状態ウィンドウのマルチライン エディット コントロールに進行状況(プログレス)を書き込みます。 一部のウィンドウ イベントは、実行中の同期操作のフェーズ(ログ ス キャン、アップロード、またはダウンロード)を表示するスタティッ ク テキスト コントロールも更新します。また、完了した操作のパーセ ンテージを表示する水平プログレスバーを制御します。 ユーザ オブジェクトまたはウィンドウ イベントに、対応する MobiLink イベントが同期プロセス中に発生した時点で実行されるコードを追加 することもできます。dbmlsync プロセスは、イベント メッセージを制 御元の PowerBuilder アプリケーションに送信し、PowerBuilder イベン ト処理が完了するまで待ってから処理を継続します。 同期のキャンセル 進行状態ウィンドウの[キャンセル]ボタンは、cancelsync ユーザ オ ブジェクト関数を呼び出して、同期プロセスをキャンセルします。ア プリケーションが進行状態ウィンドウを使用しない場合は、この関数 を、アプリケーションの別のイベント スクリプトで呼び出すことがで きます。 リモート マシンでの同期の実行時要件 リモート マシンで必 要なサポート ファイ ル PowerBuilder または SQL Anywhere をリモート マシンにインストール していない場合、PowerBuilder アプリケーションとの MobiLink 同期を 使用するには、表 13-1 に示されているファイルをコピーする必要があ ります。これらのファイルは、リモート マシンのシステム パス、または PowerBuilder アプリケーションをコピーしたディレクトリにコピーし てください。 アプリケーション テクニック 219 PowerBuilder 同期オブジェクトの使い方 表 13-1: リモート マシンのシステム パスに必要なランタイム ファイル 必須ファイル PBDPL115.DLL、PBVM115.DLL、 PBDWE115.DLL、PBSHR115.DLL、 PBODB115.DLL、PBODB115.INI、 LIBJCC.DLL、LIBJUTILS.DLL GDIPLUS.DLL、MSVCP71.DLL、 MSVCR71.DLL 説明 開発マシンの Shared\PowerBuilder ディ レクトリからコピーできる PowerBuilder ファイル PowerBuilder とともに出荷される Microsoft ファイル。クライアント アプ リケーションとこれらのファイルを配 布する際の制限については、『リリー ス ノート』マニュアルを参照してくだ さい。 D B E N G 1 1 . E X E 、開発マシンの Sybase\SQL D B M L S Y N C . E X E 、Anywhere 11\bin32 (または bin64) D B S E R V 1 1 . D L L 、ディレクトリからコピーできる SQL D B T O O L 1 1 . D L L 、Anywhere および MobiLink ファイル。 DBODBC11.DLL、DBLIB11.DLL、 これらのファイルは、PowerBuilder ア DBLGEN11.DLL、DBCON11.DLL、 プリケーションおよびサポート ランタ DBCTRS11.DLL、DBICU11.DLL、 イム ファイルをコピーする場所の DBICUDT11.DLL 「bin32」サブディレクトリにコピーす る必要がある リモート マシンのレ ジストリ要件 MobiLink 同期で使用するすべてのリモート マシンに SQL Anywhere を インストールする場合は、必要なレジストリ エントリが自動的に割り 当てられます。SQL Anywhere および MobiLink ファイルをリモート マ シ ン に コ ピ ー す る 場 合 は、 HKEY_CURRENT_USER\SOFTWARE\Sybase\SQL Anywhere\11.0 レジ ストリ キーを作成して、SQL Anywhere および MobiLink ファイルをコ ピーした bin32 または bin64 サブディレクトリの親ディレクトリを示す 「Location」文字列値を追加する必要があります(nvo_appname_sync ユー ザ オブジェクトの uf_runsync 関数のコードは、このレジストリ値に割 り当てたパスの末尾に「\bin32\dbmlsync.exe」を追加します)。 ASA MobiLink 同期ウィザードで生成されたオブジェクトも、リモート SQL Anywhere 接続の ODBC データ ソースを定義するレジストリ エン トリを必要とします。表 13-2 に、必須レジストリ エントリを示します。 これらのレジストリ エントリをインストールする REG ファイルを作 成できます。 220 PowerBuilder 第 13 章 MobiLink 同期の使い方 表 13-2: リモート マシンでの必須レジストリ エントリ レジストリ キー HKEY_LOCAL_MACHINE\SOFT WARE\ ODBC\ODBCINST.INI\SQL Anywhere\11.0 HKEY_LOCAL_MACHINE\SOFT WARE\ ODBC\ODBCINST.INI\ODBC Drivers HKEY_LOCAL_MACHINE\SOFT WARE\ ODBC\ODBC.INI\ODBC Data Sources HKEY_LOCAL_MACHINE \ S OFTWARE\ ODBC\ODBC.INI\dataSourceN ame ファイル DSN による レジストリ DSN の代 用方法 文字列値の名前と割り当てるデータ Driver = DBODBC11.DLL へのフルパス Setup = DBODBC11.DLL へのフルパス SQL Anywhere 11.0 = "Installed" dataSourceName = "SQL Anywhere 11.0" Driver = DBODBC11.DLL へのフルパス Userid = リモート データベースのユーザ 名 Password = リモート データベースへの パスワード DatabaseName = remoteDatabaseName DatabaseFile = リモート データベースへ のフルパス ServerName = remoteDatabaseName Start = "dbeng11 -c 8M" CommLinks = "shmem" リモート データベース接続に対するファイル DSN またはレジストリ DSN を使用できます。絶対パス名の指定を回避するには、ファイル DSN を ODBC レジストリ キー(通常は c:\program files\common files\ODBC\data sources)で指定したパスにコピーします。 次に、有効なファイル DSN の内容の例を示します。 [ODBC] DRIVER=SQL Anywhere 11.0 UID=dba Compress=NO AutoStop=YES Start=dbeng11 -c 8M -zl -ti 0 EngineName=SalesDB_Remote DBN=SalesDB_Remote DatabaseFile=C:\work\salesdb\salesdb_remote.db DatabaseName=SalesDB_remote MLSync オブジェクトの Datasource プロパティは、次のルールを使用 して、レジストリ DSN とファイル DSN を区別します。 アプリケーション テクニック 221 統合データベースの準備 • Datasource の名前の最後が .dsn ファイル拡張子の場合は、ファイ ル DSN • Datasource の名前の先頭が「drive:\」接頭辞の場合は、ファイル DSN(drive は任意のアルファベット文字) EBF が以前の DBMS バージョンに 適用される前のファイル DSN の場所 SQL Anywhere 10.0.0 または Adaptive Server Anywhere 9 に最新の EBF を適用していない状態で、フルパスが指定されていない場合、dbmlsync はファイル DSN を、ODBC レジストリ キーで指定されたパスではな く、現行ディレクトリで探します。SQL Anywhere 10.0.1 以降で絶対パ スが指定されていない場合は、レジストリ キーがファイル DSN の検 索に使用されます。 統合データベースの準備 新規データベースを設計しているか、既存のデータベースを MobiLink 統合データベースとして使用するように準備しているかにかかわらず、 そのデータベースに MobiLink システム テーブルをインストールする必 要があります。SQL Anywhere は、Sybase Adaptive Server Enterprise、 Oracle、Microsoft SQL Server、および IBM DB2 用のセットアップ スク リプトを提供します。SQL Anywhere データベースにはセットアップ スクリプトは必要ありません。 MobiLink システム テーブルは、MobiLink ユーザ、テーブル、スクリ プト、スクリプトのバージョンについての情報を統合データベースに 格納します。これらのテーブルに直接アクセスすることはおそらくあ りませんが、同期スクリプトを追加するなどの操作を行うとテーブル は変更されます。 ODBC 接続およびド ライバ 同期を実行するために、MobiLink 同期サーバは、統合データベースと ODBC 接続する必要があります。使用するサーバには ODBC ドライバ が必要です。また、MobiLink 同期サーバを実行しているマシン上の データベース用に ODBC データ ソースを作成する必要があります。サ ポートされているドライバのリストについては、Recommended ODBC Drivers for MobiLink のサイト http://www.sybase.com/detail?id=1011880 を参照 してください。 同期スクリプトの記述 同期中に発生するイベントには 2 つのタイプがあるので、それぞれに ついて同期スクリプトを記述する必要があります。 222 PowerBuilder 第 13 章 MobiLink 同期の使い方 • 接続イベント – それぞれの同期中に必要な全体的なタスクを実行 します。 • テーブル イベント – 特定のテーブルに関連付けられ、そのテーブ ル内のデータの変更に関連するタスクを実行します。 接続イベント 接続レベルでは、主要なイベントは次の順に発生します。 begin_connection begin_synchronization begin_upload end_upload prepare_for_download begin_download end_download end_synchronization end_connection 同期リクエストが発生すると、begin_connection イベントが発生します。 スクリプトの現行バージョンのすべての同期リクエストが完了する と、end_connection イベントが発生します。通常、これらのイベントの スクリプトに、変数宣言やデータベースのクリーンアップなどの初期 化およびクリーンアップ コードを配置します。 begin_connection および end_connection 以外のすべてのイベントは、統 合データベースの ml_user テーブルに格納されている MobiLink ユーザ 名をパラメータとして取ります。パラメータ値と置き換えたい場所に 疑問符を配置すると、スクリプトでパラメータを使用できます。 SQL Anywhere データベースのスクリプトを読みやすくするには、 begin_connection スクリプトで変数を宣言し、それを begin_synchronization スクリプトで ml_username の値に設定します。 たとえば、begin_connection に次の行を挿入します。 CREATE VARIABLE @sync_user VARCHAR(128); begin_synchronization に次の行を挿入します。 SET @sync_user = ? begin_synchronization および end_synchronization イベントは、リモート データベースと統合データベースに変更が適用される前と後に発生し ます。 アプリケーション テクニック 223 統合データベースの準備 begin_upload イベントは、アップロード トランザクションの開始を示 します。統合データベースに対する適切な挿入と更新が、すべてのリ モート テーブルについて実行されます。その後すべてのリモート テー ブルで適切に行が削除されます。end_upload の後、アップロードの変 更がコミットされます。 統合データベースから行を削除したくない場合は、upload_delete イベン ト に 対 す る ス ク リ プ ト を 書 か な い か、PowerScript コ ー ド で STOP SYNCHRONIZATION DELETE ステートメントを使用します。詳細につい ては、239 ページの「リモート データベースだけからの行の削除」を 参照してください。 begin_download イベントは、ダウンロード トランザクションの開始を 示します。すべてのリモート テーブルで適切な削除が実行され、その 後 download_cursor で、すべてのリモート テーブルで適切に行が追加さ れます。end_download の後、ダウンロードの変更がコミットされます。 これらのイベントは、最後のダウンロードの日付をパラメータとして 保持します。 handle_error、report_error、synchronization_statistics など、そのほかの接続 レベルのイベントが発生することもあります。すべてのイベントとそ の使用例については、『MobiLink 管理ガイド』マニュアルの同期イベ ントについての章を参照してください。 テーブル イベント begin_download や end_upload な ど、begin_synchronization イ ベ ン ト と end_synchronization イベントの間に発生する接続イベントの多くには、 対応するテーブル イベントもあります。これらのイベントとその他の 全体的なテーブルのイベントは、変更を保持する中間テーブルの作成 やログ ファイルへの情報の出力などのタスクに使用できます。 テーブルの各行に適用するテーブル イベントのスクリプトを記述す ることもできます。行レベルのイベントの場合、スクリプト内のカラ ム の順 序は、そ れらの カラ ムがリ モー ト デー タベー スの CREATE TABLE ステートメントで出現する順序と一致していなければなりませ ん。また、スクリプト内のカラム名は、統合データベース上のカラム 名を参照する必要があります。 224 PowerBuilder 第 13 章 MobiLink 同期の使い方 行レベルのイベントは複数ありますが、ほとんどのテーブルで必要に なるのは、3 つのアップロード イベント(INSERT、UPDATE、DELETE) と 1 つのダウンロード イベントについてのスクリプトです。各テーブ ルに対してこれらの 4 つのスクリプトを作成するタスクを高速化する には、Sybase Central の MobiLink プラグインから「create a synchronization model」タスクを実行すると、これらのスクリプトを自動的に生成でき ます。 デフォルト スクリプ トの生成 MobiLink プラグインの詳細については、『MobiLink クイック・スター ト』マニュアルを参照してください。 MobiLink プラグインを使用すると、MobiLink の以前のバージョンで生 成されたデフォルト スクリプトよりも多くの機能を、デフォルト スク リプトに追加できます。ただし、SQL Anywhere 10 または 11 ではなく ASA 8 または ASA 9 を使用している場合は、-za スイッチを使用して dbmlsync の SendColumnNames 拡張オプ MobiLink 同期サーバを起動し、 ションを設定することで、前バージョンのデフォルトの同期スクリプ トを生成できます。 PowerBuilder ユーザ インタフェースから ASA 8 または ASA 9 の同期ス クリプトを生成する方法は、次のとおりです。 v PowerBuilder で ASA 8 または ASA 9 の同期スクリプトを自動的に生成す るには 1 データベース ペインタで ODBC の[Utilities]フォルダを展開し、 [MobiLink Synchronization Server]項目をダブルクリックします。 MobiLink 同期 サーバ オプション ダイアログボックスが表示され ます。 2 [MobiLink バージョン]ドロップダウン リストから、Adaptive Server Anywhere 8 または 9 を選択します。 [自動スクリプト生成]チェックボックスをオンにします。 3 [OK]をクリックしてサーバを起動します。 このダイアログボックスは、データベース ペインタおよび DB プ ロファイル ダイアログボックスの[Utilities]フォルダから開くこ とができます。 4 アプリケーション テクニック アプリケーションで、w_appname_sync_options ウィンドウの[設定] ページの[拡張設定]テキストボックスに、 「SendColumnNames=ON」 と入力します。 225 統合データベースの準備 リモート データベースには、パブリケーション、ユーザ、サブス クリプションを少なくとも 1 つずつ定義しておく必要がありま す。複数のパブリケーションまたはユーザがある場合は、-n また は -u あるいはその両方のスイッチを使用して、作業するサブスク リプションを指定する必要があります。 統合データベースに既存のスクリプトがある場合、MobiLink は何 も実行しません。既存のスクリプトがない場合、MobiLink はパブ リケーションで指定されているすべてのテーブルについてスクリ プトを生成します。スクリプトは、クライアントと統合データベー スとの間で行われるデータのアップロードおよびダウンロードを 制御します。 リモート データベースと統合データベースでカラム名が異なる場 合は、生成されたスクリプトを変更して統合データベース上の名 前に合わせる必要があります。 コマンド プロンプトから ASA 8 または ASA 9 の同期スクリプトを生成 することもできます。-za スイッチを指定してサーバを起動し、dbmlsync を実行し、SendColumnNames 拡張オプションを on に設定します。た とえば、次のようになります。 dbmlsrv9 -c "dsn=masterdb" -za dbmlsync -c "dsn=remotedb" -e SendColumnNames=ON 生成されたスクリプト 226 表 13-3 に、Sybase Central の MobiLink プラグインで生成されるデフォ ルト スクリプトのサンプルを示します。このスクリプトは、カラム emp_id、emp_name、および dept_id を持つ emp と言う名前のテーブル に対して生成されます。主キーは emp_id です。生成されたダウンロー ド スクリプトは、ダウンロードに基づいたタイムスタンプを使用しま す。 PowerBuilder 第 13 章 MobiLink 同期の使い方 表 13-3: MobiLink プラグインで生成される同期デフォルト スクリプトのサ ンプル スクリプト名 スクリプト upload_insert INSERT INTO "GROUP1"."emp" ( "emp_id", "emp_name", "dept_id" ) VALUES ( {ml r."emp_id"}, {ml r."emp_name"}, {ml r."dept_id"} ) upload_update upload_delete download_cursor download_delete_c ursor UPDATE "GROUP1"."emp" SET "emp_name" = {ml r."emp_name"}, "dept_id" = {ml r."dept_id"} WHERE "emp_id" = {ml r."emp_id"} DELETE FROM "GROUP1"."emp" WHERE "emp_id" = {ml r."emp_id"} SELECT "GROUP1"."emp"."emp_id", "GROUP1"."emp"."emp_name", "GROUP1"."emp"."dept_id" FROM "GROUP1"."emp" WHERE "GROUP1"."emp"."last_modified" >= {ml s.last_table_download} SELECT "emp_del"."emp_id FROM "emp_del" WHERE "emp_del"."last_modified" s.last_table_download} >= {ml MobiLink プラグインで生成したスクリプトは、同期モデルを構成しま す。同期モデルを作成すると、プラグインの「Deploy a synchronization model」タスクを使用して、スクリプトを統合データベースとリモート データベース、または SQL ファイルに配布する必要があります。 表 13-3 に、ASA 9 MobiLink 同期サーバの -za コマンド スイッチを使用 して、同じテーブルに対して生成されたスクリプトを示します。デー タをダウンロードするために生成されたスクリプトは、 「スナップ ショット」同期を実行します。テーブルの完全なイメージがリモート データベースにダウンロードされます。通常、これらのスクリプトを 編集して、転送されるデータを制限する必要があります。 詳細については、237 ページの「データのダウンロードの制限」を参 照してください。 アプリケーション テクニック 227 統合データベースの準備 表 13-4: dbmlsrv9 -za で生成されたデフォルト スクリプトのサンプル スクリプト名 スクリプト upload_insert INSERT INTO emp (emp_id, emp_name, dept_id) VALUES (?,?,?) upload_update UPDATE emp SET emp_name = ?, dept_id = ? WHERE emp_id=? upload_delete DELETE FROM emp WHERE emp_id=? download_cursor SELECT emp_id, emp_name, dept_id FROM emp いずれかのスクリプトを変更する前に、同期プロセスをテストして、 生成されたスクリプトが予想どおりに動作することを確認します。1 つ変更するたびにテストを実行すると、エラーの絞り込みに役立ちま す。 Sybase Central でのスクリプトおよびユーザに対する作業 Sybase Central では、Mobile Link 同期プラグインで、既存のスクリプト を表示して変更したり、新しいスクリプトを書き込んだりすることが できます。以下の手順では、プラグインとの接続とスクリプトの記述 方法、およびユーザを統合データベースに追加する方法について説明 します。 v Sybase Central で統合データベースに接続するには 1 Sybase Central を起動し、メニューバーの[接続| Mobil Link 11 に 接続]を選択します。 2 総合データベースへの接続 ダイアログボックスの[ID]ページで、 データ ソース名またはファイルを選択するか参照し、[OK]をク リックします。 MobiLink 同期プラグインで統合データベースのノードを展開すると、 [テーブル(所有者別)]、[接続スクリプト]、[同期テーブル]、[ユー ザ]、 [バージョン]、[通知]のフォルダが表示されます。この節のす べての手順では、まず、これらのフォルダのいずれかを開きます。 スクリプト バージョ ン 228 スクリプトは、スクリプト バージョンと呼ばれるグループに分けられ ます。特定のバージョンを指定すると、MobiLink クライアントは、アッ プロード ストリームの処理とダウンロード ストリームの準備に使用 する同期スクリプトのセットを選択できます。異なるバージョンのス クリプトを定義したい場合は、統合データベースに、まずスクリプト バージョンを追加し、その後スクリプトを追加する必要があります。 PowerBuilder 第 13 章 MobiLink 同期の使い方 2 つの異なるバージョンを作成する場合は、必要なすべてのイベント のスクリプトを両方のバージョンで用意していることを確認します。 v スクリプト バージョンを追加するには 1 [バージョン]フォルダを開き、Sybase Central のメニュー バーで [ファイル|新規|バージョン]を選択します。 2 スクリプト・バージョン作成ウィザードで、バージョンの名前と、 必要に応じて説明を設定し、[完了]をクリックします。 Sybase Central によって、新しいバージョンが作成され、固有の整 数識別子が付けられます。 接続イベント用に追加されたスクリプトは、同期のたびに実行されま す。テーブル イベントに追加されたスクリプトは、特定のテーブルが 変更されたときに実行されます。テーブルに対するスクリプトを追加 する前に、そのテーブルを同期するように指定する必要があります。 同期済みのテーブルと スクリプトの追加 v 同期するテーブルを追加するには 1 [同期テーブル]フォルダを開き、 [ファイル|新規|同期済みテー ブル]を選択します。 2 同期するリモート テーブルの名前を指定するか、リモート デー タベースのテーブルと同じ名前の統合データベースのテーブルを 選択します。 3 [完了]をクリックします。 v 同期テーブルにスクリプトを追加するには 1 [同期テーブル]フォルダでテーブル名をダブルクリックし、 [ファイル|新規|テーブル・スクリプト]を選択します。 2 テーブル・スクリプト作成ウィザードで、スクリプトを追加する バージョンを選択し、スクリプトで実行させるイベントを選択し て、[次へ]をクリックします。 3 新しいスクリプト定義の作成とその定義を記述する言語(SQL、 Java、または .NET)を選択するか、新しいスクリプトとして共有 する既存のスクリプト バージョンを選択します。 4 [完了]をクリックします。 5 アプリケーション テクニック 表示されるエディタにスクリプトを入力し、ファイルを保存して 閉じます。 229 統合データベースの準備 たとえば、リモート データベースの Order テーブルから出荷済み の行を削除する場合は、次の SELECT ステートメントを download_delete_cursor イベントに配置できます。ここでは order_id は主キー カラムです。このイベントの最初のパラメータは、 last_download タイムスタンプです。ここでは、last_modified カラム の値を入力するために使用されています。 SELECT order_id FROM Order WHERE status = 'Shipped' AND last_modified >= ? download_delete_cursor イベントの使い方についての詳細は、オン ラインの『MobiLink - サーバ管理』マニュアルで 「download_delete_cursor スクリプトの作成」の節を参照してくださ い。 v 接続レベルのスクリプトを追加するには 1 [接続スクリプト]フォルダを開き、メニュー バーの[ファイル| 新規|接続スクリプト]を選択します。 2 ユーザの追加 前の手順の 2 ~ 5 に従います。 統合データベースの ml_user テーブルに直接ユーザを追加し、そのユー ザ名とオプションのパスワードをユーザに提供できます。ユーザを追 加するには、[ユーザ]フォルダを開き、[ファイル|新規|ユーザ] を選択して、ユーザ作成ウィザードで設定します。 234 ページの「Mobile Link ユーザの作成」で説明するように、各リモー ト データベースに少なくとも 1 つのユーザ名を追加する必要がありま す。 230 PowerBuilder 第 13 章 MobiLink 同期の使い方 リモート データベースの作成 MobiLink インストールでリモート データベースとして使用するため に、任意の SQL Anywhere データベースを変換できます。また、統合 された SQL Anywhere データベースの全部または一部を使用する新し い SQL Anywhere リモート データベースを作成できます。 Sybase Central SQL Anywhere プラグイン、データベース ペインタの Create ASA Database ユーティリティ、またはその他のツールを使用し てデスクトップにデータベースを作成します。データベースで英語文 字セットを使用している場合は、1252 Latin1 照合順序を使用します。 データベースを MobiLink 同期のリモート データベースとして使用す るには、少なくとも 1 つのパブリケーションと MobiLink ユーザを作成 し、そのユーザのパブリケーションにサブスクリプションを追加する 必要があります。231 ページの「パブリケーションの作成と変更」、234 ページの「Mobile Link ユーザの作成」、および 236 ページの「サブス クリプションの追加」を参照してください。 リモート データベー ス スキーマ リモート データベース内のテーブルは、統合データベース内のテーブ ルと同じでなくてもかまいませんが、一般に、統合データベースのテー ブル構造のサブセットであるテーブル構造をリモート データベース で使用することによってデザインを単純化できます。この方法では、 リモート データベース内のすべてのテーブルが必ず統合データベー ス上に存在することになります。対応するテーブルは、統合データベー スのテーブルと同じ構造および外部キー関係を持っています。 統合データベース上のテーブルには、同期されていない別のカラムが 含まれていることがよくあります。これらのカラムを使って、同期を 促進することもできます。たとえば、タイムスタンプ カラムで、統合 データベース上の新しい行または更新された行を識別できます。また、 統合データベース上の別のカラムまたはテーブルに、リモート サイト では必要ない情報を保持することもあります。 パブリケーションの作成と変更 パブリケーションは、Sybase Central または SQL CREATE PUBLICATION ステートメントを使用して作成します。Sybase Central では、すべての パブリケーションとアーティクルが[パブリケーション]フォルダに 表示されます。この節では、Sybase Central でパブリケーションを作成 する方法について説明します。SQL を使用したパブリケーションの作 成と変更については、オンラインの『MobiLink - クライアント管理』マ ニュアルを参照してください。 アプリケーション テクニック 231 リモート データベースの作成 Mobile Link 同期プラグインではなく、Sybase Central で SQL Anywhere プラグインを使用して、MobiLink クライアントおよびリモート データ ベ ー ス に つ い て 作 業 し ま す。PowerBuilder 設 計 時 環 境 か ら Sybase Central を開始する方法については、『ユーザーズ ガイド』マニュアル を参照してください。 Sybase Central での データベースへの接続 パブリケーション、MobiLink ユーザ、サブスクリプションを作成また は変更するには、DBA 権限が必要です。 v Sybase Central のデータベースに接続するには 1 Sybase Central を起動し、Sybase Central のメニュー バーの[接続| SQL Anywhere 11 に接続]を選択します。 2 接続 ダイアログボックスの[ID]ページに、ユーザ名として「DBA」、 パスワードとして「SQL」と入力します。データ ソース名または ファイルを選択するか参照し、[OK]をクリックします。 作成できる最も簡単なパブリケーションは、1 つまたは複数のテーブ ルのすべての行とカラムで構成される単一のアーティクルです。テー ブルはすでに存在していなければなりません。 テーブル内のすべての 行およびカラムのパブ リッシュ v Sybase Central で 1 つまたは複数のテーブル全体をパブリッシュするには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [パブリケーション]フォルダを開き、Sybase Central メニューの [ファイル|新規|パブリケーション]を選択します。 3 新しいパブリケーションの名前を入力し、 [次へ]をクリックしま す。 4 [テーブルの指定]ページで、 [使用可能なテーブル]リストから テーブルを選択し、[追加]をクリックします。 テーブルは、右側の[選択したテーブル]リストに表示されます。 5 さらにテーブルを追加することもできます。テーブルの順序は重 要ではありません。 6 [完了]をクリックします。 テーブルのすべての行と一部だけのカラムを含むパブリケーションを 作成できます。 テーブル内の一部のカ ラムだけのパブリッ シュ v Sybase Central でテーブル内の一部のカラムだけをパブリッシュするには 1 232 232 ページの「テーブル内のすべての行およびカラムのパブリッ シュ」の最初の 4 つの手順に従います。 PowerBuilder 第 13 章 MobiLink 同期の使い方 2 [次へ]をクリックします。 [カラムの指定]ページで、テーブル のアイコンをダブルクリックして[使用可能なカラム]リストを 展開します。パブリッシュするカラムをそれぞれ選択し、 [追加] をクリックします。 選択したカラムが右側に表示されます。 3 [完了]をクリックします。 テーブルの一部または全部のカラムと、一部だけの行を含むパブリ ケーションを作成できます。それには、パブリッシュする行だけに一 致する検索条件を記述します。 テーブル内の一部の行 だけのパブリッシュ MobiLink では、WHERE 句を使用して、すべてのサブスクリプション からパブリケーションに同じ行セットを除外します。パブリケーショ ンのすべてのサブスクライバは、検索条件を満たす行に対するすべて の変更をアップロードします。 v Sybase Central で WHERE 句を使ってパブリケーションを作成するには 1 232 ページの「テーブル内のすべての行およびカラムのパブリッ シュ」の最初の 4 つの手順、および、必要に応じて、232 ページの 「テーブル内の一部のカラムだけのパブリッシュ」の最初の 2 つの 手順に従います。 2 [次へ]をクリックします。 [WHERE 句の指定]ページで、テーブ ルを選択し、下のボックスに検索条件を入力します。 3 [完了]をクリックします。 既存のパブリケーションにアーティクルを追加できます。 アーティクルの追加 v Sybase Central でアーティクルを追加するには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [パブリケーション]フォルダを開き、アーティクルを追加するパ ブリケーションの名前をダブルクリックします。 3 Sybase Central メニューの[ファイル|新規|アーティクル]を選 択します。 4 アーティクルの作成ウィザードで、テーブルを選択し、 [次へ]を クリックします。 5 一部のカラムだけが同期されるようにしたい場合は、 [選択したカ ラム]ラジオボタンを選択し、カラムを選択します。 アプリケーション テクニック 233 リモート データベースの作成 6 WHERE 句を追加する場合は、 [次へ]をクリックし、句を入力し ます。 7 [完了]をクリックします。 パブリケーションの場所に移動し、ポップアップ メニューから[プロ パティ]または[削除]を選択すると、Sybase Central で既存のパブリ ケーションを変更または削除できます。同じ方法で、アーティクルを 変更および削除することができます。 パブリケーションと アーティクルの変更と 削除 パブリケーションを変更できるのは、DBA または パブリケーションの オーナーだけです。パブリケーションを削除するには、DBA 権限が必 要です。パブリケーションを削除した場合、そのパブリケーションの すべてのサブスクリプションも同様に自動的に削除されます。 実行中の MobiLink セットアップではパブリケーションの変更を避ける 実行中の MobiLink セットアップでパブリケーションを変更すると、複 製エラーが発生して、データの損失につながるおそれがあるので、実 行する場合は十分に注意してください。 Mobile Link ユーザの作成 Mobile Link ユーザは、データベース ユーザと同じではありません。そ れぞれのタイプのユーザは、別の名前空間に置かれています。Mobile Link ユーザ ID がデータベース ユーザの名前と一致することはありま すが、これは必須ではありません。 v Sybase Central で Mobile Link ユーザをリモート データベースに追加するには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、Sybase Central メニューの [ファイル|新規| Mobile Link ユーザ]を選択します。 3 Mobile Link ユーザの名前を入力します。 名前は、同期中に Mobile Link 同期サーバに入力されます。本稼動 データベースでは、通常、各ユーザ名が統合データベースに追加 され、個別のユーザに提供されます。 4 [完了]をクリックします。 234 PowerBuilder 第 13 章 v MobiLink 同期の使い方 Sybase Central で Mobile Link ユーザ プロパティを設定するには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、Mobile Link ユーザを右ク リックし、ポップアップ メニューから[プロパティ]を選択します。 3 v 必要に応じてプロパティを変更します。 Sybase Central で Mobile Link ユーザを削除するには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、Mobile Link ユーザを右ク リックし、ポップアップ メニューから[削除]を選択します。 Mobile Link ユーザの削除 リモート データベースから Mobile Link ユーザを削除するには、まず そのユーザに対するすべてのサブスクリプションを削除する必要があ ります。 統合データベースへの Mobile Link ユーザの 追加 統合データベースには、同期がリクエストされたときに Mobile Link ユーザの名前の認証に使用される ml_user というテーブルが含まれて います。ユーザをリモート データベースに追加するときは、そのユー ザが ml_user テーブルにも追加されていることを確認する必要があり ます。 MobiLink 同期 サーバ オプション ダイアログボックスの[ユーザの自 動追加]チェックボックスをオンにしてサーバを起動すると、ユーザ を自動的に追加できます。このダイアログボックスは、データベース ペインタまたは DB プロファイル ダイアログボックスの[Utilities] フォルダから開くことができます。または、コマンド プロンプトから、 -zu+ スイッチを指定してサーバを起動できます。 リモート データベースで定義された任意のユーザは、authenticate_user 接続イベントのスクリプトが未定義の間は、統合データベースの ml_user テーブルに追加されます。通常、-zu+ スイッチは、本稼働環境 では使用されません。名前は、通常、統合データベースの ml_user テー ブルに追加され、その後各リモート データベースに追加されます。各 ユーザには、固有の名前とオプションのパスワードが与えられます。 アプリケーション テクニック 235 リモート データベースの作成 サブスクリプションの追加 同期サブスクリプションは、特定の Mobile Link ユーザとパブリケー ションをリンクします。少なくとも 1 つのパブリケーションと 1 人の ユーザで、サブスクリプションを作成してください。 サブスクリプションには、同期に必要なほかの情報も含めることがで きます。たとえば、Mobile Link サーバのアドレス、およびその他の接 続オプションを指定できます。特定のサブスクリプションの値は、個 別の Mobile Link ユーザの設定を上書きします。 ウィザードでのオプションの上書き PowerBuilder の ASA MobiLink 同期ウィザードでの設定を使用して、サ ブスクリプションとユーザに対して設定されている Mobile Link サー バ名とポートを上書きできます。 同期サブスクリプションは、Mobile Link SQL Anywhere リモート デー タベースで必要です。サーバ ロジックは、統合データベースの Mobile Link システム テーブルに格納されている同期スクリプトを通じて実 装されます。 単一の SQL Anywhere データベースが、複数の Mobile Link 同期サーバ と同期を取ることができます。複数のサーバとの同期を可能にするに は、各ユーザに対して異なるサブスクリプションを作成します。 v Sybase Central で Mobile Link ユーザのサブスクリプションを追加するには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [パブリケーション]フォルダを開き、サブスクリプションを挿入 するパブリケーションを選択し、Sybase Central の右側のペインで [同期サブスクリプション]タブを選択します。次に、メニュー バーの[ファイル|新規|同期サブスクリプション]を選択しま す。 [パブリケーション]フォルダで新しいサブスクリプションを作成 するのではなく、 [Mobile Link ユーザ]フォルダで、サブスクリプ ションを作成するユーザをダブルクリックし、メニュー バーの [ファイル|新規|同期サブスクリプション]を選択しても、新し いサブスクリプションを作成できます。 3 236 同期サブスクリプション作成ウィザードで、サブスクリプション を挿入するユーザを選択し、[完了]をクリックします。 PowerBuilder 第 13 章 MobiLink 同期の使い方 このウィザードを[Mobile Link ユーザ]フォルダから起動した場 合は、サブスクライブするパブリケーションの選択を要求する メッセージが表示されます。パブリケーションを選択して[完了] をクリックしてください。 v Sybase Central でサブスクリプションを変更するには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、変更するサブスクリプショ ンを所有する Mobile Link ユーザの名前をダブルクリックします。 3 [同期サブスクリプション]タブで、変更するサブスクリプショ ンを右クリックし、ポップアップ メニューの[プロパティ]を選 択します。 4 v 同期サブスクリプションのプロパティ ダイアログボックスの[接 続]ページと[拡張オプション]ページで、必要に応じてプロパ ティを変更します。 Sybase Central で同期サブスクリプションを削除するには 1 232 ページの「Sybase Central でのデータベースへの接続」の説明 に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、削除するサブスクリプショ ンを所有する Mobile Link ユーザの名前をダブルクリックします。 3 [同期サブスクリプション]タブで、削除するサブスクリプション を右クリックし、[削除]をクリックします。 4 削除の確認 ダイアログボックスで、[はい]をクリックします。 同期のテクニック この節では、Mobile Link 同期を使用するアプリケーションの設計で考 慮が必要な問題を取り上げます。 データのダウンロード の制限 同期の主要な目的の 1 つは、移動されるデータの量を制限することに よって、データ移動の高速化と効率化を図ることです。download_cursor スクリプトによって転送されるデータを制限するために、タイムスタ ンプ、Mobile Link ユーザ名、またはその両方に基づいてデータを分割 できます。 アプリケーション テクニック 237 同期のテクニック タイムスタンプによる分割 ダウンロードを、前回のダウンロード以降 に変更されたデータに限定するには、統合データベースの各テーブル に last_modified カラムを追加する方法があります。テーブル自体を変更 できない場合は、主キーを保持し、download_cursor スクリプトでオリ ジナルのテーブルに結合されるシャドウ テーブルに追加します。 last_modified カラムは、統合データベースにだけ追加する必要がありま す。 SQL Anywhere では、このカラム用に組み込みの DEFAULT TIMESTAMP データ型を使用できます。他の DBMS では、更新トリガを提供して、 last_modified カラムのタイムスタンプを設定する必要があります。 タイムスタンプは、統合データベースで生成され、同期中には変更さ れずにリモート データベースにダウンロードされます。リモート デー タベースのタイム ゾーンはこれに影響しません。 ユーザベースの分割 download_cursor スクリプトには、datetime データ型 の last_download と、varchar(128)型の ml_username の 2 つのパラメー タがあります。これらのパラメータを使用すると、前回の同期以降に 変更された行だけでなく、現行ユーザに属する行にもダウンロードを 限定できます。 次のサンプル スクリプト download_cursor では、前回の同期以降に変更 された行、および ID が MobiLink ユーザ ID と一致する営業担当に該 当する行だけがダウンロードされます。 SELECT order_id, cust_id, order_date FROM Sales_Order WHERE last_modified >= ? AND sales_rep = ? こ の ス ク リ プ ト が 正 し く 機 能 す る に は、Mobile Link ユ ー ザ ID が sales_rep ID と一致しなければなりません。一致しない場合は、2 つの ID を関連付けるテーブルを結合する必要があります。 主キーの一意性 クライアントが常に接続されている従来のクライアント / サーバ環境 では、参照整合性が直接求められます。モバイル環境では、主キーが 固有であり、更新されないことを確認する必要があります。このため には、主キー プールを使用するなど、複数のテクニックがあります。 衝突の処理 たとえば、同期間隔が異なる 2 人のリモート ユーザが同じ行を更新し た場合、最新の同期が最新の更新にならない可能性があるので衝突が 発生します。この衝突を処理する必要があります。Mobile Link は、衝 突の検出と解決のためのメカニズムを提供しています。 238 PowerBuilder 第 13 章 リモート データベー スだけからの行の削除 MobiLink 同期の使い方 デフォルトでは、ユーザが同期を開始すると、前回の同期以降にデー タベースに対して行われたすべての変更の最終結果が統合データベー スにアップロードされます。しかし、データが古くなったり、顧客が 別の販売担当に移されたりしたことで、リモート ユーザがリモート データベースの特定の行を削除して空き容量を再取得している場合が あります。通常は、検出されたこれらの行を統合データベースから削 除しないでください。 削除行を処理する方法として、PowerBuilder アプリケーションのスク リプトで STOP SYNCHRONIZATION DELETE コマンドを使用して、それに 続く SQL DELETE ステートメントをトランザクション ログから隠す方 法 が あ り ま す。そ の 接 続 で の そ れ 以 降 の DELETE 操 作 は、START SYNCHRONIZATION DELETE ステートメントが実行されるまで同期され ません。 たとえば、Delete Local というメニュー項目を提供し、削除を扱うコー ドを次の例のようにラップできます。 STOP SYNCHRONIZATION DELETE; // 削除操作を実行するコードを呼び出します。 START SYNCHRONIZATION DELETE; COMMIT; 削除については、ほかの方法でも対処できます。詳細については、オ ンラインの『MobiLink - サーバ管理』マニュアルの同期のテクニック についての章を参照してください。 アプリケーション テクニック 239 同期のテクニック 240 PowerBuilder 第 1 4 章 PowerBuilder XML サービスの使 い方 この章について この章では、PowerBuilder の XML サービスの概要について説明し ます。PowerBuilder ドキュメント オブジェクト モデル(PBDOM: PowerBuilder Document Object Model)と、それを PowerBuilder ア プリケーションで使う方法について説明します。 内容 項目 XML と PowerBuilder について PBDOM について PBDOM オブジェクト階層 PBDOM ノード オブジェクト アプリケーションへの pbdom115.pbx の追加 PBDOM の使い方 PBDOM 例外の処理 XML 名前空間 ページ 241 242 243 244 260 261 267 269 XML と PowerBuilder について PowerBuilder には、Extensible Markup Language (XML)を扱うための 機能がいくつかあります。以下のことを行うことができます。 アプリケーション テクニック • データウィンドウ オブジェクト内のデータを XML にエクス ポートし、XML ドキュメント内のデータ、または文字列を データウィンドウ オブジェクトにインポートする • PowerScript 関数の XMLParseFile と XMLParseString を使用して、 XML ドキュメントや文字列が well-formed(整形式)であるか、 あるいはスキーマや DTD に準拠しているかを判断する • XML ドキュメントの作成および処理を行うアプリケーション とコンポーネントを作成する 241 PBDOM について XML の概要と、データウィンドウのエクスポート機能とインポート機 能の詳細については、PowerBuilder の『ユーザーズ ガイド』マニュア ルの「XML データのエクスポートとインポート」の章を参照してくだ さい。 XML パーサ関数については、オンライン ヘルプの解説を参照してく ださい。 この章では、PowerBuilder ドキュメント オブジェクト モデルを使用し て XML ドキュメントを作成および処理する方法について説明します。 PBDOM について PBDOM は、PowerBuilder に実装しているドキュメント オブジェクト モデル(DOM: Document Object Model)です。DOM は、XML ドキュ メントへのアクセスと操作の方法を定義するプログラミング インタ フェースです。 PBDOM は、World Wide Web コンソーシアム(W3C)DOM API の実 装ではありませんが、それとよく似ています。PBDOM PowerBuilder API を使用して、PowerScript コード内から標準形式 XML の読み書き や操作を行うことができます。PBDOM は、XML ドキュメントを相互 関連オブジェクトの集合として表現し、また、各オブジェクトの用途 と機能を直観的に示す方法を提供しています。 PBDOM は、XML ファイル用の Java ベースのドキュメント オブジェ クト モデルである JDOM とも似ています。 W3C DOM オブジェクトと JDOM オブジェクト、および階層について は、それぞれの仕様を参照してください。W3C DOM 仕様は W3C のサ イト http://www.w3.org/DOM/ から入手できます。JDOM 仕様およびその仕 様へのリンクは、JDOM のサイト http://www.jdom.org/docs/ に掲載されてい ます。 PBDOM を使用したアプリケーションでは、既存の XML ドキュメント を解析したり、外部要求への応答の中やビジネス ロジックの一部とし て含まれている情報を抽出したりすることができます。アプリケー ションは、ほかのアプリケーション、プロセス、またはシステムが要 求するタイプかスキーマに合致する XML ドキュメントを作成するこ ともできます。XML 文字列を直接編集するかわりに、オブジェクトの PBDOM ツリーを操作したり変換したりすることにより、既存の XML ドキュメントの読み込みと修正が行えます。 242 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 多層アプリケーションで使用する XML ドキュメント、または Web サービスの一部としての XML ドキュメントを作成または処理するコ ンポーネントも作成できます。 ノード ツリー PBDOM は、親ノードと子ノードで構成されるツリービュー モデルに 従って、XML ドキュメントと対話します。ドキュメント要素は、XML ドキュメントのトップ レベルのノードを表します。ドキュメント要素 のそれぞれの子ノードには、ツリーの分岐を表す 1 つ以上の子ノード があります。ツリー内のノードには、PBDOM クラスのメソッドを使っ てアクセスできます。 XML パーサ PBDOM XML パーサを使用して、XML ドキュメントをロードおよび 解析したり、ユーザ指定の DOM ノードに基づいた XML ドキュメント を生成したりします。 PBDOM には、ノード ツリー内での移動、ノードと属性値(存在する 場合)へのアクセス、ノードの挿入と削除を行うためのすべてのメソッ ドが用意されています。また、ノード ツリーをほかのシステムで使用 するために XML ドキュメントを変換する際に必要なメソッドも用意 されています。 PBDOM オブジェクト階層 次の図に、PBDOM オブジェクト階層を示します。 図 14-1: PBDOM オブジェクト階層 アプリケーション テクニック 243 PBDOM ノード オブジェクト PBDOM_OBJECT と その子孫 PBDOM_BUILDER XML ノードを表す PBDOM オブジェクトの基本クラスである PBDOM_OBJECT は、PowerBuilder NonVisualObject クラスから継承し ます。各ノード タイプは、PBDOM クラスにより表されます。このク ラスのメソッドを使用して PBDOM ノード ツリー内のオブジェクトに アクセスします。PBDOM_OBJECT とその子孫については、次の 「PBDOM ノード オブジェクト」で説明します。XML ノード タイプに ついては、PowerBuilder の『ユーザーズ ガイド』マニュアルの「XML データのエクスポートとインポート」の章でも説明しています。 PBDOM_BUILDER クラスも NonVisualObject から継承します。このク ラスは、文字列、ファイル、データストアなど各種の XML 入力元か ら PBDOM_DOCUMENT を作成するファクトリ クラスとして機能し ます。 PBDOM_DOCUMENT を最初から作成する 既存の XML ソースを使用せずに PBDOM_DOCUMENT を作成するに は、PBDOM_DOCUMENT NewDocument メソッドを使用します。 PBDOM_EXCEPTION PBDOM_EXCEPTION クラスは、PowerBuilder Exception クラスから継 承します。このクラスは、PBDOM アプリケーションで例外が発生し たときに定義済み例外コードを返すメソッドを持つ Exception クラス を拡張します。このクラスの詳細については、267 ページの「PBDOM 例外の処理」を参照してください。 PBDOM ノード オブジェクト この節では、PBDOM_OBJECT クラスと、そのクラスを継承するすべ てのクラスについて説明します。 244 • PBDOM_OBJECT • PBDOM_DOCUMENT • PBDOM_DOCTYPE • PBDOM_ELEMENT • PBDOM_ATTRIBUTE • PBDOM_ENTITYREFERENCE • PBDOM_CHARACTERDATA PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 • PBDOM_TEXT • PBDOM_CDATA • PBDOM_COMMENT • PBDOM_PROCESSINGINSTRUCTION PBDOM クラスのメソッド詳細については、『PowerBuilder エクステン ション リファレンス』マニュアルを参照してください。 PBDOM_OBJECT PBDOM_OBJECT クラスは、XML ノード ツリー内のノードを表し、特 定のノード タイプを表す専用 PBDOM クラスの基本クラスとして機能 します。PBDOM_OBJECT に対応する DOM クラスはノード オブジェ クトです。PBDOM_OBJECT には、派生クラスに必要な基本機能がす べて含まれます。ノードは、要素ノード、ドキュメント ノード、また は、上記の PBDOM_OBJECT から派生した任意のノード タイプです。 メソッド PBDOM_OBJECT 基本クラスには以下のメソッドがあります。 • AddContent、GetContent、InsertContent、RemoveContent、および SetContent では、PBDOM_OBJECT の子を操作できる • Clone では、PBDOM_OBJECT の簡易クローンか詳細クローンを作 成できる • Detach では、PBDOM_OBJECT をその親からデタッチする • Equals では、別の PBDOM_OBJECT と同等であることをテストする • GetName と SetName では、PBDOM_OBJECT の名前の取得と設定 を行う • GetObjectClass と GetObjectClassString では、PBDOM_OBJECT のク ラスを識別する • GetOwnerDocumentObject では、 現行の PBDOM_OBJECT のオーナー PBDOM_DOCUMENT を識別する • GetParentObject と SetParentObject では、PBDOM_OBJECT の親の取 得と設定を行う • GetText、GetTextNormalize、および GetTextTrim では、 PBDOM_OBJECT のテキスト データを取得する • アプリケーション テクニック HasChildren では、PBDOM_OBJECT に子があるかどうかを判断する 245 PBDOM ノード オブジェクト • IsAncestorObjectOf では、PBDOM_OBJECT が別の PBDOM_OBJECT の先祖かどうかを判断する PBDOM_OBJECT 継 承 PBDOM_OBJECT クラスは、直接インスタンス化および使用すること が前提とされない点で、C++ の仮想クラスに似ています。たとえば、 PowerScript の CREATE 文を使用して PBDOM_OBJECT を作成できます が、そのメソッドを直接使うことはできません。 PBDOM_OBJECT pbdom_obj pbdom_obj = CREATE PBDOM_OBJECT pbdom_obj.SetName("VIRTUAL_PBDOM_OBJ") // 例外 ! 上のコードの 3 行目は、基本クラス PBDOM_OBJECT の SetName メ ソッドに直接アクセスしようとするので、例外を送出します。ただし、 SetName メソッドが PBDOM_ELEMENT などの派生クラスからアクセ スされる場合には、このような実装の仕方もありえます。 PBDOM_OBJECT pbdom_obj pbdom_obj = CREATE PBDOM_ELEMENT pbdom_obj.SetName ("VIRTUAL_PBDOM_OBJ") プレースホルダとして の基本クラス PBDOM_OBJECT の 使い方 PBDOM_OBJECT クラスを、派生クラスのオブジェクトのプレースホ ルダとして使用できます。 PBDOM_DOCUMENT pbdom_doc PBDOM_OBJECT pbdom_obj pbdom_doc = CREATE PBDOM_DOCUMENT pbdom_doc.NewDocument ("", "", & "Root_Element_From_Doc_1", "", "") pbdom_obj = pbdom_doc.GetRootElement pbdom_obj.SetName & ("Root_Element_From_Doc_1_Now_Changed") インスタンス化された PBDOM_OBJECT pbdom_obj は、 PBDOM_DOCUMENT オブジェクトに割り当てられます。このオブ ジェクトには、GetRootElement メソッドの戻り値が格納されます。ここ で、pbdom_obj は、PBDOM_ELEMENT への参照を保持し、また、 PBDOM_OBJECT から派生したクラスの任意のオブジェクトに対して 有効に動作します。 スタンドアロン オブ ジェクト PBDOM_OBJECT は、すべてのドキュメントや親の PBDOM_OBJECT から独立した自己完結型のオブジェクトを作成できます。このような PBDOM_OBJECT をスタンドアロン オブジェクトと呼びます。たとえ ば、次のようになります。 PBDOM_ELEMENT pbdom_elem_1 pbdom_elem_1 = Create PBDOM_ELEMENT 246 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 pbdom_elem_1.SetName("pbdom_elem_1") pbdom_elem_1 は、Create キーワードを使用して派生クラス PBDOM_ELEMENT 内でインスタンス化されます。次に、どのドキュ メント内にも含まれないスタンドアロン オブジェクトである pbdom_elem_1 オブジェクトから、SetName メソッドを呼び出すことが できます。 スタンドアロン オブジェクトは有効な PBDOM 操作を実行できます が、スタンドアロンであることによってそのオブジェクトに特別なメ リットまたはデメリットがあるわけではありません。 親がオーナーのオブ ジェクトおよびドキュ メントがオーナーのオ ブジェクト 次の例のように、PBDOM_OBJECT を別のスタンドアロン PBDOM_OBJECT に追加することにより、PBDOM_OBJECT に親クラ スを割り当てることができます。 PBDOM_ELEMENT pbdom_elem_1 PBDOM_ELEMENT pbdom_elem_2 pbdom_elem_1 = Create PBDOM_ELEMENT pbdom_elem_2 = Create PBDOM_ELEMENT pbdom_elem_1.SetName("pbdom_elem_1") pbdom_elem_2.SetName("pbdom_elem_2") pbdom_elem_1.AddContent(pbdom_elem_2) 2 つの PBDOM_ELEMENT オブジェクト pbdom_elem_1 と pbdom_elem_2 がインスタンス化されます。pbdom_elem_2 オブジェク トは、AddContent メソッドを使用して、pbdom_elem_1 の子オブジェク トとして追加されます。 この例では、pbdom_elem_1 と pbdom_elem_2 のいずれも、オーナーは ドキュメントではありません。また、pbdom_elem_1 オブジェクトはス タンドアロンのままです。pbdom_elem_1 に、ドキュメントをオーナー とする親の PBDOM_OBJECT が割り当てられた場合、pbdom_elem_1 は スタンドアロン オブジェクトではなくなります。 PBDOM_DOCUMENT PBDOM_DOCUMENT クラスは、PBDOM_OBJECT から派生し、XML DOM ドキュメントを表します。PBDOM_DOCUMENT メソッドでは、 ルート要素、処理命令などのドキュメントレベル情報にアクセスでき ます。 アプリケーション テクニック 247 PBDOM ノード オブジェクト メソッド PBDOM_OBJECT から継承するメソッドに加え、PBDOM_DOCUMENT クラスには以下のメソッドがあります。 • DetachRootElement、GetRootElement、HasRootElement、および SetRootElement では、PBDOM_DOCUMENT のルート要素を操作 する • GetDocType と SetDocType では、XML ドキュメントの DOCTYPE 宣言を取得および設定する • NewDocument では、新規の PBDOM_DOCUMENT を最初から作成 する • SaveDocument では、PBDOM_DOCUMENT 内の DOM ツリーの内 容をファイルに保存する PBDOM_DOCTYPE PBDOM_DOCTYPE クラスは、XML DOM ドキュメントのドキュメン ト型宣言オブジェクトを表します。PBDOM_DOCTYPE メソッドを使 用して、ルート要素名、内部サブセット、および、システム ID とパブ リック ID にアクセスできます。 メソッド PBDOM_OBJECT から継承するメソッドに加え、PBDOM_DOCTYPE クラスには以下のメソッドがあります。 • GetPublicID、SetPublicID、GetSystemID、および SetSystemID では、 PBDOM_DOCTYPE 内で宣言される外部参照 ID のパブリック ID とシステム ID を取得および設定する • GetInternalSubset と SetInternalSubset では、PBDOM_DOCTYPE の内 部サブセット データを取得および設定する PBDOM_ELEMENT PBDOM_ELEMENT は、PowerScript 内でモデル化された XML 要素を 表します。PBDOM_ELEMENT メソッドを使用して、要素属性、子、 およびテキストにアクセスできます。 メソッド 248 PBDOM_OBJECT から継承するメソッドに加え、PBDOM_ELEMENT クラスには以下のメソッドがあります。 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 AddNamespaceDeclaration と RemoveNamespaceDeclaration では、 • PBDOM_ELEMENT に名前空間宣言を追加したり、 PBDOM_ELEMENT から名前空間宣言を削除したりする GetAttribute、GetAttributes、GetAttributeValue、HasAttributes、 RemoveAttribute、SetAttribute、および SetAttributes では、 • PBDOM_ELEMENT の属性を操作する GetChildElement、GetChildElements、HasChildElements、 RemoveChildElement、および RemoveChildElements では、 • PBDOM_ELEMENT の子を操作する GetNamespacePrefix と GetNamespaceURI では、PBDOM_ELEMENT • に関連付けられた名前空間の接頭辞と URI を取得する GetQualifiedName では、接頭辞(ある場合)を含めた • PBDOM_ELEMENT の完全名を取得する PBDOM_ELEMENT と PBDOM_ATTRIBUTE の関係 • SetDocument では、PBDOM_DOCUMENT を PBDOM_ELEMENT の 親として設定する • SetNamespace では、PBDOM_ELEMENT の名前空間を設定する • SetText では、PBDOM_ELEMENT のテキスト内容を設定する PBDOM では、XML 要素の属性はその要素の子ではありません。XML 要素の属性は、関連付けられた要素とは別に識別されるのではなく、 要素のプロパティです。 次の単純な XML ドキュメントについて考えてみます。 <root attr="value1"> <child attr_1="value1" attr_2="value2"/> </root> これに相当する PBDOM ツリーを図 14-2 に示します。 図 14-2: PBDOM_ELEMENT と PBDOM_ATTRIBUTE の関係 ルート と 子 を結ぶ実線は、親子関係を表します。点線は、属性とその オーナー要素との間の「~のプロパティ」という関係を表します。 アプリケーション テクニック 249 PBDOM ノード オブジェクト PBDOM_ELEMENT の内容を管理するメソッドは、PBDOM_ATTRIBUTE オブジェクトには使用できません。属性を取得、設定、および削除す るメソッドは別にあります。 属性は、オーナー要素の子ではないので PBDOM ドキュメント ツリー 全体の一部とはみなされませんが、オーナー要素を通してツリーにリ ンクされます。 属性には子オブジェクト(XML テキストとエンティティ参照ノード) を格納できるので、属性はそれ自体のサブツリーを形成します。 要素の属性はその要素の子とはみなされないので、子オブジェクト間 にあるような兄弟関係が属性間にはありません。サンプルの XML ド キュメント、および図 14-2 では、attr_1 と attr_2 は兄弟ではありませ ん。オーナー要素内での属性の表示順序には、特に意味はありません。 属性の設定と作成 PBDOM では、XML 要素の属性は、PBDOM_ELEMENT SetAttribute メ ソッドと SetAttributes メソッドを使用して設定されます。これらのメ ソッドは常に、PBDOM_ELEMENT の新規属性を作成しようとし、既 存の属性を同じ名前および同じ名前空間の URI に置き換えようとしま す。 PBDOM_ELEMENT に、同じ名前と同じ名前空間 URI の既存の属性が すでに含まれている場合、これらのメソッドは、既存の属性を削除し てから新規属性を PBDOM_ELEMENT に挿入します。SetAttribute メ ソッドを呼び出すと、PBDOM_ATTRIBUTE(PBDOM_ELEMENT の既 存属性を表す)がそのオーナー PBDOM_ELEMENT からデタッチされ ます。 たとえば、次の要素について考えてみます。 <an_element an_attr="some_value"/> PBDOM_ELEMENT オブジェクト pbdom_an_elem が an_element 要素を 表し、次の文が発行された場合、このメソッドはまず、an_element 要 素の新規属性を作成しようとします。 pbdom_an_elem.SetAttribute("an_attr", "some_other_value") 次に、an_element にはすでに an_attr という名前の属性が含まれている ので、その属性は削除されます。元の an_attr 属性を表す既存の PBDOM_ATTRIBUTE オブジェクトがある場合、この PBDOM_ATTRIBUTE はそのオーナー要素(an_element)からデタッ チされます。 属性と名前空間の詳細については、269 ページの「XML 名前空間」を 参照してください。 250 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 PBDOM_ATTRIBUTE PBDOM_ATTRIBUTE クラスは、PowerScript 内でモデル化された XML 属性を表します。PBDOM_ATTRIBUTE メソッドを使用して、要素属 性および名前空間情報にアクセスできます。 メソッド PBDOM_OBJECT から継承するメソッドに加え、PBDOM_ATTRIB ク ラスには以下のメソッドがあります。 • GetBooleanValue 、SetBooleanValue 、GetDateValue 、SetDateValue 、 GetDateTimeValue、SetDateTimeValue、GetDoubleValue、SetDoubleValue、 GetIntValue、SetIntValue、GetLongValue、SetLongValue、GetRealValue、 SetRealValue、GetTimeValue、SetTimeValue、GetUIntValue、SetUintValue、 GetULongValue および SetULongValue では、PBDOM_ATTRIBUTE の 値を指定されたデータ型として取得および設定する • GetNamespacePrefix と GetNamespaceURI では、 PBDOM_ATTRIBUTE に関連付けられた名前空間の接頭辞と URI を取得する • GetOwnerElementObject と SetOwnerElementObject では、 PBDOM_ATTRIBUTE のオーナー PBDOM_ELEMENT を取得およ び設定する • GetQualifiedName では、接頭辞(ある場合)を含めた PBDOM_ATTRIBUTE の完全名を取得する 子オブジェクト PBDOM_OBJECT • SetNamespace では、PBDOM_ATTRIBUTE の名前空間を設定する • SetText では、PBDOM_ATTRIBUTE のテキスト内容を設定する PBDOM_ATTRIBUTE には、子オブジェクト PBDOM_OBJECT のサブ ツリーが含まれています。子オブジェクトは、PBDOM_TEXT オブジェ クトと PBDOM_ENTITYREFERENCE オブジェクトを組み合わせるこ ともできます。 次の例では、attr という名前の PBDOM_ATTRIBUTE が含まれている elem という名前の PBDOM_ELEMENT を作成します。 PBDOM_ATTRIBUTE pbdom_attr PBDOM_TEXT pbdom_txt PBDOM_ENTITYREFERENCE pbdom_er PBDOM_ELEMENT pbdom_elem pbdom_elem = Create PBDOM_ELEMENT pbdom_elem.SetName ("elem") pbdom_attr = Create PBDOM_ATTRIBUTE pbdom_attr.SetName("attr") アプリケーション テクニック 251 PBDOM ノード オブジェクト pbdom_attr.SetText("Part 1 ") pbdom_txt = Create PBDOM_TEXT pbdom_txt.SetText (" End.") pbdom_er = Create PBDOM_ENTITYREFERENCE pbdom_er.SetName("ER") pbdom_attr.AddContent(pbdom_er) pbdom_attr.AddContent(pbdom_txt) pbdom_elem.SetAttribute(pbdom_attr) XML 内の要素タグは次のようになります。 <elem attr="Part 1 &ER; End."> 図 14-3 で、矢印は PBDOM_ATTRIBUTE とほかの PBDOM_OBJECT と の親子関係を示します。 図 14-3: PBDOM_ATTRIBUTE サブツリーの例 PBDOM_TEXT のデ フォルトの子オブジェ クト PBDOM_ATTRIBUTE には一般に、PBDOM_TEXT の子オブジェクト が少なくとも 1 つ含まれています。その子オブジェクトの内容が空の 文字列の場合もあります。ただし、RemoveContent メソッドの呼び出し により PBDOM_ATTRIBUTE の内容がすべて削除された場合を除きま す。 以下の例は、空の文字列を持つ PBDOM_TEXT オブジェクトがどのよ うにして PBDOM_ATTRIBUTE の子オブジェクトになるかを示しま す。 例 1 次の例では、PBDOM_ELEMENT の SetAttribute メソッドを使用し ます。PBDOM_ATTRIBUTE の名前は attr に設定されていますが、テキ スト値は空の文字列です。PBDOM_ATTRIBUTE には、空の文字列を 持つ子オブジェクト PBDOM_TEXT が 1 つあります。 PBDOM_DOCUMENT pbdom_doc PBDOM_ATTRIBUTE pbdom_attr 252 PowerBuilder 第 14 章 PBDOM_OBJECT PowerBuilder XML サービスの使い方 pbdom_obj_array[] try pbdom_doc = Create PBDOM_DOCUMENT pbdom_doc.NewDocument("root") // 属性の名前は // "attr" に設定され、そのテキスト値は空の文字列 "" です。 pbdom_doc.GetRootElement().SetAttribute("attr", "") pbdom_attr = & pbdom_doc.GetRootElement().GetAttribute("attr") MessageBox ("HasChildren", & string(pbdom_attr.HasChildren())) catch(PBDOM_EXCEPTION pbdom_except) MessageBox ("PBDOM_EXCEPTION", & pbdom_except.GetMessage()) end try SaveDocument メソッドを使用して pbdom_doc を XML として変更すると きは、次のようになります。 <root attr="" /> 次の例では、PBDOM_ATTRIBUTE を作成し、その名前を attr に 設定します。テキスト値は設定されませんが、PBDOM_TEXT オブジェ クトが自動作成され、PBDOM_ATTRIBUTE にアタッチされます。こ れは、この方法で作成されたすべての PBDOM_ATTRIBUTE のデフォ ルトの振る舞いです。 例2 PBDOM_DOCUMENT pbdom_doc PBDOM_ATTRIBUTE pbdom_attr try pbdom_doc = Create PBDOM_DOCUMENT pbdom_doc.NewDocument("root") // PBDOM_ATTRIBUTE を作成し、名前を "attr" に設定します。 pbdom_attr = Create PBDOM_ATTRIBUTE pbdom_attr.SetName("attr") pbdom_doc.GetRootElement().SetAttribute(pbdom_attr) MessageBox ("HasChildren", & string(pbdom_attr.HasChildren())) アプリケーション テクニック 253 PBDOM ノード オブジェクト catch(PBDOM_EXCEPTION pbdom_except) MessageBox ("PBDOM_EXCEPTION", & pbdom_except.GetMessage()) end try SetText メソッド(または、SetNamespace を除くほかの Set* メソッド のいずれか。)を呼び出すとき、デフォルトの PBDOM_TEXT が新規の PBDOM_TEXT に置き換わります。SetContent メソッドを呼び出すと、 デ フ ォ ル ト の PBDOM_TEXT を、PBDOM_TEXT オ ブ ジ ェ ク ト と PBDOM_ENTITYREFERENCE オブジェクトの組み合わせに置き換え ることができます。 PBDOM_ENTITYREFERENCE PBDOM_ENTITYREFERENCE クラスは、XML エンティティ参照ノー ドの振る舞いを定義します。これは、主にエンティティ参照を、属性 ノードと同様に要素ノード内にも挿入するための単純なクラスです。 PBDOM_BUILDER クラスが XML ドキュメントを解析して DOM ツ リーを構築するとき、このクラスは、DTD 内で出現するときにエン ティティを完全に拡張します。したがって、PBDOM_BUILDER 構築メ ソッドのいずれかを使用して PBDOM_DOCUMENT オブジェクトが作 成された直後は、作成されたドキュメント ツリーにエンティティ参照 ノードはありません。 PBDOM_ENTITYREFERENCE オブジェクトは、いつでも作成でき、ど のドキュメントにも挿入できます。参照されるエンティティを表す、 対応する DOM エンティティ ノードがそのドキュメント内にあるかど うかには左右されません。 メソッド PBDOM_ENTITYREFERENCE クラスには、PBDOM_OBJECT から継承 されたメソッドしかありません。 PBDOM_CHARACTERDATA PBDOM_CHARACTERDATA クラスは PBDOM_OBJECT から派生し、 XML ドキュメント内の文字ベースの内容(マークアップではない)を 表します。PBDOM_CHARACTERDATA クラスは、PBDOM_OBJECT を拡張し、文字データの操作専用のメソッドを持ちます。 メソッド 254 PBDOM_OBJECT から継承するメソッドに加え、 PBDOM_CHARACTERDATA クラスには以下のメソッドがあります。 PowerBuilder 第 14 章 3 つのクラスの親クラ ス PowerBuilder XML サービスの使い方 • Append では、PBDOM_CHARACTERDATA オブジェクトのテキス ト文字列またはテキスト データを現行オブジェクト内のテキスト に追加する • SetText では、PBDOM_CHARACTERDATA オブジェクトのテキス ト内容を設定する PBDOM_CHARACTERDATA クラスは、以下の 3 つの PBDOM クラス の親クラスです。 • PBDOM_TEXT • PBDOM_CDATA • PBDOM_COMMENT PBDOM_CHARACTERDATA クラスは、その親クラス PBDOM_OBJECT と同様に、直接インスタンス化および使用すること が前提とされない点で、「仮想」クラスといえます。これは、C++ の 仮想クラスに似ています。たとえば、CREATE 文で PBDOM_CHARACTERDATA を作成することは PowerScript では有効 ですが、PBDOM_CHARACTERDATA を SetText メソッドを呼び出し て直接操作することは無効です。次のコードの最後の行は例外を発生 します。 PBDOM_CHARACTERDATA pbdom_chrdata pbdom_chrdata = CREATE PBDOM_CHARACTERDATA pbdom_chrdata.SetText("character string") // 例外 ! この例では、pbdom_chrdata は、PBDOM_CHARACTERDATA として 宣言されますが PBDOM_TEXT としてインスタンス化されます。 pbdom_chrdata で SetText を呼び出すことは、PBDOM_TEXT SetText メ ソッドを呼び出すことに相当します。 PBDOM_CHARACTERDATA pbdom_chrdata pbdom_chrdata = CREATE PBDOM_TEXT pbdom_chrdata.SetText("character string") PBDOM_TEXT PBDOM_TEXT ク ラ ス は PBDOM_CHARACTERDATA か ら 派 生 し、 XML ドキュメント内の DOM テキスト ノードを表します。 アプリケーション テクニック 255 PBDOM ノード オブジェクト メソッド PBDOM_TEXT クラスには、PBDOM_OBJECT か PBDOM_CHARACTERDATA から継承されていないメソッドはありま せん。 PBDOM_TEXT オブ ジェクトの使い方 PBDOM_TEXT オブジェクトは、PBDOM_ELEMENT か PBDOM_ATTRIBUTE のテキスト内容を表すために広く使用されま す。PBDOM_TEXT オブジェクトは、カギカッコで区切られていませ んがオブジェクトであり、親クラス PBDOM_ELEMENT の値の一部で はありません。 PBDOM ツリー内でグラフィカルに表現された PBDOM_TEXT オブ ジェクトは、リーフ ノードであり、子オブジェクトを持ちません。た とえば、図 14-4 は次の PBDOM_ELEMENT を表します。 <parent_element>some text</parent_element> 図 14-4: PBDOM_TEXT 親子関係 矢印は親子関係を表します。 PBDOM_TEXT の出 現 XML ドキュメントの初回の解析時、要素の内容中にマークアップがな い場合は、要素内のテキストは単一の PBDOM_TEXT オブジェクトと して表されます。この PBDOM_TEXT オブジェクトは、その要素の唯 一の子です。マークアップがある場合、PBDOM_ELEMENT オブジェ クトと PBDOM_TEXT オブジェクトのリストに解析されます。このリ ストは、要素の子のリストになります。 たとえば、次の XML を解析すると、<element_1> を表す 1 つの PBDOM_ELEMENT と、テキスト内容 Some Text を表す 1 つの PBDOM_TEXT が作成されます。 <root> <element_1>Some Text</element_1> </root> <element_1> PBDOM_ELEMENT には、唯一の子としての PBDOM_TEXT オブジェクトがあります。 256 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 次のドキュメントについて考えてみます。 <root> <element_1> Some Text <element_1_1>Sub Element Text</element_1_1> More Text <element_1_2/> Yet More Text </element_1> </root> 次の XML を解析すると、<element_1> を表す PBDOM_ELEMENT と、そ の子が 5 つ作成されます。 隣接する PBDOM_TEXT オブ ジェクト • Some Text を表す PBDOM_TEXT • <element_1_1/> を表す PBDOM_ELEMENT • More Text を表す PBDOM_TEXT • <element_1_2/> を表す PBDOM_ELEMENT • Yet More Text を表す PBDOM_TEXT 指定された要素の内容をマークアップの介入なしで表している隣接す る PBDOM_TEXT オブジェクトを作成できます。たとえば、次のドキュ メントから始めます。 <root> <element_1>Some Text</element_1> </root> element_1 の PBDOM_ELEMENT で AddContent("More Text") を呼び 出すと、次のような結果になります。 <root> <element_1>Some TextMore Text</element_1> </root> 「Some Text」と「More Text」を表す、相互に隣接した 2 つの PBDOM_TEXT オブジェクトが作成されています。それらの間には何 もなく、またそれらの分離を表す方法もありません。 PBDOM_TEXT オブ ジェクトの永続格納 隣接する PBDOM_TEXT オブジェクトが離れると、DOM を編集する セッションは続きません。前の例で示した「More Text」の追加により 作成されたドキュメントが再オープンおよび再解析されると、1 つの PBDOM_TEXT オブジェクトだけが「Some TextMore Text」を表します。 アプリケーション テクニック 257 PBDOM ノード オブジェクト PBDOM_CDATA PBDOM_CDATA クラスは、PBDOM_TEXT から派生し、XML DOM CDATA セクションを表します。 メソッド PBDOM_CDATA クラスには、PBDOM_OBJECT か PBDOM_CHARACTERDATA から継承されていないメソッドはありま せん。 CDATA オブジェクト の使い方 PBDOM_CDATA オ ブ ジ ェ ク ト は、拡 張 さ れ た PBDOM_TEXT オ ブ ジェクトとして考えることができます。PBDOM_CDATA オブジェク トを使用して、<、& など、XML で禁止されている文字を含むことの できるテキストを格納できます。このオブジェクトの主な目的は、エ ンティティ参照なしで、そのような特殊文字を大きなテキスト ブロッ ク内に含めることです。 次の例には PBDOM_CDATA オブジェクトが含まれています。 <some_text> <![CDATA[ (x < y) & (y < z) => x < z ]]> </some_text> 同じテキスト内容を PBDOM_TEXT オブジェクトとして表現するに は、次のように記述します。 <some_text> (x < y) & (y < z) => x < z </some_text> PBDOM_CDATA クラスは PBDOM_TEXT から派生しますが、 PBDOM_TEXT を挿入できる個所に PBDOM_CDATA オブジェクトを 必ず挿入できるわけではありません。たとえば、PBDOM_TEXT オブ ジェクトを PBDOM_ATTRIBUTE の子オブジェクトとして追加できま すが、PBDOM_CDATA オブジェクトは追加できません。 PBDOM_COMMENT PBDOM_COMMENT クラスは、XML ドキュメント内の DOM コメン ト ノードです。PBDOM_COMMENT クラスは PBDOM_CHARACTERDATA クラスから派生します。 メソッド 258 PBDOM_COMMENT クラスには、PBDOM_OBJECT か PBDOM_CHARACTERDATA から継承されていないメソッドはありま せん。 PowerBuilder 第 14 章 コメントの使い方 PowerBuilder XML サービスの使い方 コメントは、ユーザが読める表現で XML ドキュメントに注釈を付け るのに便利です。 ドキュメントの解析時、ドキュメント内のすべてのコメントは、DOM ツリーの一部としてメモリ内に永続します。実行時に作成された PBDOM_COMMENT も DOM ツリーの一部になります。 XML コメントは、通常、ドキュメントの内容モデルの一部ではありま せん。コメントの有無はドキュメントの有効性に影響しません。また、 DTD 内でコメントを宣言する必要もありません。 PBDOM_PROCESSINGINSTRUCTION PBDOM_PROCESSINGINSTRUCTION クラスは、XML 処理命令(PI) を表します。PBDOM_PROCESSINGINSTRUCTION メソッドを使用し て、処理命令先とそのデータにアクセスできます。そのデータには、 文字列として、または、必要に応じて名前と値のペアとしてアクセス できます。 PI の実際の処理命令は文字列です。これは、命令が個別の name="value" のペアに分割される場合も同じです。PBDOM はこのよ うな PI 書式をサポートします。一般に、PI データはこれらのペアを 含みます。その場合、PBDOM_PROCESSINGINSTRUCTION はこれら のペアを名前と値の内部リストに解析します。 メソッド PBDOM_OBJECT から継承するメソッドに加え、 PBDOM_PROCESSINGINSTRUCTION クラスには以下のメソッドがあ ります。 • GetData と SetData では、PBDOM_PROCESSINGINSTRUCTION オ ブジェクトの生データを取得および設定する • GetNames では、PBDOM_PROCESSINGINSTRUCTION のデータの 一部(name="value" のペアに分割されている)から取った、名前 のリストを取得する • GetValue、RemoveValue、および SetValue では、 PBDOM_PROCESSINGINSTRUCTION オブジェクト内で、指定さ れた名前と値のペアの値を取得、削除、および設定する • アプリケーション テクニック GetTarget では、PBDOM_PROCESSINGINSTRUCTION のターゲッ トを取得する。たとえば、XML 宣言のターゲット(特殊な処理命 令)は文字列 xml になる 259 アプリケーションへの pbdom115.pbx の追加 アプリケーションへの pbdom115.pbx の追加 PBDOM クラスは、接尾辞 PBX(PowerBuilder エクステンション用)を 持つ DLL ファイルに実装されます。PBDOM クラスを PowerBuilder ターゲットに追加する最も簡単な方法は、PowerBuilder システム ツ リー内のライブラリに pbdom115.pbx PBX ファイル内のオブジェクト ディスクリプションをインポートすることです。pbdom115.pbd ファイ ル(クラスのラッパーとして動作)をターゲットのライブラリ探索パ スに追加することもできます。 pbdom115.pbx ファイルと pbdom115.pbd ファイルは、PowerBuilder のイ ンストール時に Shared\PowerBuilder ディレクトリに配置されます。 PBDOM アプリケーションの作成時に pbdom115.pbx を別の場所にコ ピーする必要はありませんが、アプリケーションの探索パス中のディ レクトリに、このファイルをアプリケーションとともに配布する必要 があります。 v エクステンション内のディスクリプションをライブラリにインポートするに は 1 2 システム ツリーで、エクステンションを使用したいターゲットを 展開し、ライブラリを右クリックし、ポップアップ メニューから [ PB エクステンションのインポート]を選択します。 PBX ファイルの位置に移動し、[開く]をクリックします。 PBX 内の各クラスがシステム ツリーに表示されます。そのためク ラスを展開し、そのプロパティ、イベント、およびメソッドを表 示して、それらをスクリプトに追加するためにドラッグアンドド ロップできます。 260 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 pbdom115.pbx をインポートした後に、PBDOM オブジェクトがシステ ム ツリーに表示されます。 PBDOM の使い方 この節では、PBDOM のクラスおよびメソッドを使用して基本的なタ スクを遂行する方法について説明します。ダウンロードしてテストで きる完全なコード サンプルを見るには、Windows の[スタート|プロ グラム| Sybase | PowerBuilder 11.5 | PB11.5 コード サンプル]を 選択します。 XML の検証 ファイルか文字列からドキュメントを作成する前に、XMLParseFile PowerScript 関数または XMLParseString PowerScript 関数を使用して、そ の XML が well formed(整形式)であるかどうか、あるいはオプショ ンで、DTD かスキーマに準拠しているかどうかをテストできます。た とえば、次のコードは、ファイル内の XML が well formed(整形式)で あるかどうかをテストします。 long ll_ret ll_ret = XMLParseFile("c:\temp\mydoc.xml", ValNever!) アプリケーション テクニック 261 PBDOM の使い方 デフォルトでは、これらの関数により、エラーが発生した場合にメッ セージ ボックスが表示されます。parsingerrors 文字列引数を指定して、 プログラムによりエラーを処理することもできます。これらの関数の 詳細については、 『PowerScript リファレンス』マニュアルかオンライ ン ヘルプの解説を参照してください。 XML から XML ドキュメントの作成 PBDOM_BUILDER クラスは、既存の XML ソースから PBDOM_DOCUMENT を作成するための 3 つのメソッドを提供しま す。また、発生したすべての解析エラーのリストを取得する GetParseErrors メソッドも提供します。 BuildFromString の使 い方 次 の 例 で は、XML 文 字 列 と PBDOM_BUILDER ク ラ ス を 使 用 し て PBDOM_DOCUMENT を作成します。まず、オブジェクトを宣言します。 PBDOM_BUILDER pbdom_builder_new PBDOM_DOCUMENT pbdom_doc 次に、コンストラクタと PBDOM_BUILDER の BuildFromString メソッド を使用してオブジェクトをインスタンス化します。 pbdombuilder_new = Create PBDOM_Builder pbdom_doc = pbdombuilder_new.BuildFromString(Xml_doc) XML は、次の例のように、文字列変数に直接ロードすることもできま す。 string Xml_str Xml_str = "<?xml version="1.0" ?>" Xml_str += "<WHITEPAPER>" Xml_str += "<TITLE>Document Title</TITLE>" Xml_str += "<AUTHOR>Author Name</AUTHOR>" Xml_str += "<PARAGRAPH>Document text.</PARAGRAPH>" Xml_str += "</WHITEPAPER>" BuildFromFile の使い 方 BuildFromFile メソッドと、PBDOM_DOCUMENT の作成元となるファイ ルへのパスを含む文字列を使用して、XML ファイルを作成できます。 PBDOM_BUILDER pbdombuilder_new PBDOM_DOCUMENT pbdom_doc pbdombuilder_new = Create PBDOM_Builder pbdom_doc = pbdombuilder_new.BuildFromFile & ("c:\pbdom_doc_1.xml") 262 PowerBuilder 第 14 章 BuildFromDataStore の使い方 PowerBuilder XML サービスの使い方 次に示す PowerScript コードの一部は、BuildFromDataStore メソッドを、 参照されるデータストア オブジェクトとともに使用する方法を示し ます。 PBDOM_Builder pbdom_bldr pbdom_document pbdom_doc datastore ds ds = Create datastore ds.DataObject = "d_customer" ds.SetTransObject (SQLCA) ds.Retrieve pbdom_doc = pbdom_bldr.BuildFromDataStore(ds) GetParseErrors の使 い方 Build メソッドのいずれかを呼び出した後、GetParseErrors メソッドを 使用して、Build メソッドで発生した解析エラーと検証エラーのリスト を取得できます。 PBDOM_Builder pbdom_bldr pbdom_document pbdom_doc string strParseErrors[] BOOLEAN bRetTemp = FALSE pbdom_buildr = Create PBDOM_BUILDER pbdom_doc = pbdom_buildr.BuildFromFile("D:\temp.xml") bRetTemp = pbdom_buildr.GetParseErrors(strParseErrors) if bRetTemp = true then for l = 1 to UpperBound(strParseErrors) MessageBox (" 解析エラー ", strParseErrors[l]) next end if 解析エラー 解析エラーが検出され、GetParseErrors が true を返した場合、調べるこ とができる完全な PBDOM ノード ツリーが作成されている場合があり ます。 アプリケーション テクニック 263 PBDOM の使い方 最初からの XML ドキュメントの作成 適切な PBDOM_OBJECT サブクラスとメソッドを使用して、スクリプ ト内に XML ドキュメントを作成できます。次のコードでは、 PBDOM_ELEMENT クラスと PBDOM_DOCUMENT クラス、およびそ れらのメソッドの一部を使用して、単純な XML ドキュメントを作成 します。 まず、オブジェクトを宣言し、インスタンス化します。 PBDOM_ELEMENT pbdom_elem_1 PBDOM_ELEMENT pbdom_elem_2 PBDOM_ELEMENT pbdom_elem_3 PBDOM_ELEMENT pbdom_elem_root PBDOM_DOCUMENT pbdom_doc1 pbdom_elem_1 = Create PBDOM_ELEMENT pbdom_elem_2 = Create PBDOM_ELEMENT pbdom_elem_3 = Create PBDOM_ELEMENT インスタンス化されたオブジェクトに命名します。 PBDOM_DOCUMENT オブジェクトの pbdom_doc1 には命名しないこ とに注意してください。 pbdom_elem_1.SetName("pbdom_elem_1") pbdom_elem_2.SetName("pbdom_elem_2") pbdom_elem_3.SetName("pbdom_elem_3") AddContent メソッドを使用して、オブジェクトをノード ツリーに配置 します。AddContent メソッドは、参照されるオブジェクトを、AddContent の呼び出し元オブジェクトの子ノードとして追加します。 pbdom_elem_1.AddContent(pbdom_elem_2) pbdom_elem_2.AddContent(pbdom_elem_3) NewDocument メソッドを使用して新規の XML ドキュメントを作成し ます。NewDocument メソッドに指定したパラメータ値が、ルート要素 の名前になります。次に、GetRootElement メソッドを使用して、 PBDOM_DOCUMENT オブジェクト pbdom_doc1 からこの名前にアク セスし、それを PBDOM_ELEMENT オブジェクト pbdom_elem_root に 割り当てます。 pbdom_doc1.NewDocument("Root_Element_From_Doc_1") pbdom_elem_root = pbdom_doc1.GetRootElement() 264 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 要素オブジェクト pbdom_elem_1 およびそのオブジェクトのすべての 子ノードを、AddContent メソッドを使用してルート要素下の新規の XML ドキュメント ノード ツリーに配置します。 子孫ノード pbdom_elem_1 をノード ツリーに配置すると、そのすべての子ノードが移動されるこ とに注目してください。 pbdom_elem_root.AddContent(pbdom_elem_1) 作成された XML ドキュメントは次のようになります。 <!DOCTYPE Root_Element_From_Doc_1> <Root_Element_From_Doc_1> <pbdom_elem_1> <pbdom_elem_2> <pbdom_elem_3/> </pbdom_elem_2> </pbdom_elem_1> </Root_Element_From_Doc_1> ノード データへのアクセス XML ドキュメントは、適切な PBDOM_OBJECT サブクラスとメソッ ドを使用してノード ツリーの要素にアクセスすることによって、読み 込むことができます。次のコードでは、配列、PBDOM_OBJECT とそ の子孫クラス PBDOM_DOCUMENT、および、PBDOM_DOCUMENT クラスの GetContent メソッドと GetRootElement メソッドを使用して、 XML ドキュメントのノード データにアクセスします。 pbdom_doc という名前の PBDOM_DOCUMENT オブジェクトには、次 の XML ドキュメントが含まれます。 <Root> <Element_1> <Element_1_1/> <Element_1_2/> <Element_1_3/> </Element_1> <Element_2/> <Element_3/> </Root> 次のコードは、GetContent メソッドから返された要素を格納する配列 を宣言します。このメソッドは、pbdom_doc という名前の PBDOM_DOCUMENT オブジェクトを読み込みます。 PBDOM_OBJECT pbdom_obj_array[] アプリケーション テクニック 265 PBDOM の使い方 ... pbdom_doc.GetContent(ref pbdom_obj_array) これで、pbdom_obj_array 配列に pbdom_doc のルート要素を表す 1 つの 値 <Root> が格納されます。 pbdom_doc 内のほかのノードにアクセスするには、GetRootElement メ ソッドを GetContent メソッドとともに使用します。 pbdom_doc.GetRootElement().GetContent & (ref pbdom_obj_array) これで、pbdom_obj_array 配列に、pbdom_doc のルート要素の 3 つの子 ノードに対応する 3 つの値、つまり <Element_1>、<Element_2>、およ び <Element_3> が格納されます。 PBDOM には、データにアクセスするためのメソッドがほかにもあり ます。InsertContent、AddContent、RemoveContent、SetContent などです。 配列によるノード内容 の変更 AddContent メソッドを使用してノード内容を変更できます。 pbdom_obj_array[3].AddContent("This is Element 3.") 次のコード行は、次のようにノード ツリーを変更します。 <Root> <Element_1> <Element_1_1/> <Element_1_2/> <Element_1_3/> </Element_1> <Element_2/> <Element_3>This is Element 3.</Element_3> </Root> 配列とオブジェクト参照 PBDOM_DOCUMENT クラスの GetContent メソッドなどのメソッドを 使用して PBDOM_OBJECT 参照の配列を返す場合、その参照は PBDOM オブジェクトに対するものです。配列項目を通してこれらのオブジェ クトのいずれかを修正した場合、変更内容は永続し、同じオブジェク ト参照を持つほかのすべての配列に反映されます。 266 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 ノード ツリー階層の操作 XML ノード ツリーは、ノードを再配置することにより再構築できま す。ノード操作の 1 つの方法は、子ノードを親ノードからデタッチす ることです。これは、次の例のように、Detach メソッドを使用して実 行できます。 pbdom_doc という名前の PBDOM_DOCUMENT オブジェクトのルート 要素を、GetRootElement メソッドを使用して取得します。 pbdom_obj = pbdom_doc.GetRootElement() ルート要素を PBDOM_DOCUMENT オブジェクトからデタッチしま す。このオブジェクトはルート要素の親ノードです。 pbdom_obj.Detach() PBDOM は、別のオブジェクトの子オブジェクトを作成する SetParentObject メソッドを提供します。 親ノードのチェック 次の例のように、GetParentObject メソッドを使用して、要素に親オブ ジェクトがあるかどうかを判断できます。 pbdom_parent_obj = pbdom_obj.GetParentObject() if not IsValid(pbdom_parent_obj) then MessageBox (" 不正 ", " ルート要素に親がありません。") end if GetParentObject が呼び出されるオブジェクトに親オブジェクトがない 場合、関数は NULL を返します。 PBDOM には、XML ノード ツリー内での要素の場所に関する情報を返 すメソッドがほかにもあります。そのようなメソッドの例は、HasChildren (オブジェクトに子オブジェクトがあるかどうかのブール値を返す)、 IsAncestorObjectOf(オブジェクトが別のオブジェクトの先祖かどうかを 示す)などです。 PBDOM 例外の処理 PBDOM は、標準の PowerBuilder Exception クラスから派生する例外ク ラス PBDOM_EXCEPTION を定義します。Exception クラスの標準 Text プロパティを使用して、送出される例外の性質に関する詳細を知るこ とができます。このクラスは PowerBuilder Exception クラスを拡張し、 1 つのメソッド GetExceptionCode を持ちます。このメソッドは、送出さ れる例外を識別する固有のコードを返します。 アプリケーション テクニック 267 PBDOM 例外の処理 例外コードのリストについては、『PowerBuilder エクステンション リ ファレンス』マニュアルか、オンライン ヘルプの PBDOM 例外に関す るトピックを参照してください。 PBDOM は PowerBuilder エクステンションであり、PBNI を使用して作 成されます。このエクステンション自体が PBXRuntimeError 例外を送 出する場合があります。次の例では、try-catch ブロックが、まず PBDOM 例外をチェックし、次に PBXRuntimeError をチェックします。 次の例では、渡されたファイル名から PBDOM_DOCUMENT を作成し、 ProcessData という名前のユーザ定義関数を使用して DOM ノードを処 理します。ProcessData 関数は、以降の処理のために DOM 要素から情 報を抽出する再帰関数である場合もあります。 Long ll_ret ll_ret = XMLParseFile(filename, ValNever!) if ll_ret < 0 then return PBDOM_Builder domBuilder TRY domBuilder = CREATE PBDOM_Builder PBDOM_Document domDoc PBDOM_Element root domDoc = domBuilder.BuildFromFile( filename ) IF IsValid( domDoc ) THEN IF domDoc.HasChildren() THEN PBDOM_Object data[] IF domDoc.GetContent( data ) THEN Long ll_index, ll_count ll_count = UpperBound( data ) FOR ll_index = 1 TO ll_count ProcessData( data[ll_index], 0 ) NEXT END IF END IF END IF CATCH ( PBDOM_Exception pbde ) MessageBox( "PBDOM 例外 ", pbde.getMessage() ) CATCH ( PBXRuntimeError re ) MessageBox( "PBNI 例外 ", re.getMessage() ) END TRY 268 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 XML 名前空間 XML 名前空間を使用すれば、グローバルに固有名を作成して、名前は 同じだが用語の種類が異なるという要素と属性とを区別することがで きます。たとえば、書店の XML 送り状ドキュメントで、「date」とい う名前は、会計処理では注文日を表し、注文処理では発行日を表す場 合があります。 XML 名前空間は、Web 上のリソースを一意に識別する短い文字列であ る Uniform Resource Identifier(URI)によって識別されます。各名前空 間内の要素と属性は、要素名または属性名(ローカル名)に名前空間 の URI を使用して接頭辞を付けることによって一意に識別できます。 接頭辞と名前空間の関 連付け xmlns を使用して、名前空間宣言属性の一部として XML 名前空間を宣 言します。名前空間宣言属性を使用して、接頭辞を名前空間に関連付 けることができます。 たとえば、次の名前空間宣言属性は、http://www.pre.com の名前空間を 宣言し、接頭辞 pre をこの名前空間に関連付けます。 xmlns:pre="http://www.pre.com" デフォルトの XML 名 前空間 XML 名前空間宣言が接頭辞を指定しない場合、その名前空間はデフォ ルトの XML 名前空間になります。たとえば、次の要素 digicom は名前 空間として http://www.digital_software.com を宣言します。 <digicom xmlns="http://www.digital_software.com" /> 名前空間 http://www.digital_software.com は、要素 digicom、および digicom に含まれる可能性のあるすべての子要素の、スコープ内でのデフォル トの名前空間です。digicom の子要素は、自動的にこの名前空間に配置 されます。 NONAMESPACE 宣 言 次の名前空間宣言を NONAMESPACE 宣言と呼びます。 xmlns="" 含んでいる要素とその子要素を名前空間内に配置しないよう宣言しま す。NONAMESPACE の名前空間内の要素には、空の文字列に設定さ れた名前空間の接頭辞および URI セットが付けられています。 初期状態 PBDOM_ELEMENT か PBDOM_ATTRIBUTE を初めて作成したとき、 そ れ に は 名 前 が あ り ま せ ん。名 前 空 間 の 情 報 は、デ フ ォ ル ト で NONAMESPACE に設定されています。(つまり、その名前空間の接頭 辞と URI はどちらも空の文字列です。)SetName メソッドを使用して ローカル名を設定し、SetNamespace メソッドを使用して名前空間の接 頭辞と URI を設定します。 アプリケーション テクニック 269 XML 名前空間 名前は必須 名前は PBDOM_ELEMENT および PBDOM_ATTRIBUTE の必須プロパ ティですが、名前空間の情報は必須ではありません。 解析済みドキュメント からの取り出し PBDOM_ELEMENT か PBDOM_ATTRIBUTE を解析済みドキュメント からプログラムによって取り出すと、名前と名前空間の情報が、解析 済みドキュメントに含まれている Element か Attribute から継承されま す。ただし解析後も、SetName メソッドおよび SetNamespace メソッド を使用して、PBDOM_ELEMENT および PBDOM_ATTRIBUTE の名前 と名前空間の情報をさらに修正することができます。 名前と名前空間の情報は、内部で個別に格納されます。 PBDOM_ELEMENT か PBDOM_ATTRIBUTE の名前の変更は、名前空 間の情報には影響しません。また、名前空間の情報の変更は、名前に 影響しません。 PBDOM_ATTRIBUTE の名前および名前空間の設定 W3C の「XML 名前空間」仕様(セクション 5.3)では、 PBDOM_ATTRIBUTE の名前および名前空間の設定に制限を設けてい ます。1 つのタグ内に同一名の属性を 2 つ置くことはできません。ま た、同一ローカル名を含んでいる修飾名、かつ同一名前空間名に関連 付けられた接頭辞を含んでいる修飾名を持つ属性を、1 つのタグ内に 2 つ置くことはできません。 この仕様では、不正な属性および有効な属性として以下の例が挙げら れています。 <!-- http://www.w3.org is bound to n1 and n2 --> <x xmlns:n1="http://www.w3.org" xmlns:n2="http://www.w3.org" > <bad a="1" a="2" /> <bad n1:a="1" n2:a="2" /> </x> <!-- http://www.w3.org is bound to n1 and is the default --> <x xmlns:n1="http://www.w3.org" xmlns="http://www.w3.org" > <good a="1" b="2" /> <good a="1" n1:a="2" /> </x> 270 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 最初の例では、<bad a="1" a="2" /> は、1 つのタグ内に同一名の属 性を 2 つ置くことはできないという規約に違反しています。2 つ目の タグにある複数の属性は、ローカル名は同じですが接頭辞が異なるの で、属性の名前は相互に異なります。しかし、これらの属性の接頭辞 は同じ名前空間 URI http://www.w3.org を指すので、同じオーナー要素 内にそれらの属性を配置することは不正です。 PBDOM シナリオ 以下のシナリオでは、どのようにして PBDOM が上の要件を満たすか を示します。 • PBDOM_ATTRIBUTE の SetName メソッドを呼び出す場合 : PBDOM_ATTRIBUTE の pbdom_attr1 のオーナー PBDOM_ELEMENT に含まれている既存の PBDOM_ATTRIBUTE が、pbdom_attr1 に設定されることになっている名前と同じ名前を 持ち、かつ pbdom_attr1 と同じ名前空間 URI を持つ場合、 EXCEPTION_INVALID_NAME 例外が送出されます。 • PBDOM_ATTRIBUTE の SetNamespace メソッドを呼び出す場合 : PBDOM_ATTRIBUTE の pbdom_attr1 のオーナー PBDOM_ELEMENT に含まれている既存の PBDOM_ATTRIBUTE が、pbdom_attr1 と同じ名前を持ち、かつ pbdom_attr1 に設定される ことになっているものと同じ名前空間 URI を持つ場合、 EXCEPTION_INVALID_NAME 例外が送出されます。 • PBDOM_ELEMENT の SetAttribute(pbdom_attribute pbdom_attribute_ref) メソッドを呼び出す場合 : PBDOM_ELEMENT に、入力 PBDOM_ATTRIBUTE と同じ名前お よび同じ名前空間 URI の属性がすでにある場合、既存の属性は入 力 PBDOM_ATTRIBUTE に置き換えられます。したがって、既存 の属性はオーナー要素から削除(デタッチ)されます。 • PBDOM_ELEMENT の SetAttributes(pbdom_attribute pbdom_attribute_array[]) メソッドを呼び出す場合 : 配列内で、いずれか 2 つの PBDOM_ATTRIBUTE オブジェクトが 同じ名前および同じ名前空間 URI を持つ場合、 EXCEPTION_INVALID_NAME 例外が送出されます。名前の衝突 または名前空間の衝突が配列内にない場合、PBDOM_ELEMENT のすべての既存の属性が、配列内で PBDOM_ATTRIBUTE オブ ジェクトに置き換えられます。 アプリケーション テクニック 271 XML 名前空間 注意 上のシナリオはすべて、NONAMESPACE 名前空間に含まれている PBDOM_ATTRIBUTE オブジェクトに適用されるものです。 • PBDOM_ELEMENT の SetAttribute(string strName, string strValue) メ ソッドを呼び出す場合 : 指定された名前と値を持つ PBDOM_ATTRIBUTE が新規に作成さ れ、PBDOM_ELEMENT に設定されます。PBDOM_ELEMENT に、 同じ名前で、かつ NONAMESPACE 名前空間内に含まれている属 性がすでにある場合、その属性は PBDOM_ELEMENT から削除(デ タッチ)されます。 • PBDOM_ELEMENT の SetAttribute(string strName, string strValue, string strNamespacePrefix, string strNamespaceUri, boolean bVerifyNamespace) メソッドを呼び出す場合 : 指定された名前、値、および名前空間の情報を持つ PBDOM_ATTRIBUTE が新規に作成され、PBDOM_ELEMENT に 設定されます。PBDOM_ELEMENT に、入力名前空間 URI と同じ 名前および同じ名前空間 URI を持つ PBDOM_ATTRIBUTE がすで にある場合、その属性は PBDOM_ELEMENT から削除(デタッ チ)されます。 例 次の例は、入力 PBDOM_ATTRIBUTE と同じ名前および同じ名前空間 URI の属性が PBDOM_ELEMENT にすでに存在する場合に、 PBDOM_ATTRIBUTE を PBDOM_ELEMENT に対して設定するとどの ような影響があるかを示します。 次の例では、次のドキュメントに基づいて PBDOM_DOCUMENT を作 成します。 <root xmlns:pre1="http://www.pre.com" xmlns:pre2="http://www.pre.com"> <child1 pre1:a="123"/> </root> 272 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 次に、PBDOM_ATTRIBUTE オブジェクトを作成し、名前を a に、接 頭辞 URI をそれぞれ pre2 と http://www.pre.com に設定します。 PBDOM_ATTRIBUTE にオーナー PBDOM_ELEMENT がまだ割り当て られていないので、bVerifyNamespace 引数を FALSE に設定します。こ れにより、事前に宣言された名前空間の信頼確認が失敗します。テキ スト値を 456 に設定します。child1 要素には、接頭辞 pre1 が示すよう に、名前空間 http://www.pre.com に属する a という名前の属性がすでに あります。新規の PBDOM_ATTRIBUTE は接頭辞 pre2 を使用します が、これは同じ名前空間 URI を表すので、新規の PBDOM_ATTRIBUTE を child1 に正常に設定すると、既存の pre1:a は 新規の PBDOM_ATTRIBUTE pre2:a に置き換えられます。 PBDOM_BUILDER pbdom_buildr PBDOM_DOCUMENT pbdom_doc PBDOM_ATTRIBUTE pbdom_attr string strXML = "<root xmlns:pre1=~"http://www.pre.com~" xmlns:pre2=~"http://www.pre.com~"><child1 pre1:a=~"123~"/></root>" try pbdom_buildr = Create PBDOM_BUILDER pbdom_doc = pbdom_buildr.BuildFromString (strXML) // PBDOM_ATTRIBUTE を作成し、そのプロパティを設定します。 pbdom_attr = Create PBDOM_ATTRIBUTE pbdom_attr.SetName ("a") pbdom_attr.SetNamespace ("pre2", & "http://www.pre.com", false) pbdom_attr.SetText("456") // child1 要素の取得を試み、 // 新規属性をそれに設定します。 pbdom_doc.GetRootElement(). & GetChildElement("child1").SetAttribute(pbdom_attr) pbdom_doc.SaveDocument & ("pbdom_elem_set_attribute_1.xml") catch (PBDOM_EXCEPTION except) MessageBox ("PBDOM_EXCEPTION", except.GetMessage()) end try アプリケーション テクニック 273 XML 名前空間 SaveDocument からの XML 出力は、次のようになります。 <root xmlns:pre1="http://www.pre.com" xmlns:pre2="http://www.pre.com"> <child1 pre2:a="456"/> </root> 274 PowerBuilder 第 1 5 章 グラフの操作 この章について この章では、実行時に、アプリケーションのグラフにアクセスし て変更するためのコードの記述方法について説明します。 内容 項目 グラフの使い方 グラフへのデータ表示 グラフのプロパティの修正 データのプロパティへのアクセス ポイント アンド クリックの使い方 ページ 275 277 279 281 283 グラフの使い方 PowerBuilder でグラフを表示するには、2 つの方法があります。 • データウィンドウで、データウィンドウ データ ソースから取 り出したデータを使用する方法 • ユーザ オブジェクトまたはウィンドウ内のグラフ コントロー ルで、アプリケーション コードから提供されたデータを使用 する方法 この章では、グラフ コントロールについて検討し、アプリケーショ ン コードを使用してグラフにデータを提供し、その外観を操作す る方法について説明します。 データウィンドウのグラフについての詳細は、 『データウィンドウ プログラマーズ ガイド』マニュアルと『データウィンドウ リファ レンス』マニュアルを参照してください。 ペインタにおけるグラフのデザインとグラフ プロパティの設定に ついては、PowerBuilder の『ユーザーズ ガイド』マニュアルを参 照してください。 アプリケーション テクニック 275 グラフの使い方 コードにおけるグラフ コントロールの操作 ウィンドウ内のグラフ コントロールは、使用可能 / 使用不可、表示 / 非表示を切り替えることができ、ドラッグ アンド ドロップを使用でき ます。また、グラフ コントロールのイベントおよび補助的なグラフ関 数を使用するコードも記述できます。 グラフ コントロール のプロパティ グラフにアクセスする(そしてオプションで修正する)には、実行時 にスクリプトでグラフのプロパティを操作します。グラフのプロパ ティには次の 2 種類があります。 • グラフ定義自体のプロパティ これは、グラフを作成するときにデー タウィンドウ ペインタで最初に設定するプロパティです。グラフ の種類、タイトル、軸ラベルを設定し、軸に目盛りを付けるかど うかを指定します。3D グラフの場合、これには Render 3D プロパ ティも含まれます。Render 3D プロパティは、オーバーレイではな く透明性を用いてグラフの概観を向上させ、より洗練されたもの にします。 • データのプロパティ これらのプロパティは、実行時にデータがグ ラフにロードされたときにだけ関係します。これらのプロパティ では、グラフ内の系列数(系列は実行時に作成される)、系列の横 棒または縦棒の色、系列がオーバーレイかどうか、項目の文字(項 目は実行時に作成される)などを設定します。 グラフ コントロール のイベント グラフ コントロールには、表 15-1 にリストされているイベントがあり ます。 表 15-1: グラフ コントロールのイベント Clicked DragLeave Constructor DragWithin Destructor GetFocus DoubleClicked LoseFocus DragDrop Other DragEnter RButtonDown たとえば、 (グラフが使用できる状態で)エンド ユーザがグラフをク リックしたとき、またはオブジェクトをグラフ上にドラッグしたとき に起動されるようなスクリプトを記述できます。 グラフ コントロール 用の関数 276 表 15-2 の PowerScript グラフ関数を使って、グラフのデータを操作で きます。 PowerBuilder 第 15 章 グラフの操作 表 15-2: PowerScript グラフ関数 関数 AddCategory AddData AddSeries DeleteCategory DeleteData DeleteSeries ImportClipboard ImportFile ImportString InsertCategory InsertData InsertSeries ModifyData Reset 動作内容 項目の追加 データ ポイントの追加 系列の追加 項目の削除 データ ポイントの削除 系列の削除 クリップボードからグラフにデータをコピー テキスト ファイル内のデータをグラフにコピー 文字列の内容をグラフにコピー ほかの項目の前に項目を挿入 系列内のほかのデータ ポイントの前にデータ ポイント を挿入 ほかの系列の前に系列を挿入 データ ポイントの値を変更 グラフのデータをリセット グラフへのデータ表示 この節では、空のグラフにデータを表示する方法を示します。 AddSeries 関数の使い 方 AddSeries 関数を使用して系列を作成します。AddSeries 関数の構文は次 のとおりです。 graphName.AddSeries ( seriesName ) AddSeries 関数は、作成された系列を識別する整数を返します。最初の 系列には 1、2 番目には 2 のように番号が付けられます。一般にこの番 号は、系列を操作するほかのグラフ関数の最初の引数として使用され ます。 ステラという名前の系列を作成するには、次のコードを使用します。 int SNum SNum = gr_1.AddSeries(" ステラ ") AddData 関数の使い 方 AddData 関数を使って、指定した系列にデータ ポイントを追加します。 AddData 関数の構文は次のとおりです。 graphName.AddData ( seriesNumber, value, categoryLabel ) アプリケーション テクニック 277 グラフへのデータ表示 AddData 関数の最初の引数は、PowerBuilder によってその系列に割り当 てられている番号です。したがって、上記のように変数 SNum に番号 が格納されているステラという系列に 2 つのデータ ポイントを追加す るには、次のコードを使用します。 gr_1.AddData(SNum, 12, "Q1") // 項目は Q1 です。 gr_1.AddData(SNum, 14, "Q2") // 項目は Q2 です。 系列番号の取得 FindSeries 関数を使用して、系列に割り当てられた番号を知ることがで きます。FindSeries 関数は系列番号を返します。これは、汎用関数を記 述してグラフを操作するときに便利です。 例 四半期ごとのプリンタ販売台数のグラフを作成するには、次のスクリ プトを使用してデータをグラフにします。 gr_1.Reset(All!)// グラフをリセットします。 // 最初の系列を作成し、データを表示します。 int SNum SNum = gr_1.AddSeries(" ステラ ") gr_1.AddData(SNum, 12, "Q1") // 項目は Q1 gr_1.AddData(SNum, 14, "Q2") // 項目は Q2 gr_1.Adddata(SNum, 18, "Q3") // 項目は Q3 gr_1.AddData(SNum, 25, "Q4") // 項目は Q4 // 2 番目の系列を作成し、データを表示します。 SNum = gr_1.AddSeries(" コスミック ") です。 です。 です。 です。 // 系列 1 と同じ項目を使用するため、データは // 系列 1 のデータの横に表示されます。 gr_1.AddData(SNum, 18, "Q1") gr_1.AddData(SNum, 24, "Q2") gr_1.Adddata(SNum, 38, "Q3") gr_1.AddData(SNum, 45, "Q4") // 3 番目の系列を作成し、データを表示します。 SNum = gr_1.AddSeries(" ギャラクティック ") gr_1.AddData(SNum, 44, "Q1") gr_1.AddData(SNum, 44, "Q2") gr_1.Adddata(SNum, 58, "Q3") gr_1.AddData(SNum, 65, "Q4") 278 PowerBuilder 第 15 章 グラフの操作 次に実行結果のグラフを示します。 実行時には、グラフ関数を介して、ウィンドウ内のグラフのデータを 追加、修正、または削除できます。 詳細情報 各グラフ関数についての詳細は、『PowerScript リファレンス』マニュ アルを参照してください。 グラフのプロパティの修正 ウィンドウまたはユーザ オブジェクト ペインタでグラフを定義する ときは、その動作と表示方法を指定します。たとえば、何らかのタイ トルをもつ縦棒グラフとしてグラフを定義し、数値軸を 4 つの目盛り に分割します。各入力項目は、グラフのプロパティに対応します。ど のグラフにも、グラフの種類を指定するカタログ型の属性 GraphType があります。 グラフの種類の動的な変更 グラフの種類を変更する場合、新しいグラフを正しく定義するには、 必要に応じてほかのプロパティも変更しなければなりません。 実行時にこれらのグラフ プロパティを変更するには、スクリプトでグ ラフ プロパティに値を割り当てます。たとえば、グラフ gr_emp の種 類を縦棒グラフに変更するには、次のコードを使用します。 gr_emp.GraphType = ColGraph! 実行時にグラフのタイトルを変更するには、次のコードを使用します。 gr_emp.Title = " 新しいタイトル " アプリケーション テクニック 279 グラフのプロパティの修正 グラフ要素の表示 グラフは、タイトル、凡例、および軸で構成されます。これらの要素 には、それぞれ表示プロパティがあります。これらの表示プロパティ は、grDispAttr という名前の Graph のサブオブジェクト(構造体)にプ ロパティとして格納されています。 グラフには、タイトルの文字を指定する Title プロパティがあります。 また、grDispAttr 型の TittleDispAttr プロパティには、フォントやサイ ズ、斜体などタイトル文字の特性を指定するプロパティが入っていま す。 同様に、グラフにはそれぞれプロパティを備えた 2 本の軸があります。 軸のプロパティは、grAxis という名前の Graph サブオブジェクト(構造 体)に格納されています。値の自動スケーリングの有無、大小の区分 の数、軸ラベルなどの数値軸プロパティを指定するためのプロパティ が、grAxis 型の Values プロパティに入っています。 以下にグラフのプロパティを示します。 Graph int Height int Depth grGraphType GraphType boolean Border string Title … grDispAttr TitleDispAttr, LegendDispAttr, PieDispAttr string FaceName int TextSize boolean Italic … grAxis Values, Category, Series boolean AutoScale int MajorDivisions int MinorDivisions string Label … グラフ要素の参照 表示プロパティを参照するには、ドット(.)表記を使用します。たと えば、グラフ タイトルのプロパティの 1 つに、その文字が斜体かどう かを指定するものがあります。この情報は、グラフの TitleDispAttr プ ロパティにある Boolean 型の Italic プロパティに格納されています。 280 PowerBuilder 第 15 章 グラフの操作 たとえば、グラフ gr_emp のタイトルを斜体にするには、次のコードを 使用します。 gr_emp.TitleDispAttr.Italic = TRUE また、グラフの数値軸を自動スケーリングするには、次のコードを使 用します。 gr_emp.Values.Autoscale = TRUE 数値軸のラベルの文字を変更するには、次のコードを使用します。 gr_emp.Values.Label = " 新しいラベル " 数値軸のラベル文字の位置を変更するには、次のコードを使用します。 gr_emp.Values.LabelDispAttr.Alignment = Left! グラフのプロパティの一覧については、『オブジェクトとコントロー ル』マニュアルを参照するか、またはブラウザを使用してください。 ブラウザについての詳細は、PowerBuilder の『ユーザーズ ガイド』マ ニュアルを参照してください。 データのプロパティへのアクセス 実行時に、グラフのデータに関連付けられているプロパティにアクセ スするには、PowerScript グラフ関数を使用します。データには、以下 のような種類の関数が関連付けられています。 関数の使い方 • グラフのデータに関する情報を提供する関数 • グラフからのデータを保存する関数 • データの色や模様などの表示プロパティを変更する関数 グラフ コントロール内のグラフに対する関数を呼び出すには、次の構 文を使用します。 graphControlName.FunctionName ( Arguments ) ウィンドウ内のグラフ gr_printer の項目数を取得するには、次のように します。 Ccount = gr_printer.CategoryCount() アプリケーション テクニック 281 データのプロパティへのアクセス データウィンドウにおけるグラフのさまざまな構文 次に示すように、グラフがデータウィンドウ内にある場合には、同じ 関数の構文がもっと複雑になります。 DataWindowName.FunctionName ( "graphName", otherArguments... ) 詳細については、『データウィンドウ プログラマーズ ガイド』マニュ アルを参照してください。 データの情報の取得 表 15-3 の PowerScript 関数を使用すれば、実行時にグラフ内のデータ に関する情報を取得できます。 表 15-3: 実行時に情報を取得するための PowerScript 関数 関数 受け取る情報 グラフ内の項目数 CategoryName 指定された項目番号に対応する項目名 DataCount 系列内のデータ ポイント数 FindCategory 指定された項目名に対応する項目番号 FindSeries 指定された系列名に対応する系列番号 GetData 指定された系列と位置に対応するデータ ポイント値 (GetDataValue の方が柔軟性が高い) GetDataLabelling DirectX 3D グラフ内のデータポイントのデータがラ ベル付けされているかどうか GetDataPieExplode 円グラフのスライスを突出させる割合 GetDataStyle 指定されたデータ ポイントの色や模様など表示関係 のプロパティ GetDataTransparency DirectX 3D グラフ内のデータポイントの透明度の値 GetDataValue 指定された系列と位置に対応するデータ ポイント値 GetSeriesLabelling DirectX 3D グラフ内のデータ系列にラベルがあるか どうか GetSeriesStyle 指定された系列の色や模様などの表示関係のプロパ ティ GetSeriesTransparency DirectX 3D グラフ内のデータ系列の透明度の値 ObjectAtPointer マウスがクリックされたときにポイントされている グラフの要素 SeriesCount グラフ内の系列数 SeriesName 指定された系列番号に対応する系列名 CategoryCount 282 PowerBuilder 第 15 章 グラフの操作 グラフのデータの保存 表 15-4 の PowerScript 関数を使って、グラフからのデータを保存でき ます。 表 15-4: グラフのデータの保存に使用する PowerScript 関数 関数 Clipboard SaveAs 動作内容 指定されたグラフのビットマップ イメージをクリッ プボードにコピー 基になるグラフ内のデータをクリップボードまたは さまざまな書式のファイルに保存 色や模様、そのほかのデータの修正 表 15-5 の PowerScript 関数を使って、グラフ内のデータの表示方法を 修正できます。 表 15-5: データの表示を修正するための PowerScript 関数 関数 ResetDataColors SetDataLabelling SetDataPieExplode SetDataStyle SetDataTransparency SetSeriesLabelling SetSeriesStyle SetSeriesTransparency 動作内容 指定されたデータ ポイントの色をリセット DirectX 3D グラフ内のデータポイントにラベルを設 定 円グラフ内のスライスを突出させる 指定されたデータ ポイントの色や模様などの表示関 係のプロパティを設定 DirectX 3D グラフ内のデータポイントに透明度の値 を設定 DirectX 3D グラフ内の系列にラベルを設定 系列の色や模様などの表示関係のプロパティを設定 DirectX 3D グラフ内の系列に透明度の値を設定 ポイント アンド クリックの使い方 エンド ユーザは、実行時にグラフをクリックできます。PowerScript に は、何がクリックされたかという情報を格納する ObjectAtPointer 関数が あります。この関数は、Clicked イベントにおいてさまざまな方法で使 用できます。たとえば、グラフ内のデータ値をポイント アンド クリッ クして、メッセージ ボックス内にその値に関する情報を表示する機能 を付けることができます。この節では、その方法について説明します。 アプリケーション テクニック 283 ポイント アンド クリックの使い方 Clicked イベントとグ ラフ 284 エンド ユーザがグラフをクリックしたときにアクションが起動する ように、グラフのコントロールに Clicked スクリプトを記述します。コ ントロールが有効でなければ、Clicked イベントは発生しません。 PowerBuilder 第 15 章 ObjectAtPointer 関数 の使い方 グラフの操作 ObjectAtPointer 関数の構文は、以下のとおりです。 graphName.ObjectAtPointer ( seriesNumber, dataNumber ) ObjectAtPointer 関数は、Clicked イベントの最初のステートメントで呼 び出さなければなりません。 呼び出された ObjectAtPointer 関数は、3 つのことを行います。 • クリックされたオブジェクトの種類を、カタログ値 grObjectType として返します。たとえばエンド ユーザがデータ ポイントをク リックした場合、ObjectAtPointer 関数は TypeData! を返します。エ ンド ユーザがグラフのタイトルをクリックした場合には、 ObjectAtPointer 関数は TypeTitle! を返します。 grObjectType のカタログ値をすべて閲覧するには、ペインタバーの [オブジェクト ブラウザ]をクリックして、ブラウザを開いて[カ タログ データ型]タブを選択してください。 • ポインタが置かれた系列の番号を、変数 seriesNumber に格納しま す。これは参照によって渡される引数です。 • データ ポイントの番号を、変数 dataNumber に格納します。これも 参照によって渡される引数です。 系列番号とデータ ポイント番号を取得したら、そのほかのグラフ関数 を使って情報を取得または提供できます。たとえば、クリックされた データ ポイントの値を、エンド ユーザにレポートします。 例 ウィンドウに gr_sale というグラフがあるとします。gr_sale の Clicked イベントに対して次のようなスクリプトを記述すると、以下のような メッセージ ボックスが開きます。 • • エンド ユーザが系列をクリックすると(つまり ObjectAtPointer 関数 が TypeSeries! を返すと) 、クリックした系列の名前がメッセージ ボッ クスに表示されます。このスクリプトでは、SeriesName 関数を使っ て、ObjectAtPointer 関数によって格納されている系列番号に対応す る系列名を取得します。 エンド ユーザがデータ ポイントをクリックすると(つまり ObjectAtPointer 関数が TypeData! を返すと) 、クリックされた系列 の名前と値のリストがメッセージ ボックスに表示されます。この スクリプトでは、GetData 関数を使って、データの系列番号とデー タ ポイント番号に対応するデータ値を取得します。 int SeriesNum, DataNum double Value grObjectType ObjectType string SeriesName, ValueAsString アプリケーション テクニック 285 ポイント アンド クリックの使い方 // 次の関数は、クリックされた系列の番号を // SeriesNum に格納し、クリックされたデータ ポイント // の番号を DataNum に格納します。 ObjectType = & gr_sale.ObjectAtPointer (SeriesNum, DataNum) IF ObjectType = TypeSeries! THEN SeriesName = gr_sale.SeriesName (SeriesNum) MessageBox(" グラフ ", & SeriesName + " の系列がクリックされました。") ELSEIF ObjectType = TypeData! THEN Value = gr_sale.GetData (SeriesNum, DataNum) ValueAsString = String(Value) MessageBox(" グラフ ", & gr_sale.SeriesName (SeriesNum) + & " の値は " + ValueAsString + " です。") END IF 286 PowerBuilder 第 1 6 章 リッチテキストの作成方法 この章について この章では、リッチテキスト データウィンドウ オブジェクトと リッチテキスト エディット コントロールにおける、リッチテキス トの使い方について説明します。 内容 はじめに 項目 アプリケーションにおけるリッチテキストの使い方 リッチテキスト データウィンドウ オブジェクトの使い方 リッチテキスト エディット コントロールの使い方 リッチテキストとエンド ユーザ ページ 287 289 292 311 この章は、PowerBuilder の『ユーザーズ ガイド』マニュアルで解 説されている、リッチテキスト データウィンドウ オブジェクトと リッチテキスト エディット コントロールの作成方法を知ってい ることを前提としています。リッチテキスト提示様式を持たない データウィンドウ オブジェクトでのリッチテキスト編集様式の使 用方法の詳細については、 『ユーザーズ ガイド』マニュアルの「デー タの表示と検証」の章を参照してください。 アプリケーションにおけるリッチテキストの使い方 リッチテキスト形式(RTF)は、1 つの ASCII 文書中に書式や文書 内容を指定するテキストファイルの標準形式です。リッチテキス ト フォーマットをサポートするエディタは、フォーマット命令を 解釈しフォーマットしたテキストを表示します。 アプリケーションでは、たとえば以下のような処理が可能です。 • リッチテキスト文書の作成用のウィンドウを表示する 本格的なワープロ機能ではありませんが、リッチテキスト エ ディット コントロールを使用することによってエンド ユーザ は、段落、単語、および文字に書式を設定することができます。 • アプリケーション テクニック 差し込み印刷をする 287 アプリケーションにおけるリッチテキストの使い方 開発者またはエンド ユーザは、データベース カラムに関連付けら れた入力フィールドを使用して、文書を作成できます。 • 書式付きテキストのレポートを表示する リッチテキスト データウィンドウ オブジェクトは、基本的に、 データ入力よりもデータ表示のために使用されるオブジェクトで す。ほかの提示様式と異なり、データウィンドウ提示様式では編 集様式は使用できません。 • リッチテキストを String 型のデータとしてデータベースに格納し、 リッチテキスト エディット コントロールで表示させる リッチテキストの作成 ワード プロセッサ リッチテキスト形式のファイルを保存またはエクスポートできるワー ド プロセッサを使用して、リッチテキストを作成できます。 PowerBuilder だけの 入力フィールド 多くのワードプロセッサではなんらかの種類のフィールドをサポート していますが、通常それらのフィールドはほかのリッチテキストと互 換 性 が あ り ま せ ん。PowerBuilder ア プ リ ケ ー シ ョ ン に お い て 入 力 フィールドを指定するには、PowerBuilder のリッチテキスト エディッ ト コントロールを使用してフィールドを挿入しなければなりません。 データベースにおける リッチテキスト リッチテキストは ASCII 文字によって表現されているため、データ ベースの String 型カラムや文字列変数に格納することもできます。デー タベースの String 型カラムからリッチテキストを取得し、PasteRTF 関 数を使用してリッチテキスト エディット コントロールに書式付きテ キストを表示できます。 リッチテキスト アプリケーションの配布 リッチテキスト アプリケーションをサーバあるいはクライアント マ シンに配布する場合は、Sybase\Shared\PowerBuilder\RTC ディレクト リにあるリッチテキスト DLL ファイルおよび OCX ファイルを、配布 マシンの PowerBuilder VM ディレクトリあるいはアプリケーションの パスのディレクトリにもコピーする必要があります。748 ページの 表 37-5 に、コピーする必要があるファイルのリストを記載していま す。 288 PowerBuilder 第 16 章 リッチテキストの作成方法 PowerBuilder ランタイム パッケージャを使用して、アプリケーション とともに必要なリッチテキスト ファイルを配布することができます。 しかし、配布マシンにおいて tp4ole13.ocx ファイルを登録する必要も あります。 ランタイム パッケージャの詳細については、737 ページの「PowerBuilder ランタイム パッケージャ」を参照してください。 リッチテキスト データウィンドウ オブジェクトの使い方 この節では、以下の項目について説明します。 ページ スクロール • ほかの提示様式とのページ スクロールの違い • 新しい行におけるデフォルト値と入力条件則 • エンド ユーザが変更を行ったときの動作 リッチテキスト データウィンドウ オブジェクトでは、複数ページの リッチテキスト(文書テンプレート)を作成でき、1 行のデータが複 数ページにまたがることもあります。これに対して、ほかの提示様式 では、1 ページに複数行のデータが表示されることもあります。 リッチテキスト データウィンドウ オブジェクトでは、1 ページの構成 がほかの提示様式と異なるため、スクロール関数はほかの提示様式と は異なる動作をします。 • ScrollNextRow 関数と ScrollPriorRow 関数は、データベース テーブル の行から行へと移動するので、リッチテキスト(文書テンプレー ト)内において、前の行または次の行のデータを表示します。 • ScrollNextPage 関数と ScrollPriorPage 関数は、行ではなく、文書の ページをスクロールします。 改ページ スクロールすると、行から行へと移動します。文書の最終 ページで次ページへスクロールすると、次の行の最初のページへ移動 します。ユーザは、文書内の多くのインスタンスでスクロールの効果 を利用することができます。 新しい行 : デフォルト のデータと入力条件則 入力フィールドに値がない場合、入力フィールドは非表示になります。 入力フィールドが見えるように、データが検索される前は、入力フィー ルドには疑問符(??)が表示されます。新しい行に対しては、カラム のデータ型を基に入力フィールドに初期値が設定されます。 アプリケーション テクニック 289 リッチテキスト データウィンドウ オブジェクトの使い方 カラムにすでに初期値が設定されている場合は、その値が使用されま す。初期値が設定されていない場合、PowerBuilder は、String 型のカラ ムに対しては空白文字(スペース)を、numeric 型のカラムに対しては ゼロを初期値として設定します。 入力条件則エラー PowerBuilder で提供されるデフォルトの初期値が入 力条件則を満たさない場合、新しい行が挿入された直後にエンド ユー ザに入力条件則エラーが表示されます。これを回避するためには、入 力条件則に合う初期値を指定する必要があります。 エンド ユーザによる 変更 リッチテキストオブジェクト プロパティ シートの[全 般]タブ ページで[編集禁止]チェックボックスをオンにすると、エ ンド ユーザはデータおよびテキストを一切変更できなくなります。 編集禁止の指定 [ポップアップ メニュー]チェックボックスをオンにした場合は、エ ンド ユーザはプロパティ シートを開くことができるので、 [編集禁止] チェックボックスをオフにして、データウィンドウ オブジェクトを編 集可能にすることができます。 入力フィールド 編集可能なデータウィンドウでは、エンド ユーザは入 力フィールドのプロパティ シートを表示し、 [データ値]テキストボッ クスを編集して、カラム入力フィールドの値を変更します。計算フィー ルドに対応する入力フィールドの場合、 [データ値]テキストボックス は変更できません。 データのかわりに入力フィールド名を表示させることができます。 データのかわりに入力フィールド名を表示して、エンド ユーザが独自 にリッチテキスト データウィンドウを作成できる編集環境を提供す ることもできます。しかし、エンド ユーザに編集環境を提供したい場 合は、リッチテキスト データウィンドウよりも、スクリプトで制御で きるリッチテキスト エディット コントロールを使用する方が適して います。 エンド ユーザがテキストまたは書式を変更した場合 は、文書テンプレートが変更されたことになります。変更はすべての 行に現れます。 リッチテキスト 文書テンプレートに対する変更を保存するスクリプトを記述しておか ないと、エンド ユーザが行った変更は現行のセッションだけに適用さ れ、次回まで保持されません。 290 PowerBuilder 第 16 章 リッチテキストの作成方法 変更を保存するには、CopyRTF 関数を使用します。この関数は、入力 フィールドを含むすべてのテキストを取得しますが、行データは取得 しません。その後、取得した文字列をファイルまたはデータベースに 保存します。これによって、エンド ユーザがリッチテキスト データ ウィンドウを操作するときに、前回の変更点を復元して表示させたり、 オリジナルの文書テンプレートに戻して表示させたりすることができ ます。 リッチテキスト デー タウィンドウにおける 関数 データウィンドウ コントロールには、数多くの関数があります。 Update 関数や Retrieve 関数のようなデータ操作関 数は、すべての提示様式のデータウィンドウ オブジェクトに対して同 様に動作します。 同様に動作する関数 コントロール内のオブジェクトがリッチテキスト データウィンドウ オブジェクトである場合には、一部の関数は適用されないか、異なる 動作を行います。 適用されない関数 関数の中には、リッチテキスト データウィンドウ オ ブジェクトでは使用できないものもあります。以下の関数は、エラー を返すか、または何も処理を行いません。 • グラフとクロスタブ データウィンドウ オブジェクトのための関数 • グループ化のための関数 : GroupCalc、FindGroupChange • コード表のための関数 : GetValue、SetValue • 行選択のための関数 : SelectRow、SetRowFocusIndicator、 GetSelectedRow • カラムと詳細区域の表示形態を指定するための関数 : SetBorderStyle、 SetDetailHeight • ObjectAtPointer • OLEActivate リッチテキスト データウィンドウの場合に異な る動作をする関数もあります。 異なる動作をする関数 • クリップボードのための関数 : Copy、Clear など • 編集可能なテキストのための関数(ほかの提示様式のエディット コントロールに適用されます): LineCount、Position、SelectText など • Find と FindNext 関数(一般的なデータウィンドウの Find 関数か、 リッチテキストの Find 関数かは、Find 関数に指定する引数によっ て決まります) • ページ スクロール アプリケーション テクニック 291 リッチテキスト エディット コントロールの使い方 リッチテキスト エディット コントロールの使い方 ウィンドウまたはユーザ オブジェクト上に配置したリッチテキスト エディット コントロールを使用して、エンド ユーザに、書式設定され た テ キ ス ト を 参 照 さ せ た り、編 集 さ せ た り す る こ と が で き ま す。 PowerScript 関数を使用して、テキストの挿入、選択されたテキストの 取得、入力フィールドの管理、内容のプロパティ設定などを行って、 コントロールの内容を操作できます。 ウィンドウ ペインタまたはユーザ オブジェクト ペインタで、リッチ テキスト エディット コントロールを定義します。 エンド ユーザに制御権を与える ウィンドウまたはユーザ オブジェクト ペインタでは、リッチテキスト エディット コントロールのプロパティ シートの[ドキュメント]ペー ジで、表 16-1 の機能を使用可能または使用不可に設定できます。 表 16-1: リッチテキスト エディット コントロールの機能 機能 編集用バー ポップアップ メ ニュー 印刷されない文字の 表示 フィールドの表示 自動ワードラップ 余白 詳細 書式設定のツールバー、ルーラ バー、およびステー タス バー プロパティシートや、ファイルの挿入、クリップボー ド コマンドが使用可能 キャリッジ リターン、タブ文字、および半角スペー ス フィールドの表示 / 非表示、フィールド名で表示す るかデータを表示するかどうか。フィールドの背景 色を変更することもできる 新たに入力されたテキストだけに影響する 既存の段落に新しいテキストを入力すると、テキス トは、コントロールの右端に達したときにワード ラップされる。コントロールがサイズ可変の場合 は、コントロールのサイズを少し縮小することに よって、既存のテキストをワードラップさせること ができる 印刷余白をデフォルトのページ サイズにあわせて 設定できる また、印刷キューに表示される文書の名前を設定することもできます。 文書名は、コントロールに挿入するテキスト ファイルとは関係ありま せん。 292 PowerBuilder 第 16 章 エンド ユーザによる プロパティの変更 リッチテキストの作成方法 エンド ユーザは、プロパティ シートを使用して、リッチテキスト文書 のプロパティを設定できますが、開発者が望まない操作を行う可能性 もあります。たとえば以下のような操作を行ってしまうかもしれませ ん。 • 上書き禁止に設定してある文書の[編集禁止]オプションをオフ にして、文書を編集する • ツール バー、ルーラ、ステータス バーを非表示にする • データではなく入力フィールド名を表示する • ポップアップ メニューを使用不可にしたため、非表示にしたツー ルを元に戻すことができなくなる このような操作ミスを防ぐために、スクリプトでプロパティ値を変更 することができます。たとえば、以下のステートメントはイベント ス クリプトで発生した時に、ポップアップ メニューを元に戻すことがで きます。 rte_1.PopMenu = TRUE 変更の取り消し エンド ユーザが〔Ctrl〕+〔Z〕を押すと、変更は取り消されます。ま た、コマンドボタンやメニュー項目のスクリプトから Undo 関数を呼び だすこともできます。 Undo 関数が繰り返し呼ばれた場合は、最大 50 までの変更を取り消し ます。スクリプトで CanUndo 関数を呼び出すと、元に戻せる変更があ るかどうか(最大数に達していないことを意味します)をチェックす ることができます。 IF rte_1.CanUndo() THEN rte_1.Undo() ELSE MessageBox(" 停止 ", " 元に戻せる操作がありません ") END IF リッチテキスト エディット コントロールのためのテキスト ウィンドウ ペインタでは、リッチテキスト エディット コントロール にテキストを入力することはできません。そのかわり、アプリケーショ ンにおいて、スクリプトからテキストを挿入したり、エンド ユーザに テキスト入力をさせたりすることができます。 アプリケーション テクニック 293 リッチテキスト エディット コントロールの使い方 デフォルト フォントの設定 リッチテキスト エディット コントロールのプロパティ ビューの[フォ ント]タブ ページで、コントロールのデフォルト フォントを設定でき ます。実行時にコントロールが最初に表示され、リッチテキスト エ ディット コントロールと一緒にツールバーを含める場合、ツールバー は設計時に[フォント]タブ ページで選択したデフォルトフォントで 表示されます。アプリケーション ユーザは実行時にフォントを変更し たり、PowerScript を使用してフォント スタイルを変更したりできます が、設計時のみデフォルト フォントを設定できます。 テキストの挿入 ファイルから挿入 InsertDocument 関数を使用して、アプリケーションに テキスト ファイルを挿入することができます。挿入できるファイル は、リッチテキスト形式または ASCII 形式です。 li_rtn = rte_1.InsertDocument & ("c:\mydir\contacts.rtf", FALSE, FileTypeRichText!) Boolean 型の clearflag 引数によって、ファイルを挿入するのか、既存 のテキストと置き換えるのかを指定できます。挿入する文書のヘッダ およびフッタを含めたい場合は、clearflag 引数に TRUE を設定して既 存のテキストを置き換える必要があります。 (実行時ポップアップ メ ニ ュ ー の InsertFile コ マ ン ド は、clearflag 引 数 に FALSE を 設 定 し た InsertDocument 関数と同じです。 ) DisplayOnly プロパティには false を設定 リッチテキスト コントロールの DisplayOnly プロパティに true が設定 されている場合は、リッチテキスト コントロールにドキュメントを挿 入することはできません。これを行おうとすると、PowerBuilder はラ ンタイム エラー メッセージを表示します。 データベースから挿入 データベースに文字列としてリッチテキストを 保存した場合、データストア オブジェクトを使用してテキストを取得 することができます。 以下のスクリプトは、データベースからテキストを取得して、リッチ テキスト エディット コントロールに貼り付けます。 ls_desc = dw_1.Object.prod_desc.Primary[1] rte_1.PasteRTF(ls_desc) 294 PowerBuilder 第 16 章 リッチテキストの作成方法 リッチテキストとクリップボード CopyRTF 関数と PasteRTF 関数は、書式指示とともにリッチテキストを 取得して、文字列に格納します。Copy、Cut、および Paste 関数でクリッ プボードを使用すると、テキストしか取得できないため、書式指示は 失われてしまいます。 データベースにリッチ テキストを保存する例 たとえば、テクニカル サポートにかかってくる電話の内容を、データ ベース テーブルに記録しているものとします。フィールドには、電話 がかかってきた日付、サポート エンジニア名、顧客名を記録します。 別のフィールドでは、内容についてのメモを格納します。リッチテキ ストを使用すると、エンド ユーザに書式付きのメモを記録させること ができます。単純なテキストではなくリッチテキストを使用すること によって、太字や斜体で強調させることができます。 編集用のウィンドウは、以下のコントロールから構成されます。 • すべてのデータを検索して、電話メモを除くすべてのデータを表 示するデータウィンドウ コントロール • 電話メモを表示するリッチテキスト エディット コントロール • データベースを更新するためのコマンドボタン RowFocusChanged イベント RowFocusChanged イベントにスクリプト を記述して、フォーカスが移動しても、常に現行の行の電話メモをリッ チテキスト エディット コントロールに表示させます。 string ls_richtext // call_notes カラムから文字列を取得します。 ls_richtext = dw_1.Object.call_notes[currentrow] // 点滅を防止します。 rte_1.SetRedraw(FALSE) // 現行の行のテキストで古いテキストを置き換えます。 rte_1.SelectTextAll() rte_1.Clear() rte_1.PasteRTF(ls_richtext) rte_1.SetRedraw(TRUE) LoseFocus イベント LoseFocus イベントに以下のスクリプトを記述し て、エンド ユーザが変更したテキストを、データウィンドウ コント ロールに転送します。LoseFocus イベントは、エンド ユーザがテキス トの編集を終えて、コマンドボタンまたはデータウィンドウを選択し たときに起動されます。 アプリケーション テクニック 295 リッチテキスト エディット コントロールの使い方 string ls_richtext long l_currow GraphicObject l_control // リッチテキスト エディット コントロールに // フォーカスが残っているかどうかを確認します。 // フォーカスが残っている場合は、テキストを転送しません。 l_control = GetFocus() IF TypeOf(l_control) = RichTextEdit! THEN RETURN 0 // 点滅を防止します。 rte_1.SetRedraw(FALSE) // 文字列 ls_richtext にすべてのテキストを格納します。 ls_richtext = rte_1.CopyRTF() // 現行の行の call_notes カラムに // リッチテキストを割り当てます。 l_currow = dw_1.GetRow() dw_1.Object.call_notes[l_currow] = ls_richtext rte_1.SetRedraw(TRUE) LoseFocus イベントとツールバー エンド ユーザがツールバーを選択したときも、LoseFocus イベントが 起動されます。ツール バーは、リッチテキスト エディット コントロー ルとは別のコントロールとして作成されているからです。しかし、リッ チテキスト エディット コントロールにはフォーカスが残っているた め、GetFocus 関数を使用して、ツールバーがクリックされたのかどう かを確認することができます。 ファイルにリッチテキ ストを保存 SaveDocument 関数を使用すると、 入力フィールドの定義とともに、リッ チテキスト エディット コントロール内のリッチテキストを保存する ことができます。保存するファイルの種類として、リッチテキスト形 式(RTF)または ASCII 形式を指定することができます。 rte_1.SaveDocument("c:\...\contacts.rtf", & FileTypeRichText!) SaveDocument 関数は、入力フィールドのデータは保存しません。文書 テンプレートを保存します。 296 PowerBuilder 第 16 章 リッチテキストの作成方法 同名のファイルが存在する場合 フ ァ イ ル が 既 に 存 在 す る 場 合 は、 SaveDocument 関 数 を 呼 ぶ と FileExists イ ベ ン ト が 起 動 さ れ ま す。 FileExists イベントのスクリプトで、エンド ユーザにファイルを上書き するかどうかを問い合わせることができます。 保存処理をキャンセルするには、FileExists イベントのスクリプトでリ ターン コードの 1 を指定します。 Modified プロパティは、リッチテキス ト エディット コントロールの文書が変更されたかどうかを示します。 また、文書が保存されていない状態であることも示します。最初の変 更で Modified イベントが起動されて、Modified プロパティに TRUE が 設定されます。SaveDocument 関数を呼ぶと、文書が保存され、Modified プロパティに FALSE が設定されます。 保存する必要のある変更があるか ファイルをリッチテキスト エディット コントロールに挿入すると、 リッチテキスト エディット コントロールの文書が変更されるので、 Modified イベントが起動されて Modified プロパティに TRUE が設定さ れます。しかし通常の場合、本当に知りたいのはファイルの内容がコ ントロールの内容に対応しているかどうかです。この点を確認するた めには、ファイルを開くスクリプトで、Modefied プロパティを FALSE に設定します。エンド ユーザが文章を編集すると Modified イベントが 起動され、Modified プロパティに TRUE が設定されるので、コントロー ルの文書の内容とファイルの内容が一致していないことがわかりま す。 アプリケーション テクニック 297 リッチテキスト エディット コントロールの使い方 ファイルを開いて保存する例 ファイルを開いたり保存したりするスクリプトの例を示します。エン ド ユーザは、既存のファイルを開いて、リッチテキスト エディット コ ントロールで文書を変更して保存することができます。また、文書を ファイルに保存することもできます。エンド ユーザが開いたファイル に文書を保存する場合は、ファイルの上書きは確認されずにそのまま 保存されます。既存のファイルと同名のファイル名で保存しようとす ると、ファイルの上書きを確認するメッセージボックスが表示されま す。 この例では、インスタンス変数の宣言、スクリプト、関数、イベント について解説します。 インスタンス変数の宣 言 ib_saveas FileExists イベントのためのフラグ。FALSE の場合は、エン ド ユーザが開いたファイルに保存しようとしているため、ファイルは 上書きされます。 boolean ib_saveas=FALSE is_filename 現行ファイル名。初期状態では「タイトル未設定」と設 定されます。 string is_filename ファイルを開くための スクリプト 298 以下のスクリプトは、エンド ユーザが選択したファイルを開きます。 ファイルを開くときに Modified イベントが起動されて Modified プロ パティが TRUE に設定されるので、スクリプトで Modified プロパティ を FALSE にリセットしています。 [変更]チェックボックスの Checked プロパティも、FALSE に設定されています。 PowerBuilder 第 16 章 リッチテキストの作成方法 integer li_answer, li_result string ls_name, ls_path li_answer = GetFileOpenName("Open File", ls_path, & ls_name, "rtf", & "Rich Text(*.RTF),*.RTF, Text files(*.TXT),*.TXT") IF li_answer = 1 THEN // エンド ユーザが、キャンセルしませんでした。 li_result = rte_1.InsertDocument(ls_path, TRUE) IF li_result = 1 THEN // 文書が正常に開かれました。 // 保存して、ファイル名を表示します。 is_filename = ls_path st_filename.Text = is_filename // 保存して、文書の変更状況を表示します。 rte_1.Modified = FALSE cbx_modified.Checked = rte_1.Modified ELSE MessageBox(" エラー ", " ファイルが開かれていません ") END IF END IF RETURN 0 文書を保存するための スクリプト エンド ユーザが文書を保存できるように、 [上書き保存]ボタンと[名 前を付けて保存]ボタンを用意します。また、必要に応じてメニュー 項目も作成し、同じスクリプトを記述します。 [上書き保存]ボタンの スクリプトでは、インスタンス変数 is_filename に正しいファイル名が 保持されているかどうかをチェックします。正しいファイル名であっ た場合は、of_save 関数へそのファイル名を渡します。無効なファイル 名の場合は、[名前を付けて保存]ボタンの Clicked イベントのスクリ プトを起動します。 integer li_result string ls_name // ファイル名が無効な場合は、ファイル名を取得します。 IF is_filename = " タイトル未設定 " THEN cb_saveas.EVENT Clicked() ELSE li_result = Parent.of_save(is_filename) END IF アプリケーション テクニック 299 リッチテキスト エディット コントロールの使い方 RETURN 0 FileExists イベントが起動された時に、ファイルの上書きの確認メッ セージを表示するために、[名前を付けて保存]ボタンの Clicked イベ ントのスクリプトで、インスタンス変数 ib_saveas に TRUE を設定しま す。このスクリプトでは、of_save 関数にファイル名を渡す前に、ファ イル名を取得するために of_getfilename 関数を呼びます。 integer li_result string ls_name ib_saveas = TRUE ls_name = Parent.of_getfilename() // エンド ユーザがキャンセルをしたか、エラーが発生した場合は、 // 中断させます。 IF ls_name = "" THEN RETURN -1 li_result = Parent.of_save(ls_name) ib_saveas = FALSE RETURN 0 ファイル名の保存と取 得を行う関数 of_save 関数 of_save 関数は、ファイル名を引数として受け取り、その ファイルに文書を保存します。また、保存したファイル名をインスタ ンス変数 is_filename に設定し、SaveDocument 関数を正常に呼び出せた 後は、自動的に FALSE に設定される Modified プロパティに対応するよ うに、[変更]チェックボックスの値を設定します。 integer li_result MessageBox(" ファイル名 ", as_name) // 拡張子が正しい種類の保存を起動するので、 // ファイルの種類は必要ありません。 li_result = rte_1.SaveDocument(as_name) IF li_result = -1 THEN MessageBox(" 警告 ", " ファイルは保存されませんでした ") RETURN -1 ELSE // ファイルが正常に保存された場合。 is_filename = as_name st_filename.Text = is_filename cbx_modified.Checked = rte_1.Modified RETURN 1 END IF 300 PowerBuilder 第 16 章 リッチテキストの作成方法 of_getfilename 関数 of_getfilename 関数では、エンド ユーザに対して ファイル名を入力するためのプロンプトを表示し、ユーザの選択した ファイル名を戻します。この関数は、ファイル名がまだ指定されてい ない場合、またはエンド ユーザが[名前を付けて保存]ボタンを選択 した場合に呼ばれます。 integer li_answer string ls_name, ls_path li_answer = GetFileSaveName(" 文書名 ", ls_path, & ls_name, "rtf", & "Rich Text(*.RTF),*.RTF, Text files(*.TXT),*.TXT") IF li_answer = 1 THEN // 指定したファイル名を戻します。 RETURN ls_path ELSE RETURN "" END IF 保存して閉じるための イベント エンド ユーザが指定したファイルが既に存在して いる場合に、警告メッセージを表示し、保存の取り消しができるよう にします。SaveDocument 関数がファイルを保存しようとして、ファイ ルが既に存在している場合に、FileExists イベントが起動されます。こ のスクリプトでは、変数 ib_saveas が TRUE かどうかを確認し、TRUE の場合はファイルの上書きを問い合わせます。 FileExists イベント integer li_answer // 現行のファイルを上書き保存する場合は、 // ファイルの上書きを確認するプロンプトは表示されません。 IF ib_saveas = FALSE THEN RETURN 0 li_answer = MessageBox(" ファイルが存在 ", & filename + " はすでに存在します。上書きしますか ?", & Exclamation!, YesNo!) // ゼロでない値を戻せば、保存がキャンセルされます。 IF li_answer = 2 THEN RETURN 1 チェックボックスに値を設定し、エンド ユー Modified イベント [変更] ザに、文書の変更が保存されていないことを表示します。Modified プ ロパティは、Modified イベントが起動されたときに自動的に設定され ます。リッチテキスト エディット コントロールの文書が変更されたと きに、Modified イベントが起動されます。 cbx_modified.Checked = TRUE アプリケーション テクニック 301 リッチテキスト エディット コントロールの使い方 保存されていない変更があるかどうかをチェッ クして、ウィンドウを閉じる前に文書の保存を確認するメッセージ ボックスを表示します。 CloseQuery イベント integer li_answer // 保存されていない変更があるかどうか。なければ、終了します。 IF rte_1.Modified = FALSE THEN RETURN 0 // 文書の保存の確認を、エンド ユーザに求めます。 li_answer = MessageBox(" 文書が保存されていません ", & " 次の文書を保存しますか ?" + is_filename, & Exclamation!, YesNo! ) IF li_answer = 1 THEN // エンド ユーザが、文書を保存する場合 // [上書き保存]ボタンの Clicked イベントを起動します。 cb_save.EVENT Clicked() END IF RETURN 0 ActiveX スペル チェック コントロールの使用 ActiveX コントロールをリッチテキスト エディット コントロール内の テキストをスペル チェックするために使用することができます。サ ポートする ActiveX スペル チェック コントロールは、ComponentOne の VSSpell および Wintertree Software の WSpell です。 リッチテキスト エディット コントロールの SelectedStartPos プロパ ティおよび SelectedTextLength プロパティを使用して、サポートする ActiveX スペル チェック コントロールで解析しているテキスト文字列 内でスペルが違う単語の位置をハイライト表示することができます。 次の手順では、ActiveX コントロールを使用して、リッチテキスト エ ディット コントロールの現行領域のテキスト全体をスペル チェック します。 v リッチテキスト エディット コントロール内の選択テキストをスペル チェッ クするには 1 302 リッチテキスト エディット コントロールを持つウィンドウで、 ウィンドウ メニューから[挿入|コントロール| OLE]を選択し ます。 PowerBuilder 第 16 章 リッチテキストの作成方法 2 オブジェクトの挿入 ダイアログボックスの[コントロールの挿入] タブをクリックして、インストールされている ActiveX スペル チェック コントロールを選択して、[OK]をクリックします。 3 ウィンドウ ペインタのウィンドウ内をクリックして、ActiveX コ ントロールを挿入します。 デフォルトでは、挿入されたコントロールの名前は ole_n で、ウィ ンドウにほかの OLE コントロールがない場合は、n は 1 になりま す。 4 現行ウィンドウに関連するメニューにメニュー項目を追加し、そ のテキスト ラベルを「スペル チェック」に変更します。 5 次のコードをメニュー項目の Clicked イベントに追加します。 windowName は、リッチテキスト エディットと ActiveX コントロー ルを含むウィンドウの名前になります。 string ls_selected // 現領域のコンテキストを取得し、選択モードのままにする windowName.rte_1.selecttext(0,0,0,0) windowName.rte_1.SelectTextAll() ls_selected = windowName.rte_1.SelectedText() windowName.rte_1.SelectedTextLength = 0 // 文字列の内容を ActiveX コントロールに割り当てる windowName.ole_1.object.text = ls_selected windowName.ole_1.object.start() 6 ウィンドウ ペインタで ActiveX コントロールを選択し、コント ロールのイベント リストから ReplaceWord を選択します。 7 次のコードを ReplaceWord イベント スクリプトに追加します。 string str str = this.object.MisspelledWord rte_1.SelectedStartPos = this.object.WordOffset rte_1.SelectedTextLength = Len(str) rte_1.ReplaceText(this.object.ReplacementWord) messagebox("misspelled word", "replaced") 次にアプリケーションを実行するときに、「スペル チェック」メ ニュー項目をクリックして、リッチテキスト エディット コント ロールの現領域の内容全体をスペル チェックすることができま す。 アプリケーション テクニック 303 リッチテキスト エディット コントロールの使い方 リッチテキストの書式設定 リッチテキスト コントロールには、ユーザがアドレス指定可能なオブ ジェクトがいくつか存在します。 • 文書(リッチテキスト データウィンドウ)全体 • 選択されたテキストと段落 • 入力フィールド • ピクチャ エンド ユーザは上記のオブジェクトを選択したり、ツールバーを使用 したり、プロパティ シートを表示させたりすることができます。 開発者またはエンドユーザが入力フィールドにデータを入力したり、 DataSource を呼び出してコントロールをデータウィンドウ オブジェク トまたはデータストアに関連付けたりすることによって、入力フィー ルドは値を取得します。 入力フィールド 入力フィールドは、名前付きの値です。入力フィールドは、名前を付 けて、値を設定して使用します。値は、入力フィールド名に関連付け られます。入力フィールドがコピーされていて、同じ名前の入力フィー ルドが複数ある場合、すべての入力フィールドに同じ値が表示されま す。また、エンド ユーザが入力フィールドの値を変更すると、その変 更は、同じ名前のすべての入力フィールドに反映されます。 以下のサンプル テキストでは、入力フィールド customer をコピーして 3 箇所で使用しています。 {customer} 様 {customer} 様からご注文いただいた品が入荷されております。ま た、30 日からセールが始まりますので、{customer} 様のお知り合 いにもお声をおかけください。 スクリプトで、入力フィールド customer にデータ値を設定することが できます。 rte_1.InputFieldChangeData("customer", " 本田 ") テキストは、以下のように表示されます。 本田様 304 PowerBuilder 第 16 章 リッチテキストの作成方法 本田様からご注文いただいた品が入荷されております。また、30 日からセールが始まりますので、本田様のお知り合いにもお声を おかけください。 さらに、エンド ユーザも、データ値を設定することができます。以下 のいずれかの方法を使用します。 • 入力フィールドを選択して、新しいデータ値を入力します。 • 入力フィールド オブジェクト プロパティ シートを表示して、[全 般]タブ ページの[データ値]テキストボックスを編集します。 スクリプトで入力フィールドを挿入 InputFieldInsert 関数は、挿入ポイント に入力フィールドを挿入します。 rtn = rte_1.InputFieldInsert("datafield") たとえば、リッチテキスト編集アプリケーションで、エンド ユーザに 入力フィールドを挿入させるとします。この場合、エンド ユーザに入 力フィールド名を指定させる方法が必要です。 たとえば、エンド ユーザに、リストボックスから入力フィールド名を 選択させるとします。以下のスクリプトは、選択された入力フィール ド名を使用して、挿入ポイントに入力フィールドを挿入します。 string ls_field integer rtn ls_field = lb_fields.SelectedItem() IF ls_field <> "" THEN rtn = rte_1.InputFieldInsert( ls_field ) IF rtn = -1 THEN MessageBox(" エラー ", " フィールドを挿入できません ") END IF ELSE MessageBox(" 未選択 ", & " フィールド名を選択してください ") END IF 日付とページ番号のた めの入力フィールド v 日付やページ番号を入れて文書を印刷するには、入力フィールドを定 義して、その入力フィールドに日付やページ番号を設定します。 文書に日付を入れるには 1 テキスト中に入力フィールドを作成し、入力フィールド名を指定 します。 2 ウィンドウの Open イベントなどで、入力フィールドのデータ値に 今日の日付を設定します。 アプリケーション テクニック 305 リッチテキスト エディット コントロールの使い方 たとえば、本文に入力フィールド today が含まれている場合、入力 フィールドにデータ値を設定するスクリプトは、以下のように記述し ます。 integer li_rtn li_rtn = rte_1.InputFieldChangeData( "today", & String(Today()) ) ページ番号の設定方法については、312 ページの「エンド ユーザへの 表示」を参照してください。 データベースのデータの使い方 リッチテキスト エディット コントロールを、データウィンドウ コン トロールまたはデータストア オブジェクトと関連付けることができ ます。入力フィールド名が、データウィンドウ オブジェクトのカラム 名または計算フィールド名と一致する場合、入力フィールドはその同 じカラム名のデータを表示します。 リッチテキスト エディット コントロールにデータ ソースがあるかな いかにかかわらず、リッチテキストの内容は常に 1 つです。つまり、 文書テンプレートとしてリッチテキスト エディット コントロールの 内容を表示することができます。行から行へスクロールしているとき は、入力フィールドのデータ値だけが変更されます。 データウィンドウ オブジェクトまたはデータストア オブジェクトと データを共有するには、DataSource 関数を使用します。 rte_1.DataSource(ds_empdata) データを共有する例 データストア オブジェクト ds_empdata に関連付けられているデータ ウィンドウ オブジェクトに 4 つのカラム emp_id、emp_lname、emp_fname、 state があり、 リッチテキスト エディット コントロールには以下のよう なテキストと入力フィールドがあるとします。 従業員テーブルのカラムを含むサンプル ID: {emp_id} {emp_lname} {emp_fname} 様 : 当社の新工場が福島県に開かれます。あなたが {state} から福島県に転 勤を希望する場合は、会社がすべての経費をカバーします。 306 PowerBuilder 第 16 章 行とページの操作 リッチテキストの作成方法 リッチテキスト エディット コントロールでは、エンド ユーザはペー ジ単位で文書をスクロールすることができます。ページ単位ではなく 行単位でスクロールさせるには、そのためのコマンドボタンを追加し、 スクリプトを記述しなければなりません。 [前の行へ移動]ボタンと[次の行へ移動]ボタンを追加する必要があ ります。スクリプトは簡単です。 [次の行へ移動]ボタンでは、以下の ように記述します。 rte_1.ScrollNextRow() [前の行へ移動]ボタンでは、以下のように記述します。 rte_1.ScrollPriorRow() ページ ボタンを用意することもできます。エンド ユーザが最終ページ で次ページへスクロールすると、先頭ページの次の行に対応するデー タ値を表示します。 rte_1.ScrollNextPage() リッチテキスト エディット コントロールにおけるカーソル位置 関数を使用して、リッチテキスト エディット コントロールで選択され ている項目を取得したり、テキストを選択したりすることができます。 挿入ポイントの位置と 選択されている内容の 判定 テキストには常に挿入ポイントがあり、挿入ポイントが、選択された テキストを含むこともあります。テキストが選択されている場合、挿 入ポイントの位置は選択範囲の先頭または最後になります。テキスト を前から後ろへドラッグして選択した場合、挿入ポイントは選択範囲 の最後にあります。テキストを後ろから前へドラッグして選択した場 合、挿入ポイントは選択範囲の先頭にあります。 Position 関数は、テキストの選択範囲と挿入ポイントに関する情報を提 供します。 Position 関数についての詳細は『PowerScript リファレンス』マニュア ルを参照してください。 カーソル イメージの 変更 リッチテキスト オブジェクト プロパティ シートの[ポインタ]ペー ジには、リッチテキスト エディット コントロールまたはリッチテキス ト データウィンドウ内のカーソル位置を示すために使用できる組み 込みポインタのリスト ボックスがあります。エンド ユーザは、リッチ テキスト オブジェクト プロパティ シートでこれらのポインタの 1 つ を選択し、 [OK]をクリックして、実行時にカーソル イメージを変更 することができます。 アプリケーション テクニック 307 リッチテキスト エディット コントロールの使い方 プログラムによるテキ ストの選択 以下の関数を使用して、挿入ポイントの位置から相対的にテキストを 選択することができます。 • SelectTextWord 関数 • SelectTextLine 関数 • SelectTextAll 関数 最も一般的なテキスト選択の関数は、SelectText 関数です。テキストの 選択範囲を、最初と最後の行番号と文字番号で指定します。 Position 関数で得られる値は、テキストの選 択範囲だけではないので、その値を直接 SelectText 関数に渡すことはで きません。特に、ゼロは選択範囲を示すには意味がありますが、テキ スト選択には有効な値ではありません。 SelectText 関数へ値を渡す Position 関数についての詳細は『PowerScript リファレンス』マニュア ルを参照してください。 スペルチェックのために、1 つずつ単語を選択したい場合は、 『PowerScript リファレンス』マニュアルの SelectTextWord 関数を参照してください。 タブ順序、フォーカ ス、選択 タブ順序 ウィンドウまたはユーザ オブジェクトで、リッチテキスト エディット コントロールをコントロールのタブ順序に含めます。ただ し、リッチテキスト エディット コントロールにタブ移動した場合、 〔Tab〕を押すたびにテキストの中にタブを挿入してしまいます。リッ チテキスト コントロールから別のコントロールへは、タブ移動できま せん。その点に注意してください。 フォーカスとテキストの選択 リッチテキスト エディット コントロール を〔Tab〕を押して選択すると、コントロールがフォーカスされ、現行 の挿入ポイントまたはテキスト選択は保持されます。リッチテキスト エディット コントロールを選択してフォーカスを設定した場合は、挿 入ポイントはエンド ユーザがクリックした位置に移動します。 LoseFocus イベント エンド ユーザがリッチテキスト エディット コン トロールのツールバーを選択すると LoseFocus イベントが発生します が、リッチテキスト エディット コントロールのフォーカスは残りま す。コントロールがフォーカスを失ったかどうかを GetFocus 関数で確 認することができます。 308 PowerBuilder 第 16 章 リッチテキストの作成方法 プレビューと印刷 エンド ユーザは、リッチテキスト エディット コントロールのレイア ウトをプレビューしたり、内容を印刷したりすることができます。印 刷プレビュー モードでは、コントロールの大きさに合わせて文書の内 容が縮小されます。コントロールが小さい場合は、プレビューはとて も小さくなります。印刷プレビュー モードでコントロールを表示する 前に印刷余白やページ サイズを設定する必要があります。 印刷プレビュー モードにするには、以下のいずれかの操作を行いま す。 • エンド ユーザは、〔Ctrl〕+〔F2〕を押すことによって、編集モー ドと印刷プレビュー モードを切り換えることができます。 • スクリプトで Preview 関数を呼び出します。 rte_1.Preview(TRUE) 印刷プレビュー モードでは、上下の矢印キーおよび〔Page Up〕と〔Page Down〕を使ってコントロールのコンテンツ ページを操作できます。 印刷余白の調整 デザイン時にページ余白を設定するか、リッチテキスト コントロール のヘッダおよびフッタを有効にすると、アプリケーション ユーザは実 行時にコントロールの余白を調整することができます。ユーザは、リッ チテキスト コントロールのプロパティ シートの[印刷の仕様]タブを 開いて上下左右の余白を変更したり、PowerScript コードで余白を変更 するイベントを起動して、余白を調整したりすることができます。リッ チテキスト オブジェクト ダイアログボックスでの余白の調整は、印刷 プレビュー モードでのリッチテキスト エディット コントロールの内 容の表示にも影響します。 アプリケーション テクニック 309 リッチテキスト エディット コントロールの使い方 デザイン時にページ余白を設定しないか、それらを 0 のままにした場 合、ユーザが実行時に行う余白の変更は、印刷プレビュー モードでの み見ることができます。 ページ サイズと紙の方向の設定 デザイン時にデフォルトのページ サイズと印刷の向きを設定するこ とはできません。しかし、ユーザは実行時にリッチテキスト オブジェ クト ダイアログボックスの[印刷の仕様]タブでこれらのプロパティ を設定することができます。このダイアログボックスは標準ビューで のみ使用できます。アプリケーション ユーザがこのダイアログボック スを表示できるようにするには、リッチテキスト エディット コント ロールのポップアップ メニューを有効にする必要があります。 印刷 リッチテキスト エディット コントロールがデータウィンドウ オブ ジェクトのデータを使用している場合、データウィンドウ コントロー ルの Print.Page.Range プロパティを設定して、印刷される行の数を制限 することができます。Print.Page.Range プロパティの値は、印刷する ページ番号をリストした文字列です。ダッシュ(-)を使用して範囲を 指定できます。 たとえば、リッチテキスト エディット コントロール が、データウィンドウ コントロール dw_source のデータを共有してい るとします。リッチテキスト文書は 3 ページで、2 行目と 5 行目のデー タを印刷するとします。印刷する前に、ページ範囲のプロパティを設 定することができます。 ページ範囲の例 310 PowerBuilder 第 16 章 リッチテキストの作成方法 dw_source.Object.DataWindow.Print.Page.Range = & "4-6,13-15" さらに、行が印刷されないように、行をフィルタまたは破棄すること ができます。 詳細については、『PowerScript リファレンス』マニュアルの SetFilter、 Filter、RowsMove、RowsDiscard 関数および『データウィンドウ リファ レンス』マニュアルの Print データウィンドウ オブジェクト プロパ ティを参照してください。 スクリプトによるフッ タ テキストの挿入 以下のサンプル コードでは、フッタに挿入ポイントを設定して、2 つ の空白行、テキスト、そして 2 つの入力フィールドを挿入しています。 rte_1.SelectText(1, 1, 0, 0, Footer!) rte_1.ReplaceText("~r~n~r~nRow ") rte_1.InputFieldInsert("row") rte_1.ReplaceText(" Page ") rte_1.InputFieldInsert("page") rte_1.SetAlignment(Center!) リッチテキストとエンド ユーザ PowerBuilder の『ユーザーズ ガイド』マニュアルのリッチテキストの 使い方に関する章、およびこの章で解説した編集ツールは、エンド ユーザも使用することができます。 エンド ユーザが行え る操作 エンド ユーザが可能 な操作のスクリプトで の記述 エンド ユーザは、以下の操作を行うことができます。 • ツールバーを使用したテキストの書式設定 • ポップアップ メニューの使用(ほかのリッチテキストや ASCII ファイルを開いたり、クリップボードを使用したりできます) • 入力フィールドの内容の編集 • 編集ツールのオン / オフの切り換え エンド ユーザが以下の操作をできるように、アプリケーションを設定 することができます。 • 入力フィールドの挿入と削除 • ピクチャの挿入 • ヘッダとフッタ編集への切り換え アプリケーション テクニック 311 リッチテキストとエンド ユーザ • 印刷する文書のプレビュー リッチテキスト エディット コントロールが、データウィンドウ オブ ジェクトまたはデータストア オブジェクトとデータを共有する場合、 以下のようにスクリプトを記述することができます。 • 行から行へスクロールさせる(ページからページへスクロールさ せるスクリプトも記述できますが、その必要はありません) • 入力フィールドで変更されたデータ値をデータベースへ更新する リッチテキストを使用するアプリケーションを作成する際には、開発 者自身がエンド ユーザとなってアプリケーションを使用し、テキスト を編集してみることをお勧めします。実行時にも、編集用のすべての ツールを使用することができます。 エンド ユーザへの表 示 デフォルトの表示は本文テキストです。ヘッダとフッタのテキストお よび印刷プレビューも表示できます。ヘッダとフッタのテキストを表 示するには、デザイン時にリッチテキスト コントロールのプロパティ ビューで HeaderFooter プロパティを選択する必要があります。この値 は実行中には変更できず、デザイン時に選択した場合は、プログラム による設定によってヘッダとフッタのテキストを実行時に表示できま す。 リッチテキスト データウィンドウ オブジェクトまた はリッチテキスト エディット コントロールにおいて、メニューまたは コマンドボタンのスクリプトで ShowHeadFoot 関数を呼ぶことができ ます。ヘッダ編集パネルを表示するには、以下の関数を呼び出します。 ヘッダとフッタ dw_1.ShowHeadFoot(TRUE) フッタ編集パネルを表示するには、以下の関数を呼び出します。 dw_1.ShowHeadFoot(TRUE, FALSE) フッタに現行のページ番号を挿入する 以下のスクリプトは、フッタに現行のページ番号を挿入し、リッチ テ キスト コントロールの文書の本文にフォーカスを戻します。挿入する PAGENO フィールドの名前は必ずすべて大文字で入力します。 rte_1.ShowHeadFoot(true,false) rte_1.SetAlignment ( Center! ) rte_1.InputFieldInsert("PAGENO") rte_1.ShowHeadFoot(false,false) PAGENO フィールドは、InputFieldChangeData 呼び出しでは変更できま せん。 312 PowerBuilder 第 16 章 リッチテキストの作成方法 多重定義関数 ShowHeadFoot では、2 番目の引数の値が指定されない と、デフォルトで TRUE になります。通常の表示に戻すには、再度 ShowHeadFoot 関数を呼び出します。 dw_1.ShowHeadFoot(FALSE) 印刷プレビュー エンド ユーザは、 〔Ctrl〕+〔F2〕を押すことによって、 印刷プレビュー モードのオンとオフを切り換えることができます。ま た、スクリプトから印刷プレビュー モードを制御することもできま す。 リッチテキスト エディット コントロールでは、Preview 関数を呼び出 します。 rte_1.Preview(TRUE) リッチテキスト データウィンドウ オブジェクトでは、Preview プロパ ティを設定します。 dw_1.Object.DataWindow.Print.Preview = TRUE エンド ユーザは、以下の項目に対して書式設定をすることができま す。 テキストの構成要素と 書式設定 v • 選択されたテキスト • 段落 • ピクチャ • リッチテキスト文書全体 オブジェクトのプロパティ シートを表示するには 1 2 v 以下の操作を行って、オブジェクトを選択します。たとえば、次 のようになります。 • ドラッグするか、または編集キーを使用してテキストを選択し ます。 • ピクチャをクリックします。 • リッチテキスト文書に挿入ポイントを設定します(テキストを 選択しないように注意してください)。 ワークスペースで右クリックして、ポップアップ メニューから[プ ロパティ]を選択します。 選択された段落に書式を設定するには • アプリケーション テクニック ルーラをダブルクリックします。 または 313 リッチテキストとエンド ユーザ 〔Ctrl〕+〔Shift〕+〔S〕を押します。 リッチテキスト オブジェクトを編集禁止に設定していない限り、エン ド ユーザは入力フィールドの値を変更できます。 入力フィールドの値の 変更 v 入力フィールドの値を変更するには 1 入力フィールドをクリックして選択します。 2 ワークスペースで右クリックして、ポップアップ メニューから[プ ロパティ]を選択します。 入力フィールド オブジェクト プロパティ シートが表示されます。 3 [全般]ページの[データ値]テキストボックスを編集します。 入力フィールドにおけるデータ値の書式設定 入力フィールドに書式を設 定することができます。入力フィールドを選択している場合は、入力 フィールド オブジェクト プロパティ シートの[フォント]ページと ツールバーによって書式を設定することができます。テキストととも に入力フィールドを選択している場合は、書式設定は、入力フィール ドを含むすべてのテキストに反映されます。 エンド ユーザは、入力フィールドの個々の文字または単語に書式を設 定することはできません。入力フィールドを選択すると、入力フィー ルド全体が選択されます。 入力フィールドの挿入と削除 スクリプトを記述して、エンド ユーザに 入力フィールドを挿入させたり削除させたりすることができます。ま た、エンド ユーザは、既存の入力フィールドをコピーして貼り付ける こともできます。コピーされた入力フィールドは、すべて同じデータ 値を表示します。 書式設定のためのキー とツールバー ツールバーが表示されている場合、エンド ユーザはツールバーのボタ ンを使用してテキストの書式を設定したり、指定済みのショートカッ ト キーを使用してリッチテキスト エディット コントロール内のテキ ストの書式を設定したりできます。 リッチテキストにおける書式設定のためのショートカット キーにつ いては、PowerBuilder の『ユーザーズ ガイド』マニュアルのリッチテ キストに関する章を参照してください。 314 PowerBuilder 第 1 7 章 データ ソース間のデータ転送 この章について この章では、アプリケーションでパイプライン オブジェクトを使 用して、1 つまたは複数の転送元テーブルから新規または既存の転 送先テーブルへデータ パイプライン処理を行う方法について説明 します。 内容 サンプル アプリケーショ ン 項目 データ パイプラインについて 必要なオブジェクトの作成 パイプライン処理の前準備 パイプライン処理の開始 エラー行の処理 パイプラインの後処理 ページ 316 317 325 328 335 339 この章では、簡単な商品受注管理システムを使ってデータ パイプ ラインの使い方を説明します。データ パイプライン処理の参考例 として、Code Examples サンプル アプリケーションのデータ パイ プライン項目にあるサンプルを参照してください。 サンプル アプリケーションの使い方についての詳細は、第 1 章「サ ンプル アプリケーションの使い方」を参照してください。 アプリケーション テクニック 315 データ パイプラインについて データ パイプラインについて データ パイプラインとは、データベース テーブル間でデータを転送で きる機能です。データ パイプライン機能によって、1 つまたは複数の 転送元テーブルから、新規または既存の転送先テーブルに行をコピー できます。また、この機能によって、同一のデータベース内、複数の データベース間、または異なる DBMS 間においてもデータを移行でき ます。 データ パイプライン処理は、以下の 2 種類の用途で使用されます。 データ パイプライン 処理の用途 • 開発時のユーティリティとして PowerBuilder 開発環境での作業中に、データを移行したいことがあ ります(運用時に使用する大きなテーブルからテスト用に小さな テーブルを作成するときなど)。この場合、データ パイプライン ペインタで対話的に作業を行って、すぐにデータを移行できます。 データ パイプライン ペインタの開発環境での使い方についての 詳細は、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照 してください。 • アプリケーションにおけるデータ移行ツールとして実装するには 複数のテーブル間でデータの移行を必要とするようなアプリケー ションを構築している場合は、データ パイプライン ペインタで適 切なデータ パイプラインを設計し、パイプラインオブジェクトを 保存しておきます。これにより、アプリケーション実行時に、エ ンド ユーザにそのデータ パイプライン処理を行わせることがで きます。 データ パイプラインは、アプリケーションのさまざまな局面で利 用できます。たとえば、アプリケーションで、データベース サー バからテーブルのローカル コピーをリモート ユーザにダウン ロードさせる場合や、分散しているトランザクション テーブルの データをマスタ トランザクション テーブルにまとめる場合など です。 アプリケーションにデータ パイプラインを使用する必要がある場合 は、そのための手順を決定しなければなりません。通常は、以下の 5 段階の基本操作を行います。 基本操作の概要 v 316 アプリケーションでデータ パイプライン処理を行うには 1 パイプライン、ユーザ オブジェクト、ウィンドウなど、必要なオ ブジェクトを作成します。 2 パイプライン処理の準備を行います。 PowerBuilder 第 17 章 3 パイプライン処理を開始します。 4 エラーとなった行を処理します。 5 パイプラインの後処理をします。 データ ソース間のデータ転送 本章の後半は、以上の各操作の詳細について説明します。 必要なオブジェクトの作成 アプリケーションでデータのパイプライン処理を実装するには、以下 の種類のオブジェクトを作成する必要があります。 • パイプライン オブジェクト • ユーザ オブジェクト • ウィンドウ パイプライン オブジェクトの作成 パイプライン オブジェクトを作成して、アプリケーションで実行した いパイプラインのデータ定義やアクセス情報を指定します。パイプラ イン オブジェクトは、PowerBuilder のデータ パイプライン ペインタで 作成し、パイプライン処理に必要な特性を定義しておきます。 パイプラインの定義 データ パイプライン ペインタでは、以下の特性を指定してパイプライ ン オブジェクトを定義します。 • アクセスする転送元テーブルとテーブルから取得(検索)するデー タ(データソースにストアド プロシージャもアクセスできる) • データを転送する転送先テーブル • パイプライン操作(作成、置き換え、リフレッシュ、追加、更新) の実行 • パイプライン操作中に COMMIT を発行する頻度(n 行ごとの発行、 すべての行を転送した後で発行、またはコミットしない。この場 合、開発者がスクリプトで COMMIT 文を実行する必要がある) • パイプライン操作が終了するまでに許容されるエラーの件数 • (転送元データベースの PowerBuilder リポジトリから)転送先デー タベースに拡張属性を転送するかどうか アプリケーション テクニック 317 必要なオブジェクトの作成 データ パイプライン ペインタを使用してパイプライン オブジェクト を作成する方法についての詳細は、PowerBuilder の『ユーザーズ ガイ ド』マニュアルを参照してください。 例 データ パイプライン ペインタを使用して、pipe_sales_extract1 というパ イプライン オブジェクトを定義する方法を以下に示します(なお、 pipe_sales_extract1 は、商品受注管理システムの w_sales_extract ウィン ドウで使用される 2 つのパイプライン オブジェクトのうちの 1 つで す) 。 このパイプライン オブジェクトは、会社の販売データ ベースの社員情報(Sales-rep)テーブルと売上一覧テーブル(Salessummary)を結合して、転送元データを形成しています。転送元データ は、ある特定の四半期の行だけを検索します(アプリケーションでは、 Quarter という検索引数に割り当てられた値によって、どの四半期に関 するデータを検索するかを指定します)。 転送元のデータ パイプライン オブジェクト pipe_sales_extract1 は、各転送元テーブルか らどのカラムを転送するかを指定しています(Sales_rep テーブルから は srep_id、srep_lname、srep_fname の各カラム、さらに、Sales_summary テーブルからは ssum_quarter、ssum_rep_team の各カラム)。また、検索 時に計算してから転送する計算カラムも定義しています。この計算カ ラムでは、Sales-summary テーブルの ssum-rep-actual カラムから ssumrep-quota カラムを減算しています。 318 PowerBuilder 第 17 章 データの転送方法 データ ソース間のデータ転送 pipe_sales_extract1 が転送元データを転送する方法を 以下に示します。 このパイプライン オブジェクトが、販売成績(Quarterly-extract)とい う転送先テーブルを新規に作成するように定義していることに注意し てください。アプリケーションで、この新規テーブルを格納する転送 先データベースを指定する方法については、 (転送元テーブルのデータ ベースを指定する方法についても)後で示します。 このほか、pipe_sales_extract1 について以下の項目に注意してください。 • コミットが発行されるのは、対象となる行がすべて転送された後 のみ(つまり、パイプラインの実行が中断されると、Quarterly_extract テーブルに対する変更内容はすべてロールバックされ破棄され る) • アプリケーションで発生するエラー件数の制限はない。したがっ て、どの行でエラーが起きても、パイプラインの実行は中断され ない • 拡張属性は、転送先データベースには転送されない • Quarterly-extract テーブルの主キーは、srep-id カラムと ssum-quarter カラムから構成される複合キーである • アプリケーション テクニック アプリケーションが Quarterly-extract テーブルに作成する計算カラ ムの名前は、computed_net である 319 必要なオブジェクトの作成 ユーザ オブジェクトの作成 ここまで、パイプライン オブジェクトにパイプラインに対するデータ やアクセスを定義する方法について説明してきましたが、パイプライ ン オブジェクトには、アプリケーションで実際にパイプラインを実行 したり管理したりする際に必要となるさまざまな定義(プロパティ、 イベント、関数など)は含まれていません。 Pipeline システム オ ブジェクトについて アプリケーションでパイプライン処理を行う際に、そのアプリケー シ ョ ン で 必 要 と な る 個 別 の 定 義 を 実 装 す る に は、PowerBuilder の Pipeline システム オブジェクトを継承させたユーザ オブジェクトの作 成が必要です。表 17-1 に、実行時にアプリケーションによるオブジェ クトの管理を可能にする、Pipeline システム オブジェクトのさまざま なプロパティ、イベント、関数を示します。 表 17-1: Pipeline システム オブジェクトのプロパティ、イベント、関数 プロパティ DataObject、 イベント PipeStart、 RowsRead、 PipeMeter、 PipeEnd RowsWritten、 関数 Start、 Repair、 Cancel RowsInError、 Syntax アプリケーションにおけるこれらのプロパティ、イベント、関数の使 い方は、この章の後半で説明します。 v パイプライン処理をサポートするユーザ オブジェクトを作成するには 1 新規作成 ダイアログボックスの[PB オブジェクト]タブから[標 準クラス]を選択します。 標準クラス データ型の選択 ダイアログボックスが表示され、新規 のユーザ オブジェクトに継承したい PowerBuilder のシステム オブ ジェクト名が指定できます。 320 PowerBuilder 第 17 章 データ ソース間のデータ転送 2 「pipeline」を選択して、[OK]ボタンを選択します。 3 必要に応じて、ユーザ オブジェクトに変更を加えます。アプリケー ションで使用するイベント、関数、変数などを記述します。 特に有効なユーザ オブジェクトの機能については、330 ページの 「パイプライン処理のモニタ」を参照してください。 再利用を考えた設計 ユーザ オブジェクトを作成する場合、そのユーザ オブジェクトが 将来再利用され、ほかのパイプライン処理の実行にも使用される ことがあることを考慮してください。ユーザ オブジェクトは、デー タ パイプライン ペインタで作成した特定のパイプライン オブ ジェクトと自動的に関連付けられるわけではなく、ほかのパイプ ライン オブジェクトに対しても使用することができます。 この柔軟性を有効に活用するためにも、ユーザ オブジェクトで記 述するイベント、関数、変数は、あらゆるパイプライン オブジェ クトに適応できるような汎用性を持たせておく必要があります。 4 ユーザ オブジェクトを保存します。 ユーザ オブジェクト ペインタでの操作手順については、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 ウィンドウの作成 ウィンドウは、アプリケーションでデータ パイプライン処理をすると きに必要となるもう 1 つのオブジェクトです。ウィンドウを作成して、 パイプライン処理に対するユーザ インタフェースを提供し、エンド ユーザによるさまざまなパイプライン操作を可能にします。通常のア プリケーションでは、以下のようなエンド ユーザ操作が考えられま す。 • パイプライン処理を開始する • エラー内容の表示や修正を行う • 必要に応じ、パイプライン処理の実行を中断する アプリケーション テクニック 321 必要なオブジェクトの作成 ウィンドウに必要とな る機能 ウィンドウを作成する際に、そのパイプライン処理でエラーとなった 行(何らかの理由で転送先テーブルに転送できない行)を表示するデー タウィンドウ コントロールが必要となります。このデータウィンドウ コントロールにデータウィンドウ オブジェクトを関連付ける必要は ありません。実行時にパイプラインによって独自のデータウィンドウ オブジェクトが提供されます。 このデータウィンドウ コントロールの使い方については、328 ページ の「パイプライン処理の開始」および 335 ページの「エラー行の処理」 を参照してください。 ウィンドウに対するオ プション機能 必要なデータウィンドウ コントロールさえ含めれば、ウィンドウは開 発者が自由に設計できます。通常は、以下のようなコントロールを配 置してユーザ インタフェースを実現します。 • エンド ユーザが(パイプラインの開始、修正、停止などの)操作 を行えるようにするコマンドボタン コントロールやピクチャボタ ン コントロール • パイプラインのステータス情報を表示するスタティック テキスト コントロール • 転送元テーブルや転送先テーブルの内容を表示するデータウィン ドウ コントロール ウィンドウの作成についての詳細は、PowerBuilder の『ユーザーズ ガ イド』マニュアルを参照してください。 322 PowerBuilder 第 17 章 例 データ ソース間のデータ転送 次のウィンドウは、商品受注管理システムにおけるデータ パイプライ ン処理のユーザ インタフェースを扱います。ウィンドウ名は、 w_sales_extract です。 このウィンドウ上の各コントロールは、パイプライン処理に関連した さまざまな機能を実現するために使用されています。使用されている コントロールの詳細を、表 17-2 にまとめています。 表 17-2: パイプラインの機能を実現するためのウィンドウ コントロール コントロールの 種類 ラジオボタン コントロール名 rb_create rb_insert アプリケーション テクニック 目的 実行するパイプライン オブジェクト に、pipe_sales_extract1 を選択する 実行するパイプライン オブジェクト に、pipe_sales_extract2 を選択する 323 必要なオブジェクトの作成 コントロールの 種類 コマンドボタン データウィンド ウ スタティック テキスト 324 コントロール名 cb_write 目的 選択したパイプライン処理の実行を 開始する cb_stop パイプラインの実行を停止し、行の修 正内容を破棄する cb_applyfixes (dw_pipe_errors データウィンドウ コ ントロール内で)エンド ユーザが行 に加えた修正内容で転送先テーブル を更新する cb_forgofixes dw_pipe_errors データウィンドウ コン トロールから、すべてのエラー行を削 除する(エンド ユーザが修復を希望 しないときに使用) dw_review_extract 転送先テーブル(Quarterly-extract)の 現行の内容を表示する dw_pipe_errors (必須)パイプライン自身が使用する データウィンドウ コントロール。 PowerBuilder のパイプライン エラー の内容(何らかのエラーで転送できな かった行のリスト)を自動的に表示す る st_status_read パイプラインが転送元テーブルから 読み込む行数を表示する st_status_written パイプラインが転送元テーブルに書 き込む行数や、dw_pipe_ errors データ ウィンドウの行数を表示する st_status_error st_status_error パイプラインが dw_pipe_ errors データウィンドウに渡 した行数(エラーとなった行数)を 表示する PowerBuilder 第 17 章 データ ソース間のデータ転送 パイプライン処理の前準備 アプリケーションで必要となるオブジェクトの準備ができたら、アプ リケーションでパイプライン処理を行うスクリプトを記述します。ま ず、アプリケーションがパイプライン処理を実行できるように、いく つかの設定を行わなければなりません。 v アプリケーションでパイプラインを実行するための準備をするには 1 パイプラインに用いる転送元および転送先データベースに接続し ます。 これは、適切なイベントにおいて、接続のための一般的なスクリ プトを記述して行います。ただし、転送元データベースに接続す る際に使用するトランザクション オブジェクトと、転送先データ ベースとの接続に使用するトランザクション オブジェクトは、 (同 一のデータベースの場合でも)異なることに注意してください。 データベースへの接続についての詳細は、第 12 章「トランザク ション オブジェクトの使い方」を参照してください。 2 ユーザ オブジェクトのインスタンスを作成します(インスタンス を作成することにより、アプリケーションでユーザ オブジェクト のプロパティ、イベント、関数が使用できるようになります)。 最初に、定義したユーザ オブジェクトをデータ型とする変数を宣 言します。次に、スクリプトで CREATE 文を使って、ユーザ オブ ジェクトのインスタンスを作成し、それを変数に代入します。 3 使用したいパイプライン オブジェクトを指定します。 これは、スクリプトで代入文を記述して行います。使用するパイプ ライン オブジェクト名を示す文字列を、ユーザ オブジェクトのイ ンスタンスの DataObject プロパティに代入します。 CREATE 文および代入文についての詳細は、 『PowerScript リファレンス』 マニュアルを参照してください。 例 次のサンプル コードは、商品受注管理システムにおけるこれらのパイ プラインの設定を行います。 転送元および転送先データベースとの接続 この場合は、会社の販売デー タベース(ABNCSALE.DB)を、転送元および転送先の両方のデータ ベースとして使用しています。この販売データベースとの接続は、 uevent_pipe_setup というユーザ イベントにスクリプトを記述して行っ ています(uevent_pipe_setup イベントは、w_sales_extract ウィンドウの Open イベントからポストされます)。 アプリケーション テクニック 325 パイプライン処理の前準備 以下のスクリプトは、転送元データベースとの接続を確立します。 // トランザクション オブジェクトのインスタンスを新規に作成し、 // itrans_source(あらかじめ Transaction データ型 // として宣言した変数)に保持します。 itrans_source = CREATE transaction // 次に、トランザクション オブジェクト itrans_destination の // プロパティに値を代入します。 ... // 転送元データベースに接続します。 CONNECT USING itrans_source; 以下のスクリプトは、転送先データベースとの接続を確立します。 // トランザクション オブジェクトのインスタンスを新規に作成し、 // itrans_destination(あらかじめ Transaction データ型 // として宣言した変数)に保持します。 itrans_destination = CREATE transaction // 次に、トランザクション オブジェクト itrans_destination の // プロパティに値を代入します。 ... // 転送先データベースに接続します。 CONNECT USING itrans_destination; ネイティブ ドライバの USERID 設定 ネイティブ ドライバを使用している場合に、パイプライン ペインタで パイプラインを実行すると、PowerBuilder は、テーブルのオーナー名 でテーブル名を自動的に修飾します。ネイティブ ドライバを使用して いる場合に、アプリケーションでパイプラインを実行するときは、テー ブル名が正しく修飾されるように、トランザクション オブジェクトで USERID プロパティを設定しなければなりません。 転送先データベースのトランザクション オブジェクトで USERID プ ロパティを設定しなかった場合には、パイプラインの実行エラーが発 生します。転送元データベースがネイティブ ドライバを使用する場合 には、USERID が設定されていなければ、拡張属性は転送されません。 326 PowerBuilder 第 17 章 データ ソース間のデータ転送 ユーザ オブジェクトのインスタンスの作成 u_sales_pipe_logistics というパ イプライン処理に必要となるユーザ オブジェクトを作成する方法に ついては、すでに説明しました。このユーザ オブジェクトをアプリ ケーションで使用するには、まずそのユーザ オブジェクトをデータ型 とする変数を宣言します。 // これは w_sales_extract ウィンドウの // インスタンス変数です。 u_sales_pipe_logistics iuo_pipe_logistics 次に、ユーザ オブジェクト u_sales_pipe_logistics のインスタンスを作 成し、iuo_pipe_logistics 変数に保持するコードを、ユーザ イベント uevent_pipe_setup に記述します。 iuo_pipe_logistics = CREATE u_sales_pipe_logistics このアプリケーションは、必 要とするパイプ操作の種類によって、以下のいずれかのパイプライン オブジェクトを使用しています。 使用するパイプライン オブジェクトの指定 • pipe_sales_extract1(前述の説明を参照)は、Quarterly-extract テーブ ルを新規に作成する(このテーブルは現時点で存在していないも のとする) • pipe_sales_extract2 は、Quarterly-extract テーブルに行を挿入する(こ のテーブルは現時点で存在しているものとする) パイプライン オブジェクトを選択し、その使用準備を行うスクリプト を、コマンドボタン cb_write の Clicked イベントに記述します(コマン ドボタンは、エンド ユーザがパイプライン処理を開始したいときにク リックします)。 // w_sales_extract ウィンドウで選択されている // ラジオボタンを確認します。次に、iuo_pipe_logistics に // 適切なパイプライン オブジェクトを代入します。 IF rb_create.checked = true THEN iuo_pipe_logistics.dataobject = "pipe_sales_extract1" ELSE iuo_pipe_logistics.dataobject = "pipe_sales_extract2" END IF このコードは、選択されたパイプラインを開始するスクリプトより前 に、通常スクリプトの先頭で記述します。 アプリケーション テクニック 327 パイプライン処理の開始 パイプライン オブジェクトを配布する際の注意 通常、アプリケーションは、実行時にパイプライン オブジェクトを (String 型の変数によって)動的に参照します。そのため、アプリケー ションを配布する場合は、これらのオブジェクトを 1 つまたは複数の PBD か DLL ファイルにパッケージ化する必要があります。なお、実行 (EXE)ファイルにパイプライン オブジェクトを含めることはできま せん。 配布についての詳細は、第 9 部「配布のテクニック」を参照してくだ さい。 パイプライン処理の開始 パイプラインの準備が整ったら、実行を開始します。 v パイプライン処理を開始するには 1 適切なスクリプトに Start 関数を記述します。この関数では、以下 の内容が指定できます。 • 転送元データベースに対するトランザクション オブジェクト • 転送先データベースに対するトランザクション オブジェクト • Start 関数がエラー行を表示するデータウィンドウ コントロール Start 関数は、PowerBuilder のパイプライン エラー データウィ ンドウ オブジェクトと、使用するデータウィンドウ コント ロールを自動的に関連付けます(必要な場合のみ)。 • パイプライン オブジェクトで定義した検索引数に対する値 これらの値を省略すると、Start 関数は、アプリケーション実行 時にそれらの入力を自動的に要求します。 2 Start 関数の結果を調べます。 Start 関数の記述についての詳細は、 『PowerScript リファレンス』マニュ アルを参照してください。 328 PowerBuilder 第 17 章 例 データ ソース間のデータ転送 以下のサンプル スクリプトは、商品受注管理システムのパイプライン を開始します。 Start 関数の呼び出し 選択したパイプラインを開始する場合は、エンド ユーザに w_sales_extract ウィンドウのコマンドボタン(cb_write)を選 択させます。 cb_write コマンドボタンの Clicked イベントが起動されます(このイベ ントのスクリプトに、Start 関数が記述されています)。 // 転送を開始します。 integer li_start_result li_start_result = iuo_pipe_logistics.Start & (itrans_source,itrans_destination,dw_pipe_errors) スクリプトでは、ユーザがパイプラインの検索引数(Quarter)に対す る値を設定していません。そこで、Start 関数が、その値を入力するよ うエンド ユーザに要求します。 cb_write コマンドボタンの Clicked イベントに対する以 下のスクリプトによって、Start 関数の戻り値を調べます。これによっ て、アプリケーションで関数が正常終了したかどうか(正常終了しな かった場合は、エラーの内容)を調べることができます。 結果を調べる CHOOSE CASE li_start_result CASE -3 Beep (1) MessageBox(" 転送エラー ", & "Quarterly_Extract テーブルは既に存在しています ... RETURN アプリケーション テクニック 329 パイプライン処理の開始 CASE -4 Beep (1) MessageBox(" 転送エラー ", & "Quarterly_Extract テーブルは存在しません ... RETURN ... END CHOOSE パイプライン処理のモニタ パイプラインの実行状態をモニタするには、Start 関数の戻り値を調べ る方法があります。そのほかの方法として、ユーザ オブジェクトがパ イプライン処理された行数を保持している集計値を取得する方法もあ ります。これにより、パイプラインによって処理された以下の数値が 求められます。 • 転送元テーブルから読み込まれた行数 • 転送先テーブルおよびエラーのデータウィンドウ コントロールに 書き込まれた行数 • (転送先テーブルではなく)エラー用のデータウィンドウ コント ロールに書き込まれたエラー行の数 これらの集計値をユーザ オブジェクトから取得し、ウィンドウ上で動 的に表示して、エンド ユーザにパイプライン処理を確認させることが できます。 v パイプラインによって処理された行の集計を表示するには 1 ユーザ オブジェクト ペインタで、ユーザ オブジェクトを開きま す。 ユーザ オブジェクト ペインタのワークスペースが表示され、ユー ザ オブジェクトの編集が可能になります。 2 StaticText 型の インスタンス変数を 3 種類宣言します。 statictext ist_status_read, ist_status_written, & ist_status_error これらのインスタンス変数は、今後、ウィンドウ上の 3 つのスタ ティック テキスト コントロールの内容を保持するために使用し ます。これにより、ユーザ オブジェクトでスタティック テキスト コントロールの内容を直接操作し、パイプラインによる各種の行 の集計を動的に表示できます。 330 PowerBuilder 第 17 章 3 データ ソース間のデータ転送 ユーザ オブジェクトの PipeMeter イベント スクリプトでは、Pipeline システム オブジェクトから継承したプロパティの値を、3 つのス タティック テキスト インスタンス変数のテキスト プロパティに 割り当てるステートメントを記述します。 ist_status_read.text = string(RowsRead) ist_status_written.text = string(RowsWritten) ist_status_error.text = string(RowsInError) 4 ユーザ オブジェクトに加えた変更内容を保存し、ユーザ オブジェ クト ペインタを閉じます。 5 使用するウィンドウをウィンドウ ペインタで開きます。 6 3 つのスタティック テキスト コントロールをウィンドウに挿入し ます。 RowsRead プロパティの値を表示するスタティック テキスト コントロール RowsWritten プロパティの値を表示するスタティック テキス ト コントロール RowsInError プロパティの値を表示するスタティック テキス ト コントロール 7 ウィンドウの Open イベントに対するスクリプト(または、ウィン ドウを開いた直後に実行するほかのイベントに対するスクリプ ト)を編集します。 ここでは、(ウィンドウに挿入したばかりの)3 つのスタティック テキスト コントロールを、ユーザ オブジェクトであらかじめ宣言 しておいた 3 つの対応するスタティック テキスト インスタンス変 数に割り当てるステートメントを記述します。これにより、その ユーザ オブジェクトからこれらのスタティック テキスト コント ロールを直接操作できます。 商品受注管理システムでは、このロジックを uevent_pipe_setup ユー ザ イベントに対して記述しています(このユーザ イベントは、 w_sales_extract ウィンドウの Open イベントからポストされます) 。 アプリケーション テクニック 331 パイプライン処理の開始 iuo_pipe_logistics.ist_status_read = st_status_read iuo_pipe_logistics.ist_status_written = & st_status_written iuo_pipe_logistics.ist_status_error = & st_status_error 8 ウィンドウへの変更内容を保存し、ウィンドウ ペインタを閉じま す。 商品受注管理システムの w_sales_extract ウィンドウでパイプライ ンを開始すると、ユーザ オブジェクトの PipeMeter イベントが起 動され、そのイベントのスクリプトが実行されて、パイプライン による行の集計が 3 個のスタティック テキスト コントロールに表 示されます。 パイプライン処理のキャンセル パイプラインの実行を途中で停止する機能をエンド ユーザ(またはア プリケーション)に提供したい場合が多くあります。たとえば、間違っ てパイプラインを開始したり、 (大量の行数を扱っているときに)処理 を途中で中断したりしたい場合などです。 332 PowerBuilder 第 17 章 v データ ソース間のデータ転送 パイプラインの実行をキャンセルするには 1 適切なスクリプトに Cancel 関数を記述します。 Cancel 関数は、パイプラインの開始後(適切であれば) 、エンド ユー ザまたはアプリケーションのどちらからでも実行できます。Cancel 関数が実行されると、それ以降の行の転送が停止されます。 処理が中断された時点までに転送された行が転送先テーブルにコ ミットされるかどうかは、データ パイプライン ペインタでパイプ ライン オブジェクトの作成時に指定した[コミット単位]オプショ ンによって決まります。コミットについては、次節で説明します。 2 Cancel 関数の結果を調べます。 Cancel 関数の記述についての詳細は、 『PowerScript リファレンス』マ ニュアルを参照してください。 例 次の例では、エンド ユーザがコマンドボタンを使って商品受注管理シ ステムのパイプライン実行を中断します。 コマンドボタンの提供 w_sales_extract ウ ィンドウ を作成す るときに、 cb_stop というコマンドボタン コントロールを配置します。また、パイ プラインの開始時にこのコマンドボタンを使用可能にし、その終了と ともに使用不可にするコードをアプリケーションのスクリプトに記述 します。 Cancel 関数の呼び出し 次に、cb_stop コマンドボタンの Clicked イベン トに対して以下のスクリプトを記述します。このスクリプトは、Cancel 関数を呼び出し、それが正しく機能しているかどうかを調べます。 IF iuo_pipe_logistics.Cancel() = 1 THEN Beep (1) MessageBox(" パイプライン処理の状況 ", & " データ転送が(ユーザの要求によって)中断されました。") ELSE Beep (1) MessageBox(" パイプライン処理の状況 ", & " データ転送の中断時にエラーが発生しました。", & Exclamation!) END IF これらの機能は、エンド ユーザが cb_stop コマンドボタンを選択する ことによって、現在実行中のパイプラインを停止できるようにします。 アプリケーション テクニック 333 パイプライン処理の開始 更新処理のコミット パイプライン オブジェクトを実行すると、データ パイプライン ペイ ンタでの指定に従って転送先テーブルへの更新がコミットされます。 開発者は、アプリケーションのスクリプトで、このコミット処理のた めに COMMIT 文を記述する必要はありません(ただし、パイプライン オブジェクトを作成したときに、[コミット単位]オプションに[な し]を指定したときを除く)。 例 たとえば、商品受注管理システムの 2 つのパイプライン オブジェクト (pipe_sales_extract1 と pipe_sales_extract2)は、すべての行が転送された 後でコミットを行うようにデータ パイプライン ペインタで定義され ています。これにより、Start 関数(または Repair 関数)は、すべての 行が転送されてから、コミットします。 かわりに、一定量の行(10 行または 100 行など)を転送するたびに定 期的にコミットするようなパイプライン オブジェクトを定義するこ ともできます。 Cancel 関数が呼び出 された場合 アプリケーションが Cancel 関数を呼び出して、現在実行しているパイ プラインを中断した場合は、コミット処理が行われるかどうかが問題 になります。その時点でコミット処理の方法が、表 17-3 に示すように、 データ パイプライン ペインタで指定する[コミット単位]オプション によって決まります。 表 17-3: [コミット単位]オプションの値 [コミット単位]オプション の値 すべて 特定の行数(1、10、100 など) Cancel 関数の処理の内容 現行の Start 関数(または Repair 関数)によっ て、転送した行をすべてロールバックします。 中断される直前までに転送した行を、すべてコ ミットします。 これは、エラーがパイプラインの最大エラー件数に達したときに起こ るコミットやロールバックの動作と同じです(なお、最大エラー件数 はデータ パイプライン ペインタで指定します)。 パイプライン オブジェクトに対するコミットやロールバックの操作 についての詳細は、PowerBuilder の『ユーザーズ ガイド』マニュアル を参照してください。 334 PowerBuilder 第 17 章 データ ソース間のデータ転送 エラー行の処理 パイプラインの実行時に、行が転送先テーブルに書き込めない場合が あります。たとえば、転送先テーブルに転送元テーブルと同じ主キー を持つ行がある場合などです。 パイプライン エラー データウィンドウの使 い方 パイプラインは、ウィンドウ上に配置され Start 関数で指定したデータ ウィンドウ コントロールにエラーとなった行を表示します。これは、 特定のデータウィンドウ オブジェクト(PowerBuilder のパイプライン エラー データウィンドウ)とデータウィンドウ コントロールが自動的 に関連付けられて行われます。 これを商品受注管理システムで考えてみましょう。w_sales_extract ウィ ンドウでパイプラインを実行する場合、Start 関数は、すべてのエラー 行を dw_pipe_errors データウィンドウ コントロールに表示します。 dw_pipe_errors には、各行のエラーを表示するエラー メッセージ カラ ムが配置されています。 エラー メッセージを短くする パイプラインの転送先のトランザクション オブジェクトが ODBC データ ソースを指定している場合は、DBParm の MsgTerse パラメータ を設定して、データウィンドウに表示するエラー メッセージを短くす ることができます。具体的には、以下のように指定します。 MsgTerse = 'Yes' アプリケーション テクニック 335 エラー行の処理 このように指定することによって、SQLSTATE エラー番号は表示され ません。 MsgTerse DBParm についての詳細は、オンライン ヘルプを参照してく ださい。 エラー行がある場合は、それらを処理する必要があります。以下のい ずれかの操作を行います。 エラー行の処理 • エラー行の一部またはすべての修復 • エラー行の一部またはすべての破棄 エラー行の修復 ほとんどの場合は、エラーとなった行を修正して、転送先テーブルに 適用できるようにすることをお勧めします。通常、1 つまたは複数の カラム値を転送先テーブルで受け入れられるように変更して修復しま す。エラー行の修正は、エラーを表示しているデータウィンドウ コン トロール上の行を以下のいずれかの方法で編集して行います。 • エンド ユーザに編集させる(開発者がスクリプトを記述する必要 なし) • アプリケーションのスクリプトによって編集する いずれの場合も、次の操作手順で、修正した行をこのデータウィンド ウ コントロールから転送先テーブルに適用します。 v 転送先テーブルに行の修正内容を適用するには 1 適切なスクリプトに Repair 関数を記述します。Repair 関数には、転 送先データベースに対する トランザクション オブジェクトを指 定します。 2 Repair 関数の結果を調べます。 Repair 関数の記述についての詳細は、 『PowerScript リファレンス』マ ニュアルを参照してください。 例 336 次の例では、エンド ユーザがデータウィンドウ コントロール dw_pipe_errors の内容を編集することで、表示されたエラー行を修正できるようにし ます。その後、修正したそれらの行を転送先テーブルに適用します。 PowerBuilder 第 17 章 データ ソース間のデータ転送 w_sales_extract ウィンドウの作成時に、cb_applyfixes というコマンドボタン コントロールを配置します。また、dw_pipe_errors データウィンドウにエラー行が入力されたときに、このコマンドボタ ンを使用可能にし、エラー行がないときには使用不可にしておくコー ドをアプリケーションのスクリプトに記述します。 コマンドボタンの提供 次に、cb_applyfixes コマンドボタンの Clicked イ ベントに対して以下のスクリプトを記述します。このスクリプトは Repair 関数を呼び出し、それが正しく機能しているかどうかを調べま す。 Repair 関数の呼び出し IF iuo_pipe_logistics.Repair(itrans_destination) & <> 1 THEN Beep (1) MessageBox(" パイプライン処理の状況 ", & " 修正しようとしたときエラーが起きました ", Exclamation!) END IF これらの機能を提供することによって、エンド ユーザが cb_applyfixes コマンドボタンをクリックすると、dw_pipe_errors データウィンドウか ら修正した行を持つ転送先テーブルを更新できるようになります。 行の修正の停止 パイプラインの実行時にエンド ユーザ(またはアプリケーション)が 転送先テーブルへの行の書き込みを中断する方法については、この章 ですでに説明しました。状況によっては、行の修正中にも同様に書き 込みを停止させることができます。 詳細については、332 ページの「パイプライン処理のキャンセル」を 参照してください。 行の修正内容のコミッ ト Repair 関数は、Start 関数と同じ方法でデータベースの更新をコミット (またはロール バック)します。 詳細については、334 ページの「更新処理のコミット」を参照してく ださい。 修正されていない行の 処理 Repair 関数の実行後、エラー行が、エラー データウィンドウ コント ロールにまだ残っていることがあります。これには、以下のような原 因が考えられます。 • エンド ユーザやアプリケーションによって修正されたにもかかわ らず、エラーがまだ直っていない場合 • エンド ユーザやアプリケーションによってエラーが修正されてい ない場合 • Cancel 関数が呼び出されたため、転送先テーブルに書き込まれな かった場合(または、停止時に、転送先テーブルからロールバッ クされた場合) アプリケーション テクニック 337 エラー行の処理 この時点でも、これらの行は、エンド ユーザやアプリケーションに よって再度修正し、Repair 関数を用いて転送先テーブルに適用するこ とができます。場合によってはこれらの行を破棄することもできます。 この方法については後述します。 エラー行の破棄 状況によっては、エラー データウィンドウ コントロールから 1 つまた は複数のエラー行を、エンド ユーザやアプリケーションによって破棄 したいことがあります。これは、修正したくないエラー行に対する有 効な措置と言えます。 表 17-4 に、エラー行の破棄を行うことができる方法を示します。 表 17-4: エラー行の破棄 破棄するエラー行 エラー データウィンドウ コントロール上の、 すべてのエラー行 エラー データウィンドウ コントロール上の、 1 つまたは複数のエラー行 使用する関数 Reset 関数 RowsDiscard 関数 これらの関数についての詳細は、 『PowerScript リファレンス』マニュ アルを参照してください。 例 次の例では、エンド ユーザが dw_pipe_errors データウィンドウ コント ロールのすべてのエラー行を破棄できるようにしています。 w_sales_extract ウィンドウの作成時に、cb_forgofixes というコマンドボタン コントロールを配置します。dw_pipe_errors デー タウィンドウにエラー行が入力されたときに、このコマンドボタンを 使用可能にし、エラー行がないときには使用不可にしておくコードを アプリケーションのスクリプトに記述します。 コマンドボタンの提供 Reset 関数の呼び出し 次に、 cb_fogofixes コマンドボタンの Clicked イベ ントに対して以下のスクリプトを記述します。このスクリプトで、 Reset 関数を呼び出します。 dw_pipe_errors.Reset() これらの機能を提供することによって、エンド ユーザが cb_forgofixes コマンドボタンを選択すると、dw_pipe_errors データウィンドウからす べてのエラー行が破棄されるようになります。 338 PowerBuilder 第 17 章 データ ソース間のデータ転送 パイプラインの後処理 アプリケーションでのパイプライン処理が終わったら、いくつかの後 処理を行わなければなりません。これらの処理には、パイプライン処 理のために取得したリソースの解放などが含まれます。 ガベージ コレクション 破棄するオブジェクトがほかで使われていないことを確認できない場 合には、リソースの後処理に DESTROY 文を使わないでください。 PowerBuilder のガベージ コレクション機能によって、参照されていな いオブジェクトは自動的に削除されます。詳細については、49 ページ の「ガベージ コレクションとメモリ管理」を参照してください。 v パイプラインの後処理を行うには 1 パイプライン処理に使用したユーザ オブジェクトのインスタンス を破棄します。 適切なスクリプトに DESTROY 文を記述し、そのユーザ オブジェ クトのインスタンス変数名を指定します。 2 パイプラインの転送元データベースおよび転送先データベースと の接続を解除します。 これは、適切なスクリプトに DISCONNECT 文を 2 行記述して行い ます。一方の DISCONNECT 文では、転送元トランザクション オ ブジェクトのインスタンス変数名を、もう一方の DISCONNECT 文 では転送先トランザクション オブジェクトのインスタンス変数名 を、それぞれ指定します。 各 DISCONNECT 文の結果を調べます。 3 転送元トランザクション オブジェクトのインスタンスと転送先ト ランザクション オブジェクトのインスタンスを破棄します。 これは、適切なスクリプトに DESTROY 文を 2 行記述して行いま す。一方の DESTROY 文では、転送元トランザクション オブジェ クトのインスタンス変数名を、もう一方の DESTROY 文では転送 先トランザクション オブジェクトのインスタンス変数名を、それ ぞれ指定します。 DESTROY 文と DISCONNECT 文についての詳細は、 『PowerScript リファ レンス』マニュアルを参照してください。 例 次のコードは、w_sales_extract ウィンドウの Close イベントに対してス クリプトを記述し、パイプラインの後処理を行います。 アプリケーション テクニック 339 パイプラインの後処理 ユーザ オブジェクト インスタンスの破棄 Close イベント スクリプトの先頭 に、以下のステートメントを記述して、(iuo_pipe_logistics 変数に保持 されている)ユーザ オブジェクト u_sales_pipe_logistics のインスタンス を破棄します。 DESTROY iuo_pipe_logistics 転送元データベースとの接続の解除 次に、以下のステートメントを記述し て転送元データベースとの接続を解除し、その結果を調べて、 (itrans_source 変数に保持されている)転送元トランザクション オブジェクトのイン スタンスを破棄します。 DISCONNECT USING itrans_source; // DISCONNECT 文の結果を調べます。 IF itrans_source.SQLCode = -1 THEN Beep (1) MessageBox(" データベース接続エラー ", & " 転送元データベースとの“ & + " 接続を解除する際に問題が発生しました。" & + " テクニカルサポートまでご連絡ください。 " & + "~n~r~n~r 詳細は以下のとおりです : " + & String(itrans_source.SQLDBCode) + " " + & itrans_source.SQLErrText, Exclamation!) END IF DESTROY itrans_source 転送先データベースとの接続の解除 最後に、以下のステートメントを記 述して転送先データベースとの接続を解除し、その結果を調べて、 (itrans_destination 変数に保持されている)転送先トランザクション オ ブジェクトのインスタンスを破棄します。 DISCONNECT USING itrans_destination; // DISCONNECT 文の結果を調べます。 IF itrans_destination.SQLCode = -1 THEN Beep (1) MessageBox(" データベース接続エラー ", & " 転送先データベースとの " + & " 接続を解除にする際に問題が発生しました。 " + & " テクニカルサポートまでご連絡ください。" + & "~n~r~n~r 詳細は以下のとおりです : " + & String(itrans_destination.SQLDBCode) + " " + & itrans_destination.SQLErrText, Exclamation!) END IF DESTROY itrans_destination 340 PowerBuilder 第 5 部 プログラム アクセス テクニック 第 5 部では、PowerBuilder によるアプリケーション開発 において、プログラム アクセス機能を実現するためのテ クニックについて説明します。アプリケーションにおけ る DDE の使い方および OLE の使い方、メール対応アプ リケーションの構築、そのほかの拡張処理機能の追加な どについて説明します。 第 1 8 章 DDE の使い方 この章について この章では、PowerBuilder がサポートする DDE 機能について説明 します。 内容 項目 DDE について DDE 関数とイベント ページ 343 344 DDE について ダイナミック データ エクスチェンジ(DDE: Dynamic Data Exchange) を使用すると、2 つの Windows アプリケーション間でコマンドや データをやり取りさせて、相互に通信することができます。つま り、2 つのアプリケーションでデータを共有したり、コマンドの遠 隔実行や、エラー状態のチェックを行ったりすることができます。 PowerBuilder は DDE をサポートするために、特別な PowerScript 関 数やイベントを提供しています。これらの関数やイベントを用い ることにより、PowerBuilder アプリケーションから DDE をサポー トするほかのアプリケーションにメッセージを送信したり、ほか の DDE アプリケーションからの DDE リクエストに対して応答し たりできます。 クライアントとサーバ DDE をサポートしているアプリケーションは、クライアントまた はサーバのどちらかの役割を果たすことができます。 用語について DDE で用いるクライアントとサーバという用語は、PC やワーク ステーションのクライアント マシンがデータベース サーバにア クセスするクライアント / サーバ アーキテクチャとは関係ありま せん。 アプリケーション テクニック 343 DDE 関数とイベント クライアント アプリケーションは、DDE をサポートしているほかのア プリケーション(サーバと呼ばれる)に対してリクエストを出します。 このリクエストは、コマンド(open、close、save など)であったりデー タに対するリクエストであったりします。 サーバ アプリケーションは、クライアント アプリケーションとは逆の 機能を実行します。サーバ アプリケーションは、DDE をサポートして いるほかのアプリケーション(クライアントと呼ばれる)からのリク エストに応答します。クライアント アプリケーションの場合と同様 に、このリクエストはコマンドや特定のデータに対するリクエストで す。 PowerBuilder のアプリケーションは、DDE クライアントとしても、DDE サーバとしても機能します。 PowerBuilder では DDE クライアントおよび DDE サーバに対して特別 な組み込み関数とイベントを用意しています。コマンドやデータがク ライアントからサーバに(またはサーバからクライアントに)送られ ると、DDE 関連のイベントが起動されます。 DDE 関数とイベント 以下の表に、DDE 関連の関数とイベントを示します。関数とイベント は DDE クライアントと DDE サーバごとにそれぞれまとめられていま す。DDE サポートの詳細については、『PowerScript リファレンス』マ ニュアルを参照してください。 戻り値 DDE 関数はすべて整数値を返します。 344 PowerBuilder 第 18 章 DDE クライアント DDE の使い方 表 18-1: DDE クライアント関数 関数 動作内容 CloseChannel OpenChannel 関数で開かれた DDE サーバ アプリケー ExecRemote GetDataDDE GetDataDDEOrigin GetRemote OpenChannel RespondRemote SetRemote StartHotLink StopHotLink ションへのチャネルを閉じる DDE サーバ アプリケーションにコマンドを実行する よう要求する ホットリンクされている DDE サーバ アプリケーショ ンから新しいデータを取得して、指定した文字列型変 数に保持する どの DDE サーバ アプリケーションがホットリンクで データを送信したかを判別する DDE サーバ アプリケーションにデータを要求する。こ の関数には、チャネルを用いる形式と用いない形式の 2 通りの構文がある 指定された DDE サーバ アプリケーションへの DDE チャネルを開く DDE アプリケーションから受信したコマンドまたは データが、DDE クライアントに受け入れられたかどう かを、DDE サーバ アプリケーションに通知する DDE サーバ アプリケーションに、ワークシートのセル などの項目や変数に特定の値を設定するように要求す る。この関数には、DDE チャネルを用いる形式と用い ない形式の 2 通りの構文がある DDE サーバ アプリケーションへのホットリンクを開 始し、DDE サーバ アプリケーションの中の特定のデー タ変更が PowerBuilder にただちに通知されるようにす る DDE サーバ アプリケーションとのホットリンクを終 了する 表 18-2: DDE クライアント イベント イベント HotLinkAlarm アプリケーション テクニック 発生する状況 DDE サーバ アプリケーションが新しい(変更され た)データを送信したとき 345 DDE 関数とイベント DDE サーバ 表 18-3: DDE サーバ関数 関数 動作内容 GetCommandDDE DDE クライアント アプリケーションが送信した コマンドを取得する どの DDE クライアント アプリケーションがコマ ンドを送信したかを判別する DDE クライアント アプリケーションが送信した データを取得して、指定した文字列型変数に保持 する どの DDE クライアント アプリケーションがホッ トリンクでデータを送信したかを判別する DDE アプリケーションから受信したコマンドま たはデータが DDE サーバに受け入れられたかど うかを、送信元の DDE クライアント アプリケー ションに通知する 指定されたデータを DDE クライアント アプリ ケーションに送信する PowerBuilder アプリケーションを DDE サーバと して起動する PowerBuilder が DDE サーバとして動作すること を終了させる GetCommandDDEOrigin GetDataDDE GetDataDDEOrigin RespondRemote SetDataDDE StartServerDDE StopServerDDE 表 18-4: DDE サーバ イベント イベント RemoteExec RemoteHotLinkStart RemoteHotLinkStop RemoteRequest RemoteSend 346 発生する状況 DDE クライアント アプリケーションがコマンド を送信したとき DDE クライアント アプリケーションがホットリ ンクの開始を要求するとき DDE クライアント アプリケーションがホットリ ンクの終了を要求するとき DDE クライアント アプリケーションがデータを 要求したとき DDE クライアント アプリケーションがデータを 送信したとき PowerBuilder 第 1 9 章 アプリケーションにおける OLE の 使い方 この章について この章では、PowerBuilder のアプリケーションで OLE を実装する 方法について説明します。 内容 項目 PowerBuilder における OLE のサポート ウィンドウにおける OLE コントロール OLE コントロールと挿入可能なオブジェクト OLE カスタム コントロール プログラム可能な OLE オブジェクト スクリプトにおける OLE オブジェクト オブジェクト ブラウザでの OLE 情報 OLE オブジェクトの高度な操作 ページ 347 348 352 366 370 380 400 402 PowerBuilder における OLE のサポート OLE(Object Linking and Embedding)を利用すると、Windows プロ グラムでのデータとプログラム機能の共有が簡単にできます。 PowerBuilder の OLE コントロールは、OLE サーバ アプリケーショ ンを呼び出して、OLE オブジェクトを表示したり、操作を行った りすることができる、OLE コンテナです。 OLE コントロール アプリケーション テクニック ウィンドウ ペインタの OLE コントロールを使用すれば、複数のア プリケーションのコンポーネントをウィンドウにリンクしたり、 埋め込んだりすることができます。さらに、OLE サーバによって 定義された関数とプロパティを使用して、OLE サーバを制御する ことができます。 347 ウィンドウにおける OLE コントロール PowerBuilder の OLE コントロールは、OLE オブジェクトのコンテナで す。エンド ユーザは、OLE オブジェクトをアクティブにして、OLE サーバ アプリケーションによって提供されている機能で編集作業が 行えます。また、OLE 関連の操作は、スクリプトで OLE オブジェクト をアクティブにして、OLE サーバへコマンドを送ることによって、自 動化できます。OLE サーバは、DLL または別個の EXE ファイルのい ずれかとすることができます。これらのサーバは、異なるコンピュー タ上で動作していてもかまいません。 PowerScript のオートメーションを使用すれば、ウィンドウに表示され ている OLE コントロール、または OLEObject 変数に保持されている非 表示の OLE オブジェクトの参照を操作できます。OLEObject 型を使用 すると、OLE コンテナをウィンドウに表示しなくても OLE オブジェク トが作成できます。 OLE カスタム コント ロール 2 番目のコントロールである、OLE カスタム コントロールは、ActiveX コントロール(OCX コントロールとも呼ばれます)用のコンテナです。 ActiveX コントロールは DLL であり(拡張子 OCX が付くこともあり ます)、アプリケーションと常に同じプロセスで動作します。 OLE オブジェクトの 管理 OLE オブジェクトの管理は、OLE オブジェクトを変数に保持して、 ファイルに保存して行うことができます。このために 2 つのオブジェ クトのデータ型 OLEStorage と OLEStream が用意されています。ほと んどのアプリケーションではこれらのオブジェクトを用いる必要はあ りません。しかし、(複数の OLE オブジェクトを 1 つのデータ構造に 組み込むような)複雑な処理を必要とする場合は、OLEStorage 型や OLEStream 型のオブジェクトとその関数を使用して対処できます。 そのほかの OLE のサ ポート データウィンドウ オブジェクトにおける OLE オブジェクトについて の詳細は、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照し てください。 ウィンドウにおける OLE コントロール OLE オブジェクトと ActiveX コントロールは、ウィンドウまたはユー ザ オブジェクトに追加できます。そのためには、OLE コンテナとして 機能する、PowerBuilder OLE コントロールの 1 つを使用します。この 節では、コントロールが OLE オブジェクト(挿入可能なオブジェクト とも呼ばれます)または ActiveX コントロールのどちらを保持するか を選ぶことによって、必要なコントロールを選択する方法について説 明します。 348 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 • 挿入可能な OLE オブジェクトは、OLE サーバ アプリケーション に関連付けられているドキュメントです。OLE オブジェクトはア クティブにできます。OLE サーバは、OLE オブジェクトを変更す るためのコマンドやツールバーを提供します。 • ActiveX コントロールまたは OLE カスタム コントロールはサーバ 自身であり、PowerBuilder でプログラミングしたスクリプトに基づ いて、ユーザのアクションを処理します。開発者は、ActiveX コン トロールのイベント用のスクリプトと、PowerBuilder コンテナのイ ベント用のスクリプトを記述できます。これらのスクリプトは、関 数を呼び出し、ActiveX コントロールに属するプロパティを設定し ます。必要であれば、ActiveX コントロールは、ユーザとの対話の ために独自のビジュアルなインタフェースを表示することもでき ます。 ActiveX コントロールは、簡単なビジュアル表示(たとえば、メータや ゲージ)やカスタマイズできる 1 つのアクティビティ(単語や句のス ペルチェックなど)を行うことができます。 OLE コントロール コ ンテナの機能 OLE コントロール コンテナは、すべて、一連の必要なインタフェース をサポートしています。PowerBuilder は、そのほかにもいくつかのサ ポートを提供しています。 • OLE コントロールは、拡張コントロールのプロ パティを使用して、実行時にその配置を決定、修正できます。 PowerBuilder では、X(Left)、Y(Top)、Width、Height の各プロパ ティをサポートしており、PowerBuilder 単位系で測定します。コン トロールの開発者がこれらのプロパティにアクセスするには、 IOleControlSite インタフェース上の GetExtendedControl メソッドか ら戻される、IDispatch から継承したインタフェースを使用できま す。 • OLE コンテナとしてのウィンドウ アプリケーション テクニック 拡張コントロール PowerBuilder は、ウィンドウ レベ ルで IOleContainer クラスを実装しているので、ウィンドウ上のす べてのコントロールは兄弟関係にあり、お互いに各コントロール の情報を共有できます。コントロールの開発者がこの情報にアク セスするには、OLE EnumObjects メソッドが使用できます。コント ロールが一連のコントロールの一部となっている場合、兄弟関係 に関する情報はとても便利です。ほかのコントロールと異なり、 ウィンドウ上の OLE コントロールは単一の階層構造に格納されま す。 349 ウィンドウにおける OLE コントロール OLE オブジェクトと OLE コントロールに限られます このオブジェクト列挙子に見えるのは OLE オブジェクトと OLE コントロールに限られます。ウィンドウ上のほかのコントロール を処理するのにはこのテクニックは使用できません。 • メッセージの反映 コントロール コンテナがメッセージの反映をサ ポートしていない場合、リフレクタ ウィンドウは、OLE コント ロールが親コントロールにメッセージを送ったときに作成されま す。リフレクタ ウィンドウはコントロールに戻るメッセージを反 映するので、コントロール自身でメッセージを処理できます。コ ンテナがメッセージの反映をサポートしている場合は、リフレク タ ウィンドウは必要なく、それに関連する実行時オーバーヘッド もなくなります。PowerBuilder の OLE コントロール コンテナは、 特定のメッセージ セットに対してメッセージの反映を行います。 OLE コントロールを作成して、その内容を選択する手順は以下のとお りです。 コントロールの定義 v ウィンドウ オブジェクトやユーザ オブジェクトで OLE コントロールを配置 するには 1 OLE コントロールを含むウィンドウまたはユーザ オブジェクトを 開きます。 2 メニュー バーから[挿入|コントロール| OLE]を選択します。 オブジェクトの挿入 ダイアログボックスが表示されます。オブ ジェクトは、3 つのタブから選択できます。 3 350 サーバ アプリケーションまたは特定の OLE オブジェクトを選択 して、OLE コントロールに OLE オブジェクトを埋め込むか、リン クできます。また、OLE カスタム コントロール(OCX)を選択し て、OLE カスタム コントロールに挿入できます。または、OLE コ ントロールにオブジェクトを挿入しないでおくこともできます。 • 新しいオブジェクトを作成して埋め込む場合は、 [新規作成] タブをクリックします。OLE サーバ アプリケーションを選択 して、[OK]ボタンをクリックします。 • OLE コントロールに既存のオブジェクトを選択する場合は、 [ファイルから作成]タブをクリックします。ファイル名を指 定して、[OK]ボタンをクリックします。 • カスタム コントロール(ActiveX コントロール)を挿入する場 合は、 [コントロールの挿入]タブをクリックします。ActiveX コントロールを選択してから、 [OK]ボタンをクリックします。 PowerBuilder 第 19 章 • アプリケーションにおける OLE の使い方 OLE コントロールにオブジェクトを挿入しない場合は、 [キャ ンセル]ボタンをクリックします。 [キャンセル]ボタンをクリックした場合には、コントロール は OLE カスタム コントロールではなく、OLE コントロールに なります。OLE コントロールへの OLE オブジェクトの埋め込 みまたはリンクは、いつでもできます。しかし、後から ActiveX コントロールを挿入することはできません。 4 コントロールを表示したい場所で、ウィンドウをクリックします。 OLE オブジェクトを挿入した場合、PowerBuilder は、OLE オブジェ クトを表示して編集できるように、OLE サーバ アプリケーション を起動します。ActiveX コントロールは開くことができません。 一覧表示されていない OLE サーバ アプリケーションに属するオブ ジェクトを挿入するときは、OLE サーバ アプリケーションをインス トールする必要があります。インストール方法については、OLE サー バ アプリケーションのマニュアルを参照してください。 オブジェクトの挿入 ダイアログボックスの使い方についての詳細は、 PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 アプリケーション テクニック 351 OLE コントロールと挿入可能なオブジェクト OLE コントロールと挿入可能なオブジェクト OLE コントロール内には、挿入可能な OLE オブジェクトがあります。 ペインタやスクリプトで OLE コントロール内の OLE オブジェクトを 変更できます。また、PowerBuilder のプロパティを設定して、OLE オ ブジェクトを指定できます。 OLE コントロールの設定 OLE コントロールを作成して、OLE オブジェクトを挿入すると、OLE サーバ アプリケーションがアクティブになり、OLE オブジェクトが修 正できます。PowerBuilderOLE オブジェクトを非アクティブにした後 (レイアウト ビューで OLE オブジェクトの枠線の外側をクリックしま す)、OLE コントロールのプロパティ シートを使用して、OLE コント ロールを設定できます。 v OLE コントロールの表示と動作の形態を指定するには 1 OLE コントロールをダブルクリックするか、コントロールのポッ プアップ メニューから[プロパティ]を選択します。 2 プロパティ ビューで、使用アプリケーションに関係する名前をコ ントロールに与えます。 スクリプトではこの名前を使用します。デフォルト名は「ole_」の 接頭辞に数字を組み合わせたものです。 3 OLE サーバが使用する表示の名前の値を指定します。OLE サーバ は、ウィンドウのタイトル バーにこの名前を使用できます。 4 コントロールの外観と動作を指定するには、プロパティ ビューで 適切な設定を選択します。 ほかのコントロールにある標準的な[表示可能]、 [使用可能]、 [フォーカス時の枠表示]、および[枠のスタイル]プロパティの ほかに、OLE オブジェクトと OLE サーバとの関係を管理するオプ ションがあります。 352 PowerBuilder 第 19 章 オプション 起動方法 アプリケーションにおける OLE の使い方 意味 コントロールをアクティブにする方法 オプションは以下のとおり • ダブルクリック(activatedoubleclick!)– コントロール がダブルクリックされたときに、OLE サーバ アプリ ケーションをアクティブにする • フォーカス(activategetfocus!) – コントロールがク リックされるか、タブによって選択されたときに、 OLE サーバ アプリケーションをアクティブにする。 また、GetFocus イベントに対するスクリプトでは、 MessageBox 関数などのフォーカス移動させるような 関数を呼び出さないようにする • スクリプト(activatemanually!)– Activate 関数をスク リプトで使用しなければ、コントロールをアクティ ブにできない 表示の種類 コントロールは、 [起動方法]オプションの設定に関係 なく、いつでもスクリプトでアクティブにできる コントロールに何を表示するかの指定 オプションは以下のとおり • 内容(displayascontent!)– コントロールのサイズに合 わせて、オブジェクトを縮小して表示する • アイコン(displayasicon!)– データに関連付けられて いるアイコンを表示する。通常このアイコンは、OLE サーバ アプリケーションから提供される 内容の更新 可能 • ActiveX ドキュメント(displayasactivexdocument!)– ActiveX ドキュメントとして表示する。ActiveX ド キュメントは、コンテナのスペースを満たし、サー バ アプリケーションのすべての機能を使用できる コントロール上のオブジェクトをリンクするか埋め込 むかの指定 オプションは以下のとおり • 埋め込み / リンク(containsany!)– オブジェクトをリ ンクまたは埋め込みで挿入できる • 埋め込み(containsembeddedonly!)– オブジェクトを 埋め込みで挿入できる • リンク(containslinkedonly!)– オブジェクトをリンク で挿入できる [内容の更新可能]オプションを設定すると、 ContentsAllowed プロパティの値が変更される アプリケーション テクニック 353 OLE コントロールと挿入可能なオブジェクト オプション 意味 リンクの更新 オプション コントロール上のオブジェクトがリンクされていると きの、リンク情報の更新方法 オプションは以下のとおり • 自動(linkupdateautomatic!)– リンクが中断されて、 PowerBuilder がリンクされたファイルを検索できな い場合に、エンド ユーザがファイルを指定できるダ イアログボックスを表示する • スクリプト(linkupdatemanual!)– リンクが中断され ると、オブジェクトはアクティブにできない。スク リプトで LinkTo 関数または UpdateLinksDialog 関数を 使用して、再リンクを行う [リンクの更新オプション]を設定すると、 LinkUpdateOptions プロパティの値が変更される サイズ モード コンテナにおけるオブジェクトの表示方法 オプションは以下のとおり • クリップ(clip!)– オブジェクトの画像がフルサイズ で表示される。画像が OLE コントロールより大きい 場合は、コントロールの枠線からはみ出す部分が切 り捨てられる • ストレッチ(stretch!)– オブジェクトの画像は、OLE コンテナ コントロールのサイズに合うようにサイズ 変更される(デフォルト) ペインタにおけるオブジェクトのアクティブ化 OLE コントロール内のオブジェクトをサーバ アプリケーションを使 用して操作するには、そのオブジェクトをアクティブにしなければな りません。デフォルトでは、ユーザがオブジェクトをアクティブにす るときには、そのオブジェクトをダブルクリックします。このデフォ ルトの方法を変更するには、コントロールの[起動方法]プロパティ を設定します(前の表を参照)。開発時は、ウィンドウ ペインタでオ ブジェクトをアクティブにします。 v ウィンドウ ペインタで OLE オブジェクトをアクティブにするには 1 OLE コントロールのポップアップ メニューから[開く]を選択し ます。 コントロールにオブジェクトが挿入されていない場合は、 [開く] は選択できません。ポップアップ メニューから[オブジェクトの 挿入]を選択して、コントロールにオブジェクトを挿入してくだ さい。 354 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 サーバ アプリケーションが起動され、オブジェクトがオフサイト でアクティブ化されます。 2 サーバ アプリケーション上で、オブジェクトを修正します。 3 更新が終わったら、ハッチング表示の枠線の外をクリックして、オ ブジェクトを非アクティブにします。 サーバ アプリケーションの[ファイル]メニューから[閉じる] または[閉じて戻る]を選択することもできます。 OLE コントロール内のオブジェクトの変更 ウィンドウ ペインタで、OLE コントロール内のオブジェクトの変更や 削除ができます。 v OLE コントロールからオブジェクトを削除するには • OLE コントロールのポップアップ メニューから[オブジェクトの 削除]を選択します。 これで OLE コントロール内のオブジェクトは削除されたので、ア クティブ化できません。 [削除]は選択しないでください。ウィン ドウから OLE コントロールが削除されます。 v OLE コントロールにオブジェクトを挿入するには 1 コントロールのポップアップ メニューから[オブジェクトの挿入] を選択します。 オブジェクトの挿入 ダイアログボックスが表示されます。 2 [新規作成]タブを選択してサーバ アプリケーションを選択する か、コントロールを定義したときと同様に、[ファイルから作成] タブを選択してファイルを指定します。 3 [OK]をクリックします。 実行時のオブジェクト の変更 InsertObject、InsertFile、InsertClass、ま た は LinkTo 関 数 を 呼 び 出 し て、 OLE コントロールに OLE オブジェクトを挿入できます。Cut 関数また は Clear 関数を呼び出して、OLE コントロールから OLE オブジェクト を削除できます。 ユーザの OLE コントロールの使い方 OLE コントロールが配置されたウィンドウが開くと、PBL(アプリケー ションが作成されている場合は、PBD または EXE ファイル)内の OLE コントロールに格納された情報を使用して、データが表示されます。 アプリケーション テクニック 355 OLE コントロールと挿入可能なオブジェクト エンド ユーザがダブルクリックするか、コントロールをタブで選択す るか、スクリプトで Activate 関数を呼び出して、オブジェクトがアク ティブ化されると、サーバ アプリケーションが起動され、OLE コント ロール内でオブジェクトが編集できます。OLE コントロール内でオブ ジェクトが編集できない場合は、オフサイトで編集できます。 エンド ユーザがオブジェクトを変更すると、OLE コントロールのデー タは最新の状態に更新されます。オブジェクトが OLE コントロール内 で編集されているときは、データが更新されていることは明らかです が、オフサイトで編集している場合も同じように更新されます。ほと んどのサーバ アプリケーションは、連続的にではなく定期的にオブ ジェクトを更新します。そのため、ユーザが認識するのは、コントロー ルの内容に対する定期的な変更だけかもしれません。また、オフサイ トの編集を終了するときは、自動的に最後に行った変更が更新されま す。したがって、OLE コントロールの内容もそのときのタイミングで 変更が反映されます。しかし、安全のためには、オフサイトの編集を 終了する前に、サーバ アプリケーションで Update コマンドを選択して おく必要があります。 リンクと埋め込み アプリケーションでは、OLE オブジェクトはリンクすることも埋め込 むこともできます。どちらの方法を選択するかは、どのようにデータ を管理したいかによって決まります。 データの埋め込み オブジェクトを埋め込んだ場合、そのデータはアプリケーションに保 持されます。開発時には、そのデータはアプリケーションの PBL ファ イルに保存されます。また、アプリケーションが完成すると、EXE ファ イルや PBD ファイルに保存されます。このデータはユーザのためのテ ンプレートまたは開始点です。埋め込みオブジェクトは構築したアプ リケーションの一部として保存されているため、実行中にそのデータ を編集することはできますが、変更内容は保存されません。 オブジェクトの埋め込みは、たとえばレター フォームの本文のよう な、変更を行わないデータに適した方法です。また、変更してどこか ほかのところに保持するデータの開始点として使用するのに適してい ます。 実行時にデータを保存するには、SaveAs 関数と Open 関数を使用して、 ファイルまたは OLE ストレージにデータを保存することができます。 356 PowerBuilder 第 19 章 データのリンク アプリケーションにおける OLE の使い方 オブジェクトのリンクでは、データそのものではなく、データへの参 照をアプリケーションに含めます。アプリケーションは、表示を目的 としたデータの画像も格納します。サーバ アプリケーションが、実際 のデータ(通常、ファイルに保存されるデータ)を取り扱います。そ のため、ほかのアプリケーションからも同じデータにリンクできます。 アプリケーションがデータに加えた変更は、リンクしているすべての 文書に現れます。 リンクには優れた点が 2 つあります。 • 複数のアプリケーションから同一のデータにアクセスできる • サーバ アプリケーションがデータの保存を管理する。そのデータ にアクセスする PowerBuilder アプリケーションが 1 つしかなくて も、データは変更できる リンク情報の管理は、PowerBuilder ではなくサーバ が行います。起動するサーバ、および使用するファイル内のデータ ファ イルや項目といった情報は、OLE オブジェクトによって PowerBuilder に通知されます。サーバは、データを提供し、そのデータを更新して 元のデータ ファイルに保存し、さらに、その項目に関する情報(たと えば、リンクした列の範囲内に列を挿入した場合の覚え書きといった 情報)を更新します。 リンク情報の管理 中断されたリンクの修復 サーバがリンクを管理しているので、開発者 は、OLE オブジェクトが埋め込まれているのかリンクされているのか を気にせずに、そのオブジェクトをアプリケーション内で移動したり 操作したりすることができます。 ファイルの移動、名前の変更、または削除などが原因でリンクが中断さ れた場合は、コントロールの[リンクの更新オプション]の設定内容に よって、それにどう対処するかが決まります。 [リンクの更新オプショ ン]が「自動」に設定されている場合は、PowerBuilder がダイアログボッ クスを表示して、ファイルの検索を指示します。UpdateLinksDialog 関数 を使用して、スクリプトで同じダイアログボックスを表示することが できます。また、リンクは、LinkTo 関数を使用してスクリプトで行う ことができます。 コントロールには、リンクされているオブジェクトが、そのオブジェ クトを開いたときと同じ画像で表示されます。 アプリケーション テクニック 357 OLE コントロールと挿入可能なオブジェクト オフサイト アクティブ化とインプレース アクティブ化 アプリケーション実行時に、エンド ユーザが OLE コントロール上の オブジェクトをアクティブにすると、PowerBuilder は、埋め込まれて いるオブジェクトをインプレース アクティブ化しようとします。つま り、エンド ユーザによるそのオブジェクトの操作は、PowerBuilder の ウィンドウ内部で行われます。サーバ アプリケーションが提供するメ ニューは、PowerBuilder アプリケーションのメニューとマージされま す。メニューのマージは、メニュー ペインタで管理できます(359 ペー ジの「インプレース アクティブ化に対するメニュー」参照)。 コントロールがインプレース アクティブ化されると、幅広のハッチン グ表示の枠線が現れます。 オフサイト アクティブ化とは、サーバ アプリケーションが開き、サー バのウィンドウ上でオブジェクトの内容(文書など)が開かれること です。この場合は、サーバのメニューすべてが使用できます。コント ロール自体は斜線ストライプの影が付けられて表示され、オブジェク トがサーバ アプリケーションで開いていることが示されます。 インプレース アクティブ化の制限 PowerBuilder が OLE オブジェクトをインプレース アクティブ化でき るかどうかは、サーバの機能によって決まります。OLE 1.0 オブジェ クトは、インプレース アクティブ化できません。また、OLE 2.0 標準 は、リンクされたオブジェクトがインプレースではなくオフサイトで アクティブ化するように指定しています。 ウィンドウ ペインタ上では、オブジェクトは常にオフサイト アクティ ブ化されます。 358 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 デフォルトの動作形態は、スクリプトで Activate 関数を呼び出し、オブ ジェクトをインプレースまたはオフサイトのどちらでアクティブ化す るかを指定して変更することができます。コントロールの[起動方法] が「スクリプト(activatemanually!)」に設定されている場合は、Activate 関数の呼び出しを DoubleClicked イベント(またはほかのイベント)に 対するスクリプトに記述します。 デフォルトの動作形態 の変更 ole_1.Activate(Offsite!) コントロールがアクティブ化されない場合 空のコントロール、つまり OLE オブジェクトと関連付けられていない OLE コントロールは、アクティブ化できません。エンド ユーザに OLE オブジェクトを選択させたい場合は、InsertObject 関数を呼び出すスク リプトを記述します。 また、コントロール上のオブジェクトをリンクするときにリンクする ファイルが見つからない場合も、そのコントロールをアクティブ化で きません。ただし、 [リンクの更新オプション]が「自動」に設定され ている場合は、PowerBuilder がダイアログボックスを表示して、エン ド ユーザにファイルを検索させることができます。 [リンクの更新オプション]が「スクリプト(activatemanually!)」に設 定されている場合は、UpdateLinksDialog 関数を使用して、スクリプトで ダイアログボックスを表示したり、LinkTo 関数を使用して、スクリプ トで別ファイルにリンクしたりすることができます。 インプレース アクティブ化に対するメニュー オブジェクトがインプレース アクティブ化すると、サーバ アプリケー ションのメニューは、PowerBuilder アプリケーションのメニューと マージされます。メニュー ペインタの[マージ オプション]の設定内 容によって、2 つのアプリケーションのメニューのマージ方法が決定 されます。選択肢としては、「merge!」と「exclude!」のほかに、標準 メニュー名があります。 v OLE オブジェクトがアクティブ化されたときに、アプリケーションのメニュー を制御するには 1 メニュー ペインタでメニューを開きます。 2 メニュー バーに表示するメニュー項目を選択します。[マージ オ プション]の設定は、ドロップダウン メニューのメニュー項目で はなく、メニュー バーのメニュー項目だけに適用されます。 アプリケーション テクニック 359 OLE コントロールと挿入可能なオブジェクト 3 プロパティ ページで、適切な[マージ オプション]の設定を選択 します。表 19-1 は設定のリストです。 表 19-1: [マージ オプション]の設定 オプション filemenu! 意味 コンテナ アプリケーション (PowerBuilder アプリケーション) のメニュー バーの一番左に表示 されるメニュー。サーバの[ファ イル]メニューは表示されない editmenu! コンテナ アプリケーションの[編 集]メニューは表示されない。サー バの[編集]メニューが表示される windowmenu! 開いているシートのリストを持つ コンテナ アプリケーションのメ ニュー。サーバの[ウィンドウ] メニューは表示されない helpmenu! コンテナ アプリケーションの[ヘ ルプ]メニューは表示されない。 サーバの[ヘルプ]メニューが表 示される merge! サーバ アプリケーションの最初 のメニューの後に、そのメニュー が表示される exclude! オブジェクトがアクティブな間 は、メニューは表示されない 4 標準メニューの標準的 な割り当て アクティブ化されたオ ブジェクトのメニュー バー 360 メニュー バーに 表示される メニューの入手先 コンテナ サーバ コンテナ サーバ コンテナ メニュー バーにある各メニュー項目に対して、操作手順 2 と 3 を 繰り返します。 通常、 [マージ オプション]の「filemenu!」、 「editmenu!」、 「windowmenu!」、 および 「helpmenu!」は、それぞれ[ファイル]、[編集]、 [ウィンド ウ]、[ヘルプ]の各メニューに割り当てます。実際のメニュー名が国 際的なアプリケーションにおいては異なるかもしれないので、 [マージ オプション]を使用して正しい関係を設定します。 [マージ オプション]を設定すると、メニュー バーに、コンテナの [ファイル]と[ウィンドウ]メニュー、およびサーバの[編集]と [ヘルプ]メニューを表示できます。 「merge!」が設定されたすべての メニューは、メニュー バーの適切な位置に挿入されます。また、メ ニュー バーには、サーバが適切であると判断したほかのメニューも表 示されます。 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 OLE コントロール上でのオブジェクトの修正 OLE オブジェクトが OLE コントロールに表示されているときは、その オブジェクトとそれを作成したアプリケーション(OLE サーバ)の操 作が可能です。また、そこで行われる可能性のある操作をスクリプト に記述することもできます。この節では、以下の方法について説明し ます。 • OLE オブジェクトをアクティブにして、一般的なコマンドをサー バに送る方法 • コントロール内のオブジェクトの変更と保存方法 • データまたはプロパティがイベントによって変更されたときに、 それを検出する方法 コントロールのオートメーションについては、380 ページの「スクリ プトにおける OLE オブジェクト」を参照してください。 OLE オブジェクトのアクティブ化 通常は、OLE コントロールでは、ダブルクリックでオブジェクトをア クティブ化できます。また、Activate 関数を呼び出せば、スクリプトか らもそのオブジェクトをアクティブ化できます。OLE コントロールの Activation プロパティが Manual に設定されている場合は、Activate 関数 を呼び出してサーバの編集セッションを開始しなければなりません。 ole_1.Activate(InPlace!) 一般的な OLE アクションは、DoVerb 関数を呼び出すことによって起動 できます。バーブ(Verb)とは、実行されるアクションを指定する整 数値のことです。各整数値の意味は、サーバによって異なります。通 常、デフォルトのアクション(0 を指定)は、編集です。また、この アクションはオブジェクトのアクティブ化も同時に行います。 たとえば、ole_1 コントロールが Microsoft Excel のスプレッドシートを 含んでいる場合は、以下の式によってオブジェクトをアクティブ化し て、編集可能にします。 ole_1.DoVerb(0) サーバ アプリケーションのマニュアルを調べ、サポートされている バーブの内容を確認してください。OLE バーブによる、オブジェクト の操作は比較的制限されます。柔軟なインタフェースを必要とする場 合は、オートメーションを使用してください。ただし、OLE 1.0 サー バは、バーブしかサポートしておらず、オートメーションはサポート していません。 アプリケーション テクニック 361 OLE コントロールと挿入可能なオブジェクト OLE コントロール上のオブジェクトの変更 PowerBuilder は、OLE コントロール上のオブジェクトを変更するため の関数をいくつか提供しています。これらの関数は、表 19-2 に示すよ うに、オブジェクトをエンド ユーザに選択させるか、オブジェクトを リンクするか埋め込むかによって使い分けます。 表 19-2: OLE コントロール上のオブジェクトを変更するための関数 選択条件 オブジェクトをエンド ユーザに選択させる。 コントロールの Contents プロパティが Any の 場合は、オブジェクトをリンクしても埋め込 んでもかまわない 指定したサーバで新たなオブジェクトを作成 し、コントロールに埋め込む 既存のオブジェクトのコピーをコントロール に埋め込む 既存のオブジェクトをコントロールにリンク する 既存のオブジェクトをファイルかストレージ から開く。ファイルの情報が、オブジェクト をリンクするか埋め込むかを決める 関数 InsertObject InsertClass InsertFile LinkTo Open 図 19-1 は、リンクか埋め込みかの選択ができない 3 つの関数の動きを 示しています。 図 19-1: リンクか埋め込みかの選択ができない関数 362 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 Blob 型変数に保持されている OLE オブジェクトのデータは、OLE コ ントロールの ObjectData プロパティに代入できます。 blob myblob ...// Blob 型変数に保持した OLE データを代入するコード ole_1.ObjectData = myblob コントロールの Contents プロパティによって、埋め込みやリンクの対 象となるオブジェクトを受け入れるかどうかが指定されます。これに よって、エンド ユーザにオブジェクトの挿入 ダイアログボックスで埋 め込みかリンクかを選択させるかどうかが決まります。また、Contents プロパティによって、使用可能な関数が決められます。このプロパティ が許可しない方法を選択する関数を呼び出すと、その関数の実行は失 敗します。 オブジェクト ブラウ ザでの OLE 情報 使用しているシステムにインストールされている OLE サーバ アプリ ケーションの登録名を検索する場合は、オブジェクト ブラウザを使 用します。ここに表示される名前は、InsertClass、ConnectToObject、 ConnectToNewObject の各関数の引数として使用できます(370 ページ の「プログラム可能な OLE オブジェクト」を参照)。 OLE とオブジェクト ブラウザについての詳細は、400 ページの「オブ ジェクト ブラウザでの OLE 情報」を参照してください。 クリップボードの使い 方 メニュー項目のスクリプトに Cut、Copy、Paste の各関数を記述すると、 クリップボード機能がエンド ユーザに提供されます。Cut 関数や Copy 関数を OLE コントロールに対して呼び出すと、そのコントロール上の OLE オブジェクトがクリップボードにコピーされます。同様に、エン ド ユーザがサーバ アプリケーションでこれらのメニュー項目を選択 すると、データがクリップボード上にコピーされます。これらの関数 は、メニュー項目に限らず、任意のスクリプトで記述できます。 OLE コントロールには、オブジェクトを挿入するための Paste 関数が いくつか用意されています。これらの関数には、貼り付けるオブジェ クトをリンクするか、埋め込むかの違いがあるだけです。 表 19-3: Paste 関数 選択条件 クリップボード上のオブジェクトをコント ロールに埋め込む 関数 クリップボード上のオブジェクトをコント ロールに貼り付けてリンクする 貼り付けるオブジェクトを埋め込むか、リン クするかをエンド ユーザに選択させる PasteLink アプリケーション テクニック Paste PasteSpecial 363 OLE コントロールと挿入可能なオブジェクト 通常 Paste 関数を用いて処理しているスクリプトで、貼り付け先が OLE コントロールになる場合があるときは、以下のようなスクリプト で PasteSpecial 関数(または PasteLink 関数)を呼び出します。 graphicobject lg_obj datawindow ldw_dw olecontrol lole_ctl // フォーカスされているオブジェクトを取得します。 lg_obj = GetFocus() // オブジェクトの種類を基に、クリップボード上のデータを挿入しま す。 CHOOSE CASE TypeOf(lg_obj) CASE DataWindow! ldw_dw = lg_obj ldw_dw.Paste() ... CASE OLEControl! lole_ctl = lg_obj lole_ctl.PasteSpecial() END CHOOSE 埋め込まれたオブジェ クトの保存 ウィンドウの設計時に埋め込まれた OLE オブジェクトは、OLE コント ロールとともにライブラリに保存されます。しかし、アプリケーショ ン実行時に埋め込まれたオブジェクトは、コントロールとともに保存 できません。アプリケーションの実行モジュールやライブラリは、読 み出し専用だからです。このオブジェクトを保存したい場合は、その データをファイルかデータベースに保存しなければなりません。 たとえば、以下のスクリプトは、SaveAs 関数を使用してオブジェクト をファイルに保存しています。ここでは、エンド ユーザに対してファ イル名の入力を指示し、コントロール上のオブジェクトを、サーバ ア プリケーション本来のデータとしてではなく、OLE データ ファイルと して保存します。このファイルは、スクリプトによって、別のセッショ ンのコントロール上で開くこともできます。 string myf ilename, mypathname integer result GetFileSaveName("Select File", mypathname, & myfilename, "OLE", & "OLE Files (*.OLE),*.OLE") result = ole_1.SaveAs(myfilename) 364 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 通常、ファイルに保存した OLE データはサーバ アプリケーションで 直接開くことができません。しかし、PowerBuilder でそのオブジェク トを開いてからサーバ アプリケーションを起動することはできます。 オブジェクトをコントロールに埋め込むと、実際のデータは Blob デー タとしてコントロールの ObjectData プロパティに保持されます。埋め 込んだオブジェクトをデータベースに保存して後から検索したい場合 は、そのオブジェクトを Blob データとして保存します。Blob 型変数と コントロール間のデータ転送は、Blob データをコントロールの ObjectData プロパティに代入したりその逆を行ったりして、実行します。 blob myblob myblob = ole_1.ObjectData Blob データは、埋め込み SQL の UPDATEBLOB 文を使用してデータベー スで更新することができます(『PowerScript リファレンス』マニュア ルを参照)。 また、OLE オブジェクトは、SaveAs 関数や Save 関数を使用して、 PowerBuilder の OLEStorage 型変数に保持できます(405 ページの「ス トレージを開く、保存する」を参照)。 リンクしたオブジェクトをサーバに保存しても、リンク情報に影響は ありません。したがって、その開いているオブジェクト自体は、保存 する必要はありません。しかし、エンド ユーザがそのオブジェクト名 を変更したり、リンクした項目の範囲に影響を及ぼした場合は、Save 関数を呼び出して、リンク情報を保存したりしなければなりません。 OLE コントロールにおけるイベント サーバ アプリケーションで OLE オブジェクトに影響するアクション が起きたことを PowerBuilder に通知するイベントがいくつか用意され ています。 データのイベント データに関するイベントは、次のとおりです。 • DataChange イベント データが変更されたとき • Rename イベント オブジェクトの名前が変更されたとき • Save、SaveObject イベント データが保存されたとき • ViewChange イベント エンド ユーザがデータの表示を変更したとき これらのイベントが起こると、その変更内容は OLE コントロールに自 動的に反映されます。オブジェクトに対する名前の変更、保存、また はオブジェクトの変更が行われたときに、何らかの処理を必要とする 場合は、適切なスクリプトを記述して対処します。 アプリケーション テクニック 365 OLE カスタム コントロール OLE アーキテクチャが起因して、上記イベント内で OLE オブジェクト を処理できない場合があります。実行すると、ランタイム エラーを引 き起こしかねません。通常は、PostEvent 関数を使用して非同期イベン ト ハンドラにイベントをポストします。SaveObject イベントをポスト する必要はないので、サーバ アプリケーションがオブジェクトを保存 する際に、常にオブジェクト内のデータをファイルに保存したい場合 には、このイベントが便利です。 プロパティのイベント サーバがプロパティ通知をサポートしている場合は、サーバのプロパティ 値が変更されたときに、PropertyRequestEdit イベントと PropertyChanged イベントが起動されます。変更をキャンセルしたり、古い値を保存し たり、または新しい値を読み込むスクリプトを記述したりすることが できます。 プロパティ通知の詳細については、393 ページの「ホット リンクの作 成」を参照してください。 OLE カスタム コントロール [コントロール]ドロップダウン ツールバーの[OLE]ボタンをクリッ クして、OLE コンテナに OLE オブジェクトまたは OLE カスタム コン トロールのどちらを挿入するかを選択できます。OLE カスタム コント ロール(ActiveX コントロール)を選択すると、コンテナの種類と内容 が確定されます。後から、挿入するオブジェクトを選択したり、別の ActiveX コントロールを選択したりすることはできません。 ActiveX コントロールには、ActiveX コントロール自身のプロパティ、 イベント、関数があります。スクリプトで ActiveX コントロールのプ ロパティとメソッドを呼び出す際に、ActiveX コントロールが変更され ないようにすることは、エラーの回避にもなります。 OLE カスタム コントロールの設定 PowerBuilder のカスタム コントロール コンテナには、どんな ActiveX コントロールにも適用するプロパティがあります。ActiveX コントロー ルは、ActiveX コントロール自身のプロパティを持っています。この節 では、それぞれの種類のプロパティの用途と設定方法について説明し ます。 PowerBuilder のプロ パティ 366 OLE カスタム コントロールのプロパティには、2 つの用途があります。 PowerBuilder 第 19 章 • アプリケーションにおける OLE の使い方 ほかのコントロールと同様に、コンテナの表示と動作の形態を設 定する [全般]プロパティ ページの標準設定([表示可能]、[使用可能] など)と同様に、表示位置、ポインタ、およびドラッグアンドド ロップの設定ができます。 • ActiveX コントロールが使用できるデフォルトの情報を提供する OLE コンテナのフォント情報や表示名をアンビエント プロパティ と呼びます。PowerBuilder が直接アンビエント プロパティを使用 して ActiveX コントロールにテキストを表示することはありませ ん。ActiveX コントロールがアンビエント プロパティを認識でき る場合は、ActiveX コントロールは、PowerBuilder のプロパティを 使用できます。ActiveX コントロールは、テキストを表示したり、 タイトル バーに OLE コンテナの名前を表示したりできます。 v OLE カスタム コントロールの PowerBuilder プロパティを変更するには 1 OLE コントロールをダブルクリックするか、コントロールのポッ プアップ メニューから[プロパティ]を選択します。 OLE カスタム コントロール プロパティ シートが表示されます。 2 コントロールに名前を付けます。スクリプトではこの名前を使用 します。デフォルト名は「ole_」の接頭辞に数字を組み合わせたも のです。 3 [全般]プロパティ ページやほかのページにあるプロパティの値も 適切な値に設定します。 4 プロパティの設定が終わったら、 [OK]ボタンをクリックします。 コントロールの説明 ウィンドウまたはコントロールの[タグ]プロパティに、使用してい る ActiveX コントロールに関する説明を入力します。別の環境でこの ウィンドウを使用する際に ActiveX コントロールがインストールされ ていない場合、ウィンドウがどの ActiveX コントロールを使用してい たかを簡単に調べることができます。 ActiveX コントロール のプロパティ ActiveX コントロールは、通常、ActiveX コントロール自身のプロパ ティと、プロパティの値を設定するためのプロパティ シートを持って います。ActiveX コントロールのプロパティは、PowerBuilder の OLE コンテナではなく、ActiveX コントロールの表示と動作の形態を管理し ます。 アプリケーション テクニック 367 OLE カスタム コントロール v OLE カスタム コントロール内の ActiveX コントロールのプロパティを設定 するには 1 コントロールのポップアップ メニューまたは[全般]プロパティ ページから、[OLE コントロール プロパティ]を選択します。 2 プロパティの値を設定したら、[OK]ボタンをクリックします。 OLE コントロールのプロパティ シートは、ActiveX コントロールのプ ロパティの一部しか提示していない場合があります。その場合、スク リプトで ActiveX コントロールのプロパティ シートにないプロパティ を設定できます。 ActiveX コントロールのプロパティについての詳細は、ActiveX コント ロールのマニュアルを参照してください。 ActiveX コントロールのプログラミング ActiveX コントロールのプロパティを設定したり、ActiveX コントロー ルの関数を呼び出すスクリプトを記述したりして、ActiveX コントロー ルの機能が使用できます。ActiveX コントロールの開発者が提供するイ ンタフェースによって、1 回の関数呼び出しで一連のアクティビティ または個々のプロパティ設定が起動される場合と、関数呼び出しで ユーザに ActiveX コントロールのアクションを制御させる場合があり ます。 ActiveX コントロールは常にアクティブです。開いたり、アクティブに したりする必要のあるオブジェクトを持っていません。つまり、エン ド ユーザは、OLE カスタム コントロールをダブルクリックして、OLE サーバを起動することはしません。しかし、ActiveX コントロールの処 理を開始する関数を呼ぶために、DoubleClicked イベントまたはほかの イベントに対するスクリプトを記述することができます。 スクリプトでのプロパ ティの設定 ActiveX コントロールのプログラミングは、挿入可能なオブジェクトの オートメーションをプログラムすることと同じです。ActiveX コント ロールのプロパティと関数を指定するには、コンテナの Object プロパ ティを使用します。 次の構文は、ActiveX コントロールのプロパティ値にアクセスします。 この構文は、式を記述できる箇所であれば、その使用箇所に制限はあ りません。この式のデータ型は Any です。式が評価されると、式の値 は、コントロール プロパティのデータ型の値になります。 olecontrol.Object.ocxproperty 368 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 次の構文は、ActiveX コントロールの関数を呼び出します。適切なデー タ型の変数で、戻り値を取得できます。 { value } = olecontrol.Object.ocxfunction ( { argumentlist } ) プロパティのアクセス 時のエラー PowerBuilder のコンパイラは、ActiveX コントロールのプロパティと関 数にアクセスするための正しい構文を認識しないため、Object プロパ ティの後の構文をチェックしません。これは、ActiveX コントロールの プログラミングに必要な柔軟性につながります。しかし、プロパティ や関数の名前が間違っていたり、不足していたりすると、アプリケー ションが実行時にエラーを起こす可能性があります。 PowerBuilder は、OLE のエラー処理をするため、ExternalException と Error という 2 つのイベントを用意しています。ActiveX control が組み 込みエラー イベントを定義した場合、PowerBuilder OLE コントロール コンテナには、追加イベントである ocx_event があります。これらのイ ベントを使用すると、割り込みの形でエラー処理ができ、SystemError イベントが起動してアプリケーションが終了することはありません。 また、例外ハンドラ TRY-CATCH も使用できます。 詳細については、390 ページの「エラー処理」を参照してください。 ActiveX コントロール のイベントの使い方 ActiveX コントロールには、ActiveX コントロール自身が持つイベント があります。PowerBuilder は、ActiveX コントロールのイベントと OLE カスタム コントロール コンテナのイベントをマージします。ActiveX コントロールのイベントは、PowerBuilder のイベントとともに、イベ ント リストビューに表示されます。PowerBuilder のイベントに対する スクリプトと同じように、PowerScript で ActiveX コントロールのイベ ントに対するスクリプトも記述できます。ActiveX コントロールのプロ パティとメソッドを参照するには、OLE カスタム コントロールの Object プロパティを使用します。 ActiveX コントロールのイベントと PowerBuilder のイベントの唯一の 違いは、イベントが起動されるタイミングです。ActiveX コントロール のイベントの詳細については、ActiveX コントロールのマニュアルを参 照してください。ActiveX コントロールの開発元が、ActiveX コント ロールのイベント、プロパティ、関数に関するマニュアルを提供して います。 ActiveX コントロールのプロパティとメソッドの一覧は、PowerBuilder オブジェクト ブラウザで参照できます。詳細については、400 ページ の「オブジェクト ブラウザでの OLE 情報」を参照してください。 アプリケーション テクニック 369 プログラム可能な OLE オブジェクト ActiveX コントロールの新規バージョン ActiveX コントロールの新規バージョンをインストールして、その ActiveX コントロールに新規のイベントがあった場合でも、ウィンドウ ペインタの[イベント]ドロップダウン リストボックスには新規のイ ベントが追加されません。新規のイベントを使用するには、既存のイ ベントのスクリプトとともに、OLE カスタム コントロールを削除して 再作成しなければなりません。新規のイベントを使用しない場合は、 コントロールをそのままにしておき、更新された既存の ActiveX コン トロール イベントを使用することができます。 プログラム可能な OLE オブジェクト OLE オブジェクトをスクリプトで操作するときは、必ずしも、ウィンド ウ上に OLE コントロールを配置しなくてもかまいません。PowerBuilder アプリケーションで表示する必要のない OLE オブジェクトは、コント ロールと無関係に作成し、サーバ アプリケーションに接続し、関数呼 び出しやプロパティを設定することができます。サーバ アプリケー ションが、関数を実行して、OLE オブジェクトのプロパティを変更し ます。つまり、OLE オブジェクトを変更します。 アプリケーションの中には、表示、非表示の指定が可能なものがあり ます。表示を指定すれば、エンド ユーザは、そのアプリケーションを アクティブ化し、サーバ アプリケーションのコマンドやツールを使用 して、OLE オブジェクトを操作できます。 OLEObject オブジェクト型 PowerBuilder の OLEObject オブジェクト データ型は、オートメーショ ン機能で用いるために設計されています。OLEObject 変数は動的オブ ジェクトの一種です。つまり、コンパイラは、このオブジェクトに対 するどのようなプロパティ名、関数名、パラメータ リストも受け入れ ます。PowerBuilder は、それらのプロパティと関数が有効かどうかを 知る必要がありません。このオブジェクトのメソッドの呼び出しやプ ロパティの設定は、そのオブジェクトを作成したサーバ アプリケー ションによって把握されています。これらの関数やプロパティが、ア プリケーション実行時に存在しない場合は、実行時エラーが起こりま す。 370 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 OLEObject 変数を使用する手順は次のとおりです。 1 変数を宣言して、インスタンスを作成します。 2 OLE オブジェクトに接続します。 3 OLE サーバのプロパティと関数を使用して、適切な OLE オブジェ クトを操作します。 4 OLE オブジェクトとの接続を解除して、インスタンスを破棄しま す。 これらの手順は、次に説明します。 OLEObject 変数の宣 言 OLEObject 変数を宣言して、メモリを割り当てる必要があります。 OLEObject myoleobject myoleobject = CREATE OLEObject OLE コンテナ コントロール (OLEControl や OLECustomControl)の Object プロパティは、OLEObject オブジェクト データ型です。 サーバへの接続 OLEObject オブジェクトと OLE サーバとの接続は、いずれかの ConnectToObject 関数を使用して行います。オブジェクトに接続する と、適切なサーバが起動されます。 表 19-4: ConnectToObject 関数 選択条件 指定した OLE サーバで新たなオブジェクトを 作成する。この関数の機能は、OLE コント ロールの InsertClass 関数に似ている サーバのセキュリティにより作成権限があ り、新規オブジェクトが PowerBuilder の OLEObject 変数に関連付けられる場合は、指 定されたリモート サーバ アプリケーションに 新たな OLE オブジェクトを作成する 既存の OLE オブジェクトをファイルから開 く。OLE クラスを指定していない場合は、 PowerBuilder がファイルの拡張子を調べて、 起動するサーバを決める OLE オブジェクトを PowerBuilder の OLEObject 変数に関連付け、リモート サーバ アプリケーションを起動する 関数 ConnectToNewObject ConnectToNewRemoteObject ConnectToObject ConnectToRemoteObject 接続を確立したら、オートメーションのために用意されている一連の サーバ コマンドを使用して、オブジェクトの操作ができます(380 ペー ジの「スクリプトにおける OLE オブジェクト」を参照)。 アプリケーション テクニック 371 プログラム可能な OLE オブジェクト コマンドにアプリケーション修飾子を付ける必要はありません。アプ リケーション修飾子は、サーバに接続したときに、アプリケーション のクラスとしてすでに指定されています。たとえば、以下のコマンド は、OLEObject 変数を作成し、Microsoft Word の OLE インタフェース (word.application)に接続し、文書を開いて文書に関する情報を表示し、 テキストを挿入し、編集された文書を保存し、サーバをシャットダウ ンします。 OLEObject o1 string s1 o1 = CREATE oleobject o1.ConnectToNewObject("word.application") o1.documents.open("c:\temp\temp.doc") // オブジェクトを表示状態にし、 // MS Word ユーザ名とファイル名を表示します。 o1.Application.Visible = True s1 = o1.UserName MessageBox("MS Word ユーザ名 ", s1) s1 = o1.ActiveDocument.Name MessageBox("MS Word 文書名 ", s1) // 新規パラグラフ内にテキストを挿入します。 o1.Selection.TypeParagraph() o1.Selection.typetext(" このテキストを挿入 ") o1.Selection.TypeParagraph() // 最初のブックマークにテキストを挿入します。 o1.ActiveDocument.Bookmarks[1].Select o1.Selection.typetext("Hail!") // End と名前の付いたブックマークにテキストを挿入します。 o1.ActiveDocument.Bookmarks.item("End").Select o1.Selection.typetext("Farewell!") // 文書を保存し、サーバをシャットダウンします。 o1.ActiveDocument.Save() o1.quit() RETURN Microsoft Word の旧バージョンでは、 word.application のかわりに word.basic を使用してください。以下のコマンドは、Microsoft Word バージョン 7.0 の OLE インタフェース(word.basic)に接続し、文書を開き、ブッ クマークの位置まで移動し、指定されたテキストを挿入します。 myoleobject.ConnectToNewObject("word.basic") 372 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 myoleobject.fileopen("c:\temp\letter1.doc") myoleobject.editgoto("NameAddress") myoleobject.Insert(" 挿入するテキスト ") 修飾子として word.application や word.basic (ConnectToNewObject 関数 のクラス)は付けません。 // 不適切なコマンド修飾子 myoleobject.word.basic.editgoto("NameAddress") Microsoft Word バージョン 7.0 の使用上の注意 OLEObject 変数では、word.basic がサーバ アプリケーション Word バー ジョン 7.0 のクラス名となります。一方、コントロール内のオブジェ クトでは、application.wordbasic 修飾子を使用してオブジェクトの階層 構造をどのように移動して目的の wordbasic オブジェクトにアクセス するのかを、Word に知らせなければなりません。 サーバのシャットダウ ンおよび接続解除 オートメーションとともにアプリケーションを終了したら、明示的に シャットダウンすることをサーバに終了を知らせる必要があります。 また、サーバとの接続を解除して、オブジェクトのメモリを解放する 必要があります。 myoleobject.Quit() rtncode = myoleobject.DisconnectObject() DESTROY myoleobject ガベージ コレクションを使って OLEObject 変数を破棄できます。 OLEObject 変数を破棄すれば、サーバとの接続を自動的に解除します。 ガベージ コレクションを使って解除する方をお勧めしますが、OLEObject 変数が使用しているメモリをただちに解放したい場合で、さらにメモ リがアプリケーションのほかの部分で使用していないことが明らかな 場合は、上記のスクリプトでも示されているように、明示的に接続を 解除して、OLEObject 変数を破棄できます。 詳細については、49 ページの「ガベージ コレクションとメモリ管理」 を参照してください。 OLEControl、OLECustomControl、OLEObject データ型の代入 OLEObject 変数に OLE コントロール(OLEControl オブジェクト デー タ型)や ActiveX コントロール(OLECustomControl オブジェクト デー タ型)を直接代入することはできません。 アプリケーション テクニック 373 プログラム可能な OLE オブジェクト コントロールのベンダがプログラム識別子(vendor.application の形式) を公開している場合は、ConnectToNewObject 関数でこの識別子を指定 することで、ビジュアル コントロールを使用せずに、プログラム可能 なインタフェースに接続できます。しかし、ActiveX コントロールで は、このテクニックを使用すると ActiveX コントロールのイベントが 使用できなくなります。ActiveX コントロールでは、このような使用法 を考慮していませんし、ほとんどの場合は役に立ちません。 OLE コントロールの Object プロパティの値を OLEObject 変数に代入し たり、関数の中で OLEObject 型として使用したりすることができます。 たとえば、ウィンドウに OLEControl の ole_1 と OLECustomControl の ole_2 があり、次のように変数を宣言したとします。 OLEObject oleobj_automate この場合、以下のように代入できます。 oleobj_automate = ole_1.Object oleobj_automate = ole_2.Object OLE コントロールの OLEObject プロパティは読み出し専用なので、 OLEObject 型のオブジェクトを代入することはできません。以下のよ うな代入はできません。 ole_1.Object = oleobj_automate // エラー ! OLEObject のイベン ト OLEObject を継承するユーザ オブジェクトを作成して、OLEObject の イベントが実装できます。PowerScript の SetAutomationPointer 関数は、 OLE オートメーションを使用できるように、OLE のオートメーション ポインタを子孫オブジェクトに割り当てます。 oleobjectchild は、OLEObject の子孫オブジェクトで、ExternalException や Error などのイベントを実装するものとします。以下に示すコード は、OLEObject と oleobjectchild のインスタンス(OLEObject の子孫とな るユーザ オブジェクト)を作成し、Excel に接続してからオートメー ション ポインタを oleobjectchild に割り当てます。 OLEObject ole1 oleobjectchild oleChild ole1 = CREATE OLEObject ole1.ConnectToNewObject( "Excel.Application") oleChild = CREATE oleobjectchild oleChild.SetAutomationPointer( ole1 ) これで、オートメーションで olechild を使用できます。 374 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 オートメーション オートメーションに関する各手順は、単一のスクリプトの中に含まれ ていたり、ウィンドウ上のいくつかのコントロールのアクションに分 離されていたりします。エンド ユーザをオートメーションによる処理 に関与させたい場合は、以下のようにします。 • OLE オブジェクトをウィンドウのインスタンス変数として宣言する • その変数のインスタンスを作成し、ウィンドウの Open イベントで サーバに接続する • エンド ユーザによるリストボックスからの選択やエディット ボッ クスへの入力に応答して、サーバにコマンドを送る • ウィンドウの Close イベントで、サーバとの接続を解除し、そのイ ンスタンスを破棄する エンド ユーザをオートメーションに関与させたくない場合は、すべて の処理を単一のスクリプトで行います。 例 : OLE を使用したレター フォームの生成 この例では、Microsoft Word で VBA スクリプティング を使用して、 データウィンドウ オブジェクトから名前と住所を、マルチラインエ ディットから手紙の本文を取り込み、手紙の作成と印刷を行います。 v レター フォームの例をセットアップするには 1 4 つのブックマークがある CONTACT.DOC という名前の Word 文 書を作成し、PowerBuilder ディレクトリに保存します。 ブックマークは次のとおりです。 • name1 – 受取人の名前 • name2 – あいさつ文に入れる名前 • address1 – 受取人の住所(番地、市、県、郵便番号) • body – 手紙の本文 手紙の本文は次のとおりです。 Multimedia Promotions, Inc. 1234 Technology Drive Westboro, Massachusetts January 12, 2001 [bookmark name1] アプリケーション テクニック 375 プログラム可能な OLE オブジェクト [bookmark address1] Dear [bookmark name2]: [bookmark body] Sincerely, Harry Mogul President 会社名や自筆サインのロゴなどを付けて、手紙の形式を充実させ ることもできます。重要な項目は、ブックマークの名前と位置で す。 2 PowerBuilder では、d_maillist というデータウィンドウ オブジェクト を定義します。このデータウィンドウ オブジェクトには、以下の カラムがあります。 id first_name last_name street city state zip データウィンドウ オブジェクトに検索引数の指定 ダイアログ ボックスを表示して、エンド ユーザが手紙を受け取る顧客を選択 できるようにします。 376 PowerBuilder 第 19 章 3 アプリケーションにおける OLE の使い方 dw_mail という データウィンドウ コントロール、mle_body という マルチライン エディット、およびコマンドボタンやピクチャボタ ンなどを含むウィンドウを定義します。 4 データウィンドウ オブジェクト d_maillist をデータウィンドウ コ ントロール dw_mail に割り当てます。 5 データベースと接続し、データをデータウィンドウ オブジェクト に読み取るスクリプトをウィンドウの Open イベントに記述しま す。以下のコードは、SQL Anywhere データベースとの接続を行い ます。そのウィンドウが大規模なアプリケーションの一部の場合、 通常、この接続はアプリケーションの Open イベントに対するスク リプトで行われます。 /************************************************** トランザクション オブジェクトを INI ファイルからセットアップ します。 **************************************************/ SQLCA.DBMS=ProfileString("myapp.ini", & "Database", "DBMS", " ") SQLCA.DbParm=ProfileString("myapp.ini", & "Database", "DbParm", " ") /************************************************** データベースと接続し、その接続が正常かどうかを テストします。 **************************************************/ CONNECT USING SQLCA; IF SQLCA.SQLCode <> 0 THEN MessageBox(" 接続が失敗しました ", " データベースに " & + " 接続できません " + SQLCA.SQLErrText) アプリケーション テクニック 377 プログラム可能な OLE オブジェクト RETURN END IF /************************************************** トランザクション オブジェクトをデータウィンドウ コントロール に対して設定し、データを検索します。 **************************************************/ dw_mail.SetTransObject(SQLCA) dw_mail.Retrieve() 6 [新規メール]ボタンに対するスクリプトを記述します(スクリプ トについては以下を参照)。 スクリプトで、以下の作業をすべて行います。 • OLEObject 変数を作成する • サーバ アプリケーション(word.application)に接続する • データウィンドウ オブジェクトの各行に対して手紙を 1 通生 成する そのために、VBA 文を使用して表 19-5 の作業を実行する 表 19-5: スクリプトの作業 VBA 文 open goto と typetext goto と typetext printout close 作業 ブックマークを備えた文書を開く データウィンドウ オブジェクトの行から名前と住 所を抽出し、それを手紙内の適切な位置に挿入する エンドユーザが mle_body に入力したテキストを手 紙に挿入する 手紙を印刷する 手紙文書を保存せずに閉じる • サーバ アプリケーションとの接続を解除する • OLEObject 変数を破棄する 7 [閉じる]ボタンに対してスクリプトを記述します。ここで必要な コマンドは次の 1 行だけです。 Close(Parent) レター フォームを生 成するスクリプト 以下のスクリプトで、レター フォームの生成と印刷を行います。 OLEObject contact_ltr integer result, n string ls_name, ls_addr /*************************************************** OLEObject 変数にメモリを割り当てます。 378 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 ***************************************************/ contact_ltr = CREATE oleObject /*************************************************** サーバに接続し、エラーをチェックします。 ***************************************************/ result = & contact_ltr.ConnectToNewObject("word.application") IF result <> 0 THEN DESTROY contact_ltr MessageBox("OLE エラー ", & "Microsoft Word に接続できません " & + " コード : " & + String(result)) RETURN END IF /*************************************************** データウィンドウ オブジェクトの各行で、 Word に顧客データを送り、手紙を印刷します。 ***************************************************/ FOR n = 1 to dw_mail.RowCount() /************************************************ ブックマークがある文書を開きます。 ************************************************/ contact_ltr.documents.open("c:\pbdocs\contact.doc") /************************************************ 名字と名前を 1 つの文字列にして、Word の name1 と name2 の各ブックマークに挿入します。 ************************************************/ ls_name = dw_mail.GetItemString(n, "first_name")& + " " + dw_mail.GetItemString(n, "last_name") contact_ltr.Selection.goto("name1") contact_ltr.Selection.typetext(ls_name) contact_ltr.Selection.goto("name2") contact_ltr.Selection.typetext(ls_name) /************************************************ 住所を 1 つの文字列にして、address1 の ブックマークに挿入します。 ************************************************/ ls_addr = dw_mail.GetItemString(n, "street") & + "~r~n" & + dw_mail.GetItemString(n, "city") & + ", " & + dw_mail.GetItemString(n, "state") & + " " & + dw_mail.GetItemString(n, "zip") contact_ltr.Selection.goto("address1") アプリケーション テクニック 379 スクリプトにおける OLE オブジェクト contact_ltr.Selection.typetext(ls_addr) /************************************************ 手紙本文のテキストを Word の body ブックマークに挿入します。 ***********************************************/ contact_ltr.Selection.goto("body") contact_ltr.Selection.typetext(mle_body.Text) /************************************************ 手紙を印刷します。 ************************************************/ contact_ltr.Application.printout() /************************************************ この文書を保存せずに閉じます。 ************************************************/ contact_ltr.Documents.close contact_ltr.quit() NEXT /*************************************************** サーバとの接続を解除し、OLEObject 変数のメモリを解放します。 ***************************************************/ contact_ltr.DisconnectObject() DESTROY contact_ltr 例の実行 例を実行するには、アプリケーション オブジェクトのスクリプトに、 ウィンドウを開くための記述をするか、パワーバーの[実行]ボタン をクリックします。 アプリケーションがウィンドウを開けば、エンド ユーザは検索引数を 指定して、手紙を受け取る顧客を選択できます。また、手紙本文のテ キストをマルチラインエディットに入力したら、 [新規メール]ボタン をクリックして、選択した各顧客への手紙を印刷することができます。 スクリプトにおける OLE オブジェクト この章では、ウィンドウやユーザ オブジェクトにおいて、以下の OLE の 3 つの使用方法について説明しました。学習した内容は以下のとお りです。 380 • OLE コントロールへのオブジェクトの挿入 • OLE カスタム コントロールへの ActiveX コントロールの配置 • OLEObject 変数の宣言と、OLE オブジェクトへの接続 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 スクリプトでは、OLE オートメーションを使用して、プロパティ値の 取得や設定、OLE サーバで定義されている関数の呼び出しなどのオブ ジェクトの操作ができます。前節では、オートメーションのコマンド の例が紹介されています。次の節では、PowerBuilder におけるオート メーションのインタフェースについて詳しく説明します。 オートメーションのインタフェース PowerBuilder では、OLEObject 変数が、OLE サーバや ActiveX コント ロール へのインタフェースとなります。OLEObject 変数を宣言して、 OLE オブジェクトに接続し、変数にドット(.)表記を使用して、サー バへ指示を送ることができます。その指示によって、プロパティ値の 取得や設定、関数の呼び出しができます。 OLEObject 変数の一般的なオートメーション構文は、次のとおりです。 oleobjectvar.serverinstruction OLE コントロールでは、Object プロパティが、OLE サーバや ActiveX コントロールへのインタフェースです。Object プロパティのデータ型 は、OLEObject 型です。 OLE コントロールの一般的なオートメーション構文は、次のとおりで す。 olecontrol.Object.serverinstruction OLE サーバへのコマンドを記述したスクリプトのコンパイル PowerBuilder コンパイラでは、サーバのコマンド セットを認識できな いので、OLEObject 変数に対してコントロールの Object プロパティと メソッドを指定したスクリプトをコンパイルする際に、Object プロパ ティの次に続くコマンドはチェックされません。実行時のエラーを回 避するには、構文が正しくなければなりません。 アプリケーションの実行テストを行って、サーバ アプリケーションの コマンドが正しいことを確認してください。 OLE サーバがサポー トするもの サーバのコマンドには、プロパティとメソッド(関数とイベント)が あります。 OLE サーバ アプリケーションには、オートメーションをサポートする コマンドが用意されています。詳細については、OLE サーバ アプリ ケーションのマニュアルを参照してください。 アプリケーション テクニック 381 スクリプトにおける OLE オブジェクト OLE カスタム コントロールとプログラム可能な OLE オブジェクトに ついては、PowerBuilder オブジェクト ブラウザでプロパティとメソッ ドのリストを参照できます。オブジェクト ブラウザにおける OLE 情 報についての詳細は、400 ページの「オブジェクト ブラウザでの OLE 情報」を参照してください。 プロパティの設定 以下の構文を使用すると、OLE コントロールの Object プロパティを介 して OLE コントロールのプロパティにアクセスできます。 olecontrolname.Object.{ serverqualifiers.}propertyname OLE オブジェクトの階層構造が複雑な場合は、そのオブジェクトの中 にさらにネストしたオブジェクトやプロパティがある場合がありま す。 たとえば、Excel スプレッドシート オブジェクトに対する以下のコマ ンドは、そのオブジェクトをアクティブ化し、セルの value プロパティ を設定します。 double value ole_1.Activate(InPlace!) ole_1.Object.cells(1.1).value ole_1.Object.cells(2.2).value ole_1.Object.cells(3.3).value ole_1.Object.cells(4.4).value = = = = 55 66 77 88 Excel バージョン 95 のスプレッドシートの場合は、セルの行と列の引 数を大カッコでなくカッコで囲みます。たとえば、次のようになりま す。 ole_1.Object.cells(1,1).value = 55 OLEObject 変数を使用してプロパティを指定する場合は、サーバ修飾 子とサーバのプロパティ名が OLEObject 変数の後ろに続きます。 oleobjectvar.{ serverqualifiers.}propertyname サーバ修飾子は、オブジェクトに接続する方法に応じて指定する必要 があります。詳細については、386 ページの「サーバ コマンドの修飾 子」を参照してください。 関数の呼び出し 以下の構文は、OLE コントロールの Object プロパティを使用して、 サーバの関数を呼び出すことができます。 382 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 olecontrolname.Object.{ serverqualifiers.}functionname ( { arguments } ) OLE オブジェクトの階層構造が複雑な場合は、そのオブジェクトの中 にさらにネストしたオブジェクトやプロパティがある場合がありま す。 カッコについて PowerScript では、サーバに対するコマンドをプロパティの設定か関数 のどちらかとみなします。メソッドをプロパティの設定と識別するた めに、メソッド名に続くパラメータをカッコで囲む必要があります。 パラメータがない場合でも、空のカッコを付加します。 引数と戻り値のデータ 型 PowerBuilder は、OLE データを PowerBuilder と互換性のあるデータ型 に変換します。引数に指定した値のデータ型は、OLE サーバで期待さ れているデータ型との互換性が必要ですが、データ型が一致する必要 はありません。 関数が戻り値を返すとき、戻り値を互換性のあるデータ型の変数に代 入することができます。 引数の参照渡し OLE サーバが値をスクリプトに渡して返すことができるように、引数 の参照渡しを要求する場合は、引数の前に REF キーワードを指定しま す。以下のように、外部関数における宣言で使用する REF キーワード と似ています。 olecontrol.Object.functionname ( REF argname ) 以下の例では、ls_string 引数と li_return 引数が参照渡しされているの で、サーバで値を変更することができます。 string ls_string integer li_return ole_1.Object.testfunc(REF ls_string, REF li_return) 以下の例では、OLEObject 変数を使用して、同じ関数の呼び出しを行 います。 OLEObject ole_obj ole_obj = CREATE OLEObject ole_obj.ConnectToNewObject("servername") ole_obj.testfunc(REF ls_string, REF li_return) アプリケーション テクニック 383 スクリプトにおける OLE オブジェクト タイムアウト時間の設定 PowerBuilder クライアントからサーバへの呼び出しは 5 分間でタイム アウトになります。特定の OLE リクエストにもっと長い時間をかけた い場合、PowerScript の SetAutomationTimeout 関数を使用してデフォルト のタイムアウト時間を変更できます。 Word とオートメー ション Microsoft Word バージョン 6.0 と 7.0 は、WordBasic のマクロ言語に似 たコマンド セットによってオートメーションをサポートしています。 このコマンド セットには、ステートメントと関数の両方が含まれ、名 前の付いたパラメータを使用できます。Microsoft Word バージョン 7.0 より後のバージョンでは Visual Basic for Applications(VBA)を使用し ており、オブジェクトの階層構造は、特定の一連のメソッドとプロパ ティを公開します。 WordBasic ステートメント WordBasic には、ステートメントと関数が あります。ステートメントと関数のうちのいくつかは、同じ名前です。 WordBasic 構文はステートメントと関数の呼び出しに違いがあります が、PowerBuilder にはありません。 ステートメントの呼び出しを指定する場合は、引数に AsStatement! (OLEFunctionCallType カタログ データ型の値)を渡すことができます。関 数と同じ名前の WordBasic ステートメントを呼び出すには、AsStatement! を使用する以外、方法はありません。ステートメントと関数の名前が 異なっていても、AsStatement! を指定した方が、効率的です。 olecontrol.Object.application.wordbasic.statementname ( argumentlist, AsStatement! ) ) たとえば、以下のコードでは、AppMinimize ステートメントを呼び出し ています。 ole_1.Object.application.wordbasic. & AppMinimize("",1,AsStatement!) 名前の付いたパラメータ PowerBuilder で は、WordBasic と Visual Basic の名前の付いたパラメータをサポートしません。カッコの中には、パ ラメータの名前ではなく、値だけを指定します。 たとえば、以下のステートメントは、Word バージョン 6.0 または 7.0 の文書中のブックマークにテキストを挿入します。 ole_1.Activate(InPlace!) Clipboard(mle_nameandaddress.Text) ole_1.Object.application.wordbasic.& fileopen("c:\msoffice\winword\doc1.doc") ole_1.Object.application.wordbasic.& 384 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 editgoto("NameandAddress", AsStatement!) ole_1.Object.application.wordbasic.& editpaste(1, AsStatement!) 最後の 2 行のコマンドは、WordBasic マクロでは以下のように記述さ れます。Destination は、名前の付いたパラメータです。 EditGoto.Destination = "NameandAddress" EditPaste PowerBuilder のスクリプトでは、Word バージョン 97 またはそれ以降 の文書にテキストを挿入するためには、次のような構文を使用します。 ole_1.Object.Selection.TypeText(" このテキストを挿入します。 ") 対応する Visual Basic ステートメントでは、Text という名前が付いた パラメータに、挿入する文字列を代入します。 Selection.TypeText Text:=" このテキストを挿入します。" オートメーションはマクロ プログラミングではありません 変数を宣言したり、実行の流れを制御したりするコマンド(IF THEN 文 など)をサーバ アプリケーションに送ることはできません。オート メーションは、ほかのコマンドとは独立して、一度に 1 つずつコマン ドを実行します。プログラムの流れを制御するには、PowerScript の条 件文やループ文を使用します。 PowerScript とサーバ コマンドを組み合わ せて使用する方法について説明します。以下のスクリプトは、Microsoft Word の OLE オブジェクトの中にあるブックマークの個数を数えて、 ブックマークの名前を表示します。 Word オートメーションの例 integer i, count string bookmarklist, curr_bookmark ole_1.Activate(InPlace!) count = ole_1.Object.Bookmarks.Count bookmarklist = "Bookmarks = " + String(count) + "~n" FOR i = 1 to count curr_bookmark = ole_1.Object.Bookmarks[i].Name bookmarklist = bookmarklist + curr_bookmark + "~n" END FOR MessageBox(" ブックマーク ", bookmarklist) アプリケーション テクニック 385 スクリプトにおける OLE オブジェクト Word オートメーションに関する参考事項 Word オートメーションに正しい構文を用いているかどうかをチェッ クするには、Word マクロ エディタが使用できます。Word でマクロ記 録を開始し、スクリプトで自動化したい手順を実行し、その後マクロ 記録を終了します。マクロ エディタを開いて作成された構文を調べる には、〔Alt〕+〔F11〕を押します。PowerBuilder では、大カッコを配 列インデックスに使用していることに注意してください。 Word バージョン 6.0 と 7.0 のオートメーションの例 次 に 示 す ス ク リ プ トでは、Microsoft Word バージョン 6.0 と 7.0 の OLE オブジェクト中に あるブックマークの個数を数えて、ブックマークの名前を表示します。 integer i, count string bookmarklist, curr_bookmark ole_1.Activate(InPlace!) // ブックマークの個数を取得します。 count = ole_1.Object. & application.wordbasic.countbookmarks bookmarklist = "Bookmarks = " + String(count) + "~n" // 各ブックマークの名前を取得します。 FOR i = 1 to count curr_bookmark = ole_1.Object. & application.wordbasic.bookmarkname(i) bookmarklist = bookmarklist + curr_bookmark + "~n" END FOR MessageBox(" ブックマーク ", bookmarklist) サーバ コマンドの修飾子 サーバ コマンドにアプリケーション名を付けて修飾するかどうかは、 サーバと、オブジェクトが接続されている形式によって決まります。 各サーバは、オブジェクトの階層構造を独自のバージョンで実現して いるため、それをコマンドの構文に反映させる必要があります。たと えば、Microsoft Excel におけるオブジェクトの階層構造は図 19-2 のよ うになっています。 386 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 図 19-2: Microsoft Excel のオブジェクト階層 サーバが Excel の場合、以下のコマンドは同じ意味を持っているよう に見えますが、実行結果は異なります。Microsoft Excel バージョン 95 の場合、セルの行と列の引数には、大カッコでなくカッコを用います。 ole_1.Object.application.cells[1,2].value = 55 ole_1.Object.cells[1,2].value = 55 最初のステートメントは、アクティブな文書のセルを変更するもので す。このステートメントでは、Excel におけるオブジェクトの階層構造 をアプリケーション オブジェクトまで上ってから、開いているシート に下りてきます。その開いているシートが、PowerBuilder のコントロー ル上の文書と同じものかどうかは問題にしません。エンド ユーザが Excel に移行して別のシートをアクティブ化すると、スクリプトは、コ ントロール上の文書ではなくそのシートを変更してしまいます。した がって、この構文は使用すべきではありません。 2 番目のステートメントは、PowerBuilder のコントロール上の文書に対 してだけ作用します。ただし、その文書がアクティブ化されていない と、実行時エラーを起こしてしまいます。こちらのステートメントの 方が、別のデータに作用する危険がないだけ安全な構文といえます。 Microsoft Word バージョン 6.0 と 7.0 では、アプリケーションの階層構 造を独自に実現しています。そのため、コントロール上のオブジェク トを操作するときには、以下のように修飾子 application.wordbasic を必 要とします。オブジェクトはアクティブ化しておかなければなりませ ん。たとえば、次のようになります。 ole_1.Object.application.wordbasic.bookmarkname(i) Microsoft Word バージョン 7.0 より後のバージョンでは修飾子は必要 ありません。しかし、修飾子を指定しても有効です。以下のすべての 構文を使用できます。 ole_1.Object.Bookmarks.[i].Name ole_1.Object.Bookmarks.item(i).Name アプリケーション テクニック 387 スクリプトにおける OLE オブジェクト ole_1.Object.application.ActiveDocument. & Bookmarks.[i].Name コントロール上のオブジェクトではなく、PowerBuilder の OLEObject オブジェクト データ型のデータを操作しているときは、コマンドのア プリケーション修飾子を省略します。これは、オブジェクトに接続す るときに、すでに指定しているからです。OLEObject オブジェクト デー タ型についての詳細は、370 ページの「プログラム可能な OLE オブ ジェクト」を参照してください。 オートメーションと Any 型 PowerBuilder は、サーバ アプリケーションのコマンドや関数を知りま せん。したがって、スクリプトをコンパイルするときもサーバ関数の 戻り値やプロパティのデータ型は認識しません。プロパティにアクセ スし、関数を呼び出す式には Any 型の変数を使用します。Any 型の変 数にデータを代入すれば、データ型の変換エラーを回避できます。 実行時に、データが Any 型の変数に代入されると、その変数は、代入 されたデータと同じデータ型に転じます。ClassName 関数を用いて、 Any 型の変数のデータ型を調べて、適切な代入を行うことができます。 矛盾する代入を行うと、実行時エラーが起こります。 不必要な Any 型は使用しないでください サーバの関数が返すデータのデータ型がわかっている場合は、Any 型 を使用しないでください。返されたデータは、正しいデータ型に直接 代入してください。 以下のサンプル コードは、Excel から読み込んだデータを、そのデー タに応じたデータ型の PowerBuilder 変数に代入します。Excel バージョ ン 95 の場合、セルの行と列の引数には、大カッコでなくカッコを用い ます。 string stringval double dblval date dateval any anyval anyval = myoleobject.application.cells[1,1].value CHOOSE CASE ClassName(anyval) CASE "string" stringval = anyval CASE "double" 388 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 dblval = anyval CASE "datetime" dateval = Date(anyval) END CHOOSE 効率的な OLEObjects 変数の使い方 オートメーションのコマンドにサーバ修飾子が複数ある場合、つまり、 オブジェクトの階層構造のネストが深い場合は、オブジェクトの階層 構造をたどってオブジェクトを参照するため、アプリケーションの実 行に時間がかかります。オブジェクトの階層構造の同じ部分を繰り返 して参照する場合は、そのオブジェクトの参照部分を OLEObject 変数 に代入しておくとよいでしょう。オブジェクトの参照は一度だけ行わ れ、その後はその参照が再利用されます。 次のステートメントをプロパティごとに使用すると、同じオブジェク トを何度も参照することになります。 ole_1.Object.application.wordbasic.propertyname OLEObject 変数に、オブジェクトの参照部分を代入した場合、次のよ うになります。オブジェクトの参照は一度だけですみます。 OLEObject ole_wordbasic ole_wordbasic = ole_1.Object.application.wordbasic ole_wordbasic.propertyname1 = value ole_wordbasic.propertyname2 = value 例 : オブジェクトの参 照の解決 次の例は、OLEObject 変数を使用して、Microsoft Word のオブジェクト を参照します。オブジェクトが FOR ループ文で繰り返し参照されてい ます。オブジェクトの参照を OLEObject 変数に代入することによって、 そのオブジェクトへの参照は一度しか行われません。そのため、処理 が効率的になります。例では、OLEObject 変数が不要になったときに、 変数を破棄しています。 integer li_i, li_count string ls_curr_bookmark OLEObject ole_wb ole_1.Activate(InPlace!) ole_wb = ole_1.Object.application.wordbasic // ブックマークの個数を取得します。 li_count = ole_wb.countbookmarks // 各ブックマークの名前を取得します。 FOR li_i = 1 to count アプリケーション テクニック 389 スクリプトにおける OLE オブジェクト ls_curr_bookmark = ole_wb.bookmarkname(i) ... // リストにブックマークの名前を保存するためのコード END FOR エラー処理 PowerBuilder は、OLE サーバが実行できるオートメーションの構文を 知らないので、スクリプトをコンパイルしても、OLE サーバのプロパ ティを参照するステートメントはチェックされません。コンパイラは エラーをチェックすることができないので、OLE サーバが認識できな いプロパティや関数の名前および引数を指定すると、アプリケーショ ンを実行したときに実行時エラーが起きます。 OLE エラー時のイベ ントの連鎖 OLE コントロールまたは OLE サーバによりエラーが発生した場合、以 下の順で PowerBuilder のイベントが連続して起動されます。 1 組み込みエラー イベントを設定している ActiveX control によりエ ラーが発生した場合、PowerBuilder OLE コントロールの ocx_error イベントが起動されます。 2 それ以外の場合は、OLE オブジェクトの ExternalException イベン トが起動されます。 3 ExternalException イベントにスクリプトが記述されていないか、 ExternalException イベントの action 引数に ExceptionFail!(デフォル ト)が設定されている場合は、OLE オブジェクトの Error イベント が起動されます。 4 Error イベントにスクリプトが記述されていないか、Error イベント の action 引数に ExceptionFail!(デフォルト)が設定されている場合 は、RuntimeError またはその子孫オブジェクトのアクティブな例外 ハンドラが起動されます。 5 例外ハンドラが存在しない場合、または既存の例外ハンドラに よって例外が処理されない場合は、アプリケーション オブジェク トの SystemError イベントが発生します。 6 SystemError イベントにスクリプトが記述されていない場合は、ア プリケーションの実行時エラーが起こり、アプリケーションは終 了します。 これらのどのイベントでも、エラー処理ができます。また、TRY-CATCH ブロックを使用してスクリプト内でもエラーは処理できます。しかし、 SystemError イベントが起動された後も処理を継続することはよくあ りません。 390 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 例外処理についての詳細は、41 ページの「例外の処理」を参照してく ださい。 OLE エラーのイベン ト PowerBuilder の OLE オブジェクトと OLE コントロールには、エラー 処理を行う 2 つのイベントがあります。それらのイベントは以下のと おりです。 OLE サーバまたは OLE コントロール で、例外を送出するか、 (ocx_error イベントがない場合の)エラー イベントが起きたときに起動されます。OLE サーバから提供され た情報は、エラーの診断に役立ちます。 • ExternalException イベント • Error イベント 例外やエラー イベントを扱わないときに起動され ます。PowerBuilder のエラー情報は、スクリプトで使用できます。 OLE コントロールで組み込みエラー イベントを設定している場合、 PowerBuilder の OLE コントロール コンテナはイベントを追加します。 OLE サーバでエラー イベントが発生したときに起動 されます。OLE サーバから提供された情報は、エラーの診断に役 立ちます。 • ocx_error OLE コントロールの作成者は、Microsoft Foundation Classes(MFC)ク ラス ウィザードを使用してコントロールの組み込みエラー イベント を生成できます。PowerBuilder での ocx_error イベントの引数は、組み 込みエラー イベントに設定された引数にマップします。 OLE エラーに対する 対応 PowerBuilder の OLE コントロールに ocx_error イベントに対するスク リプトが記述されている場合、イベントの引数からそのエラーに関す る情報を取得して、適切な対応をとることができます。ocx_error の引 数のうちの 1 つは、Boolean 型の CancelDisplay です。CancelDisplay に TRUE を設定すれば、MFC のエラー メッセージの表示をキャンセルで きます。また、エラーについてのほかの表示を行うこともできます。 ExternalException イベントと Error イベントのどちらに対するスクリプ トでも、action 引数を適切な ExceptionAction カタログ データ型の値に 設定します。どの値を設定するかは、開発者が OLE エラーについて何 を知っており、OLE サーバ アプリケーションの少ない情報をいかにう まく取り扱えるかに依存します。 表 19-6: ExceptionAction カタログ データ型の値 ExceptionAction 値 効果 ExceptionFail! アプリケーション テクニック イベントにスクリプトが記述されていない場合と同 じ。エラーが発生すると、エラー イベントの起動順位 にしたがって、次のエラー イベントが起動される 391 スクリプトにおける OLE オブジェクト ExceptionAction 値 ExceptionIgnore! 効果 エラーを無視して、何もエラーが発生しなかったよう にして戻る 注意 OLE サーバのプロパティ値の取得や OLE 関数からの 戻り値がある場合は、異なるデータ型の代入が行われ るために別のエラーが発生する可能性がある ExceptionRetry! OLE サーバへコマンドを再び送る。OLE サーバの準備 ができていない場合に有効 注意 OLE サーバの関数名、プロパティ名、引数の指定が誤っ ていることがエラーの原因である場合、何度も再試行 するように設定すると、アプリケーションは無限ルー プに入る。再試行の回数を制限するため、アプリケー ションでカウンタを設定することができる ExceptionSubstitute ReturnValue! OLE サーバが返す関数の戻り値やプロパティ値のかわ りに、returnvalue 引数に指定した値を使用して、エラー を無視する OLE サーバを呼び出して、returnvalue 引数に適切な値 を代入する前に、アプリケーションをそのまま継続し ても問題ない値をインスタンス変数に設定しておく。 returnvalue 引数のデータ型は、Any 型である。Any 型は、 すべてのデータ型のデータを代入できる エラーが発生した後もアプリケーションを継続する場 合は、OLE サーバが返す正しくない値のかわりに、有 効な値を使用するため安全である 例 : ExternalException イベント ocx_error イベントと同様、ExternalException イベントは、OLE サーバ からのエラー情報を提供します。この情報は、アプリケーションをデ バッグするときに役立ちます。 たとえば、ウィンドウ オブジェクトに 2 つのインスタンス変数がある とします。1 つは、ExceptionAction 値を指定するための変数です。もう 1 つは、OLE サーバが返す値のかわりの値を保持するための Any 型の 変数です。OLE サーバのプロパティにアクセスする前に、適切な値を インスタンス変数に設定します。 ie_action = ExceptionSubstituteReturnValue! ia_substitute = 0 li_currentsetting = ole_1.Object.Value 392 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 OLE コマンドが失敗した場合は、ExternalException イベントに対する スクリプトで、OLE サーバによって指定されたヘルプ トピックが表示 されます。そして ExternalException イベントは、OLE サーバが返す値 のかわりに、準備してあった値に置き換えます。li_currentsetting 変数 への代入は、ともに互換性のあるデータ型なので、正しく行われます。 string ls_context // WinHelp のコンテキスト ID に切り替えるためのコマンド行 ls_context = "-n " + String(helpcontext) IF Len(HelpFile) > 0 THEN Run("winhelp.exe " + ls_context + " " + HelpFile) END IF Action = ExceptionSubstituteReturnValue! ReturnValue = ia_substitute このイベントに対するスクリプトは、すべてのオートメーション コマ ンドに対応しなければなりません。各オートメーション コマンドの前 に、インスタンス変数に適切な値を設定する必要があります。 Error イベント Error イベントは、エラーが発生したときの PowerBuilder のコンテキス トに関する情報を提供します。エラーの発生したオブジェクト名、ス クリプトの内容、エラーの発生したスクリプトの行番号、PowerBuilder のエラー番号、エラー メッセージなどを取得することができます。こ の情報は、アプリケーションをデバッグするときに役立ちます。 Action 引数と ReturnValue 引数の設定は、ExternalException イベントと 同じように Error イベントにも適用されます。 エラー処理を行うためのイベントについての詳細は、『PowerScript リ ファレンス』マニュアルを参照してください。 ホット リンクの作成 OLE サーバには、 プロパティの変更通知をサポートするものがあります。 つまり、OLE サーバのプロパティの変更直前と変更直後に、OLE サーバ は、OLE コントロールにプロパティの変更に関する情報を渡して通知し ます。これらのメッセージは、OLE コントロールの PropertyRequestEdit イベントと PropertyChanged イベントを起動します。 PropertyRequestEdit イベント OLE サーバのプロパティの変更直前に、PropertyRequestEdit イベント が起動されます。このイベントに対するスクリプトで、以下のような ことが可能です。 アプリケーション テクニック 393 スクリプトにおける OLE オブジェクト • PropertyName 引数から、変更されたプロパティの名前がわかる • 古いプロパティ値を取得して保存できる。 プロパティ値はまだ変更されていないので、標準の構文を使用し てその値にアクセスできる • PropertyChanged イ ベント CancelChange 引数の値を TRUE に変更して、変更をキャンセルで きる プロパティが変更されたときに、PropertyChanged イベントが起動されま す。このイベントに対するスクリプトで、以下のようなことが可能です。 • PropertyName 引数から、変更されたプロパティの名前がわかる • 新しいプロパティ値を取得する プロパティ値はすでに変更されているので、その変更はキャンセ ルできない PropertyName 引数の 使い方 PropertyName の引数は文字列のため、ドット(.)表記を使用して、OLE サーバのプロパティの値を取得することはできません。 value = This.Object.PropertyName // プロパティ値は取得でき ません。 そのかわりに、CHOOSE CASE 文または IF 文を使用して、プロパティ 名を調べて、そのプロパティの値を取得できます。 たとえば、PropertyChanged イベントの以下のスクリプトでは、3 つの プロパティ名を調べて、変更されたプロパティの新しい値を取得しま す。プロパティ値は、適切なデータ型の変数に代入します。 integer li_index, li_minvalue long ll_color CHOOSE CASE Lower(PropertyName) CASE "value" li_index = ole_1.Object.Value CASE "minvalue" li_minvalue = ole_1.Object.MinValue CASE "backgroundcolor" ll_color = ole_1.Object.BackgroundColor CASE ELSE ... // そのほかの処理 END CHOOSE 大規模な変更が発生し た場合 394 PropertyName 引数の値に空文字列("")が返る場合があります。これ は、もっと一般的な変更が発生したことを意味します。たとえば、複 数のプロパティに影響する変更が発生したことを意味します。 PowerBuilder 第 19 章 プロパティ通知がサ ポートされない場合 アプリケーションにおける OLE の使い方 OLE サーバがプロパティの変更通知をサポートしていない場合は、 PropertyRequestEdit イベントと PropertyChanged イベントは起動されな いので、それらのイベントに記述されたスクリプトは実行されません。 OLE サーバがプロパティの変更通知をサポートしているかどうかは、 OLE サーバのマニュアルを調べてください。 OLE サーバでプロパティの変更通知がサポートされていないが、アプ リケーションで新しいプロパティ値を知る必要がある場合は、プロパ ティを定期的にチェックする独自の関数を記述します。 PropertyRequestEdit イベントと PropertyChanged イベントについての詳 細は、 『PowerScript リファレンス』マニュアルを参照してください。 OLE サーバで使用できる言語 オートメーション コマンドを記述するとき、通常はコンピュータの地 域(locale)に一致するコマンドを使用します。開発者の地域とエンド ユーザの地域が異なる場合は、SetAutomationLocale 関数でオートメー ションで使用した言語を指定できます。 OLE コントロール、OLE カスタム コントロール、OLEObject オブジェ クトに対して SetAutomationLocale 関数を使用して、アプリケーション 中のオートメーション オブジェクトとは異なる地域を指定できます。 たとえば、開発者がドイツでアプリケーションを開発し、ヨーロッパ 全体に配布する場合は、オートメーションが使用する言語がドイツ語 であることを SetAutomationLocale 関数で指定できます。ole_1 という OLE コントロールには次の構文を使用します。 ole_1.Object.SetAutomationLocale(LanguageGerman!) oleobj_report という OLEObject には次の構文を使用します。 oleobj_report.SetAutomationlocale(LanguageGerman!) OLE サーバ アプリケーションにドイツ語のオートメーション インタ フェースがなければなりません。 エンド ユーザのコンピュータがサポートする言語 エンド ユーザが OLE サーバ アプリケーションをインストールすると き、 (特に Microsoft の OLE アプリケーションの場合)は、自国の言語 と英語のオートメーション インタフェースが提供されます。エンド ユーザが開発者と異なる言語を使用している場合は、開発者の自国語 でオートメーション コマンドを記述することは適当ではありません。 アプリケーション テクニック 395 スクリプトにおける OLE オブジェクト 詳細については、『PowerScript リファレンス』マニュアルの SetAutomationLocale 関数を参照してください。 OLE オブジェクトへの低レベル アクセス C または C++ で作成された DLL 内の外部関数を PowerBuilder から呼 び出して、OLE サーバへ低レベルのアクセスをする必要がある場合、 以下の関数を使用できます。 • GetNativePointer(OLEControl と OLECustomControl の場合) • GetAutomationNativePointer (OLEObject の場合) 処理が終了したら、ポインタを解放するため以下の関数を使用します。 • ReleaseNativePointer(OLEControl と OLECustomControl の場合) • ReleaseAutomationNativePointer(OLEObject の場合) 詳細については、 『PowerScript リファレンス』マニュアルを参照して ください。 データウィンドウ オブジェクトにおける OLE オブジェクト 前節では、OLE コントロールと OLE オブジェクトへのオートメーショ ン インタフェースについて説明しました。スクリプトを使って、デー タウィンドウ オブジェクトに埋め込まれた OLE オブジェクトの設定 も変更できます。また、外部の OLE オブジェクトのプロパティを通知 することもできます。 この節では、Object プロパティにドット(.)表記を使用してデータ ウィンドウ プロパティを設定する方法について説明します。また、 データウィンドウ オブジェクトの OLE オブジェクトに対するオート メーション コマンドの発行方法についても説明します。 OLE オブジェクトの 名前付け OLE オブジェクトにドット(.)表記を使用するために、オブジェクト に名前を付けます。オブジェクトのプロパティ シートの[全般]ペー ジで名前を指定します。 プロパティの設定 OLE コンテナ オブジェクトのプロパティは、データウィンドウ オブ ジェクトのほかのオブジェクトと同様に設定します。コントロールの Object プロパティは、データウィンドウ オブジェクト内のオブジェク トへのインタフェースとなります。 396 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 たとえば、次のステートメントでは、オブジェクト ole_word の Pointer プロパティに設定します。 dw_1.Object.ole_word.Pointer = "Cross!" コンパイラは、Object プロパティ以下の構文をチェックしないので注 意してください。プロパティの設定に誤りがあると実行時エラーが起 こります。 プロパティの設定、エラー処理、および OLE DWObject のプロパティ のリストについての詳細は、 『データウィンドウ リファレンス』マニュ アルを参照してください。 OLE オブジェクトと Modify 関数 Modify 関数の CREATE キーワードを使用して、データウィンドウ オブ ジェクト中の OLE オブジェクトを動的に作成することはできません。 OLE オブジェクトのバイナリ データは、Modify 関数の構文との互換性 がありません。 関数とプロパティ OLE DWObject を呼び出すために 4 つの関数が用意されており、いず れも OLE コントロールに対して同じ効果を及ぼします。その 4 つの関 数は以下のとおりです。 • Activate • Copy • DoVerb • UpdateLinksDialog これらの関数を呼び出すには、データウィンドウ オブジェクトのプロ パティの場合と同様に、データウィンドウ コントロールの Object プロ パティを使用します。 dw_1.Object.ole_word.Activate(InPlace!) ウィンドウの OLE コントロールに適用される 4 つのプロパティは、 OLE DWObject にも適用されます。 表 19-7: OLE コントロールと OLE DWObject に適用されるプロパティ プロパティ ClassLongName アプリケーション テクニック データ型 String 説明 (読み出し専用)OLE DWObject に関連付けら れたサーバ アプリケーションのための長い 名前 397 スクリプトにおける OLE オブジェクト プロパティ ClassShortName データ型 LinkItem String String 説明 (読み出し専用)OLE DWObject に関連付けら れたサーバ アプリケーションのための短い 名前 (読み出し専用)オブジェクトのリンク先項 目の完全なリンク名 たとえば、オブジェクトが C:\FILENAME.XLS!A1:B2 にリンクされてい る場合は、LinkItem は C:\FILENAME.XLS!A1:B2 となる ObjectData Blob オブジェクトが埋め込まれている場合は、オ ブジェクト自身が ObjectData プロパティの Blob 型データとして格納される オブジェクトがリンクされている場合は、こ のプロパティにはリンク情報と(表示用の) キャッシュ イメージが含まれる オートメーション ドット(.)表記を使用して OLE サーバにコマンドが送信できます。構 文には 2 つの Object プロパティが含まれます。 • データウィンドウ コントロールの Object プロパティ OLE コ ン テ ナ の DWObject などのデータウィンドウ オブジェクトへアクセスで きる • OLE DWObject の Object プロパティ オートメーション オブジェク トへアクセスできる 構文は次のとおりです。 dwcontrol.Object.oledwobject.Object.{ serverqualifiers. }serverinstruction たとえば、次のステートメントでは、WordBasic の Insert 関数を使用し て、Word 文書のデータ テーブルの最初に報告書タイトルを追加しま す。 dw_1.Object.ole_word.Object.application.wordbasic.& Insert("Report Title " + String(Today())) アプリケーションにおける OLE カラム データウィンドウ オブジェクトの OLE カラムを使用して、データベー スの Blob 型データを格納、検索、修正できます。アプリケーションで OLE カラムを使用するには、ウィンドウに データウィンドウ コント ロールを配置し、データウィンドウ オブジェクトとの関連付けを行い ます。 398 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 SQL Server のユーザに関する注意 SQL Server データベースを使用している場合は、OLE を使用するため にはトランザクション処理を終了する必要があります。データウィン ドウ コントロールで使用されているトランザクション オブジェクト では、AutoCommit 関数に TRUE を設定します。 データウィンドウ オブジェクトの OLE カラムの作成方法については、 PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 OLE サーバ アプリ ケーションのアクティ ブ化 エンド ユーザは、開発者が データウィンドウ ペインタで前もって扱っ たのとまったく同じように Blob 型を扱えます。つまり、Blob 型をダブ ルクリックするだけで、サーバ アプリケーションを呼び出すことがで きます。また、開発者がサーバ アプリケーションを呼び出すには、ス クリプトで OLEActivate 関数を使用できます。OLEActivate 関数を呼び出 すのは、設定された Blob 型をダブルクリックするのと同じことです。 OLEActivate 関数の構文は次のとおりです。 dwcontrol.OLEActivate (row, columnnameornumber, verb ) バーブの設定 OLEActivate 関数を使用する場合は、OLE サーバ アプリケーションに渡 すアクションがわかっている必要があります。Windows では、このア クションのことをバーブと呼びます。通常、文書を編集したい場合は、 大部分のサーバでは、バーブに 0 を設定します。 特定の OLE サーバ アプリケーションでサポートされているバーブを 取得するには、Windows のレジストリ エディタ ユーティリティの高度 なインタフェース(REGEDT32 /V)を実行します。 レジストリ エディタについての詳細は、Windows のオンライン ヘルプ の REGEDT32.HLP を参照してください。 例 たとえば、ボタンに対する Clicked スクリプトで OLEActivate 関数を使 用して、エンド ユーザがダブルクリックできる Blob 型アイコンを知 らなくても OLE を使用できるようにする場合を考えます。 次のステートメントは、データウィンドウ コントロールの dw_1 の現 行の行にある OLE カラムのため、OLE サーバ アプリケーションを呼 び出します。ここでは、データウィンドウ オブジェクトの 2 番目のカ ラムが OLE カラムであると仮定しています。 dw_1.OLEActivate(dw_1.GetRow(), 2, 0) 詳細情報 データウィンドウ オブジェクトにおける OLE の使い方についての詳 細は、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してく ださい。 アプリケーション テクニック 399 オブジェクト ブラウザでの OLE 情報 オブジェクト ブラウザでの OLE 情報 OLE サーバ アプリケーションと OLE カスタム コントロール(OCX) をインストールすると、そのオブジェクトの情報がレジストリに登録 されます。 PowerBuilder は、レジストリを読み込んで、登録されたすべての OLE サーバと OCX のレジストリ情報を表示します。 v OLE 情報を表示するには 1 パワーバーの[オブジェクト ブラウザ]ボタンをクリックします。 2 オブジェクト ブラウザの[OLE]タブをクリックします。 表 19-8 に示す OLE オブジェクトの 3 つのカテゴリが表示されます。 表 19-8: OLE オブジェクトのカテゴリ OLE オブジェクトの カテゴリ 挿入可能なオブジェ クト OLE カスタム コント ロール OLE オートメーショ ン オブジェクト 説明 OLE コンテナにオブジェクトをリンクまたは埋め 込むことができる OLE サーバ。挿入可能なオブジェ クトをサポートする OLE サーバには、ビジュアル コンポーネントが必要 OLE コンテナに含めることができる ActiveX コン トロール。さらに ActiveX コントロールは、挿入可 能なオブジェクトであることもできる。ActiveX コ ントロールが挿入可能なオブジェクトの場合、挿入 可能なオブジェクトのリストに表示される オートメーションをサポートする OLE サーバ。オー トメーション オブジェクトは、非表示のオブジェク トの場合もある。つまり、オートメーションだけを サポートしており、挿入可能なオブジェクトはサ ポートしていないということである これらのカテゴリを展開すると、インストールされた個々の OLE サー バが参照できます。これらの OLE サーバはさらに展開できます。提供 される情報は、カテゴリに依存します。 クラス情報 すべてのカテゴリは、OLE サーバに関するクラス情報を提供します。 クラス情報にはレジストリ キーのリストが表示されます。キーには、 キー自身に意味があるものや、キーに対する値があるものがあります。 キーの値やキーの有無によって、OLE サーバの検索方法と OLE サーバ が何をサポートするかを知らせます。 表 19-9 は、いくつかのキーとその説明です。 400 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 表 19-9: OLE レジストリ キー レジストリ キー GUID TypeLib - GUID ProgID VersionIndependentProgID InprocServer32 ToolboxBitmap32 DefaultIcon Version Insertable Control Verb 値 OLE サーバのグローバル一意識別子 ActiveX コントロールのタイプ ライブラリのグ ローバル一意識別子 OLE サーバや ActiveX コントロールを識別する 文字列。通常、バージョン番号が含まれる OLE サーバや ActiveX コントロールを識別する 文字列だが、バージョン番号を含まない 32 ビット版 ActiveX コントロールのファイル名 開発環境でツールバーやツールボックスに 32 ビットの ActiveX コントロールを表示するため に使用するビットマップ ファイル名 OLE サーバや ActiveX コントロールをアイコン で表示するときに使用されるアイコン ファイル 名。または、アイコンを含む実行ファイル OLE サーバまたは ActiveX コントロールのバー ジョン番号名 値なし – エントリが挿入可能なオブジェクトを サポートする OLE サーバであることを表す 値なし – エントリが ActiveX コントロールであ ることを表す 値なし – エントリがバーブをコマンドとして受 け入れることを表す レジストリの情報に加えて、PowerBuilder オブジェクト ブラウザは、 ActiveX コントロールとオートメーション オブジェクトのプロパティ とメソッドも表示します。OLE の情報を提供するために、PowerBuilder は レ ジ ス ト リ の 情 報 を 使 用 し て ActiveX コ ン ト ロ ー ル を 検 索 し、 ActiveX コントロールのプロパティとメソッドを取得します。この情報 には、引数とデータ型があります。 スクリプトを記述するとき、PowerBuilder オブジェクト ブラウザを使 用して、プロパティ名や関数名を検索し、スクリプトに貼り付けるこ とができます。PowerBuilder オブジェクト ブラウザは、プロパティを アクセスするため構文を提供します。 スクリプト記述時の PowerBuilder オブ ジェクト ブラウザ v OLE の情報をスクリプトに貼り付けるには 1 ブラウザを開きます。 2 [OLE]タブをクリックします。 アプリケーション テクニック 401 OLE オブジェクトの高度な操作 3 オブジェクトを検索するためにリストを展開します。たとえば、ある ActiveX コントロール プロパティを検索するために、その ActiveX コントロール のリストをさらに展開します。 4 プロパティをハイライト表示して、ポップアップ メニューから[コ ピー]を選択します。 5 スクリプト ビューで挿入ポイントを決めて、ポップアップ メニュー から[貼り付け]を選択します。 オブジェクト ブラウザは、以下のようにスクリプトに構文を挿入 します。 OLECustomControl.Object.NeedlePosition OLECustomControl を実際のコントロール名に変更した後は、スク リプトで NeedlePosition プロパティを正しく設定してください。 オブジェクト ブラウザがスクリプトに貼り付ける内容は、選択した内 容によって異なります。オブジェクト(階層構造におけるプロパティ の 1 つ上のレベル)を選択した場合は、PowerBuilder はオブジェクト の ProgID を貼り付けます。ConnectToNewObject 関数で ProgID を使用で きます。 OLE オブジェクトの高度な操作 PowerBuilder は、コントロール上の OLE オブジェクトとオートメー ションに対するオブジェクトのほかにも、基本的な OLE データ スト レージに対するインタフェースを提供しています。 OLE データは、ストリームと呼ばれるオブジェクトに保持されていま す。また、ストリームは、ストレージと呼ばれるオブジェクトの中に 存在します。ストリームとストレージは、ファイル システムにおける ファイルとディレクトリの関係に似ています。ストリームやストレー ジを開き、読み取り、書き込み、保存、削除することにより、OLE オ ブジェクトの作成、結合、削除を行うことができます。PowerBuilder では、OLEStorage オブジェクトと OLEStream オブジェクトの 2 つの データ型を用いて、ストレージやストリームへのアクセスを行います。 OLE コントロールと OLEObject 変数を定義すれば、サーバ アプリケー ションやオートメーションのすべての機能にアクセスでき、これだけ でも、OLE の機能を活用することができます。したがって、保持され ているデータの構造が複雑でなければ、PowerBuilder のストレージ オ ブジェクトやストリーム オブジェクトは必要ありません。 402 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 ほかのアプリケーションのストレージ ファイル この節では、PowerBuilder アプリケーションが作成した OLE ストレー ジ ファイルについて説明します。ほかの PowerBuilder アプリケーショ ンも、PowerBuilder で作成したストレージ ファイル内のオブジェクト を開くことができます。Excel、Word、およびそのほかのサーバ アプ リケーションは、それらのネイティブ データを OLE ストレージに保 持しますが、各ファイルに独自の形式があるため、それらをストレー ジ ファイルとして直接開くことはお勧めしません。Word や Excel など のファイルは、 (InsertFile 関数を用いて)コントロール上に挿入するか、 (ConnectToObject 関数を用いて)コントロールとオートメーションを接 続した方がよいでしょう。 OLE ストレージの構造 OLE ストレージは、OLE データのリポジトリです。ストレージは、ディ スクのディレクトリ構造に似ています。ストレージは、1 つの OLE オ ブジェクトである場合や、ほかのストレージやサブストレージに格納 されている複数の OLE オブジェクトを格納している場合もあります。 図 19-3 に示すように、サブストレージは、ディレクトリ内のファイル のように、独立した要素の個別の OLE オブジェクトにもでき、画像を 含む文書などの大規模な OLE オブジェクトも形成できます。 図 19-3: OLE ストレージの構造 アプリケーション テクニック 403 OLE オブジェクトの高度な操作 OLE オブジェクトを含むストレージやサブストレージでは、それが特 定のサーバ アプリケーションに属していることを示すタグを付けて 情報を識別しています。これにより、その下位レベルの各コンポーネ ントは、そのサーバ アプリケーションでしか操作されなくなります。 なお、サーバのオブジェクトを格納しているストレージを開いて、そ の中からオブジェクトを取り出すことができますが、そのストレージ は変更すべきではありません。 OLE オブジェクトを格納しているストレージは、オブジェクトの表示 情報を持っています。表示情報がストレージに属しているので、OLE は、オブジェクトを表示するためにサーバ アプリケーションを起動す る必要がありません。 OLE オブジェクトを含まず、単にほかのストレージを格納しているだ けのストレージもあります。この場合は、挿入するオブジェクトがな いので、そのストレージをコントロール上で開くことはできません。 ストレージとストリームに対するオブジェクト データ型 PowerBuilder は、OLE ファイルのストレージとストリームに対するオ ブジェクト データ型を 2 種類用意しています。 • OLEStorage • OLEStream これらのオブジェクトは、トランザクション オブジェクトやメッセー ジ オブジェクトと同じようなクラス ユーザ オブジェクトです。これ らのオブジェクト データ型の変数を宣言し、そのインスタンスを作成 してから、ストレージを開きます。ストレージを使った作業を終了し たら、ストレージを閉じ、変数を破棄して、OLE サーバと変数に割り 当てられていたメモリを解放します。 ストレージを開くと、OLEStorage 変数とディスク上のファイルが関連 付けられます。このファイルは、現行セッションのための一時的なファ イルであったり、OLE オブジェクトを含む既存のファイルであったり します。ファイルが存在しない場合は、PowerBuilder が作成します。 OLE オブジェクトをストレージに格納するには、SaveAs 関数を使用し ます。また、ウィンドウ上の OLE コントロールとストレージとの接続 の確立は、OLE コントロールに対する Open 関数を呼び出して行いま す。 404 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 ストリームは、OLE オブジェクトではないので、コントロール上で開 くことはできません。しかし、ストリームを使用すると、オブジェク トに関する独自の情報をストレージ フィルに格納しておくことがで きます。ストリームは、ストレージまたはサブストレージ内部から開 き、ファイルと同様に、データの入出力を行うことができます。 パフォーマンスに関するヒント ストレージは、OLE データを効率よく表示することができます。サー バ アプリケーションで作成したファイルをコントロールに挿入する ときに、OLE は、そのサーバを起動して、オブジェクトを表示しなけ ればなりません。しかし、OLE ストレージに格納されたオブジェクト を開くときは、サーバを起動するというオーバーヘッドがありません。 OLE は、ストレージが保持している表示情報を使用して、オブジェク トを表示します。エンド ユーザがそのオブジェクトをアクティブにし ない限り、サーバを起動する必要がありません。 ストレージを開く、保存する PowerBuilder は、ストレージを管理するための関数をいくつか用意し ています。もっとも重要な関数は、Open、Save、および SaveAs です。 Open 関数の使い方 ファイル内の OLE データにアクセスする場合は、Open 関数を呼び出 します。ストレージ ファイルの構造によっては、Open 関数の呼び出し が複数回必要となることがあります。 以下のコードは、コントロールの中でファイルのルート ストレージを 開きます。この Open の構文では、ルート ストレージは、ほかのスト レージを格納しているだけのコンテナではなく、OLE オブジェクトで なければなりません。必ず戻り値を調べて、OLE 関数が成功したかど うかを確認してください。 result = ole_1.Open("MYFILE.OLE") コントロールへファイルのサブストレージを開きたい場合は、Open 関 数を 2 回呼び出す必要があります。1 回目は OLEStorage 変数へファイ ルを開くために、2 回目はコントロールへサブストレージを開くため に行います。Stg_data は、CREATE 関数を使って宣言して、インスタン スを作成した OLEStorage 変数です。 result = stg_data.Open("MYFILE.OLE") result = ole_1.Open(stg_data, "mysubstorage") アプリケーション テクニック 405 OLE オブジェクトの高度な操作 Save 関数の使い方 エンド ユーザが、コントロール上のオブジェクトをアクティブにし て、編集するものとします。この場合、サーバは、変更内容をメモリ 上のデータに保持し、DataChange イベントを PowerBuilder アプリケー ションで起動します。アプリケーションでは、Save 関数を呼び出して、 ストレージ ファイルのデータを変更しなければなりません。 result = ole_1.Save() IF result = 0 THEN result = stg_data.Save() SaveAs 関数の使い方 SaveAs 関数を使用して、コントロール上のオブジェクトをほかのスト レージ変数かファイルに保存することもできます。以下のコードは、 コントロールでストレージ ファイルを開き、さらに別のストレージ ファイルを開いた後、そのストレージ ファイルでサブストレージを開 きます。次いで、オリジナルのオブジェクトを 3 階層のネストしたサ ブ ストレージとしてコントロールに保存します。 OLEStorage stg_data, stg_subdata stg_data = CREATE OLEStorage stg_subdata = CREATE OLEStorage ole_1.Open("FILE_A.OLE") stg_data.Open("FILE_B.OLE") stg_subdata.Open("subdata", stgReadWrite!, & stgExclusive!, stg_data) ole_1.SaveAs(stg_subdata, "subsubdata") 以下の図は、ネストしたストレージを順に開き、SaveAs 関数を実行す るまでのプロセスを示しています。ファイルやストレージが存在しな い場合は、Open 関数や SaveAs 関数によって作成されます。SaveAs 関 数を呼び出す前に、コントロールに対して Save 関数を呼び出すと、コ ントロールのオブジェクトが FILE_A ファイルに保存されます。SaveAs 関数を呼び出した後に Save 関数を呼び出すと、オブジェクトは FILE_B ファイルの subsubdata に保存されます。 図 19-4: ネストした OLE ストレージ 406 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 次の例に、第 3 レベルにストレージを作成せずにサブレベルのスト レージを作成する簡単な方法を示します。この場合、第 3 レベルでス トレージをネストしたり、オブジェクトを保存するためにサブスト レージを開いたりする必要がありません。 OLEStorage stg_data, stg_subdata stg_data = CREATE OLEStorage stg_subdata = CREATE OLEStorage ole_1.Open("FILE_A.OLE") stg_data.Open("FILE_B.OLE") ole_1.SaveAs(stg_data, "subdata") ストレージのメンバーに関する情報の取得 ストレージを開くと、以下のメンバー関数を使用して、そのストレー ジ内のサブ ストレージとストリームに関する情報の取得や変更を行 うことができます。 表 19-10: OLE ストレージのメンバー関数 関数 MemberExists MemberDelete MemberRename 機能 指定したメンバーがストレージ内に存在するかどうか を調べる メンバーは、ストレージかストリームのいずれかであ る。各メンバー名は、一意でなければならない。した がって、ストレージやストリームに同じ名前は付けられ ない。メンバーは、空のまま存在してもかまわない ストレージからメンバーを削除する ストレージのメンバーの名前を変更する 以下のコードは、subdata ストレージが stg_data ストレージ内に存在す るかどうかを調べてから、そのストレージを開きます。このコードで は、stg_data と stg_subdata が宣言され、インスタンスが作成されてい るものと想定しています。 boolean lb_exists result = stg_data.MemberExists("subdata", lb_exists) IF result = 0 AND lb_exists THEN result = stg_subdata.Open(stg_data, "subdata") END IF ストレージのメンバー IOle10Native に対して MemberExists 関数を実行 するには、次のように記述します。 ole_storage.memberexists(char(1) + 'Ole10Native', & lb_boolean) アプリケーション テクニック 407 OLE オブジェクトの高度な操作 char(1) が必要なのは、Microsoft の DocFile Viewer などのユーティリ ティでストレージを見たときに、IOle10Native の "I" は I ではないから です。 ストリームを開く場合も同じように記述する必要があります。たとえ ば、次のようになります。 ole_stream.open(ole_storage, char(1) + 'Ole10Native', & StgReadWrite!, StgExclusive!) 例 : ストレージの作成 たとえば、描画ツールで描かれた製品イメージ図を、データウィンド ウ オブジェクトの製品レコードに対応させて表示するものとします。 データベース レコードにはその画像の識別子が格納されています。ア プリケーションでは、この識別子をファイル名として用いて InsertFile 関数を呼び出します。しかし、サーバ アプリケーションを呼び出して 画像を表示するには比較的時間がかかります。 以下の図のように、ストレージ ファイルを作成し、すべての図を保持 しておくことにします。アプリケーションで画像を表示したいときは、 適切なサブ ストレージが開かれるようにします。 図 19-5: OLE ストレージ ファイル サーバ アプリケーションからファイルをコントロールに挿入せずに、 このようにストレージ ファイルを使用すると、処理速度が速くなるう え、すべての画像を単一のファイルにまとめることができて扱いやす くなります。どの画像を表示するにもストレージ ファイルを 1 つだけ 開けばよく、サーバ アプリケーションの起動も必要としないので、画 像が速く表示できるようになります。 408 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 ストレージ内の OLE オブジェクト この例で示すストレージ ファイルは、画像だけを格納していますが、 ファイル内のストレージが同一のサーバ アプリケーションによるも のである必要はありません。作成するアプリケーションの用途に応じ て、ストレージ ファイルに、任意の OLE サーバ アプリケーションの オブジェクトを格納することができます。 ここに示す例は、ストレージ ファイルを作成するユーティリティ アプ リケーションです。このユーティリティ アプリケーションは、データ ウィンドウ オブジェクトと OLE コントロールが 1 つずつある単一の ウィンドウです。 dw_prodid というこのデータウィンドウ オブジェクトには、製品コード カラムが 1 つ設けられています。データベース テーブルの設定を行っ て、製品コードと製品画像ファイル名とが対応付けられるようにしま す。なお、画像は ole_product という OLE コントロール上に表示します。 スクリプトの記述例 この例は、3 つのメイン スクリプトを必要とします。 • ウィンドウの Open イベントに対するスクリプトでは、ストレージ 変数のインスタンスを作成し、ストレージ ファイルを開いて、デー タウィンドウ オブジェクトのデータを読み取る。データベースと の接続は、アプリケーションの Open イベントで行う • データウィンドウ オブジェクトの RowFocusChanged イベントに 対するスクリプトで、画像を開き、ストレージ ファイルに格納する • ウィンドウの Close イベントに対するスクリプトでは、ストレージ ファイルを保存し、ストレージ変数を破棄する ウィンドウにコント ロールを追加する 最初に、dw_prodid コントロールと ole_product コントロールをウィンド ウに追加します。 アプリケーションの Open イベントに対す るスクリプト アプリケーションの Open イベントで、データベースと接続し、ウィ ンドウを開きます。 インスタンス変数 OLEStorage 変数をウィンドウのインスタンス変数として宣言します。 OLEStorage stg_prod_pic アプリケーション テクニック 409 OLE オブジェクトの高度な操作 ウィンドウの Open イ ベントに対するスクリ プト ウィンドウの Open イベントに対する以下のコードは、OLEStorage 変 数のインスタンスを作成し、その変数で PICTURES.OLE ファイルを開 きます。 integer result stg_prod_pic = CREATE OLEStorage result = stg_prod_pic.Open("PICTURES.OLE") dw_prod.SetTransObject(SQLCA) dw_prod.Retrieve() Retrieve 関数で RowFocusChanged イベントを呼び出す ストレージ変数を作成し、ストレージ ファイルを開くコードを Retrieve 関 数の 前に 記述 してお くこ とは 重要 なこと です。Retrieve 関 数は、 RowFocusChanged イベントを起動し、そのイベントによって OLEStorage 変数が参照されることになります。したがって、Retrieve 関数を呼び出 す前に、ストレージ ファイルを開いておかなければなりません。 RowFocusChanged イベントに対するスク リプト InsertFile 関数によって、画像が OLE コントロール上に表示されます。 RowFocusChanged イベントに対するスクリプトでは、データウィンド ウ オブジェクトの prod_id カラムから製品コードを取得し、それを用い て製品画像のファイル名を作成して、InsertFile 関数を呼び出します。最 後に、表示した画像をストレージに保存します。 integer result string prodid // データウィンドウから製品コードを取得します。 prodid = this.Object.prod_id[currentrow] // 製品コードを用いてファイル名を作成します。そのファイル // のオブジェクトをコントロール上に挿入します。 result = ole_product.InsertFile( & GetCurrentDirectory() + "\" + prodid + ".gif") // OLE オブジェクトをストレージに保存し、 // 同じ製品コードを用いてそのストレージに名前を付けます。 result = ole_product.SaveAs( stg_prod_pic, prodid) Close イベントに対す るスクリプト ウィンドウの Close イベントに対するコードでは、ストレージを保存 し、OLE ストレージをサーバから解放して、さらに OLEStorage 変数 のメモリを解放します。 integer result result = stg_prod_pic.Save() DESTROY stg_prod_pic 410 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 戻り値のチェック OLE 関数を呼び出したら、必ず戻り値をチェックしてください。この チェックを行わないと、アプリケーションは、操作が正常終了したか どうかを把握できません。例では、関数の実行が失敗するとスクリプト を中断して戻りますが、エラー メッセージを表示することもできます。 ユーティリティ アプ リケーションの実行 製品画像の識別子をデータベース テーブルに設定して、製品コードご とに画像を作成したら、アプリケーションを実行します。データウィ ンドウ オブジェクトをスクロールすると、対応するファイルが開き、 その OLE オブジェクトがストレージに保存されます。 ストレージ ファイル の使い方 ストレージに格納した画像をアプリケーションで使用するためには、 prod_id カラムをデータウィンドウ オブジェクトに配置し、その製品 コードを用いて PICTURES.OLE ファイル内のストレージを開きます。 以下のコードは、 現行の行に対する画像を OLE コントロールの ole_product に表示します。通常、このコードは、上述のユーティリティ アプリ ケーションのように、いくつかのイベントに分けて使用します。 OLEStorage stg_prod_pic // ストレージ変数をインスタンス化して、ファイルを開きます。 stg_prod_pic = CREATE OLEStorage result = stg_prod_pic.Open("PICTURES.OLE") // データウィンドウからストレージ名を取り出します。 // データウィンドウの rowfocuschanging イベントに // 追加されていると仮定しています。 prodid = this.Object.prod_id[newrow] // 製品の画像をコントロール上に開きます。 result = ole_product.Open( stg_prod_pic, prodid ) 実際のアプリケーションでは、開いているストレージを閉じて、スト レージ変数を破棄するコードも記述しておきます。 ストリームを開く ストリームには、OLE オブジェクトの生データが入っているので、サー バ アプリケーションで作成したストリームを変更することはまずあ りません。しかし、ストリームをストレージ ファイルに追加してスト レージに関する情報を格納することができます。たとえば、各ストレー ジに対するラベルを付けたり、ストレージのメンバーのリストを表示 したりするようなストリームを記述できます。 アプリケーション テクニック 411 OLE オブジェクトの高度な操作 OLE のストレージ ファイルのストリームにアクセスするには、 ストリー ム変数を定義し、そのインスタンスを作成して、すでに開いているスト レージからストリームを開きます。ストリームを開くと、ストリーム変 数とストレージ内のストリーム データとの接続を確立します。 以下のコードでは、OLEStorage 変数と OLEStream 変数を宣言し、スト レージを開いてから、ストリームを開きます。 integer result OLEStorage stg_pic OLEStream stm_pic_label /*************************************************** ストレージ変数とストリーム変数にメモリを割り当てます。 ***************************************************/ stg_pic = CREATE OLEStorage stm_pic_label = CREATE OLEStream /*************************************************** ストレージを開き、戻り値をチェックします。 ***************************************************/ result = stg_prod_pic.Open("picfile.ole") IF result <> 0 THEN RETURN /*************************************************** ストリームを開き、戻り値をチェックします。 ***************************************************/ result = stm_pic_label.Open( stg_prod_pic, & "pic_label", stgReadWrite!) IF result <> 0 THEN RETURN PowerBuilder は、ストリームの開閉や、ストリームに対する情報の入 出力に用いるストリーム関数をいくつか用意しています。 412 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 表 19-11: ストリーム関数 関数 Open Length Seek Read Write Close 例 : ストリームの読み 書き 機能 指定した OLEStream 変数にストリームを開く。このストリー ムを格納しているストレージは、あらかじめ開いておかなけ ればならない ストリームのサイズをバイト単位で取得する シーク ポインタをストリーム内に配置する。次の読み書き操 作は、このポインタから行われる ストリームからのデータの読み取りをシーク ポインタの位置 から開始する ストリームへのデータの書き込みをシーク ポインタの位置か ら開始する ポインタがストリームの終わりを指していない場合は、Write 関数は既存データを上書きする。書き込むデータがストリーム の現行サイズより大きくなる場合は、そのサイズが拡張される ストリームを閉じ、OLEStream 変数との接続を解除する 以下の例は、製品の在庫データをデータウィンドウ オブジェクトの dw_product に表示するときに、その製品の画像を OLE コントロール ole_product に表示します。 ここでは、前述のユーティリティ アプリケー ションで構築したファイルを使用します(408 ページの「例 : ストレー ジの作成」を参照)。画像は、OLE ストレージ ファイルに格納されて います。また、各画像のストレージの名前はデータベース テーブルの 製品コードと同一です。この例では、各画像にラベル情報を追加し、 製品コードに接尾辞 _lbl を付けた名前のストリームに格納します。 図 19-6 はファイルの構造を示しています。 アプリケーション テクニック 413 OLE オブジェクトの高度な操作 図 19-6: OLE ストレージ ファイルの構造 この例は、3 つのスクリプトを必要とします。 • ウィンドウの Open イベントに対するスクリプトでは、ストレージ ファイルを開いて、データウィンドウ オブジェクトのデータを読 み取る。データベースとの接続は、アプリケーションの Open イベ ントで行う • データウィンドウ オブジェクトの RowFocusChanged イベントに 対するスクリプトでは、画像を表示する。また、その画像のラベ ルを持つストリームを開き、そのラベルを StaticText に表示する。 ストリーム名は、製品コードに接尾辞 _lbl を付けたものとなる ラベルが空(サイズがゼロ)の場合は、ラベルをスクリプトで記 述します。このとき記述するデータは、処理を簡単にするために ストリーム名と同じにします。ラベルは、ファイルの作成時に記 述し、ファイルの表示時に読み取るものですが、ここでは、説明 のために、ストリームの読み書きの両方について示しています。 • ウィンドウの Close イベントに対するスクリプトでは、ストレージ ファイルを保存し、ストレージ変数を破棄する OLEStorage 変数 stg_prod_pic は、ウィンドウのインスタンス変数です。 OLEStorage stg_prod_pic ウィンドウの Open イベントに対するスクリプトは以下のとおりです。 integer result stg_prod_pic = CREATE OLEStorage 414 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 result = stg_prod_pic.Open( is_ole_file) dw_prod の RowFocusChanged イベントに対するスクリプトは以下のと おりです。 integer result string prodid, labelid, ls_data long ll_stmlength OLEStream stm_pic_label /*************************************************** OLEStream 変数を作成します。 ***************************************************/ stm_pic_label = CREATE OLEStream /*************************************************** データウィンドウから製品コードを取り出します。 ***************************************************/ this.Object.prod_id[currentrow] /*************************************************** ストレージ ファイルの画像をコントロール上に開きます。 ストレージ名は製品コードと同じです。 ***************************************************/ result = ole_prod.Open(stg_prod_pic, prodid) IF result <> 0 THEN RETURN /*************************************************** 製品ラベルのストリーム名を作成し、そのストリームを 開きます。 ***************************************************/ labelid = prodid + "_lbl" result = stm_pic_label.Open( stg_prod_pic, & labelid, stgReadWrite! ) IF result <> 0 THEN RETURN /*************************************************** ストリームのサイズを求めます。データがあれば (サイズが 0 より大きければ)、そのデータを読み取り、データがなけれ ば、ラベルを記述します。 ***************************************************/ result = stm_pic_label.Length(ll_stmlength) IF ll_stmlength > 0 THEN result = stm_pic_label.Read(ls_data) IF result <> 0 THEN RETURN // ストリーム データを st_label に表示します。 st_label.Text = ls_data ELSE result = stm_pic_label.Write( labelid ) IF result < 0 THEN RETURN // 記述したデータを st_label に表示します。 アプリケーション テクニック 415 OLE オブジェクトの高度な操作 st_label.Text = labelid END IF /**************************************************** ストリームを閉じ、ストリーム変数のメモリを解放します。 ***************************************************/ result = stm_pic_label.Close() DESTROY stm_pic_label ウィンドウの Close イベントに対するスクリプトは以下のとおりです。 integer result result = stg_prod_pic.Save() DESTROY stg_prod_pic ストレージを使用する際のストラテジ データをストレージに格納することとデータベースに格納することは 異なります。ストレージ ファイルでは、ストレージを好きなように編 成できるので、データを編成する必要がありません。たとえば、スト レージ ファイルをネストさせて階層的なシステムを設計することが できます。また、アプリケーションの配布やバックアップを簡単にす るために、ストレージ ファイルのルート レベルにいくつかのサブスト レージを一緒に格納しておくだけでもかまいません。また、1 つのファ イルの中に、さまざまな OLE サーバ アプリケーションで作成したス トレージを格納することができます。 使用している DBMS が Blob 型をサポートしていない場合や、データ ベース管理者が大きな Blob 型データをデータベースのログに残さな いようにしている場合は、OLE データを保持する別の手段として、ス トレージを使用できます。 ストレージの構造の遷移を記録しておくこともできます。ストレージ ファイル内のメンバー名(ストレージやストリーム)のリストを表示 するストリームをルート レベルで記述したり、ストリームにストレー ジのラベルやデータベースのキー情報を記述してストレージの説明文 書として利用したりすることができます。 416 PowerBuilder 第 2 0 章 MAPI の使い方 この章について この章では、PowerBuilder アプリケーションで MAPI(Messaging Application Program Interface)を使用して電子メールを送受信する 方法について説明します。 内容 項目 MAPI について MAPI の使い方 ページ 417 418 MAPI について PowerBuilder は MAPI(Messaging Application Program Interface)を サポートします。これにより、アプリケーションは MAPI 準拠の 任意の電子メール システムを使用してメッセージを送受信できま す。 たとえば、PowerBuilder アプリケーションは以下を実行できます。 MAPI サポートの実装方法 アプリケーション テクニック • アプリケーションが実行した解析の結果をメールで送信する • ユーザが特定の操作を実行したときにメールを送信する • 情報を要求するメールを送信する • アプリケーションのユーザが必要とする情報を含むメールを 受け取る MAPI をサポートするために、PowerBuilder は 表 20-1 に示す項目 を提供します。 417 MAPI の使い方 表 20-1: PowerBuilder の MAPI サポート 項目 メール関連のシステム オブ ジェクト メール関連の構造体 名前 MailSession MailFileDescription MailMessage MailRecipient MailSession オブジェクトのオ ブジェクト関数 MailAddress MailDeleteMessage MailGetMessages MailHandle MailLogoff MailLogon MailReadMessage MailRecipientDetails MailResolveRecipient MailSaveMessage MailSend カタログデータ型 MailFileType MailLogonOption MailReadOption MailRecipientType MailReturnCode MAPI の使い方 MAPI を使うには、MailSession オブジェクトを作成してから、MailSession 関数を使用してそのオブジェクトを管理します。 例 MailSession PBmail PBmail = CREATE MailSession PBmail.MailLogon(...) ... // セッションの管理処理 : たとえば、メッセージの送信、 ... // メッセージの受信など PBmail.MailLogoff() DESTROY PBmail 418 PowerBuilder 第 20 章 MAPI の使い方 オブジェクト ブラウザを使用して、MailSession システム オブジェク トのプロパティと関数、メール関連の構造体のプロパティ、およびメー ル関連のカタログデータ型として有効な値についての詳細を取得でき ます。 オブジェクト ブラウザの使い方の詳細については、PowerBuilder の 『ユーザーズ ガイド』マニュアルを参照してください。MailSession 関 数の詳細については、 『PowerScript リファレンス』マニュアルを参照 してください。MAPI についての詳細は、各 MAPI に準拠したメール アプリケーションのマニュアルを参照してください。 アプリケーション テクニック 419 MAPI の使い方 420 PowerBuilder 第 2 1 章 外部関数とそのほかの拡張処理機能 の使い方 この章について この章では、PowerBuilder における外部関数の使い方とそのほか の拡張処理機能について説明します。 内容 項目 外部関数の使い方 ユーティリティ関数の使い方 Windows メッセージの送信 メッセージ オブジェクト コンテキスト情報 ページ 421 429 430 432 434 外部関数の使い方 外部関数は、PowerScript 以外の言語で記述され、ダイナミック ラ イブラリに保存されている関数です。Windows 上では、外部関数 はダイナミック リンク ライブラリ( DLL: Dynamic LinkLibrary)に 保存されます。 32 ビット プラットフォーム用の標準呼び出しシーケンスをサポー トする、任意の言語で書かれた外部関数を使用できます。 自分で書いたライブラリ内の関数を呼び出す場合は、その関数を エクスポートしなければならないので注意してください。このエ クスポートは、使用コンピュータによって関数プロトタイプまた はリンカ定義(DEF)ファイルで行います。 アプリケーション テクニック 421 外部関数の使い方 Use _stdcall 規約 C と C++ コンパイラは、通常いくつもの呼び出し規約をサポートしま す。呼び出し規約には、_cdecl (C プログラム用のデフォルトの呼び出 し規約)、_stdcallA(Windows API 呼び出し用の標準規約)、_fastcall、お よび thiscall があります。PowerBuilder は、多くのほかの Windows 開発 ツールのように、WINAPI(_stdcall)形式を使用してエクスポートされ るようにする外部関数を要求します。異なる呼び出し規約を使用する と、アプリケーション クラッシュを引き起こします。 PowerBuilder で使用される関数を含む独自の C や C++ DLL を作成する 時には、Windows API 呼び出し用の標準規約を使用することを確認し てください。たとえば、関数定義をエクスポートするために DEF ファ イルを使用している場合は、以下のように関数を宣言します。 LONG WINAPI myFunc() { ... }; PBNI の使い方 外部関数は PowerBuilder エクステンションでも呼び出せます。 PowerBuilder エクステンションは PowerBuilder Native Interface(PBNI) を使用して作成されます。PowerBuilder エクステンションの作成につ いての詳細は、『PowerBuilder ネイティブ インタフェース プログラ マーズ ガイドとリファレンス』マニュアルを参照してください。 PowerBuilder エクステンションの使い方についての詳細は、 『PowerBuilder エクステンション機能リファレンス』マニュアルを参 照してください。 外部関数の宣言 外部関数は、スクリプトで使用する前に宣言しておかなければなりま せん。 2 種類の外部関数 422 2 種類の外部関数が宣言できます。 • グローバル外部関数この関数は、アプリケーション内のどこから でも使用できます。 • ローカル外部関数この関数は、特定のウィンドウ、メニュー、ま たはユーザ オブジェクトに対して定義されます。 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 ローカル外部関数はオブジェクトの定義の一部となるので、その オブジェクト自身のスクリプトの中で使用できます。さらに、こ の関数をほかのスクリプトで使用することも可能です。 外部関数を宣言するときは、引数のデータ型がその関数のソース定義 の中で宣言されたデータ型と一致しなければなりません。 外部関数の引数のデー タ型 外部関数のデータ型と PowerBuilder 内のデータ型の比較については、 『PowerScript リファレンス』マニュアルの外部関数の宣言と呼び出し に関する章を参照してください。 v 外部関数を宣言するには 1 ローカル外部関数を宣言する場合には、関数を宣言したいオブ ジェクトを開きます。 2 スクリプト ビューでは、最初のドロップダウン リストから 「(Decleare)」を選択し、2 番目のドロップダウン リストから 「Global External Functions」または「Local External Functions」を選 択します。 3 関数宣言をスクリプト ビューに入力します。 使用する構文については、 『PowerScript リファレンス』マニュアル または下記の例を参照してください。 4 オブジェクトを保存します。 PowerBuilder は宣言をコンパイルします。構文エラーが存在する場 合には、エラー ウィンドウが開きます。その場合には、エラーを 修正しなければ、宣言を保存できません。 既存の関数の変更 スクリプト ビューでは、既存の外部関数の宣言を修正することもでき ます。 外部関数の宣言例 ここで、文字列と構造体の 2 つのパラメータを受け取る SimpleFunc と いう関数を保持する SIMPLE.DLL という C 言語のダイナミック ライ ブラリを作成したとします。以下のステートメントは、この参照で引 数を渡す関数を PowerBuilder で宣言します。 FUNCTION int SimpleFunc(REF string lastname, & REF my_str pbstr) LIBRARY "simple.dll" アプリケーション テクニック 423 外部関数の使い方 デフォルトでは、PowerBuilder は文字列引数を処理し、値を Unicode エ ンコーディングが使用されているものとして返します。SimpleFunc 関 数が引数として ANSI 文字列を渡す場合は、次の構文で関数を宣言す る必要があります。 FUNCTION int SimpleFunc(REF string lastname, & REF my_str pbstr) LIBRARY "simple.dll" & ALIAS FOR "SimpleFunc;ansi" Windows API 関数の 宣言 Windows の API には、PowerBuilder から呼び出し可能な関数が 1,000 個 以上あります。以下の例は、32 ビットの Windows API ライブラリ KERNEL32.DLL、GDI32.DLL、および USER32.DLL の中の関数の宣言 例です。 Windows API の呼び出し いくつかの 32 ビット関数名の最後には、A(ANSI の略)または W(ワ イドの略)が付いています。PowerBuilder ではワイド関数名を使用し ます。 Windows の API 関数の全リストについては、Microsoft Windows ソフト ウェア開発キット(SDK)のマニュアルを参照してください。 PowerBuilder の宣言構文とスクリプトの例については、Sybase の Technical Documents のサイト http://www.sybase.com/support/techdocs/ で Windows API call を検索してみてください。 以下のステートメントは、名前で呼び出される任意のウィンドウのハ ンドルを取得する関数と、開いたオブジェクトのハンドルを解放する 関数を宣言します。 FUNCTION ulong FindWindowW(ulong classname, & string windowname) LIBRARY "User32.dll" FUNCTION boolean CloseHandle(ulong w_handle) & LIBRARY "Kernel32.dll" 以下のステートメントは、受け取った座標に基づいて円グラフを描く 関数を宣言します。 FUNCTION boolean Pie(ulong hwnd,long x1,long y1, & long x2,long y2,long x3,long y3,long x4, & long y4) LIBRARY "Gdi32.dll" 以下のステートメントは、IsZoomed という外部 C 関数を宣言します。 FUNCTION boolean IsZoomed(Ulong handle) LIBRARY "User32.DLL" 424 & PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 外部関数 IsZoomed を使用するスクリプトは、429 ページの「ユーティ リティ関数の使い方」に例として記載してあります。 これらの関数についての詳細は、MSDN Library のサイト http://msdn.microsoft.com/en-us/library/ms674884(VS.85).aspx にある Microsoft のマニュアルを参照してください。 引数の受け渡し PowerBuilder では、外部関数を定義する際に、引数の受け渡しを参照 か値のどちらで行うかを指定できます。引数を参照(reference)で渡 す場合、外部関数はその引数のポインタを受け取るため、引数の内容 を変更できます。そして変更後の内容を、PowerBuilder に返します。一 方、引数を値(value)によって渡す場合、外部関数はその引数のコ ピーを受け取るため、そのコピーの内容しか変更できません。この場 合に変更されるのはローカル コピーだけで、オリジナルの引数の内容 は変更されません。 参照によって渡される引数の構文は以下のとおりです。 REF datatype arg 値によって渡される引数の構文は以下のとおりです。 datatype arg 数値データ型の受け渡し 以下のステートメントは、PowerBuilder で外部関数 TEMP を宣言しま す。この関数は整数値を返し、参照によって渡される整数値の引数を 必要とします。 FUNCTION int TEMP(ref int degree) LIBRARY "LibName.DLL" このステートメントは、C で記述すると以下のようになります。 int _stdcall TEMP(int * degree) 引数は参照によって渡されるため、この関数が引数の内容を変更する と、その変更内容は、PowerBuilder のオリジナルの変数値に直接影響 します。たとえば、C のステートメント *degree = 75 は、degree とい う引数を 75 に変更して、PowerBuilder に 75 を返します。 以下のステートメントは、PowerBuilder で外部関数 TEMP2 を宣言しま す。この関数は Integer 型を返し、値によって渡される Integer 型の引数 を必要とします。 アプリケーション テクニック 425 外部関数の使い方 FUNCTION int TEMP2(int degree) LIBRARY "LibName.DLL" このステートメントは、C で記述すると以下のようになります。 int _stdcall TEMP2(int degree) 引数は値によって渡されるため、関数は引数の内容を変更できます。 変更はすべて引数のローカル コピーに対して行われるので、 PowerBuilder の変数への影響はありません。 文字列の受け渡し PowerBuilder は、すべての文字列引数と戻り値が Unicode エンコーディ ングを使用するものとします。関数が ANSI エンコーディングの文字 列を使用する場合は、関数宣言に ALIAS FOR 句を追加して、セミコロ ンの後に ansi キーワードを付ける必要があります。たとえば、次のよ うになります。 FUNCTION string NAME(string CODE) LIBRARY "LibName.DLL" ALIAS FOR "NAME;ansi" 値による受け渡し 以下のステートメントは、PowerBuilder で C の外部 関数 NAME を宣言します。この関数は、値によって渡される Unicode エンコーディングの String 型の引数を取ります。 FUNCTION string NAME(string CODE) LIBRARY "LibName.DLL" C による同様のステートメントでは、この String 型が保持されている バッファをポインタで示します。 char * _stdcall NAME(char * CODE) この String 型は値によって渡されるため、この C 関数が変更できるの は引数 CODE のローカル コピーの内容だけで、PowerBuilder のオリジ ナルの変数には影響しません。 参照渡し PowerBuilder は自身のメモリにのみアクセスできます。した がって、外部関数は PowerBuilder に文字列のポインタを返すことがで きません(メモリ アドレスを返すことができません)。 値渡し、参照渡しにかかわらず、外部関数に文字列を渡すと、その文 字列のポインタが渡されます。値渡しでは、外部関数がその文字列に 行った変更内容は、PowerBuilder からアクセスすることができません。 しかし、参照渡しでは変更内容にアクセスすることができます。 以下のステートメントは、PowerBuilder で C の外部関数 NAME2 を宣言 したものです。この関数は、参照によって引き渡される String 型変数 を取り、String 型を返します。 426 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 FUNCTION string NAME2(ref string CODE) LIBRARY "LibName.DLL" & C 言語によってこれを記述すると、引数が値で渡されるステートメン トと同じになります。 char * _stdcall NAME2(char * CODE) この場合、String 型引数は参照によって渡されるので、C の関数は引数 の内容とともに、PowerBuilder のオリジナルの変数の内容も変更でき ます。たとえば、Strcpy(CODE,STUMP) は CODE の内容を変数 STUMP に変更し、呼び出し側の PowerBuilder のスクリプトの変数の値も変数 STUMP の内容に変更します。 前例の関数 NAME2 でユーザ ID を引数として取って、それをそのユー ザの名前に置き換えるものとします。このとき、PowerScript の String 型変数 CODE が、返される値を保持するのに十分な大きさでなければ なりません。十分な大きさを確保するために、String 型変数を宣言した 後で、Space 関数を使用して、NAME2 関数が返す最大文字数と同数の ブランク(空白文字)をこの String 型変数に与えておきます。 ユーザ名に許される最大文字数が 40 バイトで、ユーザ ID が常に 5 バ イト である場合には、NAME2 関数を呼び出す前に、String 型変数 CODE に 35 個のブランクを追加しておきます。 String CODE CODE = ID + Space(35) . . . NAME2(CODE) Space 関数の詳細については、 『PowerScript リファレンス』マニュアル を参照してください。 文字の受け渡し WinAPI への文字の受け渡し WinApi 文字は ANSI 値または Unicode 値 を 取 り ま す が、PowerBuilder 文 字 が 取 る の は Unicode 値 の み で す。 WinAPI 呼び出しによって受け渡される ANSI Char 値は、PowerBuilder によって自動的に変換されます。このため、文字配列の長さを定義す る場合は、必ず PowerBuilder 文字長(文字あたり 2 バイト)を設定し ます。 C の関数への文字の受け渡し C の外部関数に渡された Char 型の変数は、 渡される前に C の Char 型に変換されます。Char 型変数の配列は、C の 同等の Char 型変数の配列に変換されます。 アプリケーション テクニック 427 外部関数の使い方 構造体に埋め込まれた Char 型変数の配列は、C の構造体に埋め込まれ た配列に変換されます。これは、埋め込みの String 型(C の構造体の String への埋め込みポインタとなります)とは異なります。 注意 可能なときは必ず、関数からの戻り値として String 型の変数を PowerBuilder に返してください。 UNIX での外部関数とプログラムの呼び出し PowerBuilder カスタム クラス ユーザ オブジェクトを UNIX プラット フォーム上に EAServer コンポーネントとして配布する場合、サーバが 動作するオペレーティング システムでコンパイルされた共有ライブ ラリの外部関数を呼び出すことができます。ただし、Windows API の 呼び出しが発生する外部関数や、グラフィカル プロセスに依存する外 部関数を呼び出すことはできません。 UNIX 共有ライブラリにある関数を宣言するには、標準の PowerScript 構文を使用できます。たとえば、次のステートメントでは、Solaris の 標準 C ライブラリにある関数 getcwd を宣言します。 FUNCTION string getcwd(REF string buff, & unsigned int size) LIBRARY "/usr/lib/libc.so" アプリケーションでスクリプトから関数を呼び出す方法は、ほかの関 数を呼び出す方法と同じです。次の例では、space 関数は、getcwd に よって返されたディレクトリ名を保持するのに十分な領域を割り当て ます。 string ls_return, ls_directory ls_directory = space(100) . . . ls_return = getcwd(ls_directory, 100) ロード ライブラリ パスの更新 UNIX でコンポーネントが外部関数を呼び出す場合には、コンポーネ ントは、その関数が置かれている共有ライブラリを検出できなければ なりません。そのためには、ライブラリ パス環境変数を更新して、そ の共有ライブラリが置かれているディレクトリを追加する必要があり ます。 428 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 ユーティリティ関数の使い方 ユーティリティ関数は、Windows の情報を入手して外部関数に渡す手 段を提供するので、PowerScript の Send 関数の引数として使用できま す。表 21-1 に、PowerScript のユーティリティ関数を示します。 5 つのユーティリティ 関数 表 21-1: ユーティリティ関数 関数 戻り値 目的 Handle UnsignedInt IntHigh UnsignedInt 指定されたオブジェクトのハンドルを返す 指定された Long 型数値の上位ワードを返す UnsignedInt この関数は、外部関数やメッセージ オブジェク トの LongParm プロパティによって入手される Windows パラメータの値をデコードするときに 用いる 指定された Long 型数値の下位ワードを返す IntLow Long Long LongLong LongLong この関数は、外部関数やメッセージ オブジェク トの LongParm プロパティによって入手される Windows パラメータの値をデコードするときに 用いる 下位ワードと上位ワードを連結して、Long 型数 値にする Long 関数は、外部関数に値を渡すときに用いる 下位ワードと上位ワードを連結して、LongLong 型数値にする LongLong 関数は、外部関数に値を渡すときに用 いる 例 以下のスクリプトは、外部関数 IsZoomed を使用して、現行ウィンドウ のサイズが最大になっているかどうかテストします。このスクリプト は、Handle 関数を使用して、ウィンドウ ハンドルを IsZoomed に渡しま す。また、その結果を、sle_output という名前のシングルライン エディッ トに表示します。 boolean Maxed Maxed = IsZoomed(Handle(parent)) if Maxed then sle_output.Text = " 最大表示 " if not Maxed then sle_output.Text = " 通常の表示 " 以下のスクリプトは、ウィンドウ オブジェクトのハンドルを外部関数 FlashWindow に渡して、ウィンドウのタイトル バーを使用不可にし、し ばらくして使用可能に戻します。 // ループのカウンタ変数とウィンドウ オブジェクトのハンドルを // 宣言します。 int nLoop アプリケーション テクニック 429 Windows メッセージの送信 uint hWnd // PowerBuilder のウィンドウのハンドルを入手します。 hWnd = handle(This) // タイトル バーを使用不可にします。 FlashWindow (hWnd, TRUE) // しばらくそのままにします。 For nLoop = 1 to 300 Next // ウィンドウのタイトル バーを使用可能に戻します。 FlashWindow (hWnd, FALSE) Windows メッセージの送信 PowerBuilder で作成したウィンドウまたは外部ウィンドウ(たとえば、 外部関数で作成したウィンドウ)にメッセージを送るときは、Post 関 数または Send 関数を使用します。PowerBuilder イベントを発生させる には、EVENT 構文、TriggerEvent 関数、または PostEvent 関数を使用し ます。 Post 関数と Send 関 数の使い方 通常、Post 関数と Send 関数は、 PowerBuilder イベントにはない Windows イベントを発生させるときに使用します。これらの関数は、イベント が発生するウィンドウのスクリプト、またはアプリケーションの任意 のスクリプトで使用できます。 Post 関数は非同期関数です。つまり、メッセージはウィンドウまたは コントロールのメッセージ キューに送られます。Send 関数は同期関数 であり、ウィンドウやコントロールが直接メッセージを受け取ります。 PowerBuilder 6.0 の時点では、PowerBuilder によってポストされたすべ てのイベントは、Windows のシステム キューとは別のキューによって 処理されていました。PowerBuilder がポストしたメッセージは、Windows がポストしたメッセージの前に処理されていました。 ウィンドウのハンドルの入手方法 ウィンドウのハンドルを入手するには、Handle 関数を使用します。2 つ の Integer 型の数値を結合してメッセージの Long 値を形成するときは、 Long 関数を使用します。 Handle 関数と Long 関数はユーティリティ関数 で、この章で前述しています。 PowerBuilder イベン トの発生方法 430 PowerBuilder イベントを発生させるには、表 21-2 に示した方法を使用 できます。 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 表 21-2: PowerBuilder イベントを発生させる方法 使用するもの TriggerEvent 関数 PostEvent 関数 イベント呼び出し構文 説明 ウィンドウやコントロールのスクリプトの実行 中、指定したオブジェクトのイベントをただちに 起動する同期関数 非同期関数。イベントはウィンドウやコントロー ルのイベント キューに追加される ドット(.)表記を使用して、コントロールのイ ベントを直接呼び出す方法 3 つの方法とも、メッセージ キューをバイパスするので、Send 関数と Post 関数よりスクリプトの記述が簡単です。 以下の 3 つのステートメントはすべて、コマンドボタン cb_OK の Clicked イベントを起動します。これらのステートメントは、cb_OK が 配置されているウィンドウのスクリプトに記述されているものとしま す。 例 Send 関数では、Handle ユーティリティ関数を使用して、コマンドボタ ン cb_OK があるウィンドウのハンドルを入手します。また、Long 関数 を使用して、コマンドボタン cb_OK のハンドルと 0(BN_CLICK)を連 結し、オブジェクトとイベントを識別する Long 型の数値に変換しま す。 Send(Handle(Parent),273,0,Long(Handle(cb_OK),0)) cb_OK.TriggerEvent(Clicked!) cb_OK.EVENT Clicked() TriggerEvent 関数は、イベントを起動するオブジェクトを識別します。 Clicked イベントを起動するには、カタログデータ型の値 Clicked! を指 定します。 イベント呼び出しは、EVENT キーワードを使用して Clicked イベント を起動します。イベントを呼び出すときは、TRIGGER キーワードがデ フォルトです。Clicked イベントをポストする場合は、POST キーワー ドを使用します。 Cb_OK.EVENT POST Clicked() アプリケーション テクニック 431 メッセージ オブジェクト メッセージ オブジェクト メッセージ(Message)オブジェクトは、あらかじめ定義された PowerBuilder のグローバル オブジェクトです(デフォルトのトランザクション オブ ジェクトの SQLCA やエラー オブジェクトと同類です)。メッセージ オ ブジェクトは、PowerBuilder で定義されたイベントにない Microsoft Windows イベントを処理するスクリプ トの中で使用されます。 PowerBuilder で定義されたイベントにない Windows イベントが発生す ると、PowerBuilder はそのイベントに関する情報をメッセージ オブ ジェクトに保持します。 メッセージ オブジェ クトのそのほかの用途 メッセージ オブジェクトは、以下のような場合にも用いられます。 • ウィンドウの開閉時に、ウィンドウ間でパラメータの受け渡しを するため 詳細については、『PowerScript リファレンス』マニュアルの OpenWithParm、OpenSheetWithParm、および CloseWithReturn の各関 数の説明を参照してください。 • TriggerEvent 関数や PostEvent 関数で、オプションのパラメータが使 用された場合でも、イベントに情報を渡すため 詳細については、 『PowerScript リファレンス』マニュアルを参照し てください。 メッセージ オブジェ クトのカスタマイズ アプリケーションで使用しているグローバル メッセージ オブジェク トは、組み込みの Message オブジェクトを継承した標準クラス ユーザ オブジェクトを定義することによってカスタマイズできます。その ユーザ オブジェクトでは、新たなプロパティ(インスタンス変数)や 関数の追加が可能です。アプリケーションの必要に応じて、ユーザ定 義プロパティの設定や関数の呼び出しが行えます。 標準クラス ユーザ オブジェクトの定義の詳細については、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 メッセージ オブジェクトのプロパティ メッセージ オブジェクトの最初の 4 つのプロパティは、Microsoft Windows のメッセージ構造体の最初の 4 つのプロパティに対応しま す。 432 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 表 21-3: メッセージ オブジェクトのプロパティ プロパティ Handle データ型 用途 Integer Number Integer WordParm UnsignedInt ウィンドウやコントロールのハンドル イ ベ ン ト を 識 別 す る 番 号。こ の 番 号 は Windows から送られる イベントの Word パラメータ。このパラ メータは Windows から送られる。パラメー タの値と意味はイベントによって異なる LongParm Long DoubleParm StringParm PowerObjectParm Double Processed Boolean String PowerObject イベントの Long 型パラメータ。このパラ メータは Windows から送られる。パラメー タの値と意味はイベントによって異なる 数値または数値変数 文字列または String 型変数 構造体を含む PowerBuilder オブジェクト データ型 ユーザ定義イベントに対応するスクリプ トで設定された Boolean 型の値 • TRUE - スクリプトがイベントを処理し た。イベントの処理の後、デフォルト ウィンドウ プロシージャ (DefWindowProc 関数)を呼び出さない ReturnValue Long • FALSE -(デフォルト)イベントの処理 の後、DefWindowProc 関数を呼び出す Message.Processed プロパティが TRUE のと きに、開発者が Windows に戻す値 Message.Processed プロパティが FALSE の ときは、このプロパティは無視される メッセージ オブジェクトの値は、メッセージ オブジェクトに値が生成 されるイベント スクリプト内で使用します。たとえば、FileExists イベ ントに以下のスクリプトが記述されているとします。OpenWithParm で 応答ウィンドウを表示して、ファイルを上書きするかどうかを確認す るメッセージをユーザに表示します。ファイルを保存するかどうかは、 FileExists からの戻り値によって決まります。 OpenWithParm( w_question, & " 指定されたファイルはすでに存在します。" + & " このファイルを上書きしますか ?" ) IF Message.StringParm = "Yes" THEN RETURN 0 // ファイルを保存します ELSE RETURN -1 // 保存をキャンセルします END IF アプリケーション テクニック 433 コンテキスト情報 Microsoft Windows のメッセージ番号とパラメータの詳細については、 Microsoft Windows ソフトウェア開発キット(SDK)のマニュアルを参 照してください。 コンテキスト情報 PowerBuilder のコンテキスト機能を使用して、アプリケーションで一 定のホスト(PowerBuilder 以外)のサービスにアクセスできます。こ れは、COM QueryInterface に類似した PowerBuilder の実装機能です。 PowerBuilder では、以下のホスト サービスにアクセスできます。 • コンテキスト情報サービス • コンテキスト キーワード サービス • CORBACurrent サービス • エラー ロギング サービス • インターネット サービス • Secure Sockets Layer サービス • トランザクション サーバ サービス PowerBuilder は、現行の実行コンテキスト(ネイティブな PowerBuilder または トランザクション サーバ)に合わせて適切なサービス オブジェ クトを作成します。この機能により、アプリケーションで実行環境を 最大限利用できるようになります。 コンテキスト機能では、ContextInformation、ContextKeyword、 CORBACurrent、ErrorLogging、Inet、SSLServiceProvider、 TransactionServer という 7 つの PowerBuilder サービス オブジェクトと InternetResult オブジェクトを使用します。コンテキスト機能はコンテ キスト オブジェクトと呼ばれることがありますが、PowerBuilder のシ ステム オブジェクトではありません。 これらのオブジェクトの詳細については、 『オブジェクトとコントロー ル』マニュアルまたは PowerBuilder オブジェクト ブラウザを参照して ください。 434 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 サービスを使用する前に、GetContextService 関数を呼び出して、そのサー ビスのインスタンスを作成します。この関数を呼び出すと、PowerBuilder はそのインスタンス化されたサービスへの参照を返します。サービス の関数を呼び出すときは、この参照をドット(.)表記で使用してくだ さい。 サービスを使用可能に する方法 v サービスを使用可能にするには 1 適切な型のインスタンス変数を設定します。 ContextInformation ContextKeyword CORBACurrent ErrorLogging Inet SSLServiceProvider TransactionServer 2 icxinfo_base icxk_base corbcurr_base erl_base iinet_base sslsp_base ts_base GetContextService 関数を呼び出して、インスタンス変数のインスタ ンスを作成します。 this.GetContextService("ContextInformation", & icxinfo_base) this.GetContextService("ContextKeyword", icxk_base) // EAServer で ContextKeyword のかわりに Keyword を使用 this.GetContextService("Keyword", icxk_base) this.GetContextService("CORBACurrent", & corbcurr_base) this.GetContextService("ErrorLogging", erl_base) this.GetContextService("Internet", iinet_base) this.GetContextService("SSLServiceProvider", & sslsp_base) this.GetContextService("TransactionServer",ts_base) CREATE 文の使い方 サービス オブジェクトは、PowerScript の CREATE 文でインスタンス化 できます。ただし、このステートメントでは、アプリケーションがど こで実行しているかに関係なく、常にデフォルト コンテキスト(ネイ ティブな PowerBuilder の実行環境)のオブジェクトが作成されます。 コンテキスト情報サービス コンテキスト情報サービスは、アプリケーションの実行コンテキスト に関する情報を入手するときに使用します。このサービスでは、アプ リケーションが PowerBuilder 実行環境で実行されているかどうかがわ かるだけでなく、現行バージョンに関する情報も入手できます。 アプリケーション テクニック 435 コンテキスト情報 コンテキスト情報サービスを使用して、表 21-4 の情報にアクセスでき ます。 コンテキスト情報への アクセス 表 21-4: コンテキスト情報 項目 コンテキスト名 使用する関数 コンテキスト名 の略称 GetShortName 会社名 GetCompanyName バージョン GetVersionName メジャー バー ジョン マイナー バー ジョン GetMajorVersion フィックス バージョン GetFixesVersion 説明 戻り値はコンテキストによって異な る GetName • デフォルト :PowerBuilder Runtime 戻り値はコンテキストによって異なる • デフォルト :PBRUN GetMinorVersion 会社名を返す(Sybase, Inc など) 完全なバージョン番号を返す (11.5.0.1 など) メジャー バージョン番号を返す (11.5 など) マイナー バージョン番号を返す(0 など) フィックス バージョン番号を返す(1 など) ClassName 関数を使用したコンテキスト情報へのアクセス オブジェクトのコンテキストの判別には ClassName 関数も使用できま す。 この情報を使用して、コンテキストが現行バージョンをサポートして いるかどうかを確認できます。たとえば、アプリケーションでバージョ ン 11.5.0.1 の機能や修正部分が必要な場合は、コンテキスト情報サー ビスを使用して、現行の実行コンテキストのバージョンを確認できま す。 v コンテキスト情報にアクセスするには 1 ContextInformation 型のインスタンスまたはグローバル変数を宣言 します。 ContextInformation 2 icxinfo_base GetContextService 関数を呼び出して、コンテキスト情報サービスを 作成します。 this.GetContextService("ContextInformation", icxinfo_base) 3 436 & 必要な場合は、コンテキスト情報サービス関数を呼び出します。 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 この例では、GetShortName 関数を呼び出して現行コンテキストを 確認し、さらに GetVersionName 関数を呼び出して現行バージョン を確認します。 String ls_name String ls_version Constant String ls_currver = "11.5.01" icxinfo_base.GetShortName(ls_name) IF ls_name <> "PBRun" THEN cb_close.visible = FALSE END IF icxinfo_base.GetVersionName(ls_version) IF ls_version <> ls_currver THEN MessageBox(" エラー ", & " 次のバージョンでなければなりません " + ls_currver) END IF コンテキスト キーワード サービス 現行コンテキストの環境情報にアクセスするには、コンテキスト キー ワード サービスを使用します。デフォルト環境の場合、このサービス はホストのワークステーションの環境変数を返します。EAServer 内で 実行するときには、キーワード サービスを使用して、固有のコンポー ネントのプロパティ値を取得できます(AIX を除くすべての EAServer プラットフォームにおいて、GetContextService 関数内の文字列パラメー タとして Keyword を使用する必要があります)。 EAServer でコンテキスト キーワード サービスを使用する方法の詳細 については、497 ページの「コンポーネント プロパティへのアクセス」 を参照してください。 PowerBuilder の実行環境(デフォルトのコンテキスト)で実行してい る場合、このサービスを使用して環境変数を戻します。 環境変数のアクセス v 環境変数にアクセスするには 1 ContextKeyword 型のインスタンスまたはグローバル変数を宣言し ます。戻り値を保持する String 型の可変長配列も宣言します。 ContextKeyword icxk_base String is_values[ ] 2 GetContextService 関数を呼び出して、コンテキスト情報サービスを 作成します。 this.GetContextService("Keyword", icxk_base) アプリケーション テクニック 437 コンテキスト情報 3 GetContextKeyword 関数を呼び出して、必要な環境変数にアクセス します。この例では、GetContextKeyword 関数を呼び出して現行ア プリケーションの Path を確認します。 icxk_base.GetContextKeywords("Path", is_values) 4 戻り値の配列から値を抽出します。環境変数にアクセスする場合、 配列の構成要素は常に 1 つだけにしなければなりません。 MessageBox("Path", "Path is:" + is_values[1]) CORBACurrent サービス クライアント アプリケーションおよび[OTS スタイル]としてマーク された EAServer コンポーネントは、CORBACurrent コンテキスト サー ビス オブジェクトの関数を使用して、EAServer トランザクションに関 する情報の作成、制御、および取得ができます。CORBACurrent オブ ジェクトは、CORBACurrent インタフェース用に定義された数多くの メソッドを備えています。 詳細については、538 ページの「クライアントとコンポーネントを区 別するトランザクション」を参照してください。 エラー ロギング サービス トランザクション サーバ内で動作している PowerBuilder オブジェクト によって生成されたエラーをログ ファイルに記録するには、ErrorLogging サービス オブジェクトのインスタンスを作成し、そのログ メソッドを 呼び出します。たとえば、次のようになります。 ErrorLogging erlinfo_base this.GetContextService("ErrorLogging", & erlinfo_base) erlinfo_base.log(" この文字列をログに書き込む ") コンポーネントが EAServer で動作している場合、エラーは EAServer ログに記録されます。コンポーネントが COM+ で動作している場合 は、エラーは Windows のシステム アプリケーション ログに記録され ます。 438 PowerBuilder 第 21 章 外部関数とそのほかの拡張処理機能の使い方 インターネット サービス インターネット サービスは、以下の用途に使用します。 • • デフォルトのブラウザで Web ページを表示する。HyperLinkToURL 関数は指定された URL を使ってデフォルトのブラウザを起動す る 指定されたページの HTML にアクセスする。GetURL 関数は HTTP Get を実行する • CGI、ISAPI、または NSAPI プログラムにデータを送信する。 PostURL 関数は HTTP Post を実行する インターネット サービスの HyperLinkToURL 関数を呼び出して、指定さ れた URL を使ってデフォルトのブラウザを起動します。 URL へのハイパーリ ンク接続 v URL にハイパーリンクで接続するには 1 Inet 型のインスタンスまたはグローバル変数を宣言します。 Inet 2 iinet_base GetContextService 関数を呼び出して、インターネット サービスを作 成します。 THIS.GetContextService("Inet", iinet_base) 3 HyperLinkToURL 関数を呼び出して、ブラウザの起動時に表示され るページの URL を渡します。 iinet_base.HyperlinkToURL & ("http://www.sybase.com") URL の入手 インターネット サービスの GetURL 関数を呼び出して HTTP Get を実 行し、指定された URL の生の HTML を入手します。この関数は、 InternetResult オブジェクトを介して生の HTML を返します。 v HTTP Get を実行するには 1 Inet 型のインスタンスまたはグローバル変数を宣言します。子孫オ ブジェクト InternetResult(この例では、n_ir_msgbox)をデータ型と して使って、インスタンスまたはグローバル変数をもう 1 つ宣言 してください 。 Inet iinet_base n_ir_msgbox iir_msgbox 2 GetContextService 関数を呼び出して、インターネット サービスを作 成します。 THIS.GetContextService("Internet", iinet_base) アプリケーション テクニック 439 コンテキスト情報 3 子孫オブジェクト InternetResult のインスタンスを作成します。 iir_msgbox = CREATE n_ir_msgbox 4 GetURL 関数を呼び出し、返されるページの URL と、子孫オブジェ クト InternetResult のインスタンスへの参照を渡します。 iinet_base.GetURL & ("http://www.sybase.com", iir_msgbox) GetURL 関数は実行を終了すると、子孫オブジェクト InternetResult で定義されている InternetData 関数を呼び出し、指定された URL の HTML を渡します。 インターネット サービスの PostURL 関数を呼び出して HTTP Post を実 行し、データを CGI、ISAPI、または NSAPI プログラムに送信します。 この関数は、InternetResult オブジェクトを介して生の HTML を返しま す。 URL へのポスト v HTTP Post を実行するには 1 Inet 型のインスタンスまたはグローバル変数を宣言します。子孫オ ブジェクト InternetResult(この例では、n_ir_msgbox)をデータ型と して使って、インスタンスまたはグローバル変数をもう 1 つ宣言 してください 。 Inet iinet_base n_ir_msgbox iir_msgbox 2 GetContextService 関数を呼び出して、インターネット サービスを作 成します。 THIS.GetContextService("Internet", iinet_base) 3 子孫オブジェクト InternetResult のインスタンスを作成します。 iir_msgbox = CREATE n_ir_msgbox 4 PostURL 関数への引数を設定します。 Blob lblb_args String ls_headers String ls_url Long ll_length ls_url = "http://coltrane.sybase.com/" ls_url += "cgi-bin/pbcgi80.exe/" ls_url += "myapp/n_cst_html/f_test?" lblb_args = Blob("") ll_length = Len(lblb_args) ls_headers = "Content-Length: " & + String(ll_length) + "~n~n" 440 PowerBuilder 第 21 章 5 外部関数とそのほかの拡張処理機能の使い方 PostURL 関数を呼び出し、実行するルーチンの URL、引数、ヘッ ダ、および子孫オブジェクト InternetResult のインスタンスへの参 照を渡します。 iinet_base.PostURL & (ls_url, lblb_args, ls_headers, 8080, iir_msgbox) PostURL 関数は実行を終了すると、子孫オブジェクト InternetResult で定義された InternetData 関数を呼び出し、指定されたルーチンか ら返された HTML を渡します。 InternetResult オブ ジェクトの使い方 GetURL 関数と PostURL 関数は、いずれも InternetResult オブジェクトの データを受け取ります。このオブジェクトは、インターネット経由で 返される非同期データを受け取り、キャッシュするバッファとして動 作します。データを全部受け取ると、この InternetResult オブジェクト はその InternetData 関数を呼び出すので、必要であれば、ここでデータ を上書きして処理できます。 InternetResult の子孫オブジェクトへの実装 この機能は、InternetResult 型の標準クラス ユーザ オブジェクトを作成 して実装します。この子孫ユーザ オブジェクトのそれぞれに、渡され た HTML を必要に応じて処理する InternetData 関数を定義してくださ い。 v 子孫オブジェクト InternetResult を実装するには 1 InternetResult 型の標準クラス ユーザ オブジェクトを作成します。 2 以下のような新規ユーザ オブジェクト関数を宣言します。 3 • 名前 • アクセス レベル • 戻り値 Integer • 引数名 値渡しのデータ • 引数のデータ型 InternetData パブリック Blob 返された HTML を処理する InternetData 関数のコードを追加しま す。この例では、HTML を MessageBox に表示するだけです。 MessageBox(" 返された HTML", & String(data, EncodingANSI!)) Return 1 アプリケーション テクニック 441 コンテキスト情報 Secure Sockets Layer サービス PowerBuilder を使用すれば、EAServer への Secure Sockets Layer(SSL) 接続を設定できます。SSL プロトコルでは、デジタル認証に基づく公 開鍵の暗号化と認証のアルゴリズムを使用して、安全に接続すること ができます。SSL は「ラッパー」プロトコルであり、ほかのプロトコ ル用のパケットは、SSL パケットの内部に埋め込むことによって保護 されます。たとえば、HTTPS は、各 HTTP パケットを SSL パケット内 に埋め込むことによって保護される HTTP です。同様に、IIOPS は、 SSL 内に埋め込まれた IIOP です。 SSLServiceProvider オブジェクトのインスタンスを使用して、クライア ントからサーバへの接続を確立します。詳細については、 『PowerScript リファレンス』マニュアルおよび第 25 章「PowerBuilder クライアント での SSL の使い方」を参照してください。 トランザクション サーバ サービス EAServerなどのトランザクション サーバ内で動作するオブジェクトの コンテキスト情報にアクセスするには、トランザクション サーバ サー ビスを使用します。TransactionServer オブジェクトを使用すれば、トラ ンザクションの動作をプログラムで制御したり、トランザクション サーバ上の別のコンポーネントのメソッドにアクセスしたりすること ができます。 詳細については、第 23 章「EAServer コンポーネントの構築」を参照 してください。 442 PowerBuilder 第 6 部 分散アプリケーションの開発 第 6 部では、PowerBuilder で分散アプリケーションを構 築するためのツールとテクニックについて説明します。 PowerBuilder Enterprise 版のみ PowerBuilder で使用可能な多層アプリケーションを構築するた めのツールは、Enterprise 版でのみサポートします。 第 2 2 章 PowerBuilder を使った分散アプリ ケーション開発 この章について この章では PowerBuilder を使った分散アプリケーション開発の概 要を示します。 PowerBuilder Enterprise 版のみ 分散アプリケーション開発は、Enterprise 版でのみサポートされて います。 内容 項目 分散アプリケーションのアーキテクチャ サーバのサポート ページ 445 446 分散アプリケーションのアーキテクチャ 分散アプリケーション開発は、多階層アプリケーション開発とも 呼ばれ、自然な方法でアプリケーションで必要なビジネス ロジッ クからアプリケーションのユーザ インタフェース コンポーネン トを分離できます。ビジネス ロジックを中間層のサーバに集中す ることで、クライアントの作業負荷を軽減し、機密情報へのアク セス制御を行えます。 分散アプリケーションでは、クライアントとサーバは、連携して ビジネス ユーザのためのタスクを実行します。クライアントは、 ユーザとの対話をすべて処理し、中間層のサーバはクライアント に対してバックグラウンドのサービスを提供します。通常、中間 層のサーバがほとんどの処理とデータベース アクセスを行いま す。サーバのサービスを呼び出すには、クライアントは、サーバ に置かれたコンポーネント(またはオブジェクト)に関連付けら れているメソッド(または関数)を呼び出します。 アプリケーション テクニック 445 サーバのサポート 分割されたアプリケー ション エンタープライズ アプリケーションのクライアントサイドのロジッ クは、ネットワークの帯域幅を節約できるようにできるだけ小さく効 率的にする必要があります。このためには、アプリケーションをプレ ゼンテーション、ビジネス ロジック、データベース アクセスの 3 つに 分割します。データベースは、エンタープライズ システムの最下層に あり、組織の資産を保持し、またセキュリティ保護します。ビジネス ロジックは、中間層またはサーバに置かれます。プレゼンテーション は、ユーザのデスクトップ、つまり最上位層に配置されるか、ユーザ のデスクトップに動的にダウンロードされます。 サーバは、企業のビジネス ロジックの大多数の実行とセキュリティ保 護を担当します。このため、サーバは、ネットワーク中心のアーキテ クチャの重要なコンポーネントとなります。クライアントは、ビジネ ス ロジックを実行する中間層コンポーネントを呼び出して、サーバと 通信を行います。 Web アプリケーショ ン アーキテクチャ Web アプリケーションは分散型アーキテクチャの一種で、クライアン トは Web ブラウザでホストされます。PowerBuilder には、.NET Web フォームの配布や Web データウィンドウなど、シン クライアント ソ リューションを提供する Web アプリケーション構築テクノロジが複 数用意されています。アプリケーションのアーキテクチャは、使用す るテクノロジによって異なります。 詳細については、第 29 章「PowerBuilder での Web アプリケーション 開発」を参照してください。 サーバのサポート PowerBuilder の開発者は、Sybase EAServer、COM+、および別のアプ リケーション サーバのサービスを呼び出すクライアントを作成し、さ らに各サーバの内部でビジネス ロジックを実行するコンポーネント (またはオブジェクト)を作成できます。 また、PowerBuilder は、J2EE 準拠のサーバで動作する Enterprise JavaBeans コンポーネント(EJB)のクライアントの作成もサポートしています。 EAServer 446 PowerBuilder と EAServer は完全に統合されました。PowerBuilder アプ リケーションは、EAServer コンポーネントのクライアントの役割を果 たします。さらに、EAServer は、中間層コンポーネントとして動作す る PowerBuilder カスタム クラス ユーザ(非ビジュアル)オブジェクト を持つことができます。 PowerBuilder 第 22 章 PowerBuilder を使った分散アプリケーション開発 EAServer は、PowerBuilder 仮想マシンのネイティブのホストとして機 能します。つまり、EAServer と PowerBuilder 非ビジュアル ユーザ オ ブジェクトは互いに直接通信できます。PowerBuilder で開発された EAServer コンポーネントは、PowerScript の使いやすさと柔軟性、およ び PowerBuilder のシステム オブジェクトのパワーをフルに活用できま す。 PowerBuilder で開発されたコンポーネントは、トランザクション、相 互運用性、およびインスタンス プールなどの機能を活用できます。 図 22-1 に示すように、どのタイプのクライアントでも、コンポーネン トの開発に使用された言語に関係なく、EAServer で動作するすべての タイプのコンポーネントにアクセスできます。 図 22-1: クライアントと EAServer 上のコンポーネント 詳細については、第 23 章「EAServer コンポーネントの構築」および 第 24 章「EAServer クライアントの構築」を参照してください。 J2EE サーバ J2EE(Java 2 Platform, Enterprise Edition)は、エンタープライズ アプリ ケーション開発用の公認 Java フレームワークです。J2EE アプリケー ションは、多層システムのさまざまなコンピュータにインストールさ れた別々のコンポーネントで構成されます。図 22-2 に、このシステ ムの 3 つの階層、すなわち、クライアント層、中間層、エンタープラ イズ情報システム(EIS)層を示します。中間層は、Web 層とビジネ ス層の 2 つの層で構成されると見なす場合もあります。 アプリケーション テクニック 447 サーバのサポート 図 22-2: J2EE クライアント層、中間層、EIS 層 アプリケーション クライアントやアプレットなどのクライアント コ ンポーネントは、クライアント層のコンピュータ上で動作します。Java サーブレットおよび JavaServer Pages(JSP)コンポーネントなどの Web コンポーネントは、Web 層の J2EE サーバで動作します。Enterprise JavaBeans(EJB)コンポーネントはビジネス コンポーネントであり、 ビジネス層の J2EE サーバで動作します。EIS 層は、リレーショナル データベース管理システム、エンタープライズ リソース プランニング アプリケーション、メインフレーム トランザクション処理、そのほか のレガシ情報システムを実行するサーバで構成されます。 PowerBuilder では、任意の J2EE 準拠サーバで動作する EJB コンポーネ ントのサービスを使用するクライアント アプリケーションを構築で きます。詳細については、第 28 章「EJB クライアントの構築」を参照 してください。 448 PowerBuilder 第 22 章 PowerBuilder を使った分散アプリケーション開発 J2EE サーバのプラグ イン PowerBuilder Application Server Plug-in がインストールされているサー ドパーティのアプリケーション サーバに、カスタム クラス ユーザ オ ブジェクトを配布することも可能です。Plug-in は、複数のアプリケー ション サーバをサポートする Sybase 製品です。これらのサーバに配布 可能なアプリケーション サーバ コンポーネントおよび、クライアント ア プリケーションの構築に使用できるプロキシの生成に役立つウィザードは PowerBuilder に組み込まれていますが、Plug-in 製品は個別にインス トールする必要があります。ウィザードと手法は、EAServer コンポー ネントとクライアントの構築に使用するという点で、とてもよく似て い ま す。詳 細 に つ い て は、Sybase 製品マニュアル Web のサイト http://www.sybase.com/support/manuals/ で、PowerBuilder Application Server Plug-in のマニュアルを参照してください。 COM+ PowerBuilder アプリケーションは、COM サーバへのクライアントとし て機能できます。このサーバは、PowerBuilder またはそのほかの COM 準拠型アプリケーション開発ツールを使用して作成できます。また、 図 22-3 に示すように、インプロセス サーバとしてリモート コンピュー タ上で、または COM+ で、ローカルに実行できます。 アプリケーション テクニック 449 サーバのサポート 図 22-3: COM コンポーネントの PowerBuilder クライアント 非推奨のテクノロジ COM および COM+ は非推奨のテクノロジであり、PowerBuilder の今 後のリリースではサポートされなくなる可能性があります。 ビジネス ロジックを含むカスタム クラス ユーザ オブジェクトを PowerBuilder で開発してから、そのオブジェクトを COM オブジェクト としてパッケージすることができます。PowerBuilder COM サーバに は、1 つまたは複数の PowerBuilder カスタム クラス ユーザ オブジェク トを組み込むことができます。ユーザ オブジェクトをユーザ オブジェ クト ペインタで作成してから、プロジェクト ペインタでサーバを構築 します。COM サーバをローカルの COM+ サーバに直接配布したり、プ ロジェクト ペインタで COM+ パッケージを作成したりすることもで きます。 450 PowerBuilder 第 22 章 PowerBuilder を使った分散アプリケーション開発 詳細については、第 27 章「COM/COM+ クライアントの構築」を参照 してください。 アプリケーション テクニック 451 サーバのサポート 452 PowerBuilder 第 2 3 章 EAServer コンポーネントの構築 この章について この章では、PowerBuilder を使用して EAServer コンポーネントを 構築する方法について説明します。 内容 項目 EAServer コンポーネントの構築について 共有コンポーネントおよびサービス コンポーネントの操作 インスタンス プーリングのサポート トランザクションのサポート EAServer コンポーネントからデータベースへのアクセス コンポーネント インタフェースの定義 既存インタフェースの実装 別のサーバ コンポーネントのメソッドの呼び出し コンポーネント プロパティへのアクセス Web サービスとしての NVO の公開 コンポーネントのテストとデバッグ データの印刷 EAServer へのコンポーネントの配布 ページ 453 457 463 467 474 488 493 495 497 502 504 509 515 EAServer コンポーネントの構築について PowerBuilder には、カスタム クラス(非ビジュアル)ユーザ オブ ジェクトを開発して、それらを EAServer コンポーネントとして配 布する ための ツール がありま す。これ らのコ ンポーネ ントを Windows、UNIX、および Linux オペレーティングシステムで稼動 している EAServer ホストに配布できます。515 ページの「EAServer へのコンポーネントの配布」を参照してください。 アプリケーション テクニック 453 EAServer コンポーネントの構築について UNIX の制限 コンポーネントを UNIX または Linux サーバに配布することを予定し ている場合、これらのプラットフォーム上では PowerBuilder ランタイ ム ライブラリがグラフィック処理や、Windows アプリケーション プロ グラミング インタフェースの呼び出しをサポートしていないことに注 意してください。 ウィザードの使い方について PowerBuilder には、EAServer コンポーネントの開発と配布を容易にす るウィザードがいくつか用意されています。すべてのウィザードで EAServer プロジェクトを作成できます。 • ターゲット ウィザード 新規のターゲット、新規のアプリケーショ ン オブジェクト、新規のカスタム クラス ユーザ オブジェクト、お よび新規の EAServer プロジェクトを作成します。 • 既存のターゲットと新規の EAServer プ ロジェクトの中に、カスタム クラス ユーザ オブジェクトを新規作 成します。 • 1 つまたは複数のカスタム クラス ユーザ オブジェクトを選択する、1 つの EAServer プロジェクトを作成し ます。 オブジェクト ウィザード プロジェクト ウィザード 開発プロセスについて EAServer コンポーネ ントの作成手順 454 カスタム クラス ユーザ オブジェクトから EAServer コンポーネントを 作成して配布するには、次の手順で操作を進めます。 1 EAServer コンポーネント ターゲット ウィザードを使用して、新規 ターゲットにユーザ オブジェクトを新規作成します。既存のター ゲットで作業している場合は、この操作を行うかわりに、EAServer コンポーネント オブジェクト ウィザードを使用してオブジェク トを作成できます。これらのウィザードでは、新規ユーザ オブジェ クトを Web サービスとして公開するための情報を入力することも できます。 2 ユーザ オブジェクト ペインタで、生成されたユーザ オブジェクト に関数、イベント、およびインスタンス変数を追加します。 PowerBuilder 第 23 章 EAServer コンポーネントの構築 3 オブジェクトのテストとデバッグを行います。 4 オブジェクトを EAServer に配布します。 PowerBuilder で開発した EAServer コンポーネントのテストまたは配布 を行うには、プロジェクト オブジェクトとプロジェクトを作成しま す。プロジェクト オブジェクトは、ターゲット ウィザード、オブジェ クト ウィザード、またはプロジェクト ウィザードで作成できます。 コンポーネントを配布するには、プロジェクト ペインタでプロジェク トを開き、必要な場合はプロジェクトの設定を修正して、プロジェク トを作成します。その後、EAServer コンポーネント ジェネレータに よって、コンポーネント インタフェースと PowerBuilder に実装された そのインタフェースがターゲット サーバに配布されます。 テストのために、ライブ編集を利用してユーザ オブジェクト ペインタ から自動的にプロジェクトを作成できます。この操作では、プロジェ クト ペインタからプロジェクトを作成する必要はありません。ユーザ オブジェクト ペインタでライブ編集を有効にすると、ユーザ オブジェ クトを保存するたびに EAServer コンポーネントのプロジェクトが作 成されます。ライブ編集についての詳細は、504 ページの「コンポー ネントのテストとデバッグ」を参照してください。 To-Do リスト EAServer のターゲット ウィザードかオブジェクト ウィザードを使用 して新規のユーザ オブジェクトを作成すると、オプションで To-Do リ ストを作成できます。ウィザードの最終ページにある[To-Do リスト の作成]チェックボックスをオンにすると、ウィザードは To-Do リス トにタスクを追加して、開発の全フェーズが遂行されるように開発者 の注意を促します。 アプリケーション サーバ プロファイルの作成 アプリケーション サーバ プロファイルは、システム レジストリに保 存されている名前付きパラメータ セットで、特定の EAServer または サードパーティ製アプリケーション サーバ ホストへの接続を定義し ます。ウィザードを使用してコンポーネントを作成する前に、コンポー ネントが配布されるサーバのプロファイルを作成する必要がありま す。 アプリケーション テクニック 455 EAServer コンポーネントの構築について アプリケーションサーバ プロファイル ダイアログボックスには、定義 済みのプロファイルが一覧表示されます。このダイアログボックスか ら、アプリケーション サーバ プロファイルの作成、編集、削除、およ びテストを実行できます。 EAServer とアプリケーション サーバのコンポーネントとプロキシの 各ウィザードには、 [EAServer プロファイルの選択]ページまたは[ア プリケーションサーバ プロファイルの選択]ページに[プロファイル の編集]ボタンが表示されます。このボタンをクリックすると、アプ リケーションサーバ プロファイル ダイアログボックスが表示されま す。このダイアログボックスでは、ウィザードを終了しないで、新し いプロファイルを追加したり、既存のプロファイルを編集したりする ことができます。 アプリケーションサーバ プロファイルの編集 ダイアログボックスの [プロファイル名]は編集できません。これは、プロファイルのほかの プロパティだけでなく、名前もプロジェクト オブジェクトに格納され るためです。プロジェクトの配布時に、レジストリにプロファイル名 が見つからない場合は、プロジェクト オブジェクトに格納されている プロファイル名が使用されます。 v アプリケーションサーバ プロファイルを作成するには 1 パワーバーの[アプリケーションサーバ プロファイル]ボタンを クリックします。 アプリケーションサーバ プロファイル ダイアログボックスが表 示され、定義済みのプロファイルが一覧表示されます。 2 [追加]を選択します。 アプリケーションサーバ プロファイルの編集 ダイアログボック スが表示されます。 3 456 プロファイル名、サーバ名、ポート番号、ログイン名、およびパ スワード(必要な場合)を入力します。 PowerBuilder 第 23 章 EAServer コンポーネントの構築 4 (オプション)[テスト]を選択して、接続の検証を行います。 5 [OK]をクリックして変更内容を保存し、ダイアログボックスを 閉じます。 アプリケーションサーバ プロファイル ダイアログボックスに、 新規プロファイル名が表示されます。アプリケーション サーバ プロファイルの値は、 HKEY_CURRENT_USER\Software\Sybase\PowerBuilder\11.5\Jagu arServerProfiles のレジストリに保存されます。 共有コンポーネントおよびサービス コンポーネントの操作 PowerBuilder で EAServer コンポーネントを作成するときには、スタン ダード コンポーネント、共有コンポーネント、またはサービス コン ポーネントのどれを作成するかをウィザードで選択できます。 共有コンポーネントについて EAServer によるプロ グラム変数領域の管理 EAServer アーキテクチャはコンポーネント指向です。各コンポーネン トは、それぞれの状態を保持しています。1 つのクライアントがサー バ上でいくつかの PowerBuilder オブジェクトをインスタンス化する と、EAServer は、オブジェクトのプログラム変数領域を別々に管理し ます。EAServer で動作する各 PowerBuilder ユーザ オブジェクトは、グ ローバル変数と共有変数について独自のコピーを保持しています。 PowerBuilder オブジェクトはそれぞれ共通の状態にはありません。し たがって、PowerBuilder オブジェクトどうしは、メソッド、EAServer の共有コンポーネント、サーバ ファイル、およびデータベースを介し てのみ通信できます。 クライアントが状態情報を共有できるように、EAServer は共有コン ポーネントをサポートします。共有コンポーネントを使用すれば、複 数のクライアントが同じコンポーネント インスタンスを共有できま す。 EAServer Manager および Management Console EAServer 5.x では、EAServer Manager を使用して EAServer のプロパ ティを管理できます。EAServer 6.x では、Sybase Management Console の EAServer Manager プラグインを使用します。 アプリケーション テクニック 457 共有コンポーネントおよびサービス コンポーネントの操作 PowerBuilder ウィザードで共有コンポーネントとしてマークすると、 Management Console のコンポーネントのプロパティの[General]ペー ジ、または EAServer Manager の[Instance]ページでコンポーネントを 共有としてマークした場合と同じ結果になります。EAServer では、コ ンポーネントの 1 つのインスタンスだけをインスタンス化できます。 クライアント(とそのほかのサーバ コンポーネント)は、共有コン ポーネントに対して、それがあたかも別の種類のコンポーネントであ るかのようにアクセスします。 EAServer 共有コン ポーネントを使用する 利点 EAServer 共有コン ポーネントと PowerBuilder 共有オ ブジェクト 共有コンポーネントを使うと、以下のことが可能になります。 • クライアント接続ごとに別々に取り出す必要がある共通データに 容易にアクセスできるようにする • データベース アクセスの数を減らすことによって、データベース サーバをほかの処理に使用できるようにする EAServer 共有コンポーネントとして提供する利点の多くは、 PowerBuilder 共有オブジェクトの場合と同じです。EAServer に配布する PowerBuilder コンポーネントは、PowerBuilder 共有オブジェクトに加えて、EAServer 共有コンポーネントに対してもクライアントの役目を果たせます。 EAServer 共有コンポーネントに対しては、PowerBuilder で実装されて いないクライアントとコンポーネントからアクセスできます。 しかし、EAServer は、PowerBuilder 共有オブジェクトを EAServer 共 有コンポーネントのようには扱いません。したがって、PowerBuilder 共有オブジェクトの操作に使用する関数(SharedObjectRegister や SharedObjectGet など)は、EAServer 共有コンポーネントでは動作しま せん。EAServer で動作している PowerBuilder コンポーネント内でこれ らの関数を呼び出そうとしても、そのリクエストは失敗します。 サービス コンポーネントについて サービス コンポーネントは、EAServer クライアントとそのほかの EAServer コンポーネントのバックグラウンド処理を行います。EAServer は、サーバの起動時にサービス コンポーネントをロードします。 いずれかの PowerBuilder ウィザードで、コンポーネントをサービス コ ンポーネントとしてマークした場合には、そのコンポーネントは配布 時にサービスとして EAServer にインストールされます。 458 PowerBuilder 第 23 章 共有か非共有か サービス コンポーネ ントの関数 EAServer コンポーネントの構築 サービス コンポーネントを作成する場合は、ウィザードでサービス コ ンポーネントにマークを付けます。サービス コンポーネントの複数の インスタンスを使用したい場合は、プロジェクト ペインタで設定を変 更できます。プロジェクト ペインタの EAServer コンポーネント ジェ ネレータのプロパティ シートにある[コンポーネント]ページで、 [サービス インスタンス]スピン コントロールから使用したいインス タンスの数を選択します。インスタンスの数を複数に変更すると[同 時実行]と[自動的なデマケーション / 不活性化]がオンになるので、 注意してください。これは、EAServer でコンポーネントがスレッド実 行の問題に遭わないようにするためです。詳細については、次の「ス レッド実行の問題とコンポーネントの種類」を参照してください。 PowerBuilder ウィザードは、サービス コンポーネント用に 3 つの補助 関数を組み込みます。これらの関数は CTSServices::GenericServices イ ンタフェースに定義されており、サービスに関連付けられているバッ クグラウンド処理の動作を制御できます。 サービス コンポーネントがロードされた後、EAServer は Start 関数を呼び出します。この関数にロジックを追加すれば、サービ ス起動の初期設定を実行できます。 • Start • Run 最初に呼び出された Start 関数が戻った後、EAServer は Run 関数を呼び出します。Run 関数を使うと、反復タスクをバックグラ ウンド プロセスとして実行できます。Run 関数は、その実行を定 期的に一時停止するために、JagSleep C 関数を呼び出さなければ なりません。JagSleep 関数は、ほかのタスクを実行できるように CPU を解放します。JagSleep 関数を使用するには、PowerBuilder で JagSleep の外部関数を宣言します。関数の宣言に使用する構文を 次に示します。 subroutine JagSleep (Long seconds) LIBRARY "libjdispatch.dll" • アプリケーション テクニック この関数を使うと、Run 関数でコーディングされたバックグ ラウンド プロセスの実行も停止できます。EAServer を再起動する ことなくサービスを再開できるように、Stop、Start、および Run を 呼び出すサービス マネージャ クライアントをサービスに実装で きます。Stop 関数のスクリプトは、Start 関数で割り当てられたリ ソースの後処理も実行できます。 Stop 459 共有コンポーネントおよびサービス コンポーネントの操作 スレッド実行の問題とコンポーネントの種類 PowerBuilder コンポーネントの各インスタンスは独自のセッションを 実行しているため、各セッションではスレッドを 1 つしか実行できま せん。したがって、PowerBuilder コンポーネントのインスタンスの 1 つが、クライアントのリクエストを同時に複数実行することは不可能 です。ただし、同じコンポーネントの複数のインスタンスは、それぞ れ別のクライアントのリクエストを実行できます。コンポーネントを 作成すると、EAServer でのスレッドの処理方法に影響するいくつかの プロパティにデフォルト値が設定されます。 Thread Manager の使い方 EAServer Thread Manager では、より堅固なサービスの開発も可能です。 463 ページの「EAServer Thread Manager の使い方」を参照してください。 Concurrency プロパ ティ コンポーネントの複数のインスタンスを作成して複数のクライアント のリクエストを処理できるかどうかは、Concurrency プロパティによっ て 決 ま り ま す。com.sybase.jaguar.component.thread.safe プ ロ パ テ ィ を TRUE に設定するには、ウィザードかプロジェクト ペインタで[同時 実行]チェックボックスをオンにします。 スタンダード コンポーネントでは、コン ポーネントの複数のインスタンスでクライアントのリクエストを処理 することによって、パフォーマンスを向上できます。デフォルト設定 で は、ス タ ン ダ ー ド コ ン ポ ー ネ ン ト の Concurrency プ ロ パ テ ィ が チェックされますが、そのコンポーネントのインスタンスを 1 つしか 使用しない場合は、設定を変更することも可能です。 スタンダード コンポーネント 共有コンポーネント 共有コンポーネントの場合、コンポーネントのイ ンスタンスは常に 1 つしかアクティブになりません。したがって、ス レッドは 1 つしか実行できません。共有コンポーネントの[同時実行] チェックボックスは選択不可能で、オンにはなりません。 サービス コンポーネント 通常は、サービス コンポーネントは共有コン ポーネントとして処理されますが、サービス コンポーネントのインス タンスを複数作成して、パフォーマンスとスケーラビリティを向上さ せることも可能です。サービス コンポーネントの[コンポーネント] ページには、[同時実行]、[自動的なデマケーション / 不活性化]、お よび[サービス インスタンス]の 3 つのオプションがあり、 [サービ ス インスタンス]オプションはサービス コンポーネントでのみ変更で きます。 460 PowerBuilder 第 23 章 EAServer コンポーネントの構築 [サービス インスタンス]オプションを 2 以上に変更すると、 [同時実 行]チェックボックスと[自動的なデマケーション / 不活性化]チェッ クボックスがオンになります。必要であれば、サービス コンポーネン トの複数のインスタンスを作成し、各メソッドの呼び出し後、それら のインスタンスを非アクティブにできます。開発者がコンポーネント のインスタンスを明示的に非アクティブにするために[自動的なデマ ケーション / 不活性化]チェックボックスをオフにすると、 [サービス インスタンス]スピン コントロールは 1 にリセットされ、 [同時実行] チェックボックスがオフになります。 bind.thread、sharing、 および tx_vote プロパ ティ EAServer のスレッドの処理に影響するコンポーネント プロパティには、 ほかに sharing、tx_vote、および bind.thread の 3 つがあります。 Bind Object プロパティ(未使用) 付加的なプロパティである bind.object を使うと、クライアント スレッ ドを 1 つのインスタンス内で実行できるだけでなく、複数インスタン スの作成もサポートされます。このプロパティは、PowerBuilder コン ポーネント用には使用できないため、常に FALSE に設定されます。 bind.thread プロパティが TRUE に設定されているときは、コンポーネン ト インスタンスのメソッドは、そのインスタンスを作成したスレッド と同じスレッドで実行されなければなりません。ライブ編集を使用し てコンポーネントを作成している場合は、このプロパティを TRUE に 設定しなければなりません。UNIX サーバに配布されるコンポーネン トでは、スケーラビリティを向上させるために、このプロパティを FALSE に設定する必要があります。 sharing プロパティでは、コンポーネントを共有するかどうかを識別し ます。このプロパティは、ウィザードで[スタンダード]を選択した ときは FALSE、 [共有]または[サービス]を選択したときには TRUE に設定されます。PowerBuilder でこのプロパティを変更するには、プ ロジェクト ペインタで、サービス コンポーネントの[コンポーネン ト]タブ ページにある[サービス インスタンス]設定を変更する以 外、方法はありません。sharing プロパティか thread.safe プロパティの 一方が TRUE に設定 され ている 場合は、もう 一方の プロ パティ を FALSE に設定しなければなりません。 アプリケーション テクニック 461 共有コンポーネントおよびサービス コンポーネントの操作 連続するメソッド呼び出しの間、アクティブなまま保たれるコンポー ネントのことを、ステートフル(状態を持つ)コンポーネントと呼び ます。インスタンス プーリングをサポートしていてメソッド呼び出し 後に非アクティブになるコンポーネントのことを、ステートレス(状 態を持たない)コンポーネントと呼びます。一般に、ステートレス コ ンポーネントで作成されたアプリケーションの方が、高いスケーラビ リティを実現できます。コンポーネントがメソッド呼び出し後に非ア クティブになるかどうかは、tx_vote プロパティによって決まります。 このプロパティが FALSE(ステートレス)に設定されるのは、ウィザー ドの[自動的なデマケーション / 不活性化]チェックボックスをオン にした場合またはプロジェクト ペインタの[コンポーネント]ページ で複数のインスタンスを選択した場合です。それ以外の場合、このプ ロパティは TRUE(ステートフル)に設定されます。ステートフル サー ビス オブジェクトのインスタンスは、1 つしか所有できません。 表 23-1 に、コンポーネントの種類によるデフォルト設定と変更できる 設定を示します。 表 23-1: スレッド処理プロパティ コンポーネ ント スタンダー ド 共有 サービス (単一インス タンス) サービス (複数インス タンス) bind.thread sharing thread.safe tx_vote FALSE、変更 FALSE、変更 TRUE、変更 FALSE、変更可 可 不可 可 FALSE、変更 TRUE、変更 FALSE、変更 可 不可 不可 FALSE、変更 TRUE、変更 FALSE、変更 可 不可 可 FALSE、変更 FALSE、変更 TRUE、変更 FALSE、変更可 可 不可 可 TRUE に変更し た 場 合、イ ン ス タンス数は 1 に、 sharing は TRUE に、thread.safe は FALSE に設定さ れる FALSE、変更可 FALSE、変更可 bind.thread、thread.safe、および sharing が TRUE に設定されているサー ビス コンポーネントを配布する場合は、実行時に thread.safe プロパ ティが自動的に無効化されます。 462 PowerBuilder 第 23 章 EAServer コンポーネントの構築 EAServer Thread Manager の使い方 Thread Manager は組み込みの EAServer コンポーネントで、EAServer コ ンポーネントのインスタンスを、クライアントのメソッド呼び出しが 独立して行われるスレッド内で実行できます。Thread Manager によっ て生成されたスレッドを使用して、ユーザとの対話と非同期に発生す る処理を実行できます。 たとえば、ファイルのインデックス作成という長い操作を開始するコ ンポーネント メソッドがあるとします。この場合、メソッドを使えば、 Thread Manager を呼び出して新しいスレッドで処理を開始し、即座に 復帰できます。 PowerBuilder コンポーネントの各インスタンスは独自のセッションを 実行し、それぞれのセッションは実行のスレッドを 1 つしかサポート しないため、Thread Manager を使用せずに停止や更新ができるサービ スを開発するのは不可能です。サービスの start メソッドと run メソッ ドは、サービスの処理を行うスレッドを生成します。サービスの stop メソッドは、Thread Manager の stop メソッドを呼び出して、スレッド を停止します。 Thread Manager の詳細については、EAServer のマニュアルを参照して ください。 インスタンス プーリングのサポート インスタンス プーリ ングの利点 EAServer コンポーネントは、オプションでインスタンス プーリングを サポートできます。インスタンス プーリングを利用すると、EAServer クライアントはコンポーネント インスタンスを再利用できます。イン スタンス プーリングは、コンポーネント インスタンスを繰り返し割り 当てることにより生じるリソースの枯渇を解消し、EAServer の全体的 なパフォーマンスを改善します。 ウィザードでのプーリ ング オプションの指 定 いずれかの PowerBuilder ウィザードを使用して EAServer コンポーネ ントを作成した場合には、コンポーネントに対して表 23-2 に示すいず れかのインスタンス プーリング オプションを指定できます。 アプリケーション テクニック 463 インスタンス プーリングのサポート 表 23-2: EAServer コンポーネント プーリング オプション プーリング オプ ション 説明 [サポートする] クライアント使用のたびに必ずコンポーネントのプーリ ングを実行します。このオプションが選択された場合に は、コンポーネントに対して CanBePooled イベントは発 生しません。 このオプションをオンにすると、コンポーネントのプー リング プロパティが TRUE に設定されます。コンポーネ ントの[自動的なデマケーション / 不活性化]設定が有効 である場合には、メソッド呼び出しのたびにインスタン スがプールされます。[自動的なデマケーション / 不活性 化]設 定 が 無 効 で あ る 場 合 に は、コ ン ポ ー ネ ン ト が TransactionServer コンテキスト オブジェクトの SetComplete メソッドか SetAbort メソッドを呼び出したときに、イン スタンスがプールされます。 [サポートなし] デフォルトでは、クライアント使用後にコンポーネント プーリングは実行されません。ただし、CanBePooled イベ ントのスクリプトを作成してデフォルト動作を無効にす ることも可能です。CanBePooled イベントでは、特定のコ ンポーネント インスタンスをプールするかどうかをプロ グラムで指定できます。CanBePooled イベントのスクリプ トを作成した場合には、このイベントはクライアント使 用のたびに発生します。 このオプションをオンにすると、コンポーネントのプー リング プロパティが FALSE に設定されます。 プールされたインスタ ンスの状態の制御 インスタンス プーリングをサポートする EAServer コンポーネントを 作成した場合には、各クライアントがプールされたインスタンスの使 用を終了した後で、そのコンポーネントの状態をリセットしなければ ならないことがあります。 コンポーネントの状態を制御できるように、コンポーネントの有効期 間中に、EAServer は 表 23-3 に示すイベントを 1 つまたは複数発生さ せます。 表 23-3: コンポーネントの状態イベント イベント Activate CanBePooled Deactivate 464 PBM コード PBM_COMPONENT_ACTIVATE PBM_COMPONENT_CANBEPOOLED PBM_COMPONENT_DEACTIVATE PowerBuilder 第 23 章 EAServer コンポーネントの構築 コンポーネントのプーリング オプションを[サポートする]に設定 (プーリング プロパティを TRUE に設定)した場合には、Activate イベ ントと Deactivate イベントのスクリプトを作成して、プールされたコ ンポーネントの状態をリセットする必要があります。コンポーネント がインスタンス変数、共有変数、またはグローバル変数の状態を保持 する場合には、この操作が必要です。 コンポーネントのプーリング オプションを[サポートしない]に設定 (プーリング プロパティを FALSE に設定)した場合には、CanBePooled イベントのスクリプトを作成して、特定のコンポーネント インスタン スをプールするかどうかを指定できます。CanBePooled イベントのス クリプトを作成した場合には、Activate イベントと Deactivate イベント のスクリプトも作成して、プールされたコンポーネントの状態をリ セットする必要があります。CanBePooled イベントのスクリプトを作 成しない場合には、コンポーネント インスタンスはプールされませ ん。 EAServer コンポーネントのターゲット ウィザードとオブジェクト ウィザードは、EAServer コンポーネントとして配布されるカスタム ク ラス ユーザ オブジェクトに、Activate イベントと Deactivate イベント を自動的に組み込みます。CanBePooled イベントのスクリプトを作成 したい場合は、このイベントを自分で追加する必要があります。その 場合には、イベントを正しい PBM コードにマップしてください。 Constructor と Destructor は 1 回起動されます インスタンス プーリングが有効である場合には、Constructor イベント と Destructor イベントは、コンポーネントに対して 1 回だけ起動され ます。Constructor イベントと Destructor イベントは、新しいクライア ントがコンポーネント インスタンスを使用するたびに起動されるの ではありません。したがって、プールされるコンポーネント インスタ ンスの状態をリセットするには、Constructor イベントと Destructor イ ベントではなく、Activate イベントと Deactivate イベントにロジックを 追加します。 インスタンス プール のタイムアウト インスタンス プーリングによってクライアント応答時間を短縮でき ますが、サーバのメモリ使用量が増加することもあります。プール内 でインスタンスが休止状態を持続できる時間を秒単位で指定できま す。デフォルトは 600(10 分)です。休止状態のコンポーネント イン スタンスが使用しているリソースを解放するために、サーバは、指定 した時間が過ぎると休止状態のインスタンスを削除することができま す。 アプリケーション テクニック 465 インスタンス プーリングのサポート PowerBuilder と EAServer におけるメモリの管理方法は、環境変数で設 定できます。詳細については、51 ページの「メモリ管理の設定」およ び テ ク ニ カ ル ド キ ュ メ ン ト EAServer/PowerBuilder Memory Tuning and Troubleshooting のサイト http://www.sybase.com/detail?id=1027319 を参照し てください。 コンポーネントの有効 期間 466 インスタンス プーリングの仕組みを理解するには、コンポーネント イ ンスタンスの有効期間(ライフサイクル)を理解する必要があります。 コンポーネントの有効期間中の動作を以下に示します。 1 一般に、コンポーネントは最初のメソッド呼び出しでインスタン ス化されます。PowerBuilder で開発されたコンポーネントがこのイ ンスタンス化の対象となった場合、コンポーネントが動作するた めの新しい PowerBuilder セッションが EAServer により作成されま す。 2 PowerBuilder セッションでは、EAServer コンポーネントを表す、 PowerBuilder 非ビジュアル オブジェクトのインスタンスを作成し ます。オブジェクトを作成すると、Constructor イベントが発生 します。 3 オブジェクトがインスタンス化された後、EAServer は非ビジュア ル オブジェクト上で Activate イベントを発生させ、オブジェクト が新しいクライアントによって使用されることをオブジェクトに 通知します。この時点で、コンポーネントは、自分自身が実行可 能な状態であることを確認しなければなりません。 4 次に、EAServer はコンポーネント上のクライアントによって呼び 出されたメソッドを実行します。 5 コンポーネントがその作業の完了を知らせると、EAServer は Deactivate イベントを発生させて、コンポーネントがその後処理を行えるよう にします。コンポーネントの[自動的なデマケーション / 不活性化] 設定が有効である場合には、各メソッド呼び出しの後で、Deactivate イベントが自動的に発生します。設定が無効である場合には、コ ンポーネントが TransactionServer コンテキスト オブジェクトの SetComplete メソッドか SetAbort メソッドを呼び出したときに、 Deactivate イベントを発生させます。 PowerBuilder 第 23 章 6 EAServer コンポーネントの構築 プーリング オプションで[サポートしない]を選択するか、コン ポーネントのインスタンス プーリング プロパティを FALSE に設 定し、CanBePooled イベントのスクリプトも作成した場合には、 EAServer は、このイベントを発生させることによって、この時点 でプーリングできるかどうかをコンポーネントにたずねます。 CanBePooled イベントを発生させると、コンポーネント インスタン スは、プーリングを選択的に実行するか拒否できます。CanBePooled イベントの戻り値は、コンポーネント インスタンスがプールされ るかどうかを決定します。 戻り値が 1 である場合には、プーリングが有効です。戻り値が 0 である場合には、プーリングが無効です。CanBePooled イベントの スクリプトが作成されていない場合、デフォルトでは、インスタ ンスはプールされません。 プーリング プロパティが有効である場合の動作 プーリング オプションで[サポートする]を選択した場合、または コンポーネントのプーリング プロパティを TRUE に設定した場合 は、コンポーネント インスタンスは常にプールされ、CanBePooled イベントは発生しません。 7 非アクティブ化の後でインスタンスがプールされない場合には、 EAServer は Destructor イベントを発生させます。次に、PowerBuilder オブジェクトを破棄し、実行時セッションを終了させます。 トランザクションのサポート EAServer のトランザ クション サポートの 利点 PowerBuilder で開発する EAServer コンポーネントは、EAServer トラン ザクションに関与できます。EAServer トランザクションは、その境界 と結果が EAServer によって決定されるトランザクションです。コン ポーネントにマークを付けることによって、トランザクション サポー トを提供するコンポーネントを判別できます。コンポーネントがトラ ンザクション サポートを提供する場合には、EAServer は、コンポーネ ントのデータベース操作がトランザクションの一部として実行される ことを保証します。 アプリケーション テクニック 467 トランザクションのサポート 1 つの EAServer トランザクションに複数の EAServer コンポーネント が関与できます。EAServer では、関与するコンポーネントによるデー タベース変更内容すべてのコミットまたはロールバックが確実に完了 します。EAServer トランザクションを使用するコンポーネントを定義 すれば、トランザクションに関与するコンポーネントによって実行さ れるすべての作業は意図したとおりに行われることを保証できます。 コンポーネントによる トランザクション サ ポートの指示 各 EAServer コンポーネントには、コンポーネントが EAServer トラン ザクションにどう関与するかを指示するトランザクション属性があり ます。PowerBuilder で EAServer コンポーネントを開発する場合には、 ウィザードでトランザクション属性を指定できます。表 23-4 に、オプ ションを示します。 表 23-4: トランザクション属性オプション トランザクションの 種類 [サポートなし] [トランザクション をサポート] [トランザクション が必要] 468 説明 コンポーネントはトランザクションの一部として実 行されない。コンポーネントが、トランザクション 内部で実行中の別のコンポーネントによってアク ティブにされた場合には、その新しいインスタンス の作業は既存のトランザクションの外部で行われる コンポーネントは EAServer トランザクションのコ ンテキスト内で実行できるが、コンポーネントのメ ソッドを実行するためにトランザクションは必要と しない。コンポーネントがクライアントによって直 接インスタンス化された場合、EAServer はトランザ クションを開始しない。コンポーネント A がコン ポーネント B によってインスタンス化されていて、 コンポーネント B はトランザクション内部で実行さ れている場合には、コンポーネント A は同じトラン ザクション内で実行される コンポーネントは常にトランザクションで実行され る。コンポーネントがクライアントによって直接イ ンスタンス化された場合には、新しいトランザク ションが始まる。コンポーネント A がコンポーネン ト B によってアクティブ化され、B はトランザク ション内で実行されている場合には、A は同じトラ ンザクション内で実行される。B がトランザクショ ン内で実行されていない場合には、A は新しいトラ ンザクション内で実行される PowerBuilder 第 23 章 トランザクションの 種類 [新規のトランザク ションが必要] [Mandatory] [OTS スタイル] [Never] トランザクション サービス コンテキス ト オブジェクトの使 い方 EAServer コンポーネントの構築 説明 コンポーネントがインスタンス化されるたびに、新 しいトランザクションが始まる。コンポーネント A がコンポーネント B によってアクティブにされ、B がトランザクション内部で実行されている場合に は、A は B のトランザクションの結果に影響されな い新しいトランザクションを開始する。B がトラン ザクション内で実行されていない場合には、A は新 しいトランザクション内で実行される メソッドは、実行中のトランザクションがあるクラ イアントによってのみ呼び出される。実行中のトラ ンザクションがないときにこのコンポーネントを呼 び出すと、実行時エラーになる コンポーネントはトランザクションを管理でき、ま たクライアントのトランザクションを継承できる。 トランザクションなしで呼び出された場合、コン ポーネントは、CORBACurrent コンテキスト サービ ス オブジェクトのインスタンスを使用して、トラン ザクションの開始、コミット、およびロールバック を行う 未処理のトランザクションがある場合、メソッドの 呼び出しは不可能。実行中のトランザクションがあ るときにこのコンポーネントを呼び出すと、実行時 エラーになる コンポーネント メソッドを使うと、EAServer のトランザクション状態 プリミティブを呼び出して、EAServer が現行のトランザクションをコ ミットするか中断するかを制御できます。EAServer のトランザクショ ン状態プリミティブにアクセスできるようにするため、PowerBuilder は TransactionServer というトランザクション サービス コンテキスト オブジェクトを提供します。 TransactionServer コンテキスト オブジェクトを使用する予定の場合 は、UseContextObject DBParm パラメータに Yes を設定する必要があり ます。 アプリケーション テクニック 469 トランザクションのサポート トランザクション コンポーネントに対して、UseContextObject に Yes を 設定すると、COMMIT と ROLLBACK のかわりに TransactionServer オブ ジェクトのメソッドを使用して、コンポーネントが現行のトランザク ションの作業を完了したかどうかを示すことを PowerBuilder に指示し ます。スクリプトに COMMIT および ROLLBACK 文を含めると、スクリ プトはランタイム エラーを起こします。UseContextObject に No を設定 すると、COMMIT および ROLLBACK 文は EAServer トランザクション サービスの CommitWork および AbortWork メソッドを呼び出します。古 いコードを残して、TransactionServer オブジェクトを使用したくない 場合にだけ、この設定を使用すべきです。 トランザクションで必要のないコンポーネントについては、 UseContextObject 設定は無視され、PowerBuilder ドライバは COMMIT および ROLLBACK 文を処理します。 トランザクション コンテキスト サービスを使用するには、TransactionServer 型の変数を宣言し、GetContextService 関数を呼び出してから、トランザ クション コンテキスト サービスのインスタンスを作成します。 コンポーネントの Activate イベントか Constructor イベント発生時 は、GetContextService を呼び出して TransactionServer サービスをインス タンス化できます。 例 // インスタンス変数: // TransactionServer ts Integer li_rc li_rc = this.GetContextService("TransactionServer", & ts) IF li_rc <> 1 THEN // エラー処理 END IF いずれかのコンポーネント メソッドでは、データベースを更新して、 更新に成功した場合には SetComplete を呼び出し、失敗した場合には SetAbort を呼び出せます。 // インスタンス変数: // DataStore ids_datastore long ll_rv ... ... ll_rv = ids_datastore.Update() IF ll_rv = 1 THEN ts.SetComplete() ELSE ts.SetAbort() 470 PowerBuilder 第 23 章 EAServer コンポーネントの構築 END IF TransactionServer インタフェースが提供する 表 23-5 のメソッドを使用 すれば、EAServer のトランザクション プリミティブにアクセスできま す。 表 23-5: TransactionServer メソッド メソッド DisableCommit EnableCommit IsInTransaction IsTransactionAborted SetAbort SetComplete 自動的なデマケーショ ン / 不活性化 説明 コンポーネントの作業が完了していないため、現行の トランザクションをコミットできないことを示す。イ ンスタンスは、現行のメソッドが復帰した後もアク ティブなままである 現行のメソッドを呼び出した後で、コンポーネントを 非アクティブにしないことを示す。コンポーネント インスタンスが非アクティブにされた場合には、現行 のトランザクションをコミットできる 現行のメソッドがトランザクション内で実行されて いるかどうかを判定する 現行のトランザクションが中断されたかどうかを判定 する コンポーネントは現行のトランザクションに対する 作業を完了できず、トランザクションをロールバック することを示す。メソッドが復帰したとき、コンポー ネント インスタンスは非アクティブにされる コンポーネントが現行のトランザクションで作業を 完了し、そのコンポーネントに関する限り、トランザ クションをコミットでき、コンポーネント インスタ ンスを非アクティブにできることを示す 各メソッド呼び出しの後でコンポーネントを自動的に非アクティブに したい場合には、コンポーネントの[自動的なデマケーション / 不活 性化]を有効にしてください。これによって、コンポーネントの tx_vote プロパティに FALSE が設定されます。 [自動的なデマケーション / 不活 性化]が有効にされた場合には、デフォルトで SetComplete が想定され るため、SetComplete を明示的に呼び出して非アクティブにする必要は ありません。トランザクションをロールバックするには、SetAbort を呼 び出します。 アプリケーション テクニック 471 トランザクションのサポート 各メソッド呼び出しの後でコンポーネントを自動的に非アクティブに したくない場合には、コンポーネントの[自動的なデマケーション / 不 活性化]設定を無効にします。これによって、コンポーネントの tx_vote プロパティに TRUE が設定されます。[自動的なデマケーション / 不活 性化]を無効にすると、EAServer は、通知を待ってからトランザク ションを完了します。したがって、プログラムで SetComplete か SetAbort を明示的に呼び出すことによって、必ず非アクティブにしてください。 COMMIT 文と ROLLBACK 文 TransactionServer コンテキスト オブジェクトを無効にし、かわりに COMMIT 文 と ROLLBACK 文 を 使 用 し て、コ ン ポ ー ネ ン ト に 対 す る EAServer トランザクション状態を指定することも可能です。この機能 を使うと、コードを修正せずに、PowerBuilder 6 のオブジェクトを EAServer に移行できます。TransactionServer コンテキスト オブジェク トを無効にするには、UseContextObject DBParm パラメータを No に設 定します。これを行った場合、COMMIT は SetComplete と同じになり、 ROLLBACK は SetAbort と同じになります。 非トランザクション コンポーネントにおける COMMIT と ROLLBACK TransactionServer コンテキスト オブジェクトを無効にする非トランザ クション コンポーネントでは、COMMIT は SetComplete を呼び出さず、 ROLLBACK は SetAbort を呼び出しません。たとえば、トランザクションの 種類として[サポートされていません]を指定し、 [自動的なデマケーショ ン / 不活性化]を無効にし(tx_vote を TRUE に設定)、UseContextObject パラメータを No に設定した場合には、COMMIT を実行しても PowerBuilder 仮想マシンは SetComplete を発行しません(ROLLBACK を実行した場合 には SetAbort を発行しません)。この場合には、EAServer は、SetComplete か SetAbort への呼び出しを待機しているため、コンポーネントが解放 されません。 データベース アクセスをまったく行わないコンポーネントの[自動的 なデマケーション / 不活性化]を無効にした場合には、TransactionServer オブジェクトを使用して SetComplete か SetAbort を呼び出し、コンポー ネントを非アクティブにする必要があります。それ以外の場合は、コ ンポーネントは非アクティブにされません。 トランザクション処理 と実行時エラー 472 PBVM で内部例外が発生したとき、または PowerBuilder コンポーネン トが実行時例外を生成したときの EAServer の動作を制御できます。そ のためには、コンポーネントが実行されているサーバ上で、環境変数 PBOnFatalError または PBRollbackOnRTError をバッチ ファイル内で設 定するか、システム環境変数として設定します。 PowerBuilder 第 23 章 EAServer コンポーネントの構築 表 23-6: 例外処理用の環境変数 変数 PBOnFatalError 説明 PBVM で内部例外が発生したときに、EAServer を継続動作させるか、シャッ トダウンするか、または再起動するかを指定する。デフォルトはシャットダ ウン。EAServer で実行されている PowerBuilder コンポーネントによって未 処理の内部例外が生成されると、PBVM が不安定になり、予期しない動作を 起こす可能性がある 値は以下のとおり • continue - 動作を継続させて CORBA_TRANSACTION_ROLLEDBACK 例 外を送出する • restart - 自動的に再起動する PBRollbackOnRTError • shutdown - 自動的にシャットダウンする(デフォルト) EAServer で実行されている PowerBuilder コンポーネントによって実行時例 外が生成されたときに、トランザクションをどのように処理するかを指定す る。デフォルトでは、トランザクションをロールバックしてクライアントに 例外を送出する 値は以下のとおり • n、no、または false - トランザクションをコミットしてからクライアント に例外を送出する • y、yes、または true - トランザクションをロールバックしてからクライア ントに例外を送出する(デフォルト) トランザクションとコ ンポーネント有効期間 EAServer のトランザクション モデルとコンポーネント有効期間は密 に統合されています。トランザクションに関与するコンポーネント イ ンスタンスは、トランザクションが終了するか、トランザクションに 対するコンポーネントの関与が終了したことが示される(その作業が 終了してコミットの用意ができるか、その作業をロールバックする必 要がある)までは、非アクティブになりません。インスタンスがアク ティブになるタイミングは、トランザクションへのインスタンスの関 与開始と終了に正確に一致します。 詳細については、EAServer のマニュアルを参照してください。 アプリケーション テクニック 473 EAServer コンポーネントからデータベースへのアクセス EAServer コンポーネントからデータベースへのアクセス データベースの接続性 EAServer コ ン ポ ー ネ ン ト か ら デ ー タ ベ ー ス に ア ク セ ス で き ま す。 EAServer による接続プーリングとトランザクション管理のサポートを 活用したい場合には、EAServer によってサポートされているデータ ベース インタフェースのいずれかを使用して、データベースに接続す る必要があります。データベース インタフェースについての詳細は、 『データベースとの接続』マニュアルを参照してください。 データストアの使い方 PowerBuilder で開発された EAServer コンポーネントは、データストア を使用してデータベースと対話できます。データストアは、非ビジュ アルなデータウィンドウのコントロールです。データストアは、デー タウィンドウのコントロールと同じように機能しますが、ビジュアル 属性を持っていません。 データストアは、分散アプリケーションで使用すると便利です。デー タストアを使用すると、各クライアント マシンのかわりに、リモート サーバ上でデータベース処理を実行できます。 リッチテキスト提示様式はサポートされていません サーバ コンポーネントは、リッチテキスト提示様式を使用するデータ ウィンドウ オブジェクトを備えたデータストアを格納できません。 リッチテキスト処理は、分散アプリケーションではサポートされてい ません。 サーバとクライアント 間でのデータ共有 サーバ上で検索されるデータに視覚的なインタフェースを提供したい 場合、データウィンドウ コントロールを持つウィンドウをクライアン トに追加します。サーバ上でデータが検索されるたびに、データウィ ンドウ コントロールを更新してサーバ上のデータストアの結果集合 を表示します。同様に、ユーザがクライアント上でデータを変更する たびに、サーバ上のデータストアの内容を更新して、クライアント上 のデータウィンドウ コントロールの最新のステータスを反映させま す。 クライアントとサーバ間でデータを共有するには、サーバのデータス トアとクライアントのデータウィンドウ コントロールをプログラム によって同期させます。アプリケーションにデータベース更新の処理 を行わせたい場合は、加えてデータウィンドウのデータ バッファとス テータス フラグを、クライアントとサーバの間で互いにやりとりする 必要もあります。 サーバのデータストアとクライアントのデータウィンドウとの同期に ついての詳細は、480 ページの「更新の実行」を参照してください。 474 PowerBuilder 第 23 章 EAServer コンポーネントの構築 分散アプリケーションは ShareData 関数をサポートしません クライアント上のデータウィンドウ コントロールとサーバ上のデー タストアとの間では、ShareData 関数を使用してのデータ共有はできま せん。 接続キャッシュの使い方 接続キャッシュの利点 データベース処理を最適化するため、EAServer は接続キャッシュをサ ポートします。接続キャッシュを使用すれば、EAServer コンポーネン トは、リモート データベース サーバに対してあらかじめ割り当てられ た接続のプールを共有できるため、コンポーネントの各インスタンス が別々の接続を確立することによるオーバーヘッドを避けることが可 能です。接続キャッシュを設定することによって、サーバは同じデー タ ソースに対する接続を再利用できます。 接続キャッシュは、EAServer 6.x ではデータ ソースと呼ばれます。 動作 通常、PowerBuilder アプリケーションがデータベースに接続されると、 PowerBuilder は、DISCONNECT 文が実行された各データベース接続を 物理的に終了させます。一方、PowerBuilder コンポーネントが EAServer 接続キャッシュを使用した場合には、EAServer はデータベース接続を 論理的に終了させますが、接続を物理的に解除するわけではありませ ん。接続キャッシュ内ではデータベース接続が開いたままであり、ほ かのデータベース操作で再利用できます。 destructor イベントで接続を解除しない EAServer は、トランザクションが完了する時やコンポーネントが非ア クティブになる時に、キャッシュへのすべての接続ハンドルを解放し ます。destructor イベント(deactivate イベントの 後に発生する)に DISCONNECT 文を配置すると、 接続はすでに論理的に終了しているので、 DISCONNECT で物理的に終了されます。DISCONNECT 文は、deactivate イベントに配置できます。 キャッシュ内のすべての接続は、共通のユーザ名、パスワード、サー バ名、および接続ライブラリを共有しなければなりません。 アプリケーション テクニック 475 EAServer コンポーネントからデータベースへのアクセス ユーザによるキャッ シュへのアクセス 指定された一連のユーザ名、パスワード、サーバ、および接続ライブ ラ リ の 値 を 使 用 す る キ ャ ッ シ ュ か ら 接 続 を 検 索 し た い 場 合 に は、 キャッシュを使えるようにデータベース アクセス コードを修正する 必要はありません。EAServer Manager で、コンポーネントが必要とする データベース接続プロパティ(ユーザ名、パスワード、サーバ名、およ び接続ライブラリ)を備えた新しいキャッシュを作成します。EAServer 6.x では、データ ソース(キャッシュ)を作成するには、Management Console で[Resources | Data Sources | Add]を選択します。実行時に、コン ポーネントがデータベースへの接続を試みると、EAServer は、コン ポーネントが要求する接続値に一致する接続をキャッシュから自動的 に返します。 名前によるキャッシュ へのアクセス キャッシュ名を指定することによって、キャッシュから接続を検索し たい場合には、CacheName DBParm を設定して、使用したいキャッシュ を識別します。名前によってキャッシュにアクセスすれば、コンポー ネントの対応するソース コードを変更せずに、Management Console で ユーザ名、パスワード、またはサーバを変更できます。 次の PowerBuilder コンポーネントのコード例に、名前によるキャッシュ へのアクセス方法を示します。 SQLCA.DBMS = "ODBC" SQLCA.Database = "EAS Demo DB" SQLCA.AutoCommit = FALSE SQLCA.DBParm = "ConnectString='DSN=EAS Demo DB; UID=dba;PWD=sql',CacheName='mycache'" キャッシュ名では大文字と小文字が区別される キャッシュ名では大文字と小文字が区別されます。したがって、スク リプトに指定するキャッシュ名が EAServer での名前と完全に一致す ることを確認してください。 プロキシによる接続 476 キャッシュにユーザによってアクセスするか名前によってアクセスす るかに関係なく、プロキシで接続できます。プロキシで接続した場合 は、代替ログイン名を入力することで、別のユーザの識別情報と権限 を使用できます。 PowerBuilder 第 23 章 EAServer コンポーネントの構築 この機能は、SQL コマンド set session authorization を認識する任意の データベースで使用できます。ユーザ A が ProxyUserName DBParm を 使用して別のユーザ B の識別情報を使用するには、ユーザ A はこのス テートメントを実行する権限を所有していなければなりません。たと えば、SQL Anywhere の場合、ユーザ A は DBA 権限を所有している必 要があり、また ASE の場合、ユーザ A はシステムのセキュリティ担当 者から set session authorization を実行する権限を与えられている必要が あります。 プロキシ接続をサポートする PowerBuilder データベース インタフェー スについての詳細は、 『データベースとの接続』マニュアルを参照して ください。 プロキシ接続を使用するには、代替ログイン名を識別するための ProxyUserName DBParm を設定します。次の例に、プロキシによる接 続方法を示します。 SQLCA.DBMS = "ODBC" SQLCA.DBParm = "CacheName='MyEAServerCache', UseContextObject='Yes',ProxyUserName='pikachu'" プロキシ接続を利用す る前に コンポーネントがプロキシ接続を利用するには、事前にキャッシュ プ ロパティ ファイルでプロキシ設定の Set-proxy サポートを有効にして おく必要があります。EAServer 5.x では、EAServer Manager は、キャッ シュ作成時に個々のキャッシュのプロパティを自動作成しません。し たがって、このファイルは手動で作成する必要があります。ファイルに cachename.props という名前を付けて、EAServer\Repository\ConnCache ディレクトリに格納します。キャッシュのプロパティ ファイルを作成 したら、次の行を追加します。 com.sybase.jaguar.conncache.ssa=true この設定を有効にするには、EAServer を更新しなければなりません。 EAServer 6.x では、データ ソースを作成するには、Management Console で[Resources | Data Sources | Add]を選択します。[Set Session Authorization]を選択して、[Set Session Authorization System ID]ボックスに名前を指定します。データ ソースのプロパティ ファ イルが Instance\com\sybase\djc\sql\DataSource ディレクトリの Repository に保存されます。 接続キャッシュ(またはデータ ソース)の管理についての詳細は、 EAServer のマニュアルを参照してください。 また、データベース サーバが ProxyUserName DBParm で定義した代替 ログイン名を認識して権限を与えるように設定しなければなりませ ん。 アプリケーション テクニック 477 EAServer コンポーネントからデータベースへのアクセス すべての接続が使用中 である場合の動作 キャッシュ内のすべての接続が使用中である場合の動作を制御できま す。そのためには、GetConnectionOption DBParm に次のいずれかの値 を設定します。 値 JAG_CM_NOWAIT JAG_CM_WAIT JAG_CM_FORCE 説明 接続を返せなかった場合に、接続を試みるとエラー で停止する 接続が利用可能になるまで、コンポーネントが待機 する 新しい接続を割り当てて開く。この新しい接続は キャッシュされないため、不要になったら破棄される デフォルトでは、PowerBuilder は JAG_CM_FORCE を使用します。 接続が解放されたとき の動作 接続が解放されたときの動作も制御できます。そのためには、 ReleaseConnectionOption DBParm に以下のいずれかの値を設定します。 値 JAG_CM_DROP JAG_CM_UNUSED 説明 接続を閉じて割り当て解除する。キャッシュからの 接続である場合には、その位置に新しい接続が作成 される。エラーによって使用できなくなった場合に は、JAG_CM_DROP を使用して接続を破棄する キ ャ ッ シ ュ か ら の 接 続 で あ る 場 合 に は、接 続 が キャッシュに戻される。キャッシュの外部で作成さ れた接続は、閉じて破棄される デフォルトでは、PowerBuilder は JAG_CM_UNUSED を使用します。 Unicode 用の EAServer 接続キャッ シュをサポート 以下の EAServer ネイティブ接続キャッシュは、PowerBuilder コンポー ネント用の Unicode 接続をサポートします。 EAServer 5.x 用 • OCI_9U – Oracle9i Unicode キャッシュ • OCI_10U – Oracle 10g Unicode キャッシュ • ODBCU – ODBC Unicode キャッシュ EAServer 6.x 用 478 • JCM_Oracle_Unicode – Oracle9i または 10g Unicode キャッシュ • JCM_Odbc_Unicode – ODBC Unicode キャッシュ PowerBuilder 第 23 章 EAServer コンポーネントの構築 これらの接続キャッシュ タイプは、Unicode 接続パラメータを受け 取ってから、データベース ドライバにリクエストを送信してデータ ベースへの Unicode 接続を開きます。Unicode 接続では、PowerBuilder コンポーネントは Unicode を使用してデータベースと通信できます。 EAServer 5.x 内の PowerBuilder コンポーネントで、Oracle9i データベー スにアクセスするために Oracle9i ネイティブ インタフェース(O90) を使用している場合は、接続キャッシュ用にデータベース ドライバ タ イプ OCI_9U を使用します。 EAServer 5.x 内の ODBC 接続キャッシュに関しては、データベース ド ライバ タイプ ODBCU を使用して、SQL Anywhere Unicode データベー スの複数言語データや SQL Anywhere DBCS データベースの DBCS データにアクセスして、データベース パラメータ ODBCU_CONLIB を 1 に設定します。以下に例を示します。 SQLCA.DBParm = "CacheName='EASDemo_u', UseContextObject='Yes',ODBCU_CONLIB=1" 検索操作の実行 データストアを使用して検索操作を行うには、まずスクリプトでデー タストア オブジェクトのインスタンスを作成し、データウィンドウ オ ブジェクトをデータストアに割り当てる必要があります。次に、デー タストアのトランザクション オブジェクトを設定します。これらの設 定が完了したら、データストア内でのデータの検索や、データストア の内容の印刷などの処理を、検索した結果集合に対して実行できます。 例 : 参照による配列渡し 説明 次の例に、データストアを使用してサーバ コンポーネント内のデータ を取り出す方法を示します。サーバ コンポーネント uo_customers には、 retrieve_custlist という関数があります。retrieve_custlist は、データストア ds_datastore のインスタンスを生成し、このデータストアを使用して Customer テーブル内のすべての行を取り出します。データが取り出さ れたら、retrieve_custlist はデータをクライアント アプリケーションに戻 します。 関数の宣言 retrieve_custlist 関数は、構造体 st_custlist の配列として定義される引数 customers を受け取ります。構造体 st_custlist は、データウィンドウ オ ブジェクトがデータベースへのアクセスに使用した d_custlist と同じレ イアウトを備えています。取り出された行数を返すために使用する retrieve_custlist の戻り値は Long 型です。 アプリケーション テクニック 479 EAServer コンポーネントからデータベースへのアクセス retrieve_custlist 関数のシグネチャを次に示します。 retrieve_custlist( REF st_custlist customers [] ) returns long スクリプト retrieve_custlist 関数のスクリプトを次に示します。 datastore ds_datastore long ll_rowcount ds_datastore = create datastore ds_datastore.dataobject = "d_custlist" ds_datastore.SetTransObject (SQLCA) IF ds_datastore.Retrieve() <> -1 THEN ll_rowcount = ds_datastore.RowCount() END IF customers = ds_datastore.object.data destroy ds_datastore return ll_rowcount retrieve_custlist 関数は、処理の最後にデータストアを破棄して、取り出 された行数をクライアントに返します。 更新の実行 データウィンドウの同 期 従来のクライアント / サーバ アプリケーションでは、データベースの 更新は、クライアント マシン上で動作している 1 つのアプリケーショ ンによって開始され、PowerBuilder はデータウィンドウの状態情報を 自動的に管理できます。分散アプリケーションの場合、状況は多少異 なります。アプリケーション コンポーネントはクライアントとサーバ の間で分割されるため、ロジックを記述することによって、クライア ント上のデータウィンドウ コントロールのデータ バッファとステー タス フラグを、サーバ上のデータストアのそれらと同期させることが 必要になります。 PowerBuilder は、分散アプリケーションにおいてデータウィンドウと データストアを同期させるために 4 つの関数を提供しています。 480 • GetFullState • SetFullState • GetChanges • SetChanges PowerBuilder 第 23 章 EAServer コンポーネントの構築 これらの関数は分散アプリケーション上では非常に役立ちますが、複 数のデータウィンドウ(データストア)を同期させなければならない、 分散モデル以外のアプリケーションでも使用できます。 データウィンドウの バッファとステータス フラグの移動 クライアント上のデータウィンドウ コントロールとサーバ上のデー タストアを同期させるには、データウィンドウのデータ バッファとス テータス フラグを、データの変化が起こるたびにクライアントとサー バの間でやりとりします。これを行うための手順は、変更の原因がク ライアントにあってもサーバにあっても、本質的に同じです。 完全な状態情報を 1 つのデータウィンドウ(またはデータストア)か ら別のデータウィンドウ(またはデータストア)に適用するには、次 の手順を実行する必要があります。 1 GetFullState 関数を呼び出して、ソース データウィンドウの現行状 態を取り込みます。 2 SetFullState 関数を呼び出して、ソース データウィンドウの状態を ターゲットに適用します。 変更を 1 つのデータウィンドウ(またはデータストア)から別のデー タウィンドウ(またはデータストア)に適用するには、次の手順を実 行する必要があります。 1 GetChanges 関数を呼び出して、ソース データウィンドウから変更 を取り込みます。 2 SetChanges 関数を呼び出して、ソース データウィンドウの変更を ターゲットに適用します。 SetChanges は空のデータウィンドウに適用できます SetChanges を呼び出して、変更を空のデータウィンドウ(またはデー タストア)に適用できます。ターゲット データウィンドウは、前の取 り出し操作の結果集合を格納する必要はありません。しかし、データ ウィンドウはデータウィンドウ定義にアクセスできなければなりませ ん。つまり、SetChanges を呼び出す前に、データウィンドウ オブジェ クトをターゲット データウィンドウに割り当てる必要があります。 データウィンドウの状 態は Blob に格納され ます GetFullState 関数または GetChanges 関数を呼び出したとき、PowerBuilder はデータウィンドウのステータス情報を Blob 型の値で返します。 GetFullState 関数から返される Blob 値は、データ バッファ、ステータ ス フラグ、データウィンドウの詳細な仕様など、データウィンドウ の再構築に必要なすべての情報を提供します。GetChanges 関数から返 される Blob 値は、変更あるいは削除が行われた行についてのみ、デー タ バッファやステータス フラグの情報を提供します。 アプリケーション テクニック 481 EAServer コンポーネントからデータベースへのアクセス 更新後の同期 デフォルトでは、Update 関数は、更新に成功した後で更新フラグをリ セットします。したがって、サーバ上で Update 関数を呼び出した場合 には、サーバ データストアのステータス フラグは自動的にリセットさ れます。しかし、対応するクライアント データウィンドウ コントロー ルの更新フラグはリセットされません。したがって、サーバ データス トアの Update 関数が成功した場合には、クライアント データウィンド ウの ResetUpdate を呼び出して、フラグをリセットします。 1 つのソース、1 つの ターゲット 1 つのソース データウィンドウ(データストア)と 1 つのターゲット データウィンドウ(データストア)との同期化が可能です。1 つのソー スを複数のターゲットに同期させたり、逆に複数のソースを 1 つの ターゲットに同期させたりしないでください。 一般的な使用シナリオ サーバに、DS_1 というデータストアを使用するコンポーネントがある とします。このデータストアは、クライアント上の DW_1 というター ゲット データウィンドウのデータのソースです。Activate イベントで は、コンポーネントはデータベースに接続し、データストアを作成し、 データストアにデータウィンドウ オブジェクトを割り当てます。 そのメソッドの 1 つで、サーバ コンポーネントは DS_1 に対する Retrieve 関数を発行し、DS_1 の GetFullState 関数を呼び出して、取得した Blob をクライアントに渡します。コンポーネントの[自動的なデマケーショ ン / 不活性化]設定が無効(コンポーネントがステートフル)にされ ているため、メソッドが復帰する前に SetComplete 関数も呼び出して、 コンポーネント インスタンスを非アクティブにします。 [自動的なデマケーション / 不活性化]が有効である場合 コンポーネントに対する[自動的なデマケーション / 不活性化]設定 が有効の場合には、メソッドが実行を終了した時点で、コンポーネン ト インスタンスは自動的に非アクティブにされます。したがって、取 り出しの後に SetComplete 関数を呼び出す必要はありません。 482 PowerBuilder 第 23 章 EAServer コンポーネントの構築 クライアントがデータウィンドウ Blob を取得すると、SetFullState 関数 を呼び出して、Blob の状態情報を DW_1 に適用します。この時点で、 ユーザは DW_1 に新しい行を挿入したり、既存の行を変更または削除 したりできます。ユーザが更新リクエストを行うと、クライアントは GetChanges 関数を呼び出し、別のコンポーネント メソッドを呼び出し て取得した Blob をサーバに戻します。次に、コンポーネント メソッド は SetChanges 関数を呼び出して、DW_1 の変更を DS_1 に適用します。 サーバ コンポーネントは、DS_1 を DW_1 に同期させてから、データ ベースを更新し、SetComplete 関数または SetAbort 関数を呼び出して、 更新に成功したかどうかを示します。 更新が成功した場合には、クライアントは ResetUpdate 関数を呼び出し て、クライアント データウィンドウのステータス フラグをリセットし ます。 最初の更新操作が完了した後、クライアントとサーバは、完全な状態 情報ではなく Blob の変更結果を互いにやりとりして、それ以降の更新 を処理できます。それ以降の更新プロセスは繰り返しとなります。 例 次の例に、PowerBuilder クライアントと EAServer コンポーネントの間 で、データウィンドウの同期をとる方法を示します。この例ではステー トレス コンポーネントを使用します。 クライアント ウィン ドウの定義 クライアントには w_employee というウィンドウがあり、そのウィンド ウのボタンを使用して、ユーザはデータの検索と更新を行えるものと します。クライアント ウィンドウの[検索]ボタンには、次のスクリ プトがあります。 // // // // グローバル変数 : connection myconnect インスタンス変数 : uo_employee iuo_employee blob lblb_data long ll_rv myconnect.CreateInstance(iuo_employee) iuo_employee.RetrieveData(lblb_data) ll_rv = dw_employee.SetFullState(lblb_data) if ll_rv = -1 then MessageBox(" エラー ", "SetFullState 呼び出しに失敗 !") end if アプリケーション テクニック 483 EAServer コンポーネントからデータベースへのアクセス クライアント ウィンドウの[更新]ボタンには、次のスクリプトがあ ります。 blob lblb_data long ll_rv ll_rv = dw_employee.GetChanges(lblb_data) if ll_rv = -1 then MessageBox(" エラー ", "GetChanges 呼び出しに失敗 !") else if iuo_employee.UpdateData(lblb_data) = 1 then & dw_employee.ResetUpdate() end if サーバ オブジェクト の定義 インスタンス変数 サーバのオブジェクト uo_employee には、以下の関数があります。 • RetrieveData • UpdateData uo_employee オブジェクトには、以下のインスタンス変数があります。 protected TransactionServer ts protected DataStore ids_datastore Activate uo_employee オ ブ ジ ェ ク ト の Activate イ ベ ン ト は、TransactionServer サービスをインスタンス化します。さらに、データベースに接続して データストアを作成します。このデータストアは、データベースへの アクセスに使用されます。 this.GetContextService("TransactionServer", ts) SQLCA.DBMS="ODBC" SQLCA.DBParm="ConnectString= 'DSN=EAS Demo DB;UID=dba;PWD=sql', UseContextObject='Yes'" CONNECT USING SQLCA; IF SQLCA.SQLCode < 0 THEN // エラー処理 END IF ids_datastore = CREATE datastore ids_datastore.dataobject = "d_emplist" ids_datastore.SetTransObject (SQLCA) RetrieveData 関数の スクリプト RetrieveData 関数は ablb_data という引数を受け取ります。この引数は、 参照渡しされる Blob です。この関数は Long 値を返します。 RetrieveData 関数のスクリプトを次に示します。 long ll_rv 484 PowerBuilder 第 23 章 EAServer コンポーネントの構築 ids_datastore.Retrieve() ll_rv = ids_datastore.GetFullState(ablb_data) ts.SetComplete() return ll_rv UpdateData 関数のス クリプト UpdateData 関数は ablb_data という引数を受け取ります。この引数は、 参照渡しされる Blob です。この関数は Long 値を返します。 UpdateData 関数のスクリプトを次に示します。 long ll_rv if ids_datastore.SetChanges(ablb_data) = 1 then ll_rv = ids_datastore.Update() end if if ll_rv = 1 then ts.SetComplete() else ts.SetAbort() end if return ll_rv Deactivate uo_employee オブジェクトの Deactivate イベントは、データストアを破 棄し、データベースから接続を解除します。 DESTROY ids_datastore DISCONNECT USING SQLCA; 結果集合の受け渡し PowerBuilder は、2 つのシステム オブジェクトを提供することによっ て、EAServer で動作しているコンポーネントから結果集合を取得し、 EAServer コンポーネントとして動作している PowerBuilder ユーザ オ ブジェクトから結果集合を返します。これらのシステム オブジェクト (ResultSet と ResultSets)は、データストア オブジェクトとの間でトラ ンザクション サーバの結果集合の相互変換を簡単にするよう設計さ れており、状態情報は含まれていません。また、データベースの更新 に使用するようには設計されていません。データストア オブジェクト との間でこれらのオブジェクトに格納された結果集合を変換するに は、データストア オブジェクトの CreateFrom 関数と GenerateResultSet 関数を使用します。 アプリケーション テクニック 485 EAServer コンポーネントからデータベースへのアクセス GenerateResultSet について GenerateResultSet にはもう 1 つの構文があり、 EAServer とともに MASP (Method as Stored Procedure)を 使 用 す る と き に、TDS(Tabular Data Stream)の結果集合を返すために使用されます。詳細については、 『デー タウィンドウ リファレンス』マニュアルを参照してください。 結果集合を返すコンポーネント メソッドは、TabularResults モジュール を使用します。1 つの結果集合は TabularResults::ResultSet 構造体とし て返されます。複数の結果集合は、TabularResults::ResultSets データ型 を使用して、一連の ResultSet 構造体として返されます。 PowerBuilder クライ アントから EAServer コンポーネント内の結 果集合にアクセス TabularResults::ResultSet を返す EAServer コンポーネント メソッドに対 して、PowerBuilder で EAServer プロキシ オブジェクトを生成した場合 には、プロキシ オブジェクトのメソッドは、PowerBuilder ResultSet オブ ジェクトを返します。複数の結果集合を返すメソッドは、PowerBuilder ResultSets オブジェクトを返します。 オブジェクト ブラウザでプロキシを表示 PowerBuilder オブジェクト ブラウザの[プロキシ]タブでは、EAServer プロキシ オブジェクトのプロパティとメソッドを表示できます。 PowerBuilder クライアントから結果集合にアクセスするには、コン ポーネントのインスタンスを作成し、メソッドを呼び出し、結果集合 を使用してデータストア オブジェクトに CreateFrom 関数を追加しま す。 次の例では、SVUBookstore コンポーネントのインスタンスを作成し、 GetMajors メソッドを呼び出します。 SVUBookstore lcst_mybookstore resultset lrs_resultset datastore ds_local integer li_rc // myconnect は接続オブジェクトです li_rc = myconnect.CreateInstance(lcst_mybookstore) IF li_rc <> 0 THEN MessageBox(" インスタンスの作成 ", string(li_rc) ) myconnect.DisconnectServer() RETURN END IF lrs_resultset = lcst_mybookstore.GetMajors() 486 PowerBuilder 第 23 章 EAServer コンポーネントの構築 ds_local = CREATE datastore ds_local.CreateFrom(lrs_resultset) EAServer コンポーネ ントから結果集合を返 す EAServer に配布される PowerBuilder ユーザ オブジェクトから結果集 合を渡したり返したりするには、関数の引数または戻り値のデータ型 に ResultSet(1 つの結果集合の場合)または ResultSets(複数の結果集 合の場合)を設定します。ユーザ オブジェクトが EAServer コンポー ネントとして配布された場合には、ResultSet と ResultSets の戻り値は、 コンポーネントの IDL インタフェースでは、TabularResults::ResultSet と TabularResults::ResultSets のデータ型として表されます。 次の例では、データストア オブジェクトを作成し、その中にあるデー タを取り出し、続いて GenerateResultSet 関数を使用して、クライアン トに返す結果集合を作成しています。 datastore ds_datastore resultset lrs_resultset integer li_rc ds_datastore = create datastore ds_datastore.dataobject = "d_empdata" ds_datastore.SetTransObject (SQLCA) IF ds_datastore.Retrieve() = -1 THEN // エラーをレポートして復帰 END IF li_rc = ds_datastore.generateresultset(lrs_resultset) IF li_rc <> 1 THEN // エラーをレポートして復帰 END IF return lrs_resultset アプリケーション テクニック 487 コンポーネント インタフェースの定義 コンポーネント インタフェースの定義 インタフェースの指定 方法 EAServer は、すべてのコンポーネント インタフェースを CORBA 2.0 インタフェース定義言語(IDL: Interface Definition Language)モジュー ルに格納します。IDL は、オブジェクト マネジメント グループによっ て、コンポーネント インタフェースを定義するための標準言語として 定義されています。PowerBuilder カスタム クラス ユーザ オブジェクト を EAServer コンポーネントとして配布すると、そのオブジェクトに定 義されたメソッド(関数とイベント)とインスタンス変数がコンポー ネント インタフェースに追加されます。EAServer コンポーネント ジェ ネレータがユーザにかわって IDL を記述するため、インタフェースの ために IDL を記述する必要はありません。 EAServer 6.0 以降では、PowerBuilder コンポーネントは EJB に組み込ま れます。詳細については、Sybase の製品マニュアルの Web サイトで、 EAServer のマニュアル一覧から『CORBA Components Guide』マニュア ルを参照してください。 インタフェースに組み 込まれるもの EAServer コンポーネント ジェネレータは、ユーザ オブジェクトに宣 言されたすべてのパブリック関数をコンポーネント インタフェース に組み込みます。さらに、コンポーネントに指定した構築オプション に応じて、ジェネレータはパブリック インスタンス変数のアクセサ メ ソッドを組み込み、ユーザ イベントをメソッドとして公開できます。 メソッド名とメソッド の多重定義 IDL はメソッドの多重定義をサポートしていません。それでも、多重 定義されたメソッドを持つ EAServer に対して、PowerBuilder カスタム クラス ユーザ オブジェクトを配布できます。IDL の制約を回避するた め、多重定義されるメソッド名に対して、コンポーネント ジェネレー タは 2 つのアンダースコア(__)と一意の接尾辞を付加します。した がって、PowerBuilder オブジェクト用に生成された IDL を調べてみる と、PowerBuilder で多重定義されたメソッドに接尾辞が付加されてい ることがわかります。 多重定義されたメソッドを持つコンポーネントにスタブまたはプロキ シ オブジェクトを生成すると、クライアントが正しい名前を使用して メソッドにアクセスできるように、EAServer は IDL の接尾辞を取り除 きます。 IDL についての詳細は、EAServer のマニュアルを参照してください。 488 PowerBuilder 第 23 章 EAServer コンポーネントの構築 メソッド名には 2 つの連続したアンダースコアを使用しないでください EAServer は 2 つのアンダースコア(__)を予約区切り記号として扱う ため、EAServer コンポーネントとして配布する予定のカスタム クラス ユーザ オブジェクトの関数名には、2 つの連続したアンダースコアを 使用しないでください。 データ型 EAServer コンポーネントとして配布するユーザ オブジェクトのイン タフェースでは、以下のデータ型を使用できます。 • 標準のデータ型(Any データ型を除く) • 構造体 • EAServer コンポーネントとして配布されたカスタム クラス(非ビ ジュアル)ユーザ オブジェクト これらのデータ型は、パブリック インスタンス変数に限らず、パブ リック メソッドの戻り値と引数にも使用できます。プライベート型と プロテクト型のインスタンス変数とメソッドでは、PowerBuilder がサ ポートするすべてのデータ型を使用できます。 コンポーネントのパブリック インタフェースでは、Any 型はサポート されていません。さらに、ResultSet と ResultSets のオブジェクトを除 いて、コンポーネント インタフェースは、組み込みの PowerBuilder シ ステム オブジェクト(たとえば、トランザクション オブジェクトや データストア オブジェクト)を実装できません。コンポーネント イン タフェースに実装できないものとしては、それ以外にビジュアル オブ ジェクト(ウィンドウやメニューなど)もあります。 コンポーネント メソッドは、標準データ型の配列と構造体の配列を渡 し、カスタム クラス ユーザ オブジェクトを使用して配列を渡せます。 int と uint の short へのマップ EAServer 6.x では、int と uint のどちらの PowerBuilder のデータ型も short にマップします。そのため、1 つの int 引数を持つ int を返す関数を 定義した場合、同じコンポーネント上に、1 つの uint 引数を持つ uint を 返す同じ名前の関数を定義すると、配布は失敗します。 アプリケーション テクニック 489 コンポーネント インタフェースの定義 EAServer で使用されるデータ型、各データ型の対応する CORBA IDL、 および各データ型がマッピングされる PowerBuilder のデータ型のリス トについては、 『PowerScript リファレンス』マニュアルまたはオンラ イン ヘルプを参照してください。PowerBuilder から EJB データ型への マッピングの詳細については、Sybase の製品マニュアルの Web サイト で、EAServer マニュアルの一覧から『CORBA Components Guide』マ ニュアルを参照してください。 参照渡し 引数を参照によってコンポーネント メソッドに渡せます。しかし、分 散アプリケーションと分散モデル以外のアプリケーションでは、動作 がいくぶん異なります。 参照で渡す場合には、メソッドが実行される前に変数が実際にサーバ にコピーされ、その後、メソッドが実行を完了したときにコピーして 戻されます。通常、この動作はアプリケーションからは透過的ですが、 場合によっては処理結果に影響を与えることもあります。 たとえば、x と y の 2 つの引数(いずれも参照渡し)を受け取る、 increment_values というメソッドを定義するとします。次に示すように、 メソッドのスクリプトは x と y をインクリメントします。 x = x + 1 y = y + 1 クライアントは、次のコードを使用してメソッドを呼び出します。 int z z = 1 increment_values(z,z) 分散モデル以外のアプリケーションでは、メソッドが実行を完了した 後の z の値は 3 となります(これは、ローカル呼び出しで z へのポイ ンタを渡して z を 2 回インクリメントするためです)。分散アプリケー ションでは、z の値は 2 となります(リモート呼び出しで z の 2 つのコ ピーを渡して、別々にインクリメントするためです)。 読み込み専用値を渡す 490 読み込み専用の値を渡すときの動作は、データを変更できないことを 除けば、値渡しに似ています。データのコピーが、ネットワークを介 してサーバに渡されます。 PowerBuilder 第 23 章 オブジェクトを渡す EAServer コンポーネントの構築 EAServer コンポーネント内で作成されたオブジェクトをクライアント に戻すことは可能ですが、この場合はこれらのオブジェクトがインス トール済みの EAServer コンポーネントでなければなりません。EAServer コンポーネントではない PowerBuilder オブジェクトを戻そうとした場 合は、実行時エラーが出力されます。サーバから戻されたコンポーネ ントを使用するには、クライアントには、対応する EAServer プロキシ (PowerBuilder クライアントの場合)またはスタブ(非 PowerBuilder ク ライアントの場合)が必要です。 クライアント アプリケーションは、PowerBuilder オブジェクト参照を EAServer に渡せません。したがって、PowerBuilder オブジェクト参照 を使用しても、サーバから PowerBuilder クライアントへのメッセージ のプッシュは実行できません。しかし、クライアント上の共有オブジェ クトを使用して EAServer と通信することによって、この動作をシミュ レートすることは可能です。 サーバ プッシュをシミュレートするには、クライアントは、 SharedObjectRegister 関数と SharedObjectGet 関数を使用して、共有オブ ジェクトを作成します。オブジェクトが作成されると、クライアント から共有オブジェクトにメソッドをポストして、サーバ上で処理終了 時に通知しなければならないコールバック オブジェクトを渡せます。 共有オブジェクトのメソッドは、処理を行う EAServer コンポーネン ト メソッドの同期呼び出しを行います。共有オブジェクトはクライ アント上の独立したスレッドで動作しているため、サーバ上でプロセ スを実行しながら、クライアント アプリケーションがほかの作業を 続行できます。 NULL 値のサポート PowerBuilder では、EAServer コンポーネントのメソッドが NULL 値を 関数引数として受け取るか、戻り値の型として受け取るかを指定でき ます。コンポーネント インタフェースで NULL 値をサポートするには、 EAServer コンポーネントの生成に使用されたプロジェクトのプロパ ティ シートで、 [NULL 値をサポート]チェックボックスをオンにしま す。このボックスがオフである場合には、クライアントはどの引数に も NULL 値を渡せないため、サーバは、引数に NULL を設定したり NULL 値を返したりすることはできません。 アプリケーション テクニック 491 コンポーネント インタフェースの定義 コンポーネント メソッドのプロトタイプで NULL 値を許可する場合、 PowerBuilder はプロジェクト ペインタから生成する EAServer プロキ シのメソッド名に「_N」接尾辞を追加します。このメソッドを呼び出 すには、NVO のインスタンスではなく、プロキシのインスタンスを作 成する必要があります。そして、 「_N」接尾辞を持つメソッドを参照 する必要があります。たとえば、of_gen が NVO のメソッド名で、NULL 戻り値を許可する EAServer プロキシを作成する場合は、プロキシのイ ンスタンスを作成し、of_gen_N を呼び出してこのメソッドを使用する 必要があります。 EAServer 検証 EAServer コンポーネントとして配布する予定のカスタム クラス ユー ザ オブジェクトを設計している場合には、EAServer で無効なコード要 素が使用されたときに、PowerBuilder で警告を出すようにできます。 EAServer 検証では、パブリック インスタンス変数とパブリック関数の システム タイプ、ビジュアル タイプ、構造体、および変数をチェック します。 EAServer 検証は、EAServer ウィザードを使用してユーザ オブジェクト を作成した場合には、デフォルトでオンになっています。チェックす るには、ユーザ オブジェクト ペインタの[デザイン]メニューを選択 し、 [EAServer 検証]がオンになっていることを確認します。オブジェ クトを保存すると、出力ウィンドウに以下のような警告が一覧表示さ れます。 ---------- コンパイラ : 情報メッセージ 情報 C0197: コンポーネント検証 警告 C0198: 適切でない Jaguar タイプ : 'window' arg type for function: 'of_badfunc' 警告 C0198: 適切でない Jaguar タイプ : 'any' return type for function: 'of_badfunc' 検証は、ユーザ オブジェクト ペインタではなく、編集中のオブジェク トに関連付けられます。オブジェクトを再び開くと、オブジェクトの 検証状態は閉じたときと同じになります。 例外の送出 492 EAServer に配布するユーザ オブジェクトの関数で例外を宣言すると、 その例外はメソッドのプロトタイプの一部として、CORBA IDL に変換 されます。例外は、任意の種類の EAServer クライアント アプリケー ションまたは呼び出したコンポーネントで処理できます。詳細につい ては、39 ページの「PowerBuilder での例外処理」を参照してください。 PowerBuilder 第 23 章 EAServer コンポーネントの構築 既存インタフェースの実装 新規作成 ダイアログボックスの[ターゲット]タブまたは[PB オブ ジェクト]タブの EAServer コンポーネント ウィザードを使用して、既 存インタフェースの PowerBuilder の実装を作成できます。この機能は 一般的には、オンライン バンキングや証券取引のプロトコルなどの標 準 API の実装を作成するのに使用されます。 インタフェースの選択 ウィザードの[インタフェース実装の指定]ページで[既存の EAServer リモート インタフェースを実装する]を選択し、次に、実装したい IDL インタフェースが保存されているサーバの EAServer プロファイ ルを選択します。ウィザードでパッケージのリストを展開したときに 表示されるリストから、インタフェースを 1 つだけ選択できます。 PowerBuilder コンポーネントの場合、普通、インタフェース名はコン ポーネント名と同じですが、インタフェースのリストがそのままサー バ上のコンポーネントのリストにマッピングされるわけではありませ ん。リストには、タイプ インタフェースのすべての IDL モジュールが 含まれます。 ウィザードのオプショ ンの設定 実装するインタフェースを選択したら、コンポーネントの EAServer 名 を入力します。PowerBuilder カスタム クラス ユーザ オブジェクトの名 前は変更できません。この名前は常に、リモート インタフェースの名 前と同じになります。新規インタフェース作成時のように、パッケー ジ名、インスタンス プーリングなど、そのほか多くのオプションを設 定できます。 標準 API の PowerBuilder の実装を作成している場合、普通はリモート コンポーネントのコンポーネント名を使用しますが、同じパッケージ 名を使用してはいけません。 リモート コンポーネントのインタフェースは変更できないため、引数 に NULL 値をサポートするなど、メソッドのシグネチャが変更されて しまうようなオプションは、ウィザードでは設定できません。 ペインタでのユーザ オブジェクトの編集 ウィザードで作成したカスタム クラス ユーザ オブジェクトでは、リ モート インタフェースのパブリック属性はパブリック インスタンス 変数として表され、パブリック メソッドはパブリック関数として表さ れます。関数のスクリプトには、コンパイル エラーが発生しないよう に return ステートメントが格納されていますが、それぞれの関数を実 装するスクリプトを提供する必要があります。リモート インタフェー スにほかにも依存する要素(構造体など)が含まれている場合、ウィ ザードはユーザ オブジェクトと同じ PBL でそれらを作成します。 アプリケーション テクニック 493 既存インタフェースの実装 EAServer 6.0 以降を使用している場合、PowerBuilder コンポーネント は、EJB コンポーネントとして組み込まれ、Remove メソッドは、EAServer によってコンポーネント インタフェースの一部として生成されます。 ただし、ユーザーがこのメソッドを使用する必要はありません。 ユーザ オブジェクトは、ほかのカスタム クラス ユーザ オブジェクト と同様に編集できます。ユーザ オブジェクト ペインタで制約を適用さ れることはありません。ただし、インタフェースに影響するような変 更を行ってはいけません。既存インタフェースの属性とメソッドに対 応するインスタンス変数や関数を削除したり、そのモードをパブリッ クからプライベートやプロテクトに変更したりしないでください。関 数は多重定義できません。また、戻り値か引数には NULL 値を使用で きません。 EAServer へのコン ポーネントの配布 ウィザードによって作成されたプロジェクトには、ウィザードがコン ポーネントを構築したインタフェースに関する情報が格納されていま す。プロジェクトを実行すると、PowerBuilder は次のことをチェック します。 • 既存 IDL インタフェースのすべてのパブリック属性とメソッド が、ユーザ オブジェクトのパブリック インスタンス変数や関数と して定義されている • IDL インタフェースで定義されたメソッドが、ユーザ オブジェク トで多重定義されていない これらのチェックのいずれかが失敗した場合、コンポーネントは配布 されますが、プロジェクト ペインタと出力ウィンドウに警告が表示さ れます。 異なるプロジェクトの 使い方 これらのチェックは、コンポーネント作成時に作成されたプロジェク トを使用してコンポーネントが配布された場合のみ実行されます。新 しいプロジェクトを作成したり、別のプロジェクトにコンポーネント を追加したりした場合は、プロジェクト実行時にはチェックは実行さ れません。 コンポーネントと一緒に作成されたプロジェクトを使用して配布する と、新規の実装は常にサーバ上の既存の IDL を使用します。別のプロ ジェクトを使用する場合は、コンポーネントをオリジナル パッケージ に配布して、インタフェースの変更に関する警告なしに既存 IDL を上 書きすることがあるため、注意が必要です。 494 PowerBuilder 第 23 章 EAServer コンポーネントの構築 プロキシの生成 既存インタフェースを実装するオブジェクトのプロキシを生成し、 サーバの既存 IDL を使用するときは、プロキシは既存 IDL に基づきま す。結果として、 [EAServer パッケージ名をオブジェクト名の前に追 加]オプションを選択すると、オブジェクト名に付く名前は、新しい パッケージの名前ではなく IDL モジュールの名前になります。 別のサーバ コンポーネントのメソッドの呼び出し EAServer では、サーバ コンポーネントのメソッドを使って、ほかの サーバ コンポーネントのメソッドを呼び出せます。呼び出される側の サーバ コンポーネントは、PowerBuilder コンポーネントである必要は なく、EAServer によってサポートされる言語で実装されているコン ポーネントでもかまいません。 現行のサーバのコン ポーネントにアクセス 現行のサーバにある別の EAServer コンポーネントのメソッドにアク セスするには、PowerBuilder クライアントの場合と同じように、接続 オブジェクトを使用してコンポーネントと通信します。あるいは、 PowerBuilder が提供する、TransactionServer というトランザクション サービス コンテキスト オブジェクトを使用します。TransactionServer インタフェースが提供する CreateInstance というメソッドを使用すれ ば、ローカルで使用するほかのコンポーネントにアクセスできます。 CreateInstance は、呼び出し元のコンポーネントに適用されるものと同 じユーザ情報とパスワード情報を使用します。 トランザクション コンテキスト サービスを使用するには、 TransactionServer 型の変数を宣言し、GetContextService 関数を呼び出し てから、トランザクション コンテキスト サービスのインスタンスを作 成します。コンポーネント間呼び出しのプロキシ オブジェクトを使 用する必要があります。プロキシ オブジェクトがなければ、 TransactionServer オブジェクトは、呼び出しているコンポーネントの 正しいメソッド名を取得することはできません。 EAServer コンポーネント用のプロキシ オブジェクトの作成について は、524 ページの「EAServer プロキシ オブジェクトの生成」を参照し てください。 例 コンポーネントの Activate イベントで GetContextService を呼び出 して、TransactionServer サービスをインスタンス化できます。 アプリケーション テクニック 495 別のサーバ コンポーネントのメソッドの呼び出し // インスタンス変数: // TransactionServer ts Integer rc rc = this.GetContextService("TransactionServer", ts) IF rc <> 1 THEN // エラー処理 END IF いずれかのコンポーネント メソッドから、CreateInstance を呼び出して 2 番目のコンポーネントをインスタンス化し、そのメソッドの 1 つを 呼び出せます。アプリケーションには、以下のように 2 番目のコンポー ネントのプロキシを含めます。 // 2 番目のコンポーネントのインスタンス変数 : // nvo_comp2 mycomp2 Integer rc rc = ts.CreateInstance(mycomp2, "mypackage/nvo_comp2") IF rc <> 0 THEN // エラー処理 ELSE mycomp2.method1() END IF ほかのサーバ内にある コンポーネントへのア クセス ほかのサーバのサーバ コンポーネントにアクセスする手順は、PowerBuilder クライアントからサーバ コンポーネントにアクセスする手順と基本 的に同じです。ほかのサーバの EAServer コンポーネントにアクセスす るには、接続オブジェクトを作成し、接続オブジェクトのプロパティ を設定し、ConnectToServer を呼び出します。 EJB コンポーネント へのアクセス PowerBuilder コンポーネントは、接続オブジェクトまたは TransactionServer オブジェクトのいずれかの Lookup メソッドを使用し て、EJB コンポーネントにアクセスできます。TransactionServer オブ ジェクトの Lookup メソッドには、オプションとして、ホーム インタ フェースの名前を指定するための第 3 引数があります。この引数は、 ホーム インタフェース名が一般的な命名規約に従わない場合のみ使 用します。 このスクリプトは、Cart コンポーネントをインスタンス化し、い くつかのコンポーネント メソッドを呼び出します。次の例では、Lookup メソッドの第 2 引数に、コンポーネント名と EAServer パッケージ名を 指定しています。 例 // インスタンス変数 : //Connection myconnect CartHome MyCartHome // EJB のホーム インタフェース 496 PowerBuilder 第 23 章 EAServer コンポーネントの構築 Cart MyShoppingCart // EJB のリモート インタフェース TransactionServer ts long ll_result This.GetContextService("TransactionServer", ts) // ホーム インタフェースを取得 ll_result = & ts.Lookup(MyCartHome, "Shopping/Cart") //Cart コンポーネントのビジネス ロジックへの参照を取得 MyShoppingCart = MyCartHome.Create() // ショッピング カートを使用 MyShoppingCart.AddItem(66) MyShoppingCart.Purchase() PowerBuilder クライアントから EJB コンポーネントへのアクセスにつ いては、528 ページの「EJB コンポーネント メソッドの呼び出し」を 参照してください。 コンポーネントを区別 するトランザクション [OTS スタイル]としてマークされた EAServer コンポーネントは、 CORBACurrent コンテキスト サービス オブジェクトの関数を使用し て、EAServer トランザクションに関する情報の作成、制御、および取 得が行えます。CORBACurrent オブジェクトは、CORBACurrent インタ フェース用に定義された数多くのメソッドを備えています。 詳細については、538 ページの「クライアントとコンポーネントを区 別するトランザクション」を参照してください。 コンポーネント プロパティへのアクセス ContextKeyword サー ビス オブジェクト ContextKeyword サービス オブジェクトを使用して、コンポーネントの .properties ファイルから固有のコンポーネントのプロパティ値を取得 できます。プロパティ値を取り出すには、GetContextKeywords 関数を呼 び出します(EAServer コンポーネントのすべてのプロパティを列挙す るには、Jaguar::Repository API を使用します)。 ContextKeyword サービス オブジェクトを使用するには、 GetContextService 関数を呼び出し、サービス名として Keyword を使用 してから、オブジェクトへの参照を作成します。 アプリケーション テクニック 497 コンポーネント プロパティへのアクセス PowerBuilder の EAServer プロパティ 表 23-7 に、EAServer コンポーネントとして動作する PowerBuilder カ スタム クラス ユーザ オブジェクトに関係するコンポーネント プロパ ティを示します。コンポーネント プロパティの前には、文字列 com.sybase.jaguar.component が付けられます。EAServer 5.x では、 EAServer Manager の コンポーネントのプロパティ ダイアログボック スの[Advanced]タブには、すべてのコンポーネント プロパティの 値が表示されます。表 23-7 に示すように、いくつかのプロパティは、 このダイアログボックスのほかのタブの項目にもマップされます。 EAServer 6.x でのプロパティの詳細については、Sybase 製品マニュアル Web のサイト http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc00547_0600/ht ml/eascorba/BABCDICB.htm で『CORBA Components Guide』マニュアル を参照してください。 表 23-7: EAServer 5.x における PowerBuilder コンポーネントの EAServer コンポーネント プロパティ プロパティ auto.failover 説明 表示位置 サーバが使用できなくなったときにコンポーネントを代替サーバ Transactions に転送するためのクライアント プロキシを有効にする (Automatic このプロパティは、自動的なデマケーション / 不活性化が有効でな failover) ければ有効にできない bind.thread code.set interfaces 自動フェイルオーバでは、冗長サーバでアプリケーションのコン ポーネントを実行できるように、アプリケーションがサーバのク ラスタを使用する必要がある。クラスタは最低 1 つのネーム サー バを含み、クライアントはネーミング サービスを使用してプロキ シ参照を解決しなければならない。詳細については、『EAServer System Administration Guide』マニュアルの「Load Balancing, Failover, and Component Availability」を参照 作成するスレッド上でコンポーネント インスタンスを常に起動さ Instances(Bind せるかどうかを指示する Thread) 有効な値は TRUE と FALSE である。ライブ編集の場合には、この プロパティを TRUE に設定しなければならないが、それ以外の場合 は、スケーラビリティを向上させるために FALSE に設定する必要 がある コンポーネントが使用するコード化文字セットの名前を指定する Advanced デフォルトでは、コンポーネントはサーバのコード化文字セット (サーバの Properties ウィンドウの[General]タブで指定)を使用 する。ヨーロッパ言語またはアジア言語では、このプロパティを iso_1 または big5 などの値に設定しなければならない場合がある Advanced コンポーネントが実装するインタフェースを識別する これは、IDL インタフェース名をカンマで区切ったリストであり、 それぞれのインタフェース名は module::interface という書式と なる 498 PowerBuilder 第 23 章 プロパティ minpool maxpool name pb.appname pb.class pb.cookie EAServer コンポーネントの構築 説明 インスタンス プーリングが有効のときは、プールできるインスタ ンスの最少数を指定する プールから休止中のインスタンスを解放するため、EAServer には 定期的に実行されるガベージ コレクタ スレッドがある。このス レッドが実行されるたびに、ガベージ コレクタは、休止中のイン スタンスを 1 つプールから削除する。ただし、プールが最小サイ ズに到達したときは削除されない。デフォルトは 0 インスタンス プーリングが有効のときに、プールできるインスタ ンスの最大数を指定する 表示位置 Resources Resources プール サイズの最大値に到達した場合、EAServer は非アクティブ 化後に過剰インスタンスを破棄する。デフォルトは 0 で、最大プー ル サイズが有効でないことを意味する コンポーネントの名前を指定する General(コン ポーネント部の この値の書式は package/component でなければならない み) General PowerBuilder アプリケーションの名前を指定する PowerBuilder カスタム クラス ユーザ オブジェクトの名前を指定す General る Advanced ライブラリ リストのパスの作成に使用する数を提供する パスの書式は次のとおり Repository\Component\package\component\Ccookie debug pb.librarylist pb.live_edit pb.trace pb.version PowerBuilder デバッガでコンポーネントをデバッグできるかどう Advanced かを示す General PowerBuilder ライブラリ リストを指定する ライブラリ名の前に円記号(\)が付いている場合は、その位置は EAServer Repository ディレクトリからの相対指定であるとみなさ れる。ライブラリ名の前に円記号が付いていない場合は、その名 前は絶対パスを指定するとみなされる プロジェクト ペインタではなく、ユーザ オブジェクト ペインタで Advanced プロジェクトを構築できるかどうかを指定する 504 ページの「ライブ編集」を参照 コンポーネントに対するログ収集動作のトレース オプションを指 定する(現在無効) コンポーネントが作成された PowerBuilder のバージョンを指定す る アプリケーション テクニック Advanced Advanced 499 コンポーネント プロパティへのアクセス プロパティ pooling 説明 コンポーネントがプールされているかどうかを示す 表示位置 Instances pooling プロパティに TRUE が設定された場合は、コンポーネント は常にプールされ、CanBePooled イベントは発生しない。pooling プ ロパティに FALSE が設定された場合は、CanBePooled イベントが 発生するため、プーリングの拒否を選択できる sharing tx_vote プロパティに FALSE が設定された場合は、各メソッドの後 でコンポーネントがプールされる。それ以外の場合は、トランザ クションの最後にプールされる Instances 共有コンポーネントであるかどうかを示す sharing プロパティに TRUE が設定された場合は、すべてのクライ アントが 1 つのコンポーネント インスタンスを共有する。共有コ ンポーネントにプーリング オプションは適用されない state state.gs 共有コンポーネントをサービスにするには、 com.EAServer.server.services プロパティ用に指定したサービスのリ ストに共有コンポーネントを追加する 自動的な永続格納を使用するときに、IDL 型の名前を指定する Persistence PowerBuilder では、名前の付いている型はユーザ定義の構造体で、 永 続 す る す べ て の デ ー タ を カ プ セ ル 化 し な け れ ば な ら な い。 [Persistence]タブ ページで[Automatic Persistent State]を選択し、 [State]テキストボックスに構造体の名前を入力して[OK]をク リックすると、ページ上にあるほかのプロパティがデフォルト値 に設定される。自動的な永続格納を使用する場合、PowerBuilder コ ンポーネントのステートフル フェイルオーバがサポートされる。 詳 細 に つ い て は、 『EAServer Programmer’s Guide』マニュアルの 「managing persistent component state」の章を参照 state データ型を取得し設定する state 構造体のメソッド名で、2 項 Persistence 目のカンマ区切りのリストとして指定される (State メソッド) デフォルトは getState、setState stateless EJB セッション Beans と、コントロール インタフェース CtsComponents::ObjectControl を使用する非 EJB コンポーネントの みに適用される Instances このプロパティを設定すると、tx_vote プロパティを FALSE に設定 するのと同じ結果になるが、activate イベントと deactivate イベント も無効になる。コンポーネントをステートレスに指定する場合は、 このプロパティを設定しないこと。かわりに、pooling を TRUE に、 tx_vote を FALSE に設定する 500 PowerBuilder 第 23 章 プロパティ storage EAServer コンポーネントの構築 説明 リモート データベース サーバからコンポーネントの状態情報を読 み書きするコンポーネントの名前を指定する 自動的な永続格納を使用するとき、または EAServer の組み込み格 納コンポーネントに実装を任せてコンポーネント管理による永続 性使用するときに必要となる。デフォルトは 表示位置 Persistence(ス トレージ・コン ポーネント、接 続キャッシュ、 テーブル) CtsComponents/JdbcStorage thread.safe timeout tx_outcome また、格納コンポーネントが使用する接続キャッシュとテーブル を指定する 複数の呼び出しを同時に処理できるかどうかを示す 詳細については、460 ページの「Concurrency プロパティ」を参照 メソッド呼び出しの後、次のメソッド呼び出しまでの間に、アク ティブなコンポーネント インスタンスが自動的に非アクティブに されずにアイドル状態でいられる時間を指定する トランザクションがロールバックされたときに、 CORBA::TRANSACTION_ROLLEDBACK 例外をクライアントに送 出するかどうかを決定する Instances(同時 実効性) Resources(イン スタンス・タイ ムアウト) Advanced 以下の設定を使用できる always デフォルト。トランザクションがロール バックされる と、サーバからクライアントに例外が送出される • failed トランザクションがロール バックされても、クライアント に例外が送出されない。この設定を使用する場合、RollbackWork トランザクション プリミティブを呼び出した後で説明メッセー ジ付きの別の例外を発生するように、コンポーネントをコー ディングできる • failed 設定を有効にしても、コンポーネントのリクエストによるト ランザクションをコミットできない場合は、CORBA システム例外 が送出されることがある tx_timeout ロールバックされたトランザクションの例外をクライアントに送 りたくない場合や、別の例外を送出する必要がある場合、このプ ロパティを failed に設定できる。この設定は、トランザクションが ロールバックされた後で、クライアントが出力パラメータを得ら れるようにする必要のある場合に役立つ。例外が送出される場合 は、出力パラメータを使用できない EAServer トランザクションの最大継続時間を指定する 各メソッドが復帰した後でタイムアウトがチェックされる アプリケーション テクニック Resources(トラ ンザクション・ タイムアウト) 501 Web サービスとしての NVO の公開 プロパティ tx_type 説明 EAServer トランザクションに対するコンポーネントの関与を示す 表示位置 Transactions 有効な値は、以下のとおり • not_supported • supports • requires • requires_new • mandatory • user-managed • never tx_vote type コンポーネントで自動的なデマケーション/不活性化をサポートす Transactions るかどうかを示す ([Automatic Demarcation/ tx_vote に TRUE が設定された場合は、コンポーネントは、 Deactivation] TransactionServer サービス オブジェクトのメソッドを明示的に呼 び出すことによって、トランザクション状態とコンポーネントの チェックボック スがオンである 非アクティブ化を制御する必要がある 場合は、このプ tx_vote に FALSE が設定された場合は、各メソッド呼び出しの後で、 ロパティの値は EAServer は コ ン ポ ー ネ ン ト を 自 動的に非アクティブにする。 FALSE) SetComplete はデフォルトで呼び出されるため、SetComplete を明示 的に呼び出して非アクティブにする必要はない。SetAbort を呼び出 せば、デフォルト状態に上書きできる General コンポーネントのタイプを指定する EAServer は PowerBuilder オブジェクトのプロパティを pb に設定す る Web サービスとしての NVO の公開 EAServer コンポーネント ウィザードでは、生成されるコンポーネント を Web サービスとして公開できます。 このウィザードの[EAServer コンポーネントを Web サービスとして公 開]ページには、コンポーネントを EJB 2.1 Web サービス(EAServer 6.x)または EAServer 5.x Web サービスとして公開するオプションがあ ります。コンポーネントを EJB 2.1 Web サービスとして公開する場合 は、ウィザードまたはプロジェクト ペインタの[全般]タブのページ で、Java のパッケージ名を指定する必要があります。 EAServer 5.x Web サービスについては、表 23-8 で説明されるプロパ ティを設定する必要があります。 502 PowerBuilder 第 23 章 EAServer コンポーネントの構築 表 23-8: Web サービスとして公開されるコンポーネントのプロパティ プロパティ Web アプリケー ション名 説明 コンポーネントの配布先である Web アプリケーションの 名 前 を指定する。入力した Web アプリケーションが EAServer に存在しない場合は、そのアプリケーションの 作成後にコンポーネントが配布される。アプリケーショ ンを指定しなかった場合、コンポーネントは EAServer の デフォルトの Web アプリケーションである「ws」に配布 される サービス名 コンポーネントを Web サービスとして公開するときに使 用するサービス名を指定する。サービス名を指定しな かった場合、デフォルトの packageName_componentName が使用される WSTAdmin ポ ー EAServer で Web サービスに使用するポートを指定する。 ト番号 ポートを指定しなかった場合、デフォルトの 8080 が使用 される [コンポーネントを Web サービスとして公開]チェックボックスと 3 つのテキスト ボックス フィールドは、EAServer コンポーネントのプ ロパティ ダイアログボックスの[Web サービス]タブにもあります。 したがって、これらのプロパティは、ウィザードを使用せずに設定し たり、ウィザードの完了後に変更したりすることができます。 Web サービスとして配布する EAServer コンポーネント内の構造体オ ブジェクトを参照する場合、そのオブジェクトは自動的にカスタム データ型に変換されます。 現在、EAServer で Web サービスとして公開するコンポーネントには、 次の制限が適用されます。文字データ型を参照渡しする関数が PowerBuilder コンポーネントにある場合、そのコンポーネントを Web サービスとして公開できません。「Can't find prefix for 'http://DefaultNamespace'」などのエラー メッセージが表示されます。 アプリケーション テクニック 503 コンポーネントのテストとデバッグ コンポーネントのテストとデバッグ この節では、コンポーネントをテストするための 3 つの方法について 説明します。 • ライブ編集 • リモート デバッグ • EAServer ログへのメッセージ出力 EAServer コンポーネントのトラブルシューティング コンポーネントのトラブルシューティングについての詳細は、EAServer のマニュアルを参照してください。 ライブ編集 コンポーネントをテストまたはデバッグするには、ライブ編集という PowerBuilder の機能を利用すれば、ユーザ オブジェクト ペインタでプ ロジェクトを自動的に作成できます。ライブ編集が有効であれば、対応 するユーザ オブジェクトを保存するたびに、PowerBuilder は EAServer コンポーネントのプロジェクトを作成します。ジェネレータは、EAServer に PBD を配布しないかわりに、必要なオブジェクト定義を含む PBL へ のアクセス方法を EAServer に指示します。 サービス コンポーネント ライブ編集を利用しても、サービス コンポーネントとしてセットアッ プしたコンポーネントはテストできません。サービス コンポーネント は、サーバの稼動中は常に使用されているため、ユーザ オブジェクト ペインタで行った変更の保存はできません。 ライブ編集を有効にす る方法 ユーザ オブジェクトのライブ編集を有効にするには、次の手順を実行 する必要があります。 1 EAServer コンポーネントを生成したいユーザ オブジェクトを含む プロジェクトを作成します。 EAServer への配布を可能にする既存の PBL を使用したり、新規プ ロジェクトを作成してテスト用に使用したりできます。 2 504 必要に応じて、プロジェクトのライブ編集ライブラリ リストを修 正します。 PowerBuilder 第 23 章 EAServer コンポーネントの構築 リモート マシン上にあるサーバでコンポーネントをテストしてい る場合には、PBL の位置を EAServer に通知する必要があります。 このためには、プロジェクト ペインタで、コンポーネントのプロ パティ シートにある[高度なオプション]ページ(下図参照)の ライブラリ リストを修正します。 ここで指定するライブラリ リストは、Universal Naming Convention (UNC)名を使用する、絶対パス名を含んでいる必要があります。 UNC 名の書式は \\servername\sharename\path\file です。 デフォルトでは、ライブ編集ライブラリ リストは、アプリケーショ ン ライブラリ リストに基づいています。使用しているサーバが ローカルである場合には、ライブ編集ライブラリ リストを修正す る必要はありません。 3 ユーザ オブジェクト ペインタで、コンポーネントの生成に使用す るプロジェクトを指定します。 プロジェクト名は、 [EAServer プロジェクト]フィールドに入力し ます。このフィールドは、ユーザ オブジェクト プロパティ シート の[全般]プロパティ ページ(下図参照)にあります。 指定するプロジェクト名は、以下の要件を満たす必要があります。 コンポーネントの生成 方法 • EAServer コンポーネント プロジェクトであること • ユーザ オブジェクト ペインタで現在開いているユーザ オブ ジェクトを含んでいること • プロジェクトのライブラリ リストは、現行のアプリケーショ ン ライブラリ リストと一致すること ユーザ オブジェクト ペインタで EAServer コンポーネントを生成する には、 [ファイル|上書き保存]を選択します。 アプリケーション テクニック 505 コンポーネントのテストとデバッグ コンポーネントを生成 すると何が起きるか ユーザ オブジェクト ペインタでプロジェクトを作成すると、以下の処 理が行われます。 • 保存した非ビジュアル オブジェクトを記述する CORBA IDL を生 成。 この IDL は、さらにスタブとスケルトンの作成に使用されます。 IDL ファイル、スタブ、およびスケルトンの名前は、オブジェク トの名前をベースにしています。 コンポーネント ジェネレータは、EAServer のインストール ディレ クトリの Repository サブディレクトリに新しい IDL を格納します。 • EAServer コンポーネントのプロパティを記述する PROPS ファイ ルを生成 PROPS ファイルは、EAServer のインストール ディレクトリのサブ ディレクトリに格納されます。このサブディレクトリのパスは以 下のとおりです。Repository\Component\package-name PowerBuilder は、配布時と同様にコンポーネントを作成します。ただ し、コンポーネントの PBD は生成されません。さらに、コンポーネン ト ジェネレータは、pb.live_edit プロパティを TRUE に設定し、ライブ 編集用に指定したライブラリ リストを pb.librarylist プロパティに割り 当てます。 プロジェクトを作成するとエラーになる場合には、PowerBuilder は、出 力ウィンドウにエラー メッセージを表示します。 ユーザ オブジェクトに対するインスタンス プーリングが有効である 場合には、ジェネレータは、現行の構築に対するプーリングを無効に します。ユーザ オブジェクトを含む PBL が EAServer によってロック された場合には、PowerBuilder はユーザ オブジェクトを保存できない ため、ライブ編集ではプーリングはサポートされていません。 リモート デバッグ PowerBuilder のカスタム クラス ユーザ オブジェクトを EAServer コン ポーネントとして作成している場合には、PowerBuilder デバッガを使 用して、EAServer コンポーネントをデバッグできます。ユーザ オブ ジェクト ペインタのライブ編集機能を利用しても、プロジェクト ペイ ンタから EAServer にコンポーネントを配布しても、コンポーネントを デバッグできます。 ライブ編集についての詳細は、504 ページの「ライブ編集」を参照し てください。 506 PowerBuilder 第 23 章 コンポーネントをデ バッグするための準備 デバッグする EAServer コンポーネ ントの選択 デバッガの起動 EAServer コンポーネントの構築 リモート コンポーネントのデバッグを始める前に、ご使用の構成が以 下の条件を満たすかどうかをチェックしてください。 • 配布されるコンポーネントの開発に使用したものと同じバージョ ンのアプリケーションと PBL を使用している。配布された複数の コンポーネントを同じセッション内でデバッグしたい場合には、 それらのコンポーネントは、すべて同じバージョンの PBL、同じ アプリケーション名、および同じライブラリ リストを使用して作 成されたものでなければならない • プロジェクト ペインタのコンポーネント プロパティのページで、 [リモート デバッグのサポート]チェックボックスがオンになって いる。デバッグ オプションを設定するには、プロジェクト ウィ ザードで[リモートデバッグのサポート]チェックボックスをオ ンにする方法もある • 配布されたコンポーネントに含まれるメソッドとプロパティを実 行するクライアント アプリケーションがある。このアプリケー ションとしては、互換性のある開発ツールで作成されたコンパイ ル済みの実行ファイル、または別の PowerBuilder セッションで実 行されている PowerBuilder アプリケーションでもよい EAServer ターゲットをデバッグする場合、デバッグ可能なコンポーネ ント セットはプロジェクトで決まります。このコンポーネント セット には、プロジェクト ペインタの[コンポーネント]ページで選択した すべてのコンポーネントが含まれ、[リモート デバッグのサポート] チェックボックスがオンになっています。異なるコンポーネント セッ トを選択したり、複数のパッケージからのコンポーネントをデバッグ したりする場合は、デバッガのメニュー バーから[デバッグ|コン ポーネントの選択]を選択するか、ペインタバーの[コンポーネント の選択]ボタンをクリックします。 デバッグを始めるには、配布されたコンポーネントを含むターゲット を開きます。ペインタバーの[リモートを開始]ボタンをクリックし、 ウィザードを完了します。選択できるコンポーネントは、PowerBuilder で[リモート デバッグのサポート]をオンにして生成されたコンポー ネントだけです。[リモート デバッグのサポート]はセキュリティ設 定の 1 つであり、コンポーネントにデバッグ情報を追加しません。コ ンポーネントをテストするときに[リモート デバッグのサポート]を オンにします。コンポーネントをユーザのサイトに配布するときには、 [リモート デバッグのサポート]をオフにして、ユーザにコードがわ からないようにします。 アプリケーション テクニック 507 コンポーネントのテストとデバッグ ローカル アプリケーションをデバッグするときのようにブレークポ イントを設定してから、リモート コンポーネントを呼び出すクライア ント アプリケーションを起動します(まだ実行されていない場合)。 ローカル デバッグと の違い ローカル アプリケーションとリモート アプリケーションのデバッグ には、2 つの主な違いがあります。 • • デバッガを起動しても、デバッガは最小化されない 新規インスタンス ビューには、デバッグ中のコンポーネントの各 インスタンスが表示される。インスタンスごとに、コンポーネン ト名とパッケージ名、インスタンス番号、およびその現在の状態 (アイドル、実行中、または一時停止)が表示される。複数のイン スタンスがある場合には、現在デバッグ中のインスタンスが黄色 の矢印で示される サポートされていない機能 メモリ内のオブジェクト ビュー、式の評価、および変数値の変更はサ ポートされていません。 状態について インスタンス ビューには、コンポーネントごとに各インスタンスの状 態が示されます。 • コンポーネントは休止中か、インスタンス プール内にあ アイドル る コンポーネントは、現在コードを実行している • 実行中 • 一時停止 コンポーネントはブレークポイントで一時停止して、デ バッガ操作を待機している インスタンスが破棄されると、インスタンス ビューから取り除かれま す。 複数のインスタンス 同時に複数のコンポーネント インスタンスを一時停止させることは 可能ですが、デバッガで行う操作は、ブレークポイントに到達した最 初のインスタンスにだけ作用します。このインスタンスは、インスタ ンス ビューの黄色の矢印によって示されます。メソッドが完了する か、 [実行の継続]をクリックした場合には、現行のインスタンスは キュー内の次のインスタンスに変わります。 インスタンス ビューで新規インスタンスをダブルクリックしても、1 つのインスタンスから別のインスタンスにコンテキストを変更できま す。別のコンポーネント インスタンスへの呼び出しを除いて、インス タンス ビューに呼び出されたインスタンスが一時停止したことが示 されている場合には、この方法を利用できます。 508 PowerBuilder 第 23 章 EAServer コンポーネントの構築 EAServer ログへのメッセージ出力 EAServer で動作している PowerBuilder オブジェクトによって生成され たエラーを EAServer ログに記録するには、ErrorLogging サービス コン テキスト オブジェクトのインスタンスを作成し、その log メソッドを 呼び出します。たとえば、次のようになります。 ErrorLogging inv_el this.GetContextService("ErrorLogging", inv_el) inv_el.log("Write this string to log") ErrorLogging サービスを使用して、サーバ上のシステム エラーまたは 実行時エラーのコンテキストに関する詳細情報を表示できます。この 情報は、システム管理者や開発者が問題を解決する際に役立ちます。 コンポーネントの開発中は、ErrorLogging サービスを使用して、コン ポーネントの実行をトレースできます。たとえば、関数に入るときや 出るときに、ログにメッセージを書き込むことも可能です。このメッ セージによって、コンポーネントの名前、関数に入っているか出てい るか、それはどの関数かを特定できます。 例外情報の自動記録 サーバで実行している PowerBuilder コンポーネントが引き起こす例外 の種類および例外の位置に関する情報は、自動的にサーバ ログに記録 されます。これらの例外についての最低限の情報を取得するためにエ ラー ログ サービスを実行する必要はありません。 XSL-FO を使用して PDF ファイルを生成するときに、詳細情報メッ セージと警告メッセージがログに送信されます。環境変数 PB_FOP_SUPPRESSLOG に 1 を設定すると、これらのメッセージの出 力を抑制できます。 データの印刷 サーバが Windows または Solaris で動作している場合は、データストア を使用してデータをリモート サーバに印刷できます。 アプリケーション テクニック 509 データの印刷 プラットフォームに関する注意 次の例は、HP-UX または AIX 上では機能しません。これらのプラット フォームでは、EAServer が Windows の機能を利用しない PowerBuilder 実行環境を使用するため、印刷などのグラフィック処理はサポートし ていません。データストア印刷関数を使用した印刷は、現在 Solaris だ けでサポートしています。ただし、SaveAs 関数と PDF SaveAsType を 使用すれば、データストア オブジェクトをすべての UNIX プラット フォームで印刷できます。 詳細については、514 ページの「PDF への印刷」を参照してください。 この例では、サーバ コンポーネント uo_employees は、print_employees という関数を備えています。print_employees はデータストア ds_datastore のインスタンスを生成し、このデータストアの内容を印刷 します。 print_employees 関数のシグネチャを次に示します。 print_employees( ) returns integer print_employees 関数のスクリプトを次に示します。 datastore ds_datastore int li_rc ds_datastore = create datastore ds_datastore.dataobject = "d_empdata" ds_datastore.SetTransObject (SQLCA) ds_datastore.Retrieve() li_rc = ds_datastore.Print() return li_rc Solaris オペレーティング システムでの印刷 Solaris では、PostScript または PCL5 ファイルに直接印刷できます。 Windows ではなく Solaris でレポートを印刷するためにコードを変更 する必要はありません。Windows の場合と同じプロパティ、関数、お よびイベントを使用できます。 データストアを印刷するには、データストア Print メソッドまたは PrintDataWindow(PrintJobName, DataStoreName) を使用します。データ ストアをデータウィンドウにリンクしてデータウィンドウ オブジェ クトを Solaris で印刷する場合、印刷結果は、データウィンドウ オブ ジェクトで定義したフォントとレイアウトになります。 510 PowerBuilder 第 23 章 EAServer コンポーネントの構築 スペース Solaris で は 印 刷 ジ ョ ブ で の ス ペ ー ス を サ ポ ー ト し て い な い た め、 PBVM によって、印刷ジョブをプリンタに送信する前に印刷ジョブ名 の各スペースがハイフンに置き換えられます。 フォントの使い方 印刷に使用されるフォントは、dwprinter/fontmetrics ディレクトリに用 意されているフォントです。AFM ファイルと TFM ファイルは、特定 の PostScript(AFM)と PCL(TFM)のフォントに関する情報を含む ASCII 形式のファイルです。PostScript と PCL の各フォントには、対応 するフォント メトリック ファイルがあります。 印刷メカニズムで、フォント メトリック情報を取得するために AFM ファイルと TFM ファイルが読み込まれます。この情報には、文字幅、 ベースライン位置、アセンダ サイズ、ディセンダ サイズ、下線スト ローク幅、下線位置などがあります。次に、このメトリック情報は、 XTextWidth のような Xlib API が要求する形式に変換されます。 最善の方法は、データウィンドウの設計時に、Windows と Solaris の両 方で使用可能なフォントを選択することです。ただし、各プラット フォームには独自のフォントレンダリング エンジンがあるため、 Solaris と Windows でのフォント サイズの違いが気になることがあり ます。Solaris での印刷結果を開発プロセスの早い時期にテストする必 要があります。 制限 データウィンドウ オブジェクトの印刷のサポートは、Bristol Technology の Wind/U 製品に基づいています。Wind/U GDI ライブラリと Xprinter ライブラリには、以下の制限があります。 • マルチバイト文字セット(MBCS)および Unicode はサポートして いない • Xprinter はスレッド セーフではないため、印刷ジョブはシリアラ イズされる プリンタの設定 データウィンドウ オブジェクトを印刷するプリンタを設定するには、 プリンタへのアクセスの追加、dwprint.ini 環境設定ファイルの設定、お よび XPPATH 環境変数の作成を行わなければなりません。 プリンタへのアクセス の追加 ルート ユーザで、Solaris admintool ユーティリティを使用して Solaris 上 のプリンタへのアクセスを追加します。詳細については、Solaris のマ ニュアルを参照してください。 アプリケーション テクニック 511 データの印刷 dwprint.ini の設定 $EAServer/bin ディレクトリの dwprint.ini ファイルは、データウィンド ウ印刷用の環境設定ファイルです。このファイルは、Microsoft Windows のプリンタ環境設定方法に厳密に従っています。その結果、このファ イルには[windows] 、 [devices]、 [ports]の各セクションが用意されて おり、各セクションにプリンタの適切なエントリを指定しなければな りません。 通常、このファイルのほかのセクションを変更する必要はありません。 ただし、いくつかの問題を解決するために、ほかのセクションの追加 または変更を行います。たとえば、 [intl]セクションに次のようなエ ントリを追加して日付形式を変更できます。 [intl] sShortDate=m/d/yyyy // 4 桁の年を設定します。 ポートの指定 dwprint.ini の[ports]セクションの各行には、出力ファイルのスプー ルに使用されるユーザ定義のポート名と関連コマンドを記述します。 たとえば、システムに直接接続されている myprinter というプリンタに 印刷ジョブを送信するコマンドは、次のとおりです。 lp -s -d myprinter -t$XPDOCNAME $XPDOCNAME は、プリンタに送信された出力ファイルの名前を表し ます。-s オプションを指定すると、EAServer コンソールでの lp から送 信されたメッセージの表示が抑制されます。 この後に、dwprint.ini ファイルの[ports]セクションの例を示します。 このセクションでは、prnt1、prnt2 というリモート プリンタ用に定義さ れた 2 つのポート、ローカル プリンタ用の 1 つのポート、およびファ イルへの印刷用のエントリが記述されています。出力ファイルの名前 は引用符で囲みます。このように指定すると、複数単語のファイル名 を使用できます。rsh スクリプトで引用符が取り除かれるので、リモー ト サーバでエスケープしなければなりません。 [ports] colorpr1=rsh prntsvr lp -s -d prnt1 -t\"$XPDOCNAME\" colorpr2=rsh prntsvr lp -s -d prnt2 -t\"$XPDOCNAME\" LOCAL=lp -d myprinter -t"$XPDOCNAME" FILE: = プリンタの種類を定義 済みのポートに合わせ る 512 [devices]セクションには、現在設定されているすべてのプリンタのリ ストを記述します。各行には、プリンタのユーザ定義のエリアス、お よび 3 つの引数としてプリンタ機種、プリンタ モード(PCL4、PCL5、 または PostScript)、プリンタが接続されている 1 つまたは複数のポー トが記述されます。 PowerBuilder 第 23 章 EAServer コンポーネントの構築 プリンタ機種は、プリンタで使用されるプリンタ記述ファイル(PPD) の名前です。PPD ファイルは、PBVM のインストール時に dwprinter/ppds ディレクトリにインストールされています。そのディレクトリ内のテ キスト ファイル filename_map.txt で、プリンタ記述を含むファイルの 名前をプリンタの種類にマップします。たとえば、次に示すのは、以 降の例で使用する color_lj モデルのマッピングです。 color_lj.pcl:"HP Color LaserJet PCL Cartridge" color_lj.ps:"HP Color LaserJet PS" プリンタ機種とモードは、スペースで区切ります。モードとポートは、 カンマで区切ります。たとえば、次の[devices]セクションで指定さ れている最初のデバイスの場合は、エリアスが HP Color LaserJet PS で あり、機種は color_lj、モードは PostScript で、2 つのポート(FILE: と colorpr1)が指定されています。 [devices] HP Color LaserJet PS=color_lj PostScript,FILE:,colorpr1 HP Color LaserJet PS=color_lj PCL5,colorpr2 HP Color LaserJet PS=color_lj PostScript,LOCAL HP LaserJet PS=NULL PostScript,FILE: HP LaserJet PCL=NULL PCL,FILE: デフォルト プリンタ の指定 [windows] セクションには、デフォルト プリンタ情報を記述します。 ポートの指定と同様に、各デバイス行で 3 つの引数として PPD ファイ ル、ドライバ、およびポートの名前を指定しますが、[windows]セク ションでは、それらをすべてカンマで区切ります。 次の例は、プリンタ ファイル記述が NULL に設定されたときにファイ ルに印刷するためのデフォルト エントリ、およびほかの 2 つのエント リを示しています。後半 2 行の先頭のセミコロンはコメント文字なの で、現在のデフォルト プリンタは、ポート colorpr1 の HP Color LaserJet プリンタになっています。 [windows] device=color_lj,PostScript,colorpr1 ;device=color_lj,PostScript,colorpr2 ;device=NULL,PostScript,FILE: プリンタ オプション の設定 dwprint.ini ファイルには、 [windows]、 [devices]、 [ports]の各セクショ ンで定義した機種ごとに環境設定セクションを記述しなければなりま せん。環境設定セクションでは、部数、印刷の向き、ページ サイズ、 DPI などの、プリンタのデフォルト設定情報を指定します。 たとえば、先ほどの例で使用された color_lj プリンタの場合は、次のよ うに環境設定セクションを追加します。 [color_lj,PostScript] アプリケーション テクニック 513 データの印刷 Filename=jaguar.ps Scale=1.00 Copies=1 Orientation=Portrait PageSize=Letter DPI=300 [color_lj,PCL5] Filename=jaguar.pcl Scale=1.00 Copies=1 Orientation=Portrait PageSize=Letter DPI=300 XPPATH 環境変数の 設定 印刷ジョブを開始する前に、XPPATH 環境変数を設定します。XPPATH 変数には、プリンタ記述ファイルとプリンタ固有のフォント マッピン グ ファイルを格納しているディレクトリへのパスを設定しなければ なりません。これらのファイルは、PBVM のインストール時に dwprinter ディレクトリにインストールされます。 C シェルの場合は、次のようにパスを設定します。 setenv XPPATH $EAServer/dwprinter Korn シェルまたは Bourne シェルの場合は、次のようにパスを設定し ます。 XPPATH = $EAServer/dwprinter;export XPPATH PDF への印刷 データストアのデータを PDF に保存するには、GNU Ghostscript distiller を利用するか、XSL Formatting Objects(XSL-FO)を使用してデータを 処理する機能を利用します。データウィンドウ オブジェクトのデータ を XSL-FO または PDF に保存し、Java の印刷機能を利用して印刷でき ます。 GNU Ghostscript distiller の使い方 514 GNU Ghostscript distiller を使用するには、Ghostscript ファイルおよびデ フォルト PostScript プリンタ ドライバと関連ファイルをサーバ上の PowerBuilder ランタイム ファイルと同じディレクトリにインストール しておく必要があります。Ghostscript メソッドは、UNIX ではサポート されていません。 PowerBuilder 第 23 章 XSL-FO の使い方 EAServer コンポーネントの構築 XSL-FO を使用するには、Apache XSL Formatting Objects プロセッサ (FOP)をサーバ上の PowerBuilder ランタイム ファイルと同じディレク トリにインストールされていて、以下の JAR ファイルがクラスパスに なければなりません。 fop-0.20.4\build\fop.jar fop-0.20.4\lib\batik.jar fop-0.20.4\lib\xalan-2.3.1.jar fop-0.20.4\lib\xercesImpl-2.1.0.jar fop-0.20.4\lib\xml-apis.jar fop-0.20.4\lib\avalon-framework-cvs-20020315.jar これらのファイルを CLASSPATH 環境変数、あるいは User_setenv.bat または Serverstart.bat に追加できます。 EAServer で XSL-FO を使用して PDF ファイルを生成すると、詳細情報 メッセージと警告メッセージが Jaguar ログに書き込まれます。これら のメッセージの出力を抑制するには、環境変数 PB_FOP_SUPPRESSLOG に 1 を設定します。 詳細については、PowerBuilder の『ユーザーズ ガイド』マニュアルの 「データウィンドウ オブジェクトの機能拡張」の章を参照してくださ い。 EAServer へのコンポーネントの配布 サーバ上に PowerBuilder VM が必 要 コンポーネントを、Windows、UNIX および Linux 上で稼動している EAServer ホストに配布できます。開発に使用したコンピュータの PowerBuilder VM のバージョンが、サーバ上でも使用できる必要があ ります。 PowerBuilder VM には、PBVM115.DLL、PBJAG115.DLL、 PBDWE115.DLL など、実行時に必要な PowerBuilder ファイルが用意 されています。UNIX および Linux の場合、共有ライブラリは libpbvm115x.ext、libdwe115x.ext、などと呼ばれ、ext は各プラット フォームの共有ライブラリ拡張子です。EAServer は PowerBuilder ラン タイム ファイルを使用します。PowerBuilder ランタイム ファイルは、 ファイル名の最後に x が付き、印刷を含む Window API の呼び出しや グラフィック処理をサポートしていません。 アプリケーション テクニック 515 EAServer へのコンポーネントの配布 PowerBuilder NVO からの .NET Web サービスの利用 EAServer で稼働している PowerBuilder コンポーネントから .NET Web サービスを呼び出す場合、Sybase.PowerBuilder.WebService.Runtime.dll、 Sybase.PowerBuilder.WebService.RuntimeRemoteLoader.dll、お よ び 動 的 に生成される .NET アセンブリを EAServer bin ディレクトリに配布す る必要があります。 EAServer は、同一サーバ上で PowerBuilder VM の複数のバージョンを サポートします。異なるバージョンの PowerBuilder で作成されたコン ポーネントは、必要なバージョンの PowerBuilder VM がサーバ上で使 用できる限り、同一サーバ上で共存できます。 PowerBuilder 11.5 から EAServer にコンポーネントを配布するときは、 コンポーネントは使用している PowerBuilder VM のバージョンに関連 付けられます。EAServer 5.x の EAServer Manager では、コンポーネン トのプロパティ シートの[Advanced]タブ ページの com.sybase.jaguar.component.pb.version プロパティが 11.5 に設定されま す。EAServer 6.x では、CORBA Packages ノード下のコンポーネントの [General]プロパティ ページに表示されます。 PowerBuilder 開発環境を使用しないで PowerBuilder コンポーネントを EAServer に配布する場合は、EAServer Manager のコンポーネントのプ ロパティ シートに、正しい VM のバージョンを指定できます。 開発環境で使った PowerBuilder VM のバージョンがないサーバでは、 PowerBuilder コンポーネントを配布しても、そのコンポーネントはイ ンスタンス化できません。 EAServer コンポーネ ントの配布について コンポーネントを EAServer に配布するには、プロジェクトを新規作成 して構築します。新規プロジェクトでは、組み込まれるオブジェクト の一覧を表示し、生成されたコンポーネントを格納する出力ライブラ リの名前を指定します。 データウィンドウの定義の有効化 データウィンドウ オブジェクトを動的に参照するスクリプトの場合 は、ウィザードまたはペインタの[統合 PBD に参照されないオブジェ クトを含める]ボックスをオンにして、データウィンドウの定義がコ ンポーネントで使用できるようにしなければなりません。 コンポーネントの配布 方法 516 コンポーネントを EAServer に配布するには、ウィザードによって作成 されたプロジェクトを開いて、 [デザイン|プロジェクトの配布]を選 択します。 PowerBuilder 第 23 章 EAServer への配布後 の処理内容 EAServer コンポーネントの構築 コンポーネントを EAServer に配布すると、コンポーネント ジェネレー タによって以下の処理が行われます。 • 配布用に選択した非ビジュアル オブジェクトを記述する CORBA IDL を生成 この IDL は、さらにスタブとスケルトンの作成に使用されます。 IDL ファイル、スタブ、およびスケルトンの名前は、オブジェク トの名前に基づいています。 コンポーネント ジェネレータは、EAServer のインストール ディレ クトリの Repository サブディレクトリに新しい IDL を格納します。 • 配布されたコンポーネントに対して 1 つまたは複数の PBD ファイ ルを生成 PBD ファイルは、EAServer のインストール ディレクトリのサブ ディレクトリに格納されます。このサブディレクトリのパスを次 に示します。Repository\Component\package\component\Ccookie ここで、cookie は構築の生成番号を表します。ライブラリ名が修飾 されていない(パスが指定されない)場合には、コンポーネント ジェネレータは名前の前に円記号(\)を付けます。デフォルトで は、EAServer は最新版のコンポーネントを使用します。 • EAServer 6.0 以降に配布する場合、Jaguar コンパイラ コマンドライ ン ツールを呼び出し、コンポーネントを EJB としてラップします。 この処理では、PB CORBA パッケージ MyPackage 全体を EJB モ ジュール mypackage.jar にマッピングし、この EJB-JAR を同じパッ ケージ名で配布します。 配布によって、Ant XML 設定スクリプトも生成されます。このス クリプトを使って、EAServer config フォルダ内にある配布済の EJB-JAR コンポーネントの実行時設定を変更できます。 • EAServer 5.x に配布する場合、EAServer コンポーネントのプロパ ティを記述する PROPS ファイルを生成します。 PROPS フ ァ イ ル は、EAServer イ ン ス ト ー ル デ ィ レ ク ト リ の Repository\Component\package-name サブディレクトリ内に格納さ れています。 EAServer リポジトリ の後処理 EAServer 6.0 以降では、EAServer Web コンソールを使用して、古いバー ジョンの PowerBuilder コンポーネントのクリーンアップを定期的なス ケジュール タスク(CleanupPBCookies)として実行するように設定で きます。以前のバージョンの EAServer の場合、以下の手順で不要な ディレクトリを削除し、ディスク スペースの再割り当てを行えます。 アプリケーション テクニック 517 EAServer へのコンポーネントの配布 v 不要なディレクトリと PBD ファイルを削除するには 1 最新のディレクトリ以外のディレクトリをすべて削除します。 2 残りのディレクトリの名前を C1 に変更します。 3 4 コンポーネントのコー ド セットの変更 EAServer Manager のコンポーネントのプロパティ シートにある [Advanced]タブ ページ、または Management Console の[Advanced] タブ ページで、pb.cookie プロパティの値を 1 に設定します。 EAServer を再起動します。 PowerBuilder によって配布された EAServer コンポーネントは、自動的 にサーバのコード セットを使用します。コンポーネントに別のコー ド セットを使用させたい場合は、コンポーネントの com.sybase.jaguar.component.code.set プロパティに適切な値を設定しま す。 このプロパティを設定する場合、EAServer Manager では、[Advanced] タブ ページのコンポーネント プロパティ ダイアログボックスを使用 します。com.sybase.jaguar.component.code.set プロパティを追加して、 big5 や iso_1 などの適切な値を指定します。Management Console では、 [General]ページの[Code Set]ドロップダウン リストから値を選択し ます。 EAServer が utf-8 コード セットを使用して起動され、コンポーネント でユーロまたは英国ポンドの記号、あるいはその両方を含んでいる文 字列を返す場合は、code.set プロパティに cp1252 を設定します。 518 PowerBuilder 第 2 4 章 EAServer クライアントの構築 この章について この章では、EAServer コンポーネントにアクセスする PowerBuilder クライアントの作成方法について説明します。セキュリティで保 護された接続については、第 25 章「PowerBuilder クライアントで の SSL の使い方」を参照してください。 内容 項目 EAServer クライアントの構築について EAServer への接続 EAServer プロキシ オブジェクトの生成 コンポーネント メソッドの呼び出し JaguarORB オブジェクトの使用 クライアントとコンポーネントを区別するトランザクション サーバ メッセージ返送の要求 エラー処理 クライアント アプリケーションの配布 ページ 519 521 524 526 533 538 541 546 551 EAServer クライアントの構築について PowerBuilder アプリケーションは、EAServer コンポーネントのク ライアントの役割を果たします。サーバ上のコンポーネントに関 連付けられたメソッドにアクセスするには、PowerBuilder クライ アントは、サーバに接続し、コンポーネントをインスタンス化し、 コンポーネント メソッドを呼び出す必要があります。 EAServer への接続には、接続オブジェクトのインスタンスを使用 するのが一般的ですが、CORBA 互換クライアントを作成する場合 には、JaguarORB オブジェクトを使用してサーバへの接続を確立 することも可能です。 JaguarORB オブジェクトを使うと、 PowerBuilder クライアントは、C++ クライアントと同じ方法で EAServer にアク セスできます。 アプリケーション テクニック 519 EAServer クライアントの構築について この章で説明する技法を使えば、EAServer で実行する EJB コンポーネ ントのクライアントを構築できます。EAServer やほかの J2EE 準拠の サーバで EJB コンポーネントのクライアントを構築する方法について は、第 28 章「EJB クライアントの構築」を参照してください。 ウィザードの使い方について PowerBuilder には、EAServer クライアントの開発に役立つ 2 つのウィ ザードがあります。 • 接続オブジェクト ウィザード サーバへの接続に必要なコードを追 加する • クライアントからアクセスする EAServer コンポーネントのプロキシ オブジェクトを構築するため のプロジェクトの作成に役立つ EAServer プロキシ ウィザード 開発プロセスについて EAServer クライアン トの構築手順 EAServer クライアントを構築して配布するには、以下の手順をすべて 実行する必要があります。 1 EAServer 接続オブジェクト ウィザードを使用して、Connection オ ブジェクトから継承した標準クラスのユーザ オブジェクトを作成 します。その後で、このオブジェクトを、接続を確立するために スクリプトの中で使用できます。 テンプレート アプリケーション ウィザードを使用してクライア ント アプリケーションを作成した場合は、そのウィザードで接続 オブジェクトを作成できます。 520 2 EAServer プロキシ ウィザードを使用して、プロキシ オブジェクト を作成するためのプロジェクト作成します。続いてプロキシ オブ ジェクトを生成します。 3 ユーザ インタフェースの実装に必要なウィンドウ、メニュー、お よびスクリプトを作成します。 4 EAServer コンポーネント インスタンスの作成と、クライアントか ら 1 つまたは複数のコンポーネント メソッドの呼び出しを行うた めに必要なコードを記述します。 5 クライアントのテストとデバッグを行います。 PowerBuilder 第 24 章 6 EAServer クライアントの構築 アプリケーションを配布します。 EAServer への接続 接続オブジェクトの使 用 EAServer に接続するには、接続オブジェクト(サーバとの通信を処理 する非ビジュアル オブジェクト)の機能を利用するのがもっとも簡単 な方法です。サーバに接続するには、接続のためのコードをすべて手 動で記述するか、接続オブジェクト ウィザードを使用して接続を開始 します。 コードを手書きする方法 connection 変数の宣 言 接続オブジェクトは組み込みのグローバル オブジェクトではありま せん。connection 型を指定して、グローバル変数またはインスタンス変 数を宣言する必要があります。 接続の確立 サーバへの接続を確立するには、以下の操作を実行するために必要な PowerScript 文を実行する必要があります。 1 Create 文を使用して、接続オブジェクトをインスタンス化します。 2 接続オブジェクトのプロパティを設定します。 3 ConnectToServer 関数を呼び出して、サーバへの接続を確立します。 4 エラーの有無をチェックします。 これらの操作は、1 つのスクリプトまたは複数のスクリプトで実行で きますが、上記の順に行う必要があります。 次のスクリプトでは、myconnect 接続オブジェクトをインスタンス 化し、EAServer の通信ドライバ、サーバのホスト名とポート番号、お よびデフォルト パッケージを識別するための接続プロパティを設定 します。続いて、このスクリプトは ConnectToServer 関数を呼び出して サーバへの接続を確立し、エラーをチェックします。 例 // グローバル変数 : // connection myconnect long ll_rc myconnect = create connection myconnect.driver = "jaguar" myconnect.location = "Jagserver1:2000" myconnect.application = "PB_pkg_1" アプリケーション テクニック 521 EAServer への接続 myconnect.userID = "bjones" myconnect.password = "mypass" ll_rc = myconnect.ConnectToServer() IF ll_rc <> 0 THEN MessageBox(" 接続失敗 ", ll_rc) END IF 接続オブジェクト プ ロパティの設定 表 24-1 に EAServer と通信する際の、接続オブジェクト プロパティを 設定するためのガイドラインを示します。 表 24-1: EAServer の接続オブジェクト プロパティ プロパティ名 Application Driver Location 説明 例 "PB_pkg_1" EAServer コンポーネントに 使用するデフォルト パッ ケージ "jaguar" EAServer ドライバの名前 "localserver:2000" サーバのホスト名とポート 番号をコロンで区切ったも "iiop://srv1:2000" の "iiops://srv3:2001" Location プロパティには、 "http://srv5:8000" 以下のいずれかの書式を使 用する。絶対パス URL も指 "iiop://s1:2000;iiop://s2:2000" 定できる iiop://host:port iiops://host:port http://host:port https://host:port Password UserID Options 複数の接続を確立 522 EAserver の負荷分散とフェ イルオーバのサポートを利 用する際、サーバの位置をセ ミコロンで区切ってリスト 形式で指定することも可能 "mypass" EAServer のパスワード "bjones" EAServer のユーザ ID 1 つまたは複数の EAServer "ORBLogFile='jaglog.log'" ORB プロパティ設定 PowerBuilder では、複数の接続オブジェクトをインスタンス化できま す。したがって、1 つのクライアント アプリケーションで複数の接続 を確立できます。たとえば、2 つの別個の接続オブジェクトをインス タンス化して、2 台の別々のサーバ にクライアントを接続することも 可能です。 PowerBuilder 第 24 章 EAServer クライアントの構築 設定オプション 接続オブジェクトまたは JaguarORB オブジェクトのいずれかを使用し て EAServer に接続するときは、EAServer クライアント ORB を使用す ることになります。そのプロパティは、接続オブジェクトの Options 文 字列に設定するか、JaguarORB の Init 関数を使用して設定できます。 使用するコード セッ トの変更 PowerBuilder 9.x 以前のバージョンでは、2 バイト文字を扱う EAServer コンポーネントに接続する際には、コンポーネントが適切なコード セットを設定する必要がありました。 myConnection.Options = "ORBCodeSet='eucksc'" PowerBuilder 10 以降では、UNICODE で処理を行なっているために ORBCodeSet の設定をする必要がなくなりました。以前のバージョン から、ORBCodeSet を使用しているアプリケーションを移行する場合 は、ORBCodeSet パラメータを削除する必要があります。 接続のトラブルシュー ティング 接続が失敗した場合、ORBLogIIOP オプションをオンにし、ORBLogFile オプションの値を指定して、失敗に関する詳細をログ ファイルに記録 できます。設定するオプションが複数ある場合は、それらのオプショ ンを同一の文中に設定しなければなりません。オプションは、次のよ うにカンマで区切ります。 myConnection.Options = & "ORBLogIIOP='TRUE', ORBLogFile='d:\temp\ORBLog.txt'" 全オプションの一覧については、接続オブジェクトに関するオンライ ン ヘルプまたは EAServer のマニュアルを参照してください。 ウィザードを使用した接続オブジェクトの作成 接続オブジェクト ウィザードで、接続タイプとして EAServer を選択 した場合には、接続オブジェクトから継承された標準クラスのユーザ オブジェクトが作成されます。ウィザードで接続オブジェクト プロパ ティを指定し、接続情報の提供元としてレジストリ、INI ファイル、ま たはスクリプトを指定します。接続オブジェクト ウィザードは、開発 者がセットアップした EAServer プロファイルから、接続先のサーバに 関する情報を取得します。EAServer プロファイルの作成方法について は、455 ページの「アプリケーション サーバ プロファイルの作成」を 参照してください。 接続オブジェクトの Constructor イベントは、of_getconnectioninfo 関数を 呼び出して、指定したソースから格納済みの接続情報を取得します。 アプリケーション テクニック 523 EAServer プロキシ オブジェクトの生成 接続オブジェクト ウィザードを使用して接続オブジェクトを作成し たら、以下の操作の実行に必要な PowerScript 文を実行する必要があり ます。 1 Create 文を使用して、接続オブジェクトをインスタンス化します。 2 ConnectToServer 関数を呼び出して、サーバへの接続を確立します。 3 エラーをチェックします(省略可)。 接続オブジェクトのプロパティは設定不要ですが、それらのプロパ ティは of_getconnctioninfo 関数で修正できます。接続オブジェクトのオ プションを constructor イベントで設定することも可能です。たとえば、 次のようにします。 this.options = "ORBHttp='TRUE'" 例 次のスクリプトでは、ウィザードで作成された n_myclient_connect オブジェクトの myconnect インスタンスをインスタンス化し、 ConnectToServer 関数を呼び出してサーバへの接続を確立し、エラーを チェックします。 long ll_rc myconnect = create n_myclient_connect ll_rc = myconnect.ConnectToServer() IF ll_rc <> 0 THEN MessageBox(" 接続失敗 ", ll_rc) END IF 複数の接続を確立 1 つのクライアント アプリケーションで複数の接続を確立できます。2 台の別々のサーバにクライアント接続したい場合には、もう一度接続 オブジェクト ウィザードを実行して、別々の接続プロパティを持つ新 規ユーザ オブジェクトを作成します。 EAServer プロキシ オブジェクトの生成 EAServer プロキシ オ ブジェクトについて 524 各 EAServer コンポーネントには、クライアント アプリケーション内 に対応するプロキシ オブジェクトがあります。EAServer コンポーネン トにアクセスするには、EAServer プロキシを通じて通信する必要があ ります。 PowerBuilder 第 24 章 EAServer クライアントの構築 EAServer 6.0 以降では、CORBA コンポーネント(PowerBuilder が生成 したコンポーネントを含む)を EJB としてラップします。クライア ント アプリケーションには、EJB コンポーネントに対応する 2 つのプ ロキシ オブジェクト(ホーム インタフェース用とリモート インタ フェース用)があります。たとえば、Cart という名前の EJB コンポー ネントは、CartHome と Cart という 2 つのプロキシを生成します。EJB コンポーネントにアクセスするには、これら 2 つのプロキシを介して 通信する必要があります。 EAServer クライアントのプロキシ オブジェクトは、新規プロジェクト を作成してから生成する必要があります。新規プロジェクトでは、組 み込まれるオブジェクトの一覧を表示し、生成されたプロキシ オブ ジェクトを格納する出力ライブラリの名前を指定します。 EAServer プロキシ ウィザードの使い方 EAServer プロキシ ウィザードは、EAServer プロキシ オブジェクトを 作成するためのプロジェクトの作成に役立ちます。このウィザードを 使うと、EAServer サーバに接続して、クライアントからアクセスでき るようにしたいコンポーネントを選択できます。プロジェクトを作成 したら、続いてプロジェクト ペインタを使用してプロジェクト設定を 修正し、プロキシ ライブラリを作成できます。 EJB クライアントの構築 EAServer やほかの J2EE 準拠のサーバで EJB コンポーネントのサービ スを利用できる EJB クライアントを構築するには、EJB クライアント プロキシ ウィザードを使います。詳細については、第 28 章「EJB ク ライアントの構築」を参照してください。 メソッド名の予約語 PowerBuilder で作成されなかった EAServer コンポーネント用にプロキ シを生成すると、PowerBuilder の予約語を使用するメソッドの名前が 変更されます。プロキシ ジェネレータは、これらのメソッド名の先頭 にアンダースコア(_)を自動的に追加します。たとえば、コンポーネ ントに destroy という名前のメソッドがある場合、プロキシのメソッド は _destroy になります。 TO 句の配列の使い方 CORBA IDL では TO 句がサポートされていないため、TO 句を使用す る配列を含む PowerBuilder コンポーネントのプロキシを生成する場 合、プロキシ オブジェクトは範囲を単一値として表します。たとえば、 Int ar1[5 TO 10] は Int ar1[6] と表します。この [6] は、配列の要 素数を表しています。クライアント アプリケーションは、範囲ではな く単一値を使用して配列を宣言しなければなりません。 アプリケーション テクニック 525 コンポーネント メソッドの呼び出し モジュール名の付加 コンポーネントを定義する IDL モジュールの名前を、作成したプロキ シ オブジェクトの名前の前に付加しておくと、名前が類似するプロキ シ オブジェクトどうしを容易に判別できます。たとえば、CTSSecurity モジュールの SessionInfo コンポーネントを選択して、ウィザードかプ ロジェクト ペインタの[EAServer パッケージ名をオブジェクト名の前 に 追 加]オ プ シ ョ ン を オ ン に す る と、プ ロ キ シ オ ブ ジ ェ ク ト が ctssecrity_sessioninfo という名前になります。一部の EAServer シ ステム モジュール(現在のところ、CtsComponents と XDT)では、名 前の二重定義を避ける目的から、常にモジュール名がオブジェクトに 付加されます。 パッケージ名と IDL モジュールの名前は普通は同じですが、異なって いてもかまいません。いずれの場合にも、前に付加されるのは IDL モ ジュールの名前です。 例外の除外 EAServer コンポーネントのなかには、クライアント アプリケーション で処理できる例外を送出するものが数多くあります。例外を処理しな い既存のクライアント アプリケーションでプロキシを生成して使用 したい場合、または構築しているクライアント内で例外を宣言したく ない場合は、ウィザードかプロジェクト ペインタで、生成されたプロ キシから例外を除外できます。クライアントでのエラー処理について の詳細は、546 ページの「エラー処理」を参照してください。 データ型マッピング EAServer コンポーネント インタフェースはすべて、標準の CORBA IDL で定義されます。EAServer で使用されるデータ型、各データ型の対応 する CORBA IDL、および各データ型がマッピングされる PowerBuilder のデータ型のリストについては、 『PowerScript リファレンス』マニュ アルまたはオンライン ヘルプを参照してください。 コンポーネント メソッドの呼び出し EAServer への接続が確立され、プロキシ オブジェクトかオブジェクト が作成された後ではじめて、クライアント アプリケーションはサーバ コンポーネントを使用できます。 コンポーネント メソッドの呼び出し ほとんどのコンポーネント タイプでメソッドを呼び出す際は、以下の 操作を行うのに必要な PowerScript 文を実行する必要があります。 526 PowerBuilder 第 24 章 1 EAServer クライアントの構築 CreateInstance メソッドを使用して、コンポーネントのインスタンス を作成する 2 メソッドを呼び出す EJB コンポーネント メソッドは、別の方法で呼び出します。528 ペー ジの「EJB コンポーネント メソッドの呼び出し」を参照してください。 例 1 次のスクリプトでは、サーバ上のコンポーネントをインスタンス 化し、コンポーネント メソッドを呼び出します。この例では、パッ ケージを CreateInstance メソッドに指定していません。したがって、 EAServer は、接続オブジェクトの Application プロパティに指定されて いるデフォルト パッケージを使用します。 // グローバル変数 : // connection myconnect uo_customer iuo_customer string ls_custid long ll_rc ls_custid = Trim(sle_custid.text) ll_rc = myconnect.CreateInstance(iuo_customer) if ll_rc <> 0 then MessageBox("CreateInstance 失敗 ", ll_rc) return 999 end if if iuo_customer.retrieve_balance(ls_custid) != 1 then MessageBox(" エラー ", " 検索失敗 !") end if 例 2 次のスクリプトでは、サーバ上のコンポーネントをインスタンス 化して、データ型がコンポーネントのクラスの先祖である変数に、オ ブジェクト参照を割り当てます。CreateInstance 関数の第 2 引数には、 コンポーネントのクラス名に加えて、EAServer パッケージ名も指定し ます。 // グローバル変数 : // connection myconnect uo_person lnv_object string ls_custid long ll_rc ls_custid = Trim(sle_custid.text) ll_rc = myconnect.CreateInstance(lnv_object, & "PB_pkg_1/uo_customer") if ll_rc <> 0 then アプリケーション テクニック 527 コンポーネント メソッドの呼び出し MessageBox("CreateInstance 失敗 ", ll_rc) return 999 end if if iuo_customer.retrieve_balance(ls_custid) != 1 then MessageBox(" エラー ", " 検索失敗 !") end if ローカル インスタンスの呼び出し デフォルトでは、 TransactionServer の CreateInstance メソッドは EAServer のネーム サービスを呼び出してプロキシを作成します。リモート コン ポーネントのプロキシは、ローカルで実行されているインスタンスで はなくネーム サービスから返される場合があります。ローカルのイン スタンスが使用されるようにするには、コンポーネント名として 「local:package/component」を指定します。package はパッケージ名、 component はコンポーネント名です。コンポーネントが同じサーバにイ ンストールされていない場合、呼び出しはエラーになります。 EJB コンポーネント メソッドの呼び出し EJB コンポーネント メソッドを呼び出すには、以下の操作を行うのに 必要な PowerScript 文を実行する必要があります。 1 Lookup 関数を使用して、コンポーネントのホーム インタフェース にアクセスする 2 インタフェースでメソッドを呼び出し、コンポーネントのインス タンスの作成か検索を実行して、コンポーネントのリモート イン タフェースへの参照を取得する 3 リモート インタフェースでビジネス メソッドを呼び出す EJBConnection メソッドに適用されないこと 本節の内容は、EAServer プロキシ オブジェクトと PowerScript 関数を 使用するクライアント アプリケーションに適用されます。EJB クライ アント プロキシと EJBConnection メソッドを使用するクライアント ア プリケーションで EJB メソッドを呼び出す方法については、第 28 章 「EJB クライアントの構築」を参照してください。 528 PowerBuilder 第 24 章 ホーム インタフェー ス名の指定 EAServer クライアントの構築 PowerBuilder の Lookup 関数には第 3 引数(省略可能)が用意されてい て、この引数にホーム インタフェース名を指定できます。EAServer で は、EJB コンポーネントに com.sybase.jaguar.component.home.ids という プロパティが設定されます。home.ids プロパティが次のような形式で あれば、Lookup 関数に第 3 引数を指定する必要はありません。 IDL:PackageName/ComponentNameHome:1.0 例 IDL:vacation/TripFinderHome:1.0 ただし多くの場合は home.ids プロパティに java パッケージの命名ス キーマを使うため、開発者は EJB インタフェースが確実に見つけられ るように、第 3 引数を使用しなければなりません。この引数には、先 頭の IDL: と末尾の :1.0 を除いて、コンポーネントの com.sybase.jaguar.component.home.ids プロパティと一致している文字列 を指定する必要があります。 たとえば、次のような home.ids プロパティがあるとします。 IDL:com/myproj/myejbs/TripFindHome:1.0 この場合、Lookup 関数呼び出しは次のようになります。 myconn.lookup(myTripFindHome,"MyEJBs/TripFindHome", & "com/myproj/myejbs/TripFinderHome") あるいは、ドット表記で指定するホーム インタフェースの完全修飾 Java クラス名を使用することもできます。たとえば、次のようになり ます。 ts.lookup(MyCartHome, "MyEJBs/TripFindHome", & "com.myproj.myejbs.TripFinderHome") Lookup の大文字と小文字の区別 EAServer の Lookup では大文字と小文字が区別されます。Lookup 関数の 引数に指定する文字列の大文字と小文字は、home.ids プロパティの大 文字と小文字に一致させる必要があります。 EJB のインスタンス の作成や検索 EAServer では、3 種類の EJB(セッション Bean、エンティティ Bean、 およびメッセージ駆動型 Bean)をサポートしています。 セッション Bean は、クライアントのリクエストに応答して作成されま す。クライアントは、通常の場合、そのクライアント セッションの持 続中はセッション Bean を排他的に使用します。 アプリケーション テクニック 529 コンポーネント メソッドの呼び出し エンティティ Bean は、データベースに保存される永続情報を表しま す。クライアントは、ほかのクライアントと同時にエンティティ Bean を使用します。エンティティ Bean はクライアントの有効期間が終了し ても持続するため、エンティティ Bean がすでに作成されている場合 は、主キーのクラス名を使用して、既存のコンポーネントの識別や検 索を行う必要があります。 メッセージ駆動型 Bean はステートレス セッション Bean に似ています が、JMS メッセージのみに応答し、直接のクライアント インタフェー スは備えていません。 次の例では、E コマースのショッピング カート機能を提供する EJB コ ンポーネントが EAServer 上で実行されていることを想定しています。 このコンポーネントは Cart と呼ばれ、Shopping というパッケージに含 まれています。 例 1 このスクリプトは、Cart コンポーネントをインスタンス化し、い くつかのコンポーネント メソッドを呼び出します。次の例では、Lookup メソッドの第 2 引数に、コンポーネント名と EAServer パッケージ名を 指定しています。 // インスタンス変数: //Connection myconnect CartHome MyCartHome // EJB のホーム インタフェース Cart MyShoppingCart // EJB のリモート インタフェース long ll_result // ホーム インタフェースを取得 ll_result = & myconnect.Lookup(MyCartHome, "Shopping/Cart", & "com.sybase.shopping.Cart") // Cart コンポーネントのビジネス ロジックへの参照を取得 TRY MyShoppingCart = MyCartHome.Create() CATCH (ctscomponents_createexception ce) MessageBox(" 例外を作成 ", ce.getmessage()) // 例外を処理 END TRY // ショッピング カートを使用 MyShoppingCart.AddItem(66) MyShoppingCart.Purchase() 530 PowerBuilder 第 24 章 EAServer クライアントの構築 CartEJB コンポーネントがエンティティ Bean として定義されて いる場合は、スクリプトは findByPrimaryKey メソッドを使用して、既存 のコンポーネントか永続コンポーネントを検索し参照しなければなり ません。 例2 // インスタンス変数: //Connection myconnect CartHome MyCartHome // EJB のホーム インタフェース Cart MyCart // EJB のリモート インタフェース long ll_result // ホーム インタフェースを取得 ll_result = & myconnect.Lookup(MyCartHome, "Shopping/Cart", & "com.sybase.shopping.Cart") // 前のセッションからの Cart への参照を取得 TRY MyCart = MyCartHome.findByPrimaryKey("MYkey") CATCH ( ctscomponents_finderexception fe ) MessageBox(" 検索例外 ", & fe.getmessage()) // 例外を処理 END TRY // ショッピング カートを使用 MyCart.AddItem(66) MyCart.Purchase() 制約 EJB オブジェクトに対して PowerBuilder クライアントは CORBA クラ イアントの役割を果たします。つまり、PowerBuilder クライアントに は Java クライアントの全機能はありません。Java クライアントは、 javax.ejb.EJBObject インタフェースから継承したメソッドを使用でき ます。 たとえば、Java クライアントはリモート インタフェース インスタンス のハンドルを取得できます。ハンドルは、クライアントと Bean の間の セッション状態を示すバイナリ エンコーディングです。クライアント はハンドルを取得し、それをディスクに保存するか別の場所に送信し、 後でセッションを再び確立できます。PowerBuilder クライアントが同 等の機能を得るには、JaguarORB オブジェクトの Object_To_String 関数 と String_To_Object 関数を使用する必要があります。 アプリケーション テクニック 531 コンポーネント メソッドの呼び出し 例外の処理 EJB コンポーネントのリモート インタフェースに、エラーか警告が示 される場合があります。EJB コンポーネントから送出された標準例外 は、CORBA システム例外にマッピングされます。また EJB コンポー ネントが、ユーザ定義の例外を送出する場合もあります。EAServer コ ンポーネントから送出された例外の処理については、546 ページの「エ ラー処理」を参照してください。 EAServer 内の PowerBuilder コンポーネントからの EJB コンポーネント の呼び出しについては、496 ページの「EJB コンポーネントへのアク セス」を参照してください。 インスタンスの破棄 プロキシ オブジェク トのインスタンスの破 棄 EAServer コンポーネントを使い終わったら、DESTROY 文を使用して EAServer プロキシ オブジェクトを明示的に破棄するか、PowerBuilder のガベージ コレクション機能を利用してオブジェクトを自動的にメ モリから消去できます。いずれの場合でも、クライアントサイド プロ キシ オブジェクトの破棄は、サーバ コンポーネントの有効期間に影響 を与えません。サーバ コンポーネントの破棄は、EAServer によって処 理されます。 コンポーネントのイン スタンスの非アクティ ブ化 コンポーネントの自動的なデマケーション / 不活性化設定が無効であ り、しかもコンポーネントがまだクライアントにバインドされている間に クライアント アプリケーションを閉じた(コンポーネントが SetComplete も SetAbort も呼び出さなかった)場合には、コンポーネントは非アク ティブにされません。コンポーネントのインスタンスを非アクティブ にするには、次のいずれかの操作を行います。 532 • クライアント アプリケーションの Close イベントで、 (SetComplete か SetAbort を呼び出して)コンポーネントを非アクティブにする サーバ コンポーネントのメソッドを呼び出します。 • コンポーネントの Timeout プロパティを 0 に設定してしまうと、コ ンポーネントがタイムアウトしなくなるので、0 以外の値に設定し ます。 PowerBuilder 第 24 章 EAServer クライアントの構築 JaguarORB オブジェクトの使用 CORBA 互換クライアントを作成するには、接続オブジェクトのかわ りに JaguarORB オブジェクトを使用して、サーバへの接続を確立しま す。JaguarORB オブジェクトを使用すると、C++ クライアントと同じ 方法で PowerBuilder クライアントから EAServer へアクセスすること ができます。 2 つの方法 JaguarORB オブジェクトは、String_To_Object 関数と Resolve_Initial_References 関数を使用する 2 つの方法でコンポーネント インタフェースにアクセスできます。 String_To_Object 関数の使用は、接続オブジェクトでの ConnectToServer 関 数 と CreateInstance 関 数 の 内 部 的 な 動 作 と 同 じ 動 作 を し ま す。 String_To_Object 関数では、コンポーネントをホストするサーバへの接 続方法を記述する文字列引数を渡すことで、プロキシのインスタンス をインスタンス化できます。この方法の不利な点は、ネーミング サー ビス API を明示的に使用することによって提供されるサーバ アドレ ス抽象化を活用できないことです。 EAServer ネーミング サービス API を使用する場合は、 Resolve_Initial_References 関数を使用して初期状態のネーミング コンテ キストを取得できます。ただし、この方法は廃止予定の SessionManager::Factory create メソッドを使用する必要があるため、こ の方法はお勧めしません。ほとんどの PowerBuilder クライアントは、 CORBA ネーミング サービスを明示的に使用する必要はありません。 かわりに、接続オブジェクトの CreateInstance 関数と Lookup 関数を使 用して EAServer コンポーネントのインスタンスを作成するときに自 動的に実行される名前解決に頼ることができます。 ネーミング サービス について EAServer ネーミング サービスは、CORBA CosNaming コンポーネント (オブジェクトのバインドと参照のサポートを提供するインタフェー スのコレクション)の実装です。CosNaming モジュールについての詳 細は、EAServer インタフェース リポジトリのマニュアルを参照して ください。インタフェース リポジトリのマニュアルは、URL http://yourhost:yourport/ir/ のサーバに接続すれば、Web ブラウザで参照 できます。ここで、yourhost はサーバのホスト名、yourport は HTTP ポート番号です。 アプリケーション テクニック 533 JaguarORB オブジェクトの使用 String_To_Object を使用したインスタンス化 SessionManage イン タフェースのプロキシ の取得 CORBA ネーミング サービスを明示的に使用せずにプロキシをインスタ ンス化するには、SessionManager モジュールに定義されているインタ フェースと一緒に、JaguarORB オブジェクトの String_To_Object 関数を 使用します。Manager、Session、および Factory インタフェースを使用す るには、事前に、EAServer プロキシ ウィザードを使用して SessionManager モジュールのプロキシ ライブラリ プロジェクトを作成し、プロジェク トを構築して、生成されたプロキシ ライブラリをクライアント ター ゲットのライブラリ リストに含めておく必要があります。 サーバの識別 サーバと対話するには、SessionManager::Manager インタフェースを使 用します。サーバは、Interoperable Object Reference(IOR)か URL を 使うと識別できます。IOR 文字列は、サーバのホスト アドレスと、サー バが IIOP リクエストを受け取るポートをエンコードします。サーバは 起動のたびに、標準エンコーディングで 16 進にエンコードされた IOR 文字列を、接続受け付けごとに 2 つのファイルに書き込みます。1 つ のファイルには IOR 文字列そのものが格納され、もう 1 つのファイル には IOR が、APPLET タグに挿入可能な HTML PARAM 定義の一部と して格納されます。ファイルは、EAServer ディレクトリの HTML サブ ディレクトリに常駐しています。これらのファイルのいずれかから IOR 文字列を取得するように、クライアントのコードを記述できます。 認証済みセッションの 作成 ORB を初期化してサーバの IOR か URL を取得した後で、String_To_Object 関数で文字列を CORBA オブジェクト参照に変換し、それを _Narrow 関 数で Manager インタフェースへの参照に変換できます。その後で、Manager インタフェースの createSession メソッドを使用して、クライアント ア プリケーションとサーバの間で認証されたセッションを作成します。 コンポーネントのイン タフェースへの参照の 作成 セッションの lookup メソッドを使用して、呼び出したいコンポーネン トへのプロキシ オブジェクト参照のファクトリを返します。次に、 Factory オブジェクトの create メソッドを呼び出して、コンポーネント のプロキシを取得します。create メソッドで CORBA オブジェクト参照 が返されたら、_Narrow 関数を使用して、それをコンポーネントのイン タフェースへの参照に変換できます。 コンポーネントのデフォルト名はパッケージ名とコンポーネント名で 構成され、calculator/calc のようにスラッシュで区切られています。た だし、コンポーネントの com.sybase.jaguar.component.naming プロパ ティで別の名前を指定することも可能です。たとえば、 USA/MyCompany/FinanceServer/Payroll などの論理名を指定できます。 ネーミング サービスの環境設定の詳細については、EAServer のマ ニュアルを参照してください。 534 PowerBuilder 第 24 章 例 EAServer クライアントの構築 次の例では、String_To_Object 関数の第 1 引数に、クラスタ内の 2 つの サーバの URL が含まれています。 // PowerBuilder オブジェクト JaguarORB my_JaguarORB CORBAObject my_corbaobj n_bank_acct my_acct // プロキシ オブジェクト Manager my_manager Session my_session Factory my_factory long ll_return my_JaguarORB = CREATE JaguarORB //ORB を初期化 ll_return = my_JaguarORB.init("ORBRetryCount=3, ORBRetryDelay=1000") //URL 文字列をオブジェクト参照に変換 ll_return = my_JaguarORB.String_To_Object (''iiop://JagOne:2000;iiop://JagTwo:2000'', my_corbaobj) //Manager インタフェースへのオブジェクト参照を制限 ll_return = my_corbaobj._narrow(my_manager, "SessionManager/Manager") // セッション オブジェクト参照を作成 my_session = my_manager.createSession("admin", "") // リモート インタフェースへの // プロキシ オブジェクト参照の Factory を作成 my_corbaobj = my_session.lookup("Bank/n_bank_acct ") my_corbaobj._narrow(my_Factory, "SessionManager/Factory") // プロキシを取得し、それをリモート インタフェースに // 制限してメソッドを呼び出す my_corbaobj = my_Factory.create() my_corbaobj._narrow(my_acct, "Bank/n_bank_acct") my_acct.withdraw(1000.0) この例では、コンポーネントは EJB コンポーネントです。ホーム イン タフェースは、CORBA コンポーネントに対してファクトリ インタ フェースが行うのと同じ役割を、EJB に対して効果的に実行します。 アプリケーション テクニック 535 JaguarORB オブジェクトの使用 JaguarORB my_orb CORBAObject my_corbaobj Manager my_mgr Session my_session CartHome my_cartHome Cart my_cart my_orb = CREATE JaguarORB my_orb.init("ORBLogFile='c:\temp\orblog'") my_orb.String_to_Object("iiop://svr1:2000", & my_corbaObj) my_corbaObj._narrow(my_mgr, "SessionManager/Manager" ) my_Session = my_mgr.createSession("admin", "") my_corbaObj = my_session.lookup("Cart") my_corbaObj._narrow(my_CartHome, "shopping/CartHome") my_corbaObj = my_CartHome.create() my_Cart.addItem() 接続オブジェクトの使用 接続オブジェクトの Lookup 関数を使用して、EJB コンポーネントの ホーム インタフェースへの参照を取得できます。528 ページの「EJB コンポーネント メソッドの呼び出し」を参照してください。 ネーミング サービス API によるインスタンス化 CosNaming インタ フェースと SessionManage イン タフェースのプロキシ の取得 CORBA ネーミング サービス API を使用してプロキシをインスタンス 化するには、ネーミング サービス インタフェースのプロキシを生成し て、生成したプロキシをクライアントのライブラリ リストに含める必 要があります。EAServer プロキシ ウィザードを使用して CosNaming モ ジュールのプロキシ プロジェクトを作成し、プロキシ ライブラリを作 成するためのプロジェクトを作成して、プロキシ ライブラリをクライ アント ターゲットのライブラリ リストに追加します。SessionManager モジュールにもプロキシが必要です。 初期状態のネーミング コンテキストの取得 ORB の初期化後、Resolve_Initial_References 関数を呼び出して初期状態 のネーミング コンテキストを取得し、_Narrow を使用してそれを CORBA ネーミング コンテキスト インタフェースへの参照に変換します。次の 例に示すように、クラス名に omg.orb を含めて、CosNaming パッケー ジを識別しなければなりません。 536 PowerBuilder 第 24 章 EAServer クライアントの構築 ネーミング コンテキ ストの解決 ネーミング コンテキストを解決してコンポーネントの Factory オブ ジ ェ ク ト へ の 参 照 を 取 得 し、そ の 後 で そ の イ ン タ フ ェ ー ス を SessionManager::Factory インタフェースへの参照に制限する必要があ ります。resolve メソッドは、一連の NameComponent 構造体である名前 パラメータを取ります。各 NameComponent 構造体には、コンポーネン トを識別する id 属性と、コンポーネントの記述に使用できる kind 属性 があります。次の例では、名前には 1 つのコンポーネントしかありま せん。 コンポーネントのイン タフェースへの参照の 作成 Factory オブジェクトの create メソッドを呼び出して、コンポーネント のプロキシを取得します。create メソッドで CORBA オブジェクト参照 が返されたら、_Narrow 関数を使用して、それをコンポーネントのイン タフェースへの参照に変換できます。 例 次の例で使用されている NamingContext 型と NameComponent 型は、 EAServer の CosNaming パッケージからインポートされたプロキシで、 Factory 型は SessionManager パッケージからインポートされます。 CORBAObject my_corbaobj JaguarORB my_orb NamingContext my_nc NameComponent the_name[] Factory my_Factory n_jagcomp my_jagcomp my_orb = CREATE JaguarORB // URL の名前は単一引用符で囲む my_orb.init("ORBNameServiceURL='iiop://server1:2000'") my_orb.Resolve_Initial_References("NameService", & my_corbaobj) my_corbaobj._narrow(my_nc, & "omg.org/CosNaming/NamingContext") the_name[1].id = "mypackage/n_jagcomp" the_name[1].kind = "" my_corbaobj = my_nc.resolve(the_name) my_corbaobj._narrow(my_Factory, & "SessionManager/Factory") my_corbaobj = my_Factory.create("admin","") my_corbaobj._narrow(my_jagcomp, "mypackage/n_jagcomp") my_jagcomp.getdata() アプリケーション テクニック 537 クライアントとコンポーネントを区別するトランザクション クライアントとコンポーネントを区別するトランザクション クライアント アプリケーションおよび[OTS スタイル]または [Bean Managed]としてマークされた EAServer コンポーネントは、 CORBACurrent コンテキスト サービス オブジェクトの関数を使用し て、EAServer トランザクションに関する情報の作成、制御、および取 得が行えます。CORBACurrent オブジェクトは、CORBACurrent イン タフェース用に定義された数多くのメソッドを備えています。 2 フェーズ コミット クライアントまたはコンポーネントをマークしたトランザクションの コンポーネントは、OTS/XA トランザクション コーディネータを使用 するサーバ上で実行されていなければなりません。このトランザク ション コーディネータは、システム障害から保護するため、すべての 参加者からの詳細レコードを使用する、2 フェーズ コミット プロトコ ルをサポートします。準備フェーズでは、トランザクション コーディ ネータがトランザクションの各参加者から、そのトランザクションが コミットできるという保証を得て、準備レコードをログに書き込みま す。コミット フェーズでは、コーディネータはすべての参加者に対し、 リソースが解放され、トランザクションがコミットされ、コミット レ コードがログに記録されることを通知します。 2 フェーズ コミットを使用するコンポーネントは、XA 準拠の PowerBuilder データベース インタフェースを使用してデータベースに接続しなけ れはなりません。 OTS/XA トランザクション コーディネータは、接続キャッシュではな く XA リソースを使用してトランザクションを管理します。XA リソー スの作成と管理の詳細については、EAServer のマニュアルを参照して ください。 トランザクションを管 理するコンポーネント の作成 CORBACurrent オブ ジェクトの初期化 トランザクションを管理する EAServer コンポーネントを作成するに は、EAServer プロジェクト ウィザードかプロジェクト ペインタの [OTS スタイル]ボックスをオンにします。また、コンポーネント配布後、 EAServer Manager のコンポーネントのプロパティ シートの[Transaction] タブで[OTS Style]を、または Management Console の[Bean Managed] を選択することも可能です。 CORBACurrent コンテキスト サービス オブジェクトの関数を呼び出す 前に、GetContextService 関数を使用してオブジェクトのインスタンスを 作成し、次に Init 関数を使用してそのインスタンスを初期化する必要が あります。 コンポーネントが管理するトランザクションでは、Init 関数を引数なし で呼び出します。 GetContextService("CORBACurrent", myCorbCurr) 538 PowerBuilder 第 24 章 EAServer クライアントの構築 myCorbCurr.Init() クライアントを区別するトランザクションでは、Init 関数に引数を指定 して呼び出さなければなりません。引数は、すでに接続を確立した接 続オブジェクトのインスタンスか有効な EAServer ホストを識別する URL です。 移植性が高いため、接続オブジェクトを使用する方法がよく用いられ ます。 myCorbCurr.Init( myconnect ) // または myCorbCurr.Init( "iiop://localhost:2000") トランザクションの開 始と終了 クライアントかコンポーネントを区別するトランザクションを開始す るには BeginTransaction 関数を呼び出し、終了するには CommitTransaction か RollbackTransaction を呼び出します。トランザクションに関与するた めインスタンス化するコンポーネントは、トランザクションをサポー トしていなければなりません。 // インスタンス変数 : // CORBACurrent corbcurr // Connection myconnect int li_rc long ll_rc boolean lb_rc, lb_success ll_rc = myconnect.CreateInstance(mycomponent) li_rc = this.GetContextService("CORBACurrent", & corbcurr) IF li_rc <> 1 THEN // エラーを処理 RETURN END IF li_rc = corbcurr.Init( myconnect ) IF li_rc <> 0 THEN // エラーを処理 RETURN END IF lb_rc = corbcurr.BeginTransaction() // サーバ上で処理を実行 // 成功か失敗かを検査 ... IF lb_success THEN アプリケーション テクニック 539 クライアントとコンポーネントを区別するトランザクション corbcurr.CommitTransaction() ELSE corbcurr.RollbackTransaction() END IF ネストされないトランザクション 2 番目のトランザクションは、最初のトランザクションのコミットか ロールバックが完了するまでは開始できません。 コンポーネントが OTS スタイルとしてマークされている場合、EAServer はコンポーネントがインスタンス化されたときにはトランザクション を開始しません。EAServer は、コンポーネントが CORBACurrent オブ ジェクトのインスタンスで BeginTransaction 関数を呼び出してトランザ クションを開始するものとみなします。 SetComplete を呼び出さない コンポーネントがトランザクションを開始して SetComplete を呼び出 すには、その前にトランザクションのコミットかロールバックを実行 する必要があります。トランザクションは、タイムアウトするか別の トランザクションによって選択されるまでは、孤立しています。 トランザクションに関 する情報の取得 CORBACurrent には、トランザクションに関する情報を取得するため の GetStatus と GetTransactionName と い う 2 つ の 関 数 が あ り ま す。 GetStatus は、トランザクションがアクティブか、ロールバックのマー クが付いているか、準備フェーズにあるかコミット フェーズにある か、またはコミット済みかロールバック済みかを示す Integer 型の値を 返します。GetTransactionName は、現行トランザクションを識別する String 型の値を返します。これは、デバッグで使用するための関数です。 トランザクションの一 時停止と再開 呼び出しスレッドは、スレッドがトランザクション以外の処理を実行 している間はトランザクションを一時停止し、その後、そのトランザ クションを再開できます。SuspendTransaction は、ResumeTransaction 関 数に渡すことができるトランザクションへのハンドルを返します。 ResumeTransaction は、同じ実行コンテキスト内にある別のスレッドか ら呼び出せます。次の例では、トランザクションが同じスレッドに再 度関連付けられています。 540 PowerBuilder 第 24 章 EAServer クライアントの構築 long ll_rc unsignedlong ll_handle ... ll_rc = corbcurr.BeginTransaction() // トランザクション処理を実行 ll_handle = corbcurr.SuspendTransaction() // 非トランザクション処理を実行 corbcurr.ResumeTransaction(ll_handle) // さらにトランザクション処理を実行 トランザクションのタ イムアウト時間の設定 呼び出し元のスレッドで、トランザクションをロールバックするタイ ムアウト時間を指定できます。次の例では、タイムアウト時間を 3 分 (180 秒)に設定しています。 integer li_rc li_rc = this.GetContextService("CORBACurrent", & corbcurr) IF li_rc <> 1 THEN // エラーを処理して復帰 END IF li_rc = corbcurr.Init() IF li_rc <> 1 THEN // エラーを処理して復帰 END IF corbcurr.SetTimeout(180) corbcurr.BeginTransaction() サーバ メッセージ返送の要求 サーバ プッシュのシ ミュレーション クライアント アプリケーションは、PowerBuilder オブジェクト参照を EAServer に渡せません。したがって、PowerBuilder オブジェクト参照 を使用しても、サーバから PowerBuilder クライアントにメッセージを プッシュできません。しかし、クライアント上の共有オブジェクトを 使用して EAServer と通信することによって、この動作をシミュレート することは可能です。クライアント上の共有オブジェクトがサーバか らデータをプルするため、このテクニックはクライアント プルとみな すことができます。 アプリケーション テクニック 541 サーバ メッセージ返送の要求 動作 サーバ プッシュをシミュレートするには、クライアントは、 SharedObjectRegister 関数と SharedObjectGet 関数を使用して、共有オブ ジェクトを作成します。オブジェクトが作成されたら、クライアント 上のメイン スレッドは、共有オブジェクトのメソッドの非同期呼び 出しを行って、コールバック オブジェクトを渡します。このコール バック オブジェクトは、サーバ上で処理が終了したときに通知され ます。共有オブジェクトのメソッドは、処理を行う EAServer コン ポーネント メソッドの同期呼び出しを行います。共有オブジェクト はクライアント上の別のスレッドで動作しているため、サーバ上でプ ロセスを実行しながら、クライアント上のメイン スレッドはほかの 作業を続行できます。 EAServer の非同期処理 次の例では、POST を使用してクライアント上の共有オブジェクトのメ ソッドを非同期で呼び出します。POST の使用は、EAServer コンポーネ ントへの呼び出しのコンテキストではサポートされていません。EAServer での非同期処理については、EAServer のマニュアルで、ThreadManager モジュールと MessageService モジュールに関する項目を参照してくだ さい。 EAServer 6.x の Thread Manager の詳細については、Automated Configuration Guide のサイト http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc00548_0600/ht ml/easautoconfig/title.htm を参照してください。メッセージ サービスの 使用方法の詳細については、Java Message Service User’s Guide のサイト http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc00486_0600/ht ml/easjms/title.htm を参照してください。 例 次の例では、共有オブジェクトを使用して、EAServer コンポーネント メソッドに対して非同期リクエストを行い、データをクライアント ア プリケーション ウィンドウに返す方法を示します。 542 PowerBuilder 第 24 章 EAServer クライアントの構築 クライアント アプリケーションのウィンドウ クライアント アプリケーションには、w_employee というウィンドウが あり、従業員データをデータウィンドウ コントロールに表示します。 ユーザがこのウィンドウの[検索]ボタンをクリックすると、クライ アントは、EAServer と通信する共有オブジェクトを作成します。さら に、ユーザ オブジェクトのインスタンスも作成します。このインスタ ンスは、共有オブジェクトのコールバックの処理に使用されます。 インスタンス変数 w_employee ウィンドウには、以下の定義されたインスタンス変数があ ります。 uo_sharedobject iuo_sharedobject uo_callback iuo_callback [検索]ボタン [検索]ボタンは、EAServer と通信する共有オブジェクトを作成しま す。さらに、ユーザ オブジェクトのインスタンスも作成します。この インスタンスは、共有オブジェクトのコールバックの処理に使用しま す。コールバック オブジェクトがウィンドウに処理の終了を通知でき るように、次のスクリプトはコールバック オブジェクト上で PassObject という関数を呼び出し、ウィンドウへの参照を渡します。最後に、こ のスクリプトは、共有オブジェクトの RetrieveData 関数の非同期呼び出 しを行って、コールバック オブジェクトへの参照を渡します。 [検索]ボタンには次のスクリプトがあります。 long ll_rv SharedObjectRegister("uo_sharedobject","myshare") SharedObjectGet("myshare",iuo_sharedobject) iuo_callback = CREATE uo_callback iuo_callback.passobject (parent) iuo_sharedobject.post retrievedata(iuo_callback) SetDW 関数 SetDW 関数は、EAServer コンポーネントから返されたデータウィンド ウ Blob の内容を、ウィンドウ内のデータウィンドウ コントロールに適 用します。SetDW 関数は、Blob 型の引数 ablb_data を受け取り、Long 値 を返します。この関数には、次のスクリプトがあります。 long ll_rv ll_rv = dw_employee.SetFullState(ablb_data) if ll_rv = -1 then MessageBox(" エラー ", "SetFullState 呼び出しに失敗しま した !") end if アプリケーション テクニック 543 サーバ メッセージ返送の要求 return ll_rv EAServer コンポーネント EAServer コンポーネントは、uo_employee という PowerBuilder ユーザ オブジェクトです。この uo_employee オブジェクトには、データスト アを使用してデータベースから従業員の行を取り出す、RetrieveData と いう関数があります。 インスタンス変数 uo_employee オブジェクトには、以下の定義されたインスタンス変数が あります。 protected TransactionServer txnsrv protected DataStore ids_datastore RetrieveData 関数 RetrieveData 関数は、Blob 型の引数 ablb_data を受け取り、Long 値を返 します。この関数には、次のスクリプトがあります。 long ll_rv ll_rv = ids_datastore.Retrieve() ll_rv = ids_datastore.GetFullState(ablb_data) txnsrv.SetComplete() return ll_rv 共有オブジェクトの定義 クライアント アプリケーションは、uo_sharedobject という共有オブ ジェクトを使用して、EAServer コンポーネントと通信します。この共 有オブジェクトには、RetrieveData という 1 つの関数があります。 インスタンス変数 uo_sharedobject オブジェクトには、以下の定義されたインスタンス変 数があります。 uo_employee iuo_employee n_jagclnt_connect myconnect Constructor イベント Constructor イベントは、n_jagclnt_connect というカスタム接続オブジェ クトを使用して、サーバに接続します。続いて、EAServer コンポーネ ントのインスタンスを作成します。 long ll_rc, ll_rv myconnect = create n_jagclnt_connect ll_rc = myconnect.ConnectToServer() ll_rv = myconnect.CreateInstance(iuo_employee, & "uo_employee") 544 PowerBuilder 第 24 章 RetrieveData 関数 EAServer クライアントの構築 RetrieveData 関数は、EAServer コンポーネントの RetrieveData 関数の同 期呼び出しを行います。関数の処理が終了すると、コールバック オブ ジェクトの Notify 関数を呼び出し、サーバ コンポーネントから返され たデータウィンドウ Blob を渡します。 RetrieveData 関数は、uo_callback 型の auo_callback という引数を受け取 ります。 blob lblb_data long ll_rv ll_rv = iuo_employee.retrievedata(lblb_data) auo_callback.notify(lblb_data) return ll_rv コールバック オブジェクトの定義 EAServer コンポーネントが処理を終了したら、共有オブジェクトが uo_callback というユーザ オブジェクトに通知し、このユーザ オブジェ クトが同様に w_employee ウィンドウに通知します。uo_callback オブ ジェクトには、Notify と PassObject という、2 つの関数があります。 Notify 関数 Notify 関数は、w_employee ウィンドウの SetDW という関数を呼び出し、 サーバ コンポーネントから返されたデータウィンドウ Blob に渡しま す。Notify 関数は、Blob 型の引数 ablb_data を受け取り、Long 値を返し ます。この関数には、次のスクリプトがあります。 long ll_rv ll_rv = iw_employee.setdw(ablb_data) if ll_rv = -1 then MessageBox(" エラー ", "SetDW 呼び出しに失敗 !") end if return ll_rv PassObject 関数 PassObject 関数は、w_employee ウィンドウへの参照を iw_employee イン スタンス変数にキャッシュします。この関数は、w_employee 型の引数 aw_employee を受け取り、Long 値を返します。 iw_employee = aw_employee return 1 アプリケーション テクニック 545 エラー処理 エラー処理 PowerBuilder は、EAServer に接続しているクライアントが使用できる 3 階層のエラー処理を提供します。 • EAServer で実行されているコンポーネントから送出された例外を、 try/catch/finally ブロックを使用して処理するメカニズム システム エラーと実行時エラーはすべて、RuntimeError 型から派 生したオブジェクトに変換されます。 • EAServer 接続のコンテキストで発生するエラーを処理する、接続 オブジェクトと JaguarORB オブジェクトの Error イベント • ほかのメカニズムでトラップされなかったエラーを処理する、ア プリケーション オブジェクトの SystemError イベント PowerBuilder では、エラーに関する情報は組み込みの Error 構造に記録 されます。この構造体は、Error イベントと SystemError イベントによっ て使用されます。 クライアントができる こと クライアント アプリケーションは、さまざまな方法で通信エラーを処 理できます。たとえば、クライアントがサーバに接続し、オブジェク トのメソッドを呼び出そうとしたのにそのオブジェクトが存在しな かった場合は、サーバとの接続を解除し、別のサーバに接続して操作 を再試行する方法があります。あるいは、クライアントがユーザにメッ セージを表示して、次に起こることを制御する機会をユーザに与える 方法もあります。 クライアントが操作の再開のために新しいサーバに接続している場 合、エラー発生時には、新しいサーバ上でリモート オブジェクトをイ ンスタンス化してから、リモート オブジェクトのメソッドを呼び出す 必要があります。 エラーが処理される場 所 546 次に、PowerBuilder が EAServer クライアントでエラー処理コードを実 行するシーケンスを示します。 1 接続オブジェクトまたは JaguarORB オブジェクトのコンテキスト でエラーが発生し、そのオブジェクトの Error イベントに関連付け られているスクリプトがある場合は、イベント スクリプトがあれ ば、それが実行されます。 2 以下のいずれかが真の場合、RuntimeError またはその子孫のアク ティブな例外ハンドラが起動されます。 • Error イベントのスクリプトが作成されていない • Error イベントのアクション引数が ExceptionFail! に設定され ている PowerBuilder 第 24 章 • 3 EAServer クライアントの構築 接続オブジェクトまたは JaguarORB オブジェクトのコンテキ ストでエラーが発生しない 例外ハンドラがない場合、または既存の例外ハンドラがその例外 を処理しない場合、アプリケーション オブジェクトの SystemError イベントが実行されます。SystemError イベントのスクリプトが作 成されていない場合は、アプリケーション エラーが起きて、アプ リケーションは終了します。 システム例外ハンドラ PowerBuilder には、致命的なシステム エラーの捕捉を試みる、システ ム例外ハンドラがあります。このハンドラは、個々のクライアント接 続のトラブルによるサーバ停止の防止に役立ちます。クライアント接 続時に致命的なエラーが発生するたびに、PowerBuilder は、サーバを 停止させたり、ほかのクライアント接続を妨げたりすることなく、ク ライアント接続の終了を試みます。トラブルが発見されたら、クライ アント上のほかの実行時エラーの場合と同様に、システム例外ハンド ラはアプリケーション オブジェクト内で SystemError イベントを発生 させます。 コンテキスト対応のエ ラー処理 try/catch メカニズムを利用すると、発生した場所でエラーを処理でき、 コンポーネントから送出されたエラーが、クライアント アプリケー ションで致命的なエラーになる可能性を最小限に抑えることも可能で す。接続オブジェクトの Error イベントをスクリプトで実行させる方法 は正確性が低く、Error イベントのアクション引数を ExceptionFail! に設 定しない限り、try/catch 例外ハンドラを無視してしまいます。 したがって、Error イベントはスクリプトで実行せずに、コードに try/catch ブロックを追加して、もっとも効果的なエラー処理を実現し なければなりません。GetMessage 関数を使用して、例外のエラー メッ セージを取得できます。 例外についての詳細は、39 ページの「PowerBuilder での例外処理」を 参照してください。 作成したエラー処理コードでは発生したすべてのエラーをトラップで きるわけではないため、必ず、アプリケーション オブジェクトの SystemError イベントのスクリプトを作成する必要があります。 アプリケーション テクニック 547 エラー処理 CORBA 例外の処理 CORBA は、コンポーネントがエラーまたは警告を通知するための標 準的な方法を提供します。CORBA は 2 種類の例外をサポートします。 • システム例外 • ユーザ定義の例外 システム例外は、サーバで生成される標準エラーのセットの 1 つです。 これらの例外は、CORBA 仕様で定義されています。 ユーザ定義例外は、コンポーネントの IDL で定義されるエラーまたは 警告です。ユーザ定義例外は新しいデータ型であり、例外が生成され たときにクライアントに返される一連のデータ要素を表します。 システム例外 PowerBuilder では、CORBA システム例外は RuntimeError オブジェクト から継承した一連のオブジェクトにマッピングされます。このような 例外のリストを参照するには、PowerBuilder オブジェクト ブラウザの [システム]タブで「corbasystemexception」を選択し、ポップアップ メ ニューで[階層の表示]を選択して、ツリービュー項目を展開します。 PowerBuilder の CORBASystemException オブジェクトの名前は、 CORBA/IIOP 仕様にアンダースコア文字を省略して定義されている CORBA システム例外の名前にマッピングされます。たとえば、 PowerBuilder CORBACommFailure 例外は CORBA_COMM_FAILURE 例 外にマッピングします。CORBA 例外についての詳細は、OMG のサイ ト http://www.omg.org/ からダウンロードできる CORBA/IIOP 仕様を参照 してください。 コンポーネントのメソッドを呼び出すときには、次に示すような例外 に対してエラー処理を実行できます。 TRY ... // メソッドの呼び出し CATCH (corbacommfailure cf) // コンポーネントによる EAServer トランザクションの異常終了 // またはトランザクションのタイムアウト。 // 必要であれば トランザクションを再試行 CATCH (corbatransactionrolledback tr) // 多くの場合はトランザクションを再試行 CATCH (corbaobjectnotexist one) // 存在しないコンポーネントを初期化しようと // したときに受け取る。また、 // オブジェクト参照の有効期限が切れた場合に // メソッドを呼び出したときも受け取る // これは、コンポーネントがステートフルで、 // 有限の Instance Timeout プロパティが 548 PowerBuilder 第 24 章 EAServer クライアントの構築 // 設定してある場合に実行 // 必要であれば新しいプロキシ インスタンスを作成 CATCH (corbanopermission np) // ユーザに、認証されていないことを通知 CATCH (corbasystemexception se) ... // エラーを通知するが再試行はしない FINALLY // クリーンアップ コードはここに挿入 END TRY ユーザ定義の例外 ユーザ定義例外は、Exception オブジェクトから継承され CORBAUserException オブジェクトにマッピングされます。 PowerBuilder クライアントは、どのコンポーネント タイプから送出さ れた例外も処理できます。 EAServer コ ン ポ ー ネ ン ト に 例 外 を 送 出 す る メ ソ ッ ド が あ る 場 合、 PowerBuilder プロキシ オブジェクトのそのメソッドも、ユーザ定義例 外を送出するように宣言されます。ユーザ定義例外に関する定義は、 開発者がコンポーネント プロキシを作成したときに作成されます。 CORBA では、例外階層構造をサポートしていません。 CORBA IDL では、例外階層構造をサポートしていません。その結果、 例外を継承したサーバ コンポーネントのプロキシを生成すると、生成 されたプロキシはすべて CORBAUserException から直接継承します。 EJB コンポーネントで Create、Remove、および FindByPrimaryKey メソッ ドをすべて使用すると、EJB の CreateException、RemoveException、お よび FinderException 例外が送出されます。これらの例外は、EAServer の CtsComponents パッケージでは同名の IDL 例外で表されています。 Error イベントのスクリプト作成 実行方法 接続オブジェクトの Error イベントのエラーを処理するには、オブジェ クトの定義をカスタマイズするユーザ オブジェクトを作成します。カ スタム接続オブジェクトを作成したら、接続オブジェクトを使用する スクリプト内のどこからでも、そのオブジェクトを参照できます。 JaguarORB イベントを使用する場合は、同じように Error イベントのス クリプトを作成できます。 接続オブジェクト ウィザードは、カスタム接続オブジェクトを作成し ます。523 ページの「ウィザードを使用した接続オブジェクトの作成」 を参照してください。 アプリケーション テクニック 549 エラー処理 Error イベントの引数 カスタム接続オブジェクトの Error イベントには引数がいくつかあり ます。これらの引数を使うと、エラーの原因となった条件についての 情報を取得できます。たとえば、エラー番号とエラー メッセージに加 えて、エラーを起こしたオブジェクトの名前や、エラーが発生したス クリプトの全テキストなども、これらの引数から取得できます。 エラー情報を提供する引数に加えて、Error イベントには次に実行すべ き動作を指定する引数があります。動作を指定するには、4 つの値 (ExceptionFail!、ExceptionRetry!、ExceptionIgnore!、 ExceptionSubstituteReturnValue!)の 1 つを Error イベントの Action 引数に 指定します。 例 次の例では、Error イベント スクリプトは、通信エラーを引き起こした 条件をユーザに伝えて、次に起こることを制御する機会をユーザに与 えます。ユーザの入力に応じて、クライアント アプリケーションは、 異常終了したり、操作を再試行したり、エラーを無視して処理を続行 したりします。 int li_choice li_choice = MessageBox(" 接続エラー " + & string(ErrorNumber), ErrorText, & Question!,AbortRetryIgnore!) CHOOSE CASE li_choice CASE 1 Action = ExceptionFail! CASE 2 Action = ExceptionRetry! CASE 3 Action = ExceptionIgnore! END CHOOSE SystemError イベントのスクリプト作成 実行方法 アプリケーション オブジェクトの SystemError イベントには、 PowerBuilder にアプリケーションの実行を中断させたり、エラーを無 視するように指示するスクリプトを記述したりできます。 例 次の例では、SystemError イベント スクリプトは、メッセージを表示し て、ユーザに通信エラーを引き起こした条件を知らせ、ユーザに次に 起こることを制御する機会を与えます。ユーザの入力に応じて、クラ イアント アプリケーションは、実行を中断するか、エラーを無視して 処理を続行します。 string ls_logline = " システム エラー : " ls_logline += String(error.number) + " " + error.text 550 PowerBuilder 第 24 章 EAServer クライアントの構築 ls_logline += " エラー発生行 " + & String(error.line) + " " ls_logline += " イベント " + error.objectevent ls_logline += " オブジェクト " + error.object if Messagebox(" システム エラー ", ls_logline + & "~r~n~r~n プログラムを終了しますか ?", & Question!, YesNo!)= 1 then HALT CLOSE end if クライアント アプリケーションの配布 分散コンピューティング環境でクライアント アプリケーションを配 布する手順は、ほかの PowerBuilder アプリケーションの配布手順とほ ぼ同じです。クライアント アプリケーションのパッケージ化には 2 つ の基本的な方法があります。 • アプリケーションのオブジェクトをすべて含む、1 つのスタンドア ロン実行ファイル(EXE)として • 実行ファイルと 1 つまたは複数の動的ライブラリとして ビットマップやアイコンのような、アプリケーションが使う補助的な リソースをいくつか供給しなくてはいけないこともあります。リソー スは、実行ファイルや動的ライブラリで供給するか、別々に配布する ことも可能です。 ア プ リ ケ ー シ ョ ン の 実 行 フ ァ イ ル を 作 成 す る 方 法 に つ い て は、 PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 アプリケーションと一緒に配置する必要があるファイルについては、 第 37 章「アプリケーションとコンポーネントの配布」を参照してくだ さい。 アプリケーション テクニック 551 クライアント アプリケーションの配布 552 PowerBuilder 第 2 5 章 PowerBuilder クライアントでの SSL の使い方 PowerBuilder クライアントは、Secure Sockets Layer(SSL)を使用 して EAServer に接続できます。ほかのセキュリティ機能の中で も、SSL は、証明書に基づくサーバ認証、証明書に基づく任意の クライアント認証、およびネットワーク経由で送信される任意の データの暗号化を提供します。 内容 項目 EAServer とのセキュアな接続 PowerBuilder での SSL 接続 セキュアな接続の確立 SSL コールバックの使い方 セッション セキュリティ情報の取得 ページ 553 555 559 562 566 EAServer とのセキュアな接続 SSL プロトコルでは、デジタル認証に基づく公開鍵の暗号化と認 証のアルゴリズムを利用して、安全に接続できます。SSL は「ラッ パー」プロトコルであり、ほかのプロトコル用のパケットは、SSL パケットの内部に埋め込むことによって保護されます。たとえば、 HTTPS は、各 HTTP パケットを SSL パケット内に埋め込むことに よって保護される HTTP です。同様に、IIOPS は、SSL 内に埋め込 まれた IIOP です。 EAServer の組み込み SSL ドライバは、動的ネゴシエーション、 キャッシュ セッション、共有セッション、および X.509 デジタル 証明書サポートによるクライアント / サーバの認証をサポートし ます。 アプリケーション テクニック 553 EAServer とのセキュアな接続 EAServer でのセキュリティの概要および EAServer と SSL の詳細につ いては、EAServer のマニュアルを参照してください。EAServer 6.x の 詳細については、Security Administration and Programming Guide のサイト http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc38035_0600/ht ml/eassec/title.htm を参照してください。 保護の質 EAServer パッケージ、コンポーネント、およびメソッドの保護の質 (QOP: quality of protection)は、Management Console で設定できます。 QOP は、クライアントがコンポーネントのビジネス ロジックにアクセ スするために満たさなければならない、最低レベルの暗号化および認 証を構築します。たとえばコンポーネントに対する QOP を設定するに は、コン ポー ネント のプ ロパ ティ シート の[Advanced]ペ ージ で com.sybase.jaguar.component.qop プロパティを追加し、EAServer が提供 する sybpks_intl などのセキュリティ特性を設定します。 サーバでの QOP の設定について、および EAServer が提供するセキュ リティ特性のリストについては、EAServer のマニュアルを参照してく ださい。この章では、クライアントでの QOP の設定について説明しま す。 SSL の証明書に基づ く認証 Management Console では、リスナを設定し、そのリスナにセキュリティ プロファイルを関連付けることで、セキュアな IIOP または HTTP ポー トを構成できます。プロファイルは、目的のサーバでの接続終了を確 認するためにクライアントに送信されるセキュリティ証明書と、その ほかのセキュリティ設定を指定します。 PowerBuilder クライアントには、デジタル証明書の管理のために公開 鍵基盤(PKI: Public key Infrastructure)システムが必要です。EAServer 証明書データベースを管理する Security Manager を使用できます。 PKI およびセキュアなポートと認証オプションの設定の詳細について は、EAServer のマニュアルを参照してください。 クライアント側のイン ストール要件 554 EAServer は、いくつかのクライアント ランタイム ファイルを提供し ます。PowerBuilder クライアントの SSL サポートは、クライアント ORB を介して提供されるため、PowerBuilder SSL クライアントが動作 するコンピュータには SSL ランタイム ファイルをインストールする 必要があります。このインストールには、クライアント側のセキュリ ティ データベース、SSL サポート ライブラリ、クライアント側の Security Manager などが含まれます。また、アプリケーションの実行時 にクライアント ライブラリが読み込まれるように、クライアントのイ ンストールを構成する必要もあります。詳細については、『EAServer Installation Guide』マニュアルを参照してください。 PowerBuilder 第 25 章 PowerBuilder クライアントでの SSL の使い方 PowerBuilder での SSL 接続 PowerBuilder は、セキュアな接続に使用する 2 つのシステム オブジェ クトを提供します。 • SSLServiceProvider サービス オブジェクト SSLServiceProvider オブ ジ ェ ク ト は、EAServer の CtsSecurity::SSLServiceProvider イ ン タ フェースの実装です。このインタフェースの詳細については、Web ブラウザでお使いのサーバ(http://hostname:portnumber)に接続し て、EAServer インタフェース リポジトリ ドキュメントを参照して ください。 SSLServiceProvider オブジェクトの GetGlobalProperty および SetGlobalProperty 関数を使用して、グローバル SSL プロパティを設 定します。設定または取得、あるいはその両方が可能なグローバル プロパティについては、555 ページの「SSL プロパティ」を参照し てください。 また、接続オブジェクトまたは JaguarORB オブジェクトに対して、 SSL プロパティを Options 文字列で指定して、接続レベルで設定す る こ と も で き ま す。対 話 型 の ア プ リ ケ ー シ ョ ン で は 一 般 に、 SSLServiceProvider オブジェクトは SSLCallback オブジェクトとと もに使用されます。ユーザとの対話操作を提供しないアプリケー ションでは、接続レベルで SSL 設定を構成するのが普通です。接 続レベルでのプロパティの設定については、558 ページの「ORB プロパティ」を参照してください。 • SSLCallback オブジェクト EAServer で、コールバック メソッドを 使用してクライアントに追加情報を要求する場合は、SSLCallBack オブジェクトのインスタンスにコールバック メソッド用の独自の ロジックを実装できます。SSLCallback オブジェクトは、EAServer の CtsSecurity::SSLCallback インタフェースの実装です。 SSL プロパティ 表 25-1 に、SetGlobalProperty または GetGlobalProperty を使用して設定ま たは取得できるプロパティを示します。SSL 接続では、qop(quality of protection)プロパティを設定しなければなりません。また、このプロ パティを取得するためのコールバックを実装しない場合は、pin プロパ ティを設定する必要があります。選択したセキュリティ レベルをサ ポートするサーバ アドレスに接続する必要もあります。これについて は、558 ページの「セキュアなサーバ アドレス」に記載されています。 アプリケーション テクニック 555 PowerBuilder での SSL 接続 PowerBuilder セッションでのグローバル プロパティの設定 PowerBuilder でクライアント アプリケーションを実行している場合、 PowerBuilder のセッション時にグローバル プロパティを設定できるの は一度だけです。グローバル SSL プロパティを設定するコードをテス トするたびに、PowerBuilder を再起動する必要があります。 設定されていないプロパティか、誤って設定されているプロパティが ある場合は、SSL コールバック メソッドが呼び出されます。SSLCallback オブジェクトのインスタンスを指定していない場合は、デフォルトの コールバック実装によって接続試行が中断されます。 表 25-1: SSL プロパティのリスト プロパティ callbackImpl certificateLabel qop cacheSize SessLingerTime SessShareCount pin 説明 取得 SSLCallback オブジェクトのインスタンス。詳細については、562 可 ページの「SSL コールバックの使い方」を参照してください。 相互認証が必要な接続で使用するクライアント証明書。ラベル 可 は、PKCS #11 トークンの X.509 証明書およびプライベート キー を識別する単純な名前 相互認証で必要このプロパティを設定せずに接続の相互認証を 要求すると、コールバック メソッド getCertificateLabel が呼び出さ れ、使用可能な証明書名の配列が入力パラメータとして渡される 使用するセキュリティ特性の名前。SSL で必要。詳細については、 557 ページの「セキュリティ特性の選択」を参照してください。 SSL セッション ID のキャッシュのサイズ。デフォルトは 100 前回の接続で使用したセッション ID エントリをキャッシュに保 管する期間(秒単位)。デフォルトは 28800 秒(8 時間) 同じセッション ID を同時に使用できる SSL セッションの数。デ フォルトは 10 PKCS #11 トークンの PIN 設定 可 可 可 可 可 可 可 可 可 可 不可 可 これは、クライアント認証のために PKCS #11 トークンにログイ ンする場合、および信頼情報を取得する場合に必要。SSL で必要 availableQop availableQopDesc availableVersions 556 このプロパティが設定されていない場合は、any が設定される。 また、誤って設定されている場合は、コールバック メソッド getPin が呼び出される 使用可能なセキュリティ特性のリスト。qop プロパティには、こ 可 のリスト内の値のみ設定できる 使用可能なセキュリティ特性の説明のリスト。availableQop プロ 可 パティの値と同じ順序で指定する SSL ランタイム エンジンでサポートされる SSL プロトコル バー 可 ジョンのリスト 不可 不可 不可 PowerBuilder 第 25 章 プロパティ entrustReady entrustIniFile entrustUserProfile useEntrustID entrustPassword PowerBuilder クライアントでの SSL の使い方 説明 取得 クライアントで Entrust PKI ソフトウェアが使用できる場合は 可 TRUE、それ以外の場合は FALSE Entrust へのアクセ ス方法に関する情報を定義した Entrust INI 可 ファイルへのパス名。useEntrustid プロパティが true に設定されて いる場合に必要 このプロパティが設定されていない場合は、コールバック メソッ ド getCredentialAttribute が呼び出される Entrust ユーザ プロファイルを含むファイルへのフル パス。Entrust 可 のシングルログイン機能が使用可能な場合は省略できる。それ以 外の場合は必ず指定する このプロパティが設定されていない場合は、コールバック メソッ ド getCredentialAttribute が呼び出される 認証に、Entrust ID または Sybase の PKCS #11 トークンのどちら を使用するかを指定する。これは Boolean 型のプロパティである 可 このプロパティが FALSE に設定されている場合、Sybase の PKCS #11 トークンのプロパティが有効になり、Entrust 固有のプロパ ティは無視される。このプロパティが TRUE に設定されている場 合、Entrust 固有のプロパティが有効になり、Sybase の PKCS #11 トークンのプロパティは無視される 指定されたユーザ プロファイルを使用して Entrust にログインす 不可 る際のパスワード。Entrust のシングルログイン機能が使用可能な 場合は省略できる。それ以外の場合は必ず指定する 設定 不可 可 可 可 可 パスワードが必要な場合に、このプロパティが設定されていない ときや、誤って設定されているときは、コールバック メソッド getPin が呼び出される セキュリティ特性の選 択 SSL を使用するには、使用可能なセキュリティ特性の名前を qop プロ パティに指定しなければなりません。この特性は、SSL 接続のネゴシ エーションの際にクライアントが使用する CipherSuite を定義します。 接続時に、クライアントは自分が使用する CipherSuite のリストをサー バに送信します。サーバは、そのリストから CipherSuite を選択します。 サーバは、そのリスト内から、使用可能な最初の CipherSuite を選択し ます。サーバで使用できる CipherSuite がない場合、接続は失敗します。 EAServer のマニュアルでは、EAServer から提供されるセキュリティ特 性について説明しています。サーバで使用可能な特性のリストおよびそ の説明を取得するには、GetGlobalProperty を使用して availableQop およ び availableQopDesc プロパティを取得します。 アプリケーション テクニック 557 PowerBuilder での SSL 接続 セキュアなサーバ ア ドレス qop 設定で要求されるセキュリティ レベルと同じまたはそれ以上のレ ベルのサーバ リスナにのみ接続できます。JaguarORB.string_to_ オブ ジェクトを使用して SessionManager::Manager インタフェースのプロシ キのインスタンスを作成する場合、サーバ アドレスで指定されるリス ナでは、クライアントの qop 設定と一致するセキュリティ プロファイ ルを使用しなければなりません。 ORB プロパティ 接続オブジェクトまたは JaguarORB オブジェクトのいずれかを使用し て EAServer に接続する場合、EAServer のクライアント ORB を使用し ます。そのプロパティは、接続オブジェクトの Options 文字列に設定 するか、JaguarORB の Init 関数を使用して設定できます。以下のプロパ ティは、特にセキュアな接続に対して適用される ORB プロパティで す。 • ORBqop • ORBcertificateLabel • ORBpin • ORBuseEntrustID • ORBentrustPassword • ORBentrustIniFile • ORBentrustUserProfile 以上のプロパティの機能は、対応する SSL プロパティと同じですが、 その値は確立中の接続にのみ影響し、セッション全体には影響しませ ん。ORBqop に sybpks_none を設定すると、どの SSL も接続で使用さ れなくなります。この設定が便利なのは、SSLServiceProvider オブジェ クトを使用してすべての ORB に対して QOP をグローバルに設定して いる場合に、単一の接続の QOP をオーバーライドするときです。 ORB プロパティのリストについては、接続オブジェクトのヘルプを参 照してください。 次の例では、ORBqop プロパティに sybpks_simple を設定し、ログ ファ イルを指定します。 myconnect.options = "ORBqop='sybpks_simple', " & + "ORBLogFile='C:\tmp\log.txt'" 558 PowerBuilder 第 25 章 PowerBuilder クライアントでの SSL の使い方 セキュアな接続の確立 EAServer へのセキュアな接続を確立するには、次の手順を行います。 1 SSLServiceProvider オブジェクトのインスタンスを作成します。 2 (省略可能)GetGlobalProperty 関数を使用して、サーバからセキュ リティ情報を取得します。 3 SetGlobalProperty 関数を使用して、サーバに必要なプロパティを設 定します。 4 SSLServiceProvider オブジェクトのインス タンスの作成 接続オブジェクトの ConnectToServer 関数を使用して、サーバに接 続します。 次のコードは、SSLServiceProvider オブジェクトのインスタンスを作成 します。 SSLServiceProvider sp GetContextService( "SSLServiceProvider", sp ) サーバからの情報の取 得 GetGlobalProperty を使用して、サーバのセキュリティ特性に関する情報 を取得します。次の例では、サポートされている CipherSuite の情報を availableQop プロパティから取得し、その情報をドロップダウン リス トボックスに表示します。 int i, rc string ls_values[] rc = sp.GetGlobalProperty("availableQop", ls_values) IF rc <> 0 THEN MessageBox("Qop の取得に失敗しました ", & "rc = " + string(rc)) RETURN END IF FOR i = 1 to UpperBound(ls_values) ddlb_1.AddItem( ls_values[i] ) NEXT RETURN グローバル プロパ ティの設定 サーバに接続するには、まず必要なグローバル プロパティを設定しな ければなりません。次のコードでは、qop に値 sybpks_intl を設定し、 pin に値 sybase を設定します。 int rc rc = sp.SetGlobalProperty( "qop", "sybpks_intl" ) アプリケーション テクニック 559 セキュアな接続の確立 IF rc <> 0 THEN MessageBox( "QOP の設定に失敗しました ", & "rc = " + string(rc) ) ELSE MessageBox( "SSL の QOP プロパティの設定 ", & " 成功しました " ) END IF rc = sp.SetGlobalProperty( "pin", "sybase" ) IF rc <> 0 THEN MessageBox( "PIN の設定に失敗しました ", & "rc = " + string(rc) ) ELSE MessageBox( "SSL の PIN プロパティの設定 ", & " 成功しました " ) END IF SetGlobalProperty を使用して設定するプロパティのほとんどは、クライ アントの実行中に一度だけ設定できます。これらのプロパティは、ク ライアントがサーバとの接続を解除した場合またはサーバに再接続し た場合も有効です。 PowerBuilder の再起動 PowerBuilder でクライアント アプリケーションを実行している場合、 PowerBuilder のセッション時にグローバル プロパティを設定できるの は一度だけです。グローバル SSL プロパティを設定するコードをテス トするたびに、PowerBuilder を再起動する必要があります。 SSLCallback オブジェクトのインスタンスを使用して、ユーザ入力を対 話形式で取得する場合は、グローバル プロパティ CallBackImpl を設定 する必要があります。562 ページの「SSL コールバックの使い方」を 参照してください。 サーバへの接続 560 セキュアなセッションを開始すると、クライアントおよびサーバは SSL ハンドシェイク プロセスでメッセージを交換します。クライアン トは、サーバとの通信で必要とされる情報を提供し、サーバはクライ アントに対してサーバ自身の認証を行ったうえで、プロセスを継続し ます。サーバがクライアント認証を必要とする場合は、プロセスを継 続する前にクライアントが認証されなければなりません。必要な認証 が完了すると、クライアントおよびサーバは、暗号化、復号化、およ び SSL セッションの不正箇所の検出に使用する、双方で対称的なキー を作成します。このプロセスで発生する例外を取り込むには、try-catch ブロックに ConnectToServer 呼び出しを置く必要があります。 PowerBuilder 第 25 章 PowerBuilder クライアントでの SSL の使い方 セキュアな接続が確立したら、接続オブジェクトの location プロパティ で iiop ではなく iiops を使用します。サーバは一般的には、ポート 2001 または 2002 でセキュアな接続要求を待機します。次の例では、グ ローバル変数として宣言された接続オブジェクト g_connect を使用し ます。ここでは、接続オブジェクトの options プロパティを使用して、 この接続に別の CypherSuite を指定します。 long l_rc g_connect.userid = sle_user.text g_connect.password = sle_password.text g_connect.driver = "jaguar" g_connect.application = "myserverpkg" g_connect.location = "iiops://myserver:2001" g_connect.options = "ORBqop='sybpks_simple'" TRY l_rc = g_connect.ConnectToServer() CATCH (userabortedexception uae) MessageBox("UserAbortedException を取得しました ", & "ConnectToServer が次を取得しました :" & + uae.getMessage() ) l_rc = 999 CATCH ( CORBASystemException cse ) MessageBox("CORBASystemException を取得しました ", & "ConnectToServer が次を取得しました :"& + cse.getMessage() ) l_rc = 998 END TRY IF l_rc <> 0 THEN MessageBox(" エラー ", " 接続に失敗しました - コード : " & + string(l_rc) ) MessageBox(" エラー情報 ", " エラーコード = " & + string(g_connect.ErrCode) + "~nErrText= " & + g_connect.ErrText) ELSE MessageBox("OK", " 接続が確立されました ") END IF 接続のトラブルシュー ティング セキュアな接続が失敗した場合は、セキュアでない接続の場合と同じ エラー メッセージが表示されます。そのエラー メッセージには、失敗 の原因に関する情報は示されません。ログ ファイルに記録された詳細 情報を取得するには、ORBLogIIOP オプションを有効にし、ORBLogFile オプションに値を指定します。上の例であれば、g_connect.options 文を次のような文で置き換えます。 アプリケーション テクニック 561 SSL コールバックの使い方 g_connect.options = "ORBqop='sybpks_simple'" + & "ORBLogIIOP='TRUE', ORBLogFile='d:\temp\ORBLog.txt'" また、環境変数 JAG_LOGFILE を設定して、初期化に関するエラーを 記録するログ ファイルを指定することもできます。 SSL コールバックの使い方 SSLCallback オブジェクトは、サーバからクライアント アプリケーショ ンに送られる追加認証情報に対する SSL リクエストを処理します。pin など必要な設定が指定されていない場合や、無効な値が指定されてい る場合は、C++ ORB によってコールバック メソッドが呼び出されま す。 コールバックは、有効期限が切れたサーバ証明書など、例外的な状況 に対応します。相互認証を使用する場合、コールバック メソッド getCertificateLabel を使うと、使用可能な証明書のリストをユーザに提示 できます。また、コールバックを使用すると、ユーザが無効な証明書 や無効なパスワードを登録した際の再試行ロジックの処理を簡素化で きます。 SSL コールバック メカニズムを使用するには、次の手順を行う必要が あります。 1 EAServer の CTS Security モジュールに対してプロキシ オブジェク トを作成して、SSL セッション情報を取得します。 2 SSLCallback オブジェクトから継承した、標準カスタム クラス ユー ザ オブジェクトを作成し、必要なコールバック関数を実装します。 3 SSL のグローバル プロパティ CallBackImpl に SSLCallback オブ ジェクトの名前を設定し、サーバに接続します。 セッション情報の取得 どの SSL コールバック関数からでも、SSL セッション情報にアクセス できます。この情報を使用することで、クライアント アプリケーショ ンのユーザに対して、必要な認証情報を提供するために必要となる情 報を渡さなければなりません。 SSL セッション情報をコールバック関数で使用するためには、 CTSSecurity モジュールに対して EAServer プロキシを作成します。 562 PowerBuilder 第 25 章 v PowerBuilder クライアントでの SSL の使い方 CTSSecurity モジュールに対してプロキシを作成するには 1 新規作成 ダイアログボックスの[プロジェクト]ページで[EAServer プロキシ ウィザード]を選択し、[ターゲット]ドロップダウン リストボックスから対象のクライアント アプリケーションを選択 します。 2 いずれかの EAServer ホストに接続し、CTSSecurity モジュールを選 択します。 CTSSecurity モジュールは、すべてのサーバで使用可能な標準モ ジュールです。 ウィザードでの操作を完了し、プロジェクトを作成します。 3 システム ツリーに表示されるプロキシ オブジェクトのうち、 Sessioninfo オブジェクトはすべての SSLCallback 関数に渡されま す。 SSLCallback オブジェクトの実装 4 つのコールバック関数があります。 表 25-2: SSL コールバック関数 関数 呼び出しのタイミング GetCertificateLabel サーバがクライアント認証を要求しているが、クラ イアント アプリケーションにクライアント認証用の 証明書ラベルが設定されていない場合 クライアント アプリケーションにアカウント情報属 性が設定されていない場合 GetCredentialAttribute GetPin アプリケーション テクニック この属性は、クライアント アプリケーションで SSLServiceProvider オブジェクトを使用して UseEntrustId プロパティを設定した場合に使用され る。Entrust ID を使用している場合のみ GetCredentialAttribute が便利。Entrust および PKCS 11 トークンの詳細については、EAServer のマニュアル を参照してください。 PKCS11 トークンがログインされず、PIN が SSLServiceProvider オブジェクトのプロパティとし て設定されていない場合。また、ログイン セッショ ンがタイムアウトした場合にも呼び出される 563 SSL コールバックの使い方 関数 TrustVerify 呼び出しのタイミング サーバ内部での SSL 信頼確認チェックが失敗して、 サーバの証明書チェーンを確認できない場合、また は Sybase の PKCS11 トークンにログインするための pin が設定されていないか正しくない場合、 TrustVerify は SSL プロトコルを使用する場合も呼び 出すことができる サーバ認証は SSL ハンドシェイク プロセスで必要 な手順のため、任意の SSL プロトコルを使用してい るときに TrustVerify を呼び出すことができる。ユー ザは、内部チェックをオーバーライドして SSL 接続 を続行するかどうかを選択できる 以上の各関数は、SSLCallback クラスによって実装されており、デフォ ルトの実装があります。コールバックを使用する場合は、その関数を 実装する必要があります。各関数の実装例については、 『PowerScript リ ファレンス』マニュアルまたはオンライン ヘルプを参照してくださ い。 v SSLCallBack クラスを実装するには 1 デフォルトの実装 新規作成 ダイアログボックスの[PB オブジェクト]ページから [標準クラス]を選択します。 2 標準クラス データ型の選択 ダイアログボックスで[SSLCallback] を選択し、[OK]をクリックします。 3 セッション情報をユーザに提供し、ユーザから必要な認証情報を 返させるための、コールバック関数のコードを記述します。 4 実装するそのほかのコールバック関数に対して、手順 3 を繰り返 します。 実装を提供していない場合、または実装から空の文字列が返された場 合は、コールバックのデフォルトの実装が使用されます。 GetCertificateLabel および GetCredentialAttribute の場合、引数リストには、 コールバックに対して有効な戻り値である文字列値の配列が含まれま す。これらのコールバックのデフォルトの実装は、この配列が空の場 合、例外を送出し、配列が空でない場合は、その配列の最初の要素を 返します。その結果、配列の最初の要素がサーバで受け入れ可能であ れば、接続プロセスは継続しますが、受け入れ可能でなければ失敗し ます。 TrustVerify の場合、デフォルトの実装は現行の接続を拒否します。 564 PowerBuilder 第 25 章 例外の処理 PowerBuilder クライアントでの SSL の使い方 GetPin、GetCertificateLabel、および GetCredentialAttribute の実装では、要 求された情報をユーザが提供できない場合には、ユーザ側で接続を キャンセルできるようにする必要があります。これを実現するには、 関数の実装内で例外を送出し、ConnectToServer 呼び出しを置く trycatch ブロック内でその例外を取り込みます。コールバック関数内で送 出した例外によって、CTSSecurity::UserAbortedException 例外が発生し ます。関数によって送出できる例外は、その関数のプロトタイプの Throws 句に追加する必要があります。 SSLCallback オブジェクトの指定 サーバに接続するには、まず、SSLCallback オブジェクトの名前を SSLServiceProvider の CallbackImpl プロパティに指定します。 SSLServiceProvider sp int rc getcontextservice("SSLServiceProvider", sp) rc = sp.setglobalproperty( "CallbackImpl", & "uo_sslcallback" ) IF rc <> 0 THEN MessageBox("CallbackImpl の設定に失敗しました ", "rc= " + string(rc)) RETURN END IF MessageBox( "CallbackImpl プロパティの設定 ", & " 成功しました " ) RETURN & クライアント アプリケーションの実行バージョンでコールバック オ ブジェクトを参照できるようにするために、アプリケーション内でそ のコールバック オブジェクト型の変数を宣言しておく必要がありま す。次に例を示します。 uo_sslcallback iuo_sslcb このような宣言を行う理由は、コールバック オブジェクトはその文字 列名によってのみ参照されるため、技術的には非参照オブジェクトで あり、実行ファイルには含まれないためです。宣言した変数をコード で使用する必要はありません。 アプリケーション テクニック 565 セッション セキュリティ情報の取得 セッション セキュリティ情報の取得 CtsSecurity.SSLSession および CtsSecurity.SSLSessionInfo クラスを使用す ると、クライアント アプリケーションでは、プロキシからサーバへの 接続で SSL が使用されるかどうかを判断でき、SSL が使用される場合 には、SSL セッション設定を取得してユーザに対して表示できます。 値を取得できるプロパティの一覧については、Web ブラウザでお使い のサーバ(http://hostname:portnumber/ir/CtsSecurity__SSLSessionInfo.html)に 接続して、SessionInfo に関する EAServer インタフェース リポジトリの マニュアルを参照してください。 long rc string stmp CTSSecurity_sslSessionInfo mySessionInfo rc = thesessioninfo._narrow( mySessionInfo, & "SessionInfo" ) MessageBox( str_header, "Narrow:rc=" + string(rc)) sTmp sTmp stmp sTmp stmp = += += += += "Properties" "~nVersion: " mySessionInfo.getProperty( "Version" ) "~nHost: " mySessionInfo.getProperty( "host" ) stmp += "~nport: " stmp += mySessionInfo.getProperty( stmp += "~nciphersuite: " stmp += mySessionInfo.getProperty( stmp += "~nCertificateLabel: " stmp += mySessionInfo.getProperty( ) stmp += "~nUserData: " stmp += mySessionInfo.getProperty( stmp += "~ntokenName: " stmp += mySessionInfo.getProperty( stmp += "~nuseEntrustID: " stmp += mySessionInfo.getProperty( MessageBox( str_header, stmp) 566 "port" ) "ciphersuite" ) "certificateLabel" "UserData" ) "tokenName" ) "useEntrustID" ) PowerBuilder 第 2 6 章 COM/COM+ コンポーネントの構築 この章について この章では、PowerBuilder を使用して、COM/COM+ コンポーネン トを構築する方法について説明します。 非推奨のテクノロジ COM および COM+ は非推奨のテクノロジであり、PowerBuilder の 今後のリリースではサポートされなくなる可能性があります。 内容 項目 ページ 567 COM/COM+ コンポーネントの構築について 570 コンポーネント オブジェクト モデルについて 574 コンポーネント インタフェースの定義 578 COM コンポーネントからデータベースへのアクセス 582 トランザクションのサポート 585 別のサーバ コンポーネントのメソッドの呼び出し 586 セキュリティ問題 プロジェクト ペインタでの COM/COM+ コンポーネントの構 587 築 590 PowerBuilder COM オブジェクトの実行 591 PowerBuilder COM サーバの配布 593 クライアントから PowerBuilder COM サーバへのアクセス COM/COM+ コンポーネントの構築について ビジネス ロジックを含むカスタム クラス ユーザ オブジェクトを PowerBuilder で開発すると、そのオブジェクトを COM サーバまた は COM+ アプリケーションとしてパッケージ化することができま す。 Windows XP などの COM+ をサポートしているプラットフォーム では、COM+ アプリケーションを構築して COM+ に配布できます。 アプリケーション テクニック 567 COM/COM+ コンポーネントの構築について この章以降では、COM と COM+ をサポートしているコンポーネント のことを、COM コンポーネントと呼んでいます。 PowerBuilder COM アプリケーションには、 1 つまたは複数の PowerBuilder カスタム クラス ユーザ オブジェクトを組み込むことができます。ユー ザ オブジェクトをユーザ オブジェクト ペインタでコード化してから、 プロジェクト ペインタでサーバを構築します。アプリケーションを ローカルの COM+ サーバに直接配布したり、プロジェクト ペインタで COM+ Microsoft インストーラ パッケージを作成したりすることもで きます。 PowerBuilder COM アプリケーションを生成して配布すると、ユーザ は、PowerBuilder、Visual Basic、C++ コンパイラなどのツールで構築 された COM 対応クライアント アプリケーションから、PowerBuilder COM アプリケーションに格納された PowerBuilder オブジェクトのメ ソッドを呼び出すことができます。 ウィザードの使い方について PowerBuilder は、COM コンポーネントの開発と配布を簡単にする以下 のウィザードを用意しています。 • 既存のアプリケーションに新規のカスタ ム クラス ユーザ オブジェクトを作成し、新規のプロジェクトを作 成します。 • プロジェクト ウィザード 1 つまたは複数の既存のカスタム クラス ユーザ オブジェクトから、COM サーバの構築に使用するプロジェ クトを作成し、オプションで COM+ パッケージも作成します。 オブジェクト ウィザード COM/COM+ のオブジェクト ウィザードを使用して、新規のユーザ オ ブジェクトを作成した場合、以下のとおりとなります。 ウィザードを使用する タイミング 568 • オブジェクトには、Activate と Deactivate という、2 つの新しいイ ベントがあります。 • オブジェクトは、COM の検証のサポートを有効にしています。 • ウィザードの最終ページのボックスをオンにした場合には、ウィ ザードは To-Do リストに項目を追加することによって、開発のす べてのステップを実行するよう注意を促します。 新規オブジェクト 単一の新規カスタム クラス ユーザ オブジェクトを 含むサーバを構築する場合には、オブジェクト ウィザードを使用し て、その機能を利用します。 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 複数の新規カスタム クラス ユーザ オブジェクトを含むサーバを構築 する場合にオブジェクト ウィザードを使用すると、オブジェクトごと に異なるプロジェクトが作成されます。したがって、いずれか 1 つの プロジェクトにすべてのオブジェクトを追加し、それ以外のプロジェ クトは破棄する必要があります。 また、オブジェクト ウィザードを使用せずに新規カスタム クラス ユー ザ オブジェクトを作成し、その後でプロジェクト ウィザードまたはプ ロジェクト ペインタを使用してプロジェクトを作成することもでき ます。 ユ ー ザ オ ブ ジ ェ ク ト ペ イ ン タ で は、COM の 検 証 を 有 効 に し て、 Activate イベントと Deactivate イベントをユーザ定義イベントとして 追加することができます。詳細については、577 ページの「COM の検 証」を参照してください。 COM サーバとして配布する 1 つまたは複数のカス タム クラス ユーザ オブジェクトがある場合は、それらのオブジェク トが、574 ページの「コンポーネント インタフェースの定義」および それ以降の節で説明する要件を満たしていることを確認してくださ い。新規のユーザ オブジェクトに関しては、ユーザ オブジェクト ペ インタで COM の検証を有効にし、Activate イベントと Deactivate イベ ントをユーザ定義イベントとして追加します。サーバの構築準備がで きたら、プロジェクト ウィザードを使用してプロジェクトを設定しま す。 既存オブジェクト 開発プロセスについて 1 つまたは複数のカスタム クラス ユーザ オブジェクトから PowerBuilder COM サーバを構築および配布するには、以下の手順を実行する必要が あります。 1 新規カスタム クラス ユーザ オブジェクトを作成するか、または既 存のユーザ オブジェクトを開きます。 オブジェクト ウィザードを使用する場合には、新規オブジェクト の作成と配布に使用するプロジェクト オブジェクトも作成しま す。 2 ユーザ オブジェクト ペインタでユーザ オブジェクトのスクリプ トを記述します。 574 ページの「コンポーネント インタフェースの定義」を参照し てください。 アプリケーション テクニック 569 コンポーネント オブジェクト モデルについて 3 場合によっては、同じアプリケーションで追加のユーザ オブジェ クトの作成とスクリプトの記述を行います。 4 ウィザードを使わずにユーザ オブジェクトを作成した場合は、 COM/COM+ プロジェクト ウィザードまたはプロジェクト ペイン タを使用してプロジェクトを作成します。 587 ページの「プロジェクト ペインタでの COM/COM+ コンポー ネントの構築」を参照してください。 5 プロジェクトを開いて、必要であれば、選択されたオブジェクト とそのプロパティのリストを修正し、プロジェクトを作成します。 6 サーバを配布します。 591 ページの「PowerBuilder COM サーバの配布」を参照してくだ さい。 コンポーネント オブジェクト モデルについて Microsoft コンポーネント オブジェクト モデル(COM)は、ソフトウェ ア コンポーネントが互いにサービスを提供するための標準的な方法 を定義します。実行環境、レジストリ エントリ、およびタイプ ライブ ラリ(オプション)を提供すれば、どの PowerBuilder カスタム クラス ユーザ オブジェクトでも、COM オブジェクトとして使用できます。 PowerBuilder や Visual Basic などの COM 準拠ツールで作成したクライ アントは、COM オブジェクトのビジネス ロジックを使用できます。そ れには、COM オブジェクトのインスタンスを作成し、そのインタ フェースによって公開されているメソッドを呼び出します。サポート するインタフェースによって、COM オブジェクトは、Java と C++ の クライアントからも使用できます。 COM+ は、より多くのリソース管理タスクに対処し、スレッド プーリ ング、オブジェクト プーリング、ジャストインタイムのオブジェクト のアクティブ化を実現することで、COM を拡張したものです。 570 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 PowerBuilder COM サーバについて PowerBuilder は、単一の PowerBuilder COM サーバを作成します。この COM サーバには、プロジェクト作成時に選択したすべてのカスタム ク ラス ユーザ オブジェクトに対応する PowerBuilder COM オブジェクト が含まれています。 COM は、オブジェクトを作成と破棄する方法、インタフェースを公開す る方法、メソッドの呼び出し方法を指定します。PowerBuilder COM サー バは COM 仕様に従います。つまり、PowerBuilder COM オブジェクト が、PowerBuilder 仮想マシンを介してカスタム クラス ユーザ オブジェ クトとやり取りしていることを、クライアントが意識することはあり ません。 オートメーション サーバと PowerBuilder COM サーバの比較 以前のリリースの PowerBuilder では、PowerBuilder COM サーバとオー トメーション サーバという 2 つの方法で COM オブジェクトを生成で きました。いずれもウィザードとプロジェクト ペインタからのアクセス が可能でした。PowerBuilder COM サーバは、オートメーション サーバ より多くの機能を提供します。 オートメーション サーバの使用終了について PowerBuilder では、オートメーション サーバでの COM オブジェクト の生成をサポートしなくなりました。このため、このセクションは参 考情報用としてのみ維持します。 PowerBuilder COM サーバには、複数のカス タム クラス ユーザ オブジェクトを含めることができます。ユーザ オ ブジェクトをコーディングした後で、プロジェクト ペインタを使用し て、すべてのオブジェクト用の 1 つの自己登録型 DLL を生成します。 構築コンピュータ上で実行する場合には、作成した COM サーバは、 COM+ に直接配布できます。また、COM+ パッケージを作成すること もできます。COM サーバ内の PowerBuilder COM オブジェクトは、実 行時セッションを共有できます。また、同じ COM クライアントから 作成されたオブジェクト間で参照を受け渡すこともできます。 PowerBuilder COM サーバ COM サーバには、埋め込み PowerBuilder 動的ライブラリ(PBD)ファ イルも含まれています。PBD ファイルは、選択したすべてのカスタム クラス ユーザ オブジェクトとそれに依存するコンパイル済みオブ ジェクトに加えて、レジストリとタイプ ライブラリの情報も含みま す。 アプリケーション テクニック 571 コンポーネント オブジェクト モデルについて PowerBuilder COM サーバを、サーバが要求するすべてのランタイム ファイルと合わせて PowerBuilder 仮想マシンに配布します。 以前のバージョンの PowerBuider では、カス タム クラス ユーザ オブジェクトが構築するオートメーション サーバ に含まれるオブジェクトは 1 つのみでした。ユーザ オブジェクトの記 述後は、それを含む PBL からランタイム ライブラリを構築し、次にプ ロジェクト ペインタを使用してレジストリ ファイルとオプションの タイプ ライブラリ ファイルを作成しなければなりませんでした。オー トメーション サーバの配布後は、ユーザのコンピュータに合わせてレ ジストリ ファイルをカスタマイズし、そのレジストリ ファイルを実行 することによってオートメーション サーバの登録が可能でした。 オートメーション サーバ ディスパッチ、デュア ル、カスタムの各イン タフェース オートメーション サーバは、ディスパッチ インタフェース(dispinterface ともいう)を使用します。これによって、ユーザは、IDispatch という 標準 COM インタフェースの Invoke メソッドを使用して、サーバ上の メソッドを呼び出すことができます。 COM サーバでは、ディスパッチベースのインタフェースよりも高いパ フォーマンスを提供する、カスタム インタフェースまたはデュアル イ ンタフェースを使用できます。カスタム インタフェースは、サーバの インタフェース内のメソッドへのポインタが格納された仮想テーブル (VTBL または vtable ともいう)を介して、サーバ上のメソッドへのア クセスを提供します。デュアル インタフェースを使用すれば、クライ アントは、IDispatch::Invoke または仮想テーブルのどちらを使用しても、 メソッドを呼び出すことができます。 詳細については、589 ページの「カスタム インタフェースとデュアル インタフェースの選択」を参照してください。 サーバ間の相違のまと め 572 表 26-1 に、PowerBuilder オートメーション サーバと、デュアル インタ フェースまたはカスタム インタフェースを使用する PowerBuilder COM サーバとの相違をまとめます。 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 表 26-1: オートメーション サーバと COM サーバの比較 機能 インプロセス サーバのサポート IDL ファイルの生成 C++ クライアントのサポート Java クライアントのサポート PowerBuilder クライアントのサ ポート Visual Basic 4 クライアントのサ ポート * # $ オートメー ション サー COM サーバ バ *(ディス (デュアル パッチ イン インタ タフェース) フェース) Yes Yes# No Yes No Yes Yes Yes Yes Yes COM サーバ (カスタム インタ フェース) Yes Yes Yes No No Yes Yes No Visual Basic 5 カスタム インタ フェースのサポート No No Yes インスタンス変数およびメソッ ド引数タイプとしての PowerBuilder 構造体のサポート すべての C 言語データ型のサ ポート 埋め込みタイプ ライブラリのサ ポート 自己登録サーバ DCOM のサポート $ EAServer のサポート COM+ のサポート 別個のプロキシ / スタブ DLL が 必要 PowerBuilder ランタイム DLL が 必要(最低限 PBVM115.DLL と その依存ライブラリ) ライブラリ ペインタで作成した アプリケーション ランタイム ラ イブラリの配布が必要 No No No No No No No Yes Yes No Yes Yes No No Yes Yes Yes Yes No Yes Yes No Yes No Yes Yes Yes Yes No No 以前のリリースの PowerBuilder でのみ利用可能です。 PowerBuilder 実行 DLL(PBVM115.dll)は、インプロセス サーバです。 PowerBuilder 実行 DLL を収容するために、代理ホストを使用する必要があります。 アプリケーション テクニック 573 コンポーネント インタフェースの定義 コンポーネント インタフェースの定義 PowerBuilder カスタム クラス ユーザ オブジェクトを COM コンポーネ ントとして構築した場合には、そのオブジェクトに定義された関数と インスタンス変数(オプション)がコンポーネント インタフェースに 表示されます。PowerBuilder が生成する IDL ファイルでは、サーバ内 に含まれるカスタム クラス ユーザ オブジェクトごとの COM クラス と 1 つのインタフェースに加えて、PowerBuilder COM サーバのタイプ ライブラリ名と関連する ID も定義します。 メソッドとデータ型 関数 各 PowerBuilder COM オブジェクトは単一のインタフェースをサポー トしており、これによって、カスタム クラス ユーザ オブジェクト内 のユーザ定義パブリック関数ごとにメソッドを公開します。 関数の戻り値は、追加の retval 引数によって表されます。たとえば、オ ブジェクトに以下のユーザ オブジェクト関数が存在するとします。 f_addtwo (long al_num1, long al_num2) returns long f_getinfo (REF string as_name, REF integer ai_age, REF character ac_gender) returns integer IDL ファイル内に以下のメンバー関数が生成されます。 HRESULT f_addtwo( [in] long al_num1, [in] long al_num2, [out, retval] long * retval ); HRESULT f_getinfo( [in, out] BSTR * as_name, [in, out] short * ai_age, [in, out] unsigned char * ac_gender, [out, retval] short * retval ); インスタンス変数 COM オブジェクトは自分のデータを公開しないため、カスタム クラ ス ユーザ オブジェクト内のパブリック インスタンス変数は、COM オ ブジェクトにおいて変数値を取得および設定するためのインタフェー ス メソッドとして表現します。変数のアクセサ メソッドをインタ フェースとして公開するための指定は、プロジェクト ウィザードまた はプロジェクト ペインタの[オブジェクト]プロパティ ページで行い ます。 パブリック変数が書き込み可能である場合には、Put メソッドが公開され ます。プライベート変数とプロテクト変数、privateread または protectedread として宣言された変数、および privatewrite または protectedwrite として 宣言された変数の場合には、メソッドは生成されません。変数がパブ リックに読み込み可能である場合には、Get メソッドが公開されます。 たとえば、オブジェクトに以下のインスタンス変数があるとします。 574 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 public string is_name private integer ii_a public privatewrite string is_label constant real lr_pi = 3.14159265 IDL ファイル内に以下のメソッドが作成されます。 [id(4), propget] HRESULT BSTR *is_name); [id(4), propput] HRESULT BSTR is_name); [id(1), propget] HRESULT BSTR *is_label); [id(6), propget] HRESULT float * lr_pi); データ型マッピング is_name([out,retval] is_name([in] is_label([out,retval] lr_pi( [out,retval] 表 26-2 で示すように PowerBuilder のデータ型は COM のデータ型に マップします。 表 26-2: PowerBuilder と COM のデータ型のマッピング PowerBuilder データ型 COM のデータ型(バリアント) Boolean Variant_BOOL Character Unsigned char Integer Short UnsignedInteger Unsigned short Long Long UnsignedLong Unsigned long Real Float Double Double Decimal Double String BSTR Date DATE Time DATE DateTime DATE Blob SAFEARRAY(Unsigned char) Arrays(PowerBuilder データ型) ResultSet SAFEARRAY(COM データ型) LPDISPATCH カスタム クラス ユーザ オブジェ LPDISPATCH クト * Any サポートなし グローバル構造体 サポートなし OLEObjects サポートなし アプリケーション テクニック 575 コンポーネント インタフェースの定義 * カスタム クラス ユーザ オブジェクトは、同じ COM アパートメントの同じクライア ント内(つまり、同じスレッド内)で作成する必要があります。 コーディング上の制約 ユーザ オブジェクトを COM コンポーネントとして配布する場合に は、コードで使用できない要素がいくつかあります。 関数の多重定義は使用 できない COM は、COM オブジェクトへのインタフェースにおいて、関数の多 重定義をサポートしていません。ユーザ オブジェクト(およびその先 祖)内の各関数の名前は一意でなければなりません。PowerBuilder COM オブジェクトは単一のインタフェースしか持ちません。同じ名前で あってもシグネチャが異なる複数の関数は、複数のインタフェースが 必要となります。 先祖変数と先祖関数の 表現方法 子孫ユーザ オブジェクトから PowerBuilder COM オブジェクトを生成 すると、先祖と子孫のパブリック インスタンス変数と関数がその COM オブジェクトに表現されます。一部のコンポーネント メソッドは先祖 オブジェクトから派生したものになりますが、そのことはクライアン トからは見えません。上述の関数の多重定義の制約によって、子孫オ ブジェクトの関数は先祖オブジェクトの関数を上書きはできますが、 多重定義することはできません。 引数と戻り値のデータ 型 COM オブジェクトとして配布する非ビジュアル オブジェクトに関連 付けられたメソッドは、以下のデータ型を持つ引数を受け取ることが できます。 • 標準の OLE オートメーション データ型 • カスタム クラスの(非ビジュアル)ユーザ オブジェクト COM コンポーネント メソッドは、PowerBuilder 構造体または Any 型の 引数または戻り値を受け取ることができません。引数として Any 変数 を受け取ったり、Any 変数を返したりする PowerBuilder 非ビジュアル オブジェクト上で定義された関数は、そのオブジェクトのローカルな コードからは呼び出せますが、クライアントまたはそのほかの COM コ ンポーネントからこれらの関数にアクセスすることはできません。 コンポーネント メソッドへの引数には、ビジュアル オブジェクト (ウィンドウやメニューなど) 、および大半のシステム タイプ(Transaction オブジェクトや DataStore オブジェクトなど)も指定できません。サ ポートされている唯一のシステム タイプは、ResultSet オブジェクトで す。 576 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 コンポーネント メソッドの戻り値には、任意の標準データ型を指定で きます。また、カスタム クラス(非ビジュアル)ユーザ オブジェクト も指定できます。 COM の検証 COM コンポーネントとして配布する予定のカスタム クラス ユーザ オ ブジェクトを設計する場合には、COM において有効でないコード要素 を使用したときに、PowerBuilder に警告させることができます。 COM の検証では、関数の多重定義の有無をチェックし、パブリック イ ンスタンス変数とパブリック関数で、システム タイプ、ビジュアル タ イプ、構造体、および Any 変数が使用されていないかチェックします。 ユーザ オブジェクト ペインタで、メニューバーから[デザイン| COM 検証]がチェックされていることを確認してください。オブジェクト を保存すると、出力ウィンドウに以下のような警告が一覧表示されま す。 情報 C0197: コンポーネント検証 警告 C0198: 適切でない COM タイプ : 'any' arg type for function: 'of_badfunc' 警告 C0198: 適切でない COM タイプ : 'window' arg type for function: 'of_badfunc' 検証状態は、ユーザ オブジェクト ペインタではなく、編集中のオブ ジェクトに関連付けられます。オブジェクトを再び開くと、オブジェ クトの検証状態は閉じたときと同じになります。新規の COM オブジェ クトは、COM 検証がチェックされた状態で作成されます。 ログ ファイルへのエラー記録 COM+ で動作している COM オブジェクトによって生成されたエラー を、Windows シ ス テ ム の ア プ リ ケ ー シ ョ ン ロ グ に 出 力 す る に は、 ErrorLogging サービス コンテキスト オブジェクトのインスタンスを作 成し、その log メソッドを呼び出します。たとえば、次のようになり ます。 ErrorLogging el this.GetContextService("ErrorLogging", el) el.log(" この文字列をログに書き込みます ") アプリケーション テクニック 577 COM コンポーネントからデータベースへのアクセス 例外情報の自動記録 サーバで実行している PowerBuilder コンポーネントが引き起こす例外 の種類および例外の位置に関する情報は、自動的にサーバ ログに記録 されます。これらの例外についての最低限の情報を取得するためにエ ラー ロギング サービスを実行する必要はありません。 COM コンポーネントからデータベースへのアクセス COM+ のトランザクション管理サポートを活用するには、COM+ がサ ポートするデータベース インタフェースのいずれかを使用してデー タベースに接続する必要があります。PowerBuilder で開発したコン ポーネントのデータベース接続の詳細については、 『データベースとの 接続』マニュアルを参照してください。 PowerBuilder で開発された COM コンポーネントは、データストアを使 用して、データベースとの対話処理を行うことができます。データス トア は非表示のデータウィンドウ コントロールです。つまり、データ ウィンドウ コントロールと同じように動作しますがビジュアル属性 を持ちません。データストア オブジェクトを分散アプリケーションで 使用すると、データベース処理を、各クライアント コンピュータ上で はなくリモート サーバ上で行うことができます。 トランザクション サーバ環境におけるデータベース アクセスに デー タストア を使用する方法についての詳細は、474 ページの「データス トアの使い方」を参照してください。 578 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 結果集合の受け渡し PowerBuilder は、3 つのシステム オブジェクトによって、トランザク ション サーバ環境で動作しているコンポーネントから結果集合を取 得したり、トランザクション サーバ コンポーネントとして動作してい る PowerBuilder ユーザ オブジェクトから結果集合を返したりする操作 を行います。これらのシステム オブジェクト(ResultSet、ResultSets、 および ADOResultSet)は、データストア オブジェクトとの間でトラン ザクション サーバの結果集合の変換を簡単にするために設計された ものであり、状態情報を含んでいません。また、データベースの更新 用には設計されていません。ADOResultSet は、COM コンポーネント でのみ使用できます。 COM+ は、ActiveX Data Objects(ADO)RecordSet オブジェクトを使用 して、結果集合を返します。ADO Recordset オブジェクトは、レコード (行)とフィールド(カラム)から構成され、データベース テーブル 内のレコードの集合を表します。 ADO Recordsets と PowerBuilder システ ム オブジェクト PowerBuilder では、PowerBuilder ADOResultSet システム オブジェクト 上の関数を使用して、データを取得および設定します。データは ADO Recordset として受け渡しされます。PowerBuilder クライアントは、 OLEObjects を使用して ADO Recordsets を処理します。ResultSet オブ ジェクトに格納された結果集合のデータストアへの変換とデータスト ア オブジェクトから結果集合への変換を行うには、データストア オブ ジェクトの CreateFrom 関数と GenerateResultSet 関数を使用します。 GenerateResultSet について GenerateResultSet には、EAServer で MASP(Method as Stored Procedure) を使用するとき、結果集合を戻すのに使用する別の構文もあります。 表 26-3 に、これらのオブジェクトの対話方法を示します。 表 26-3: 結果集合オブジェクト 使用する変数の タイプ ResultSet OLEObject アプリケーション テクニック 使用方法 COM コンポーネントに定義されたメソッド(関数)の戻 り値として使用する。データは ADO Recordset としてマー シャリングされる ResultSet を返す COM コンポーネント上のメソッドから 返 された ADO Recordset を保持する。OLEObject は、 MoveFirst などの ADO Recordset 関数を使用して操作でき る 579 COM コンポーネントからデータベースへのアクセス 使用する変数の タイプ 使用方法 ADOResultSet SetResultSet を使用して、ADOResultSet オブジェクトに ResultSet オブジェクトのデータ値を設定する SetRecordSet を使用して、ADOResultSet オブジェクトに、 ADO Recordset を保持する OLEObject のデータ値を設定す る DataStore GetRecordSet を使用して、OLEObject に ADOResultSet の データ値を設定する。OLEObject は、MoveFirst などの ADO Recordset 関数を使用して操作できる CreateFrom を使用して、ResultSet 型または ADOResultSet 型のオブジェクトからデータストアを作成する GenerateResultSet を使用して、トランザクション サーバ上 のメソッドでデータストア オブジェクトから ResultSet オ ブジェクトを生成する。ResultSet オブジェクトは、クライ アントに返すことができる PowerBuilder クライ アントから COM コン ポーネント内の結果集 合にアクセス PowerBuilder クライアントが、ADO Recordset を返す COM コンポーネ ント メソッドを呼び出すと、返されたデータは OLEObject オブジェクト に格納されます。ADO Recordset 内のデータを操作するには、Recordset 関数を使用します。これについては、次の「PowerBuilder における ADO Recordset の使い方」で説明します。 OLEObject オブジェクト内のデータを使用してデータストア オブジェ クトを設定するには、ADOResultSet オブジェクトを作成してから、そ の SetRecordSet 関数を呼び出して、OLEObject オブジェクトに格納さ れたデータ値を設定します。 ADOResultSet オブジェクト内のデータをデータストア オブジェクト に設定するには、CreateFrom データストア関数を使用します。 OLEObject loo_mycomponent OLEObject loo_ADOrecordset ADOresultset lrs_ADOresultset datastore ds_local integer li_rc loo_mycomponent = CREATE OLEObject li_rc = loo_mycomponent.ConnectToNewObject("PB.Test") if li_rc <> 0 then MessageBox(" 接続失敗 ", string(li_rc) ) Return end if // OLEObject を使用して、COM コンポーネント上の 580 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 // メソッドから返された ADO Recordset を保持する loo_ADOrecordset = loo_mycomponent.GetTestResult() // ADOResultSet を作成し、渡された ADO Recordset を // 保持している OLEObject からそのデータを取得する lrs_ADOresultset = CREATE ADOResultSet lrs_ADOresultset.SetRecordSet(loo_ADOrecordset) // CreateFrom を使用して、ADOResultSet オブジェクト // のデータをデータストアに設定する ds_local = CREATE datastore ds_local.createfrom(lrs_ADOresultset) PowerBuilder におけ る ADO Recordset の 使い方 MoveFirst や MoveNext な ど の ADO Recordset メ ソ ッ ド を 使 用 し て、 PowerBuilder で ADO Recordset を操作する場合は、SetResultSet 関数と GetRecordSet 関数を使用します。SetResultSet 関数を使用して、新規の ADOResultSet オブジェクトに ResultSet オブジェクトのデータ値を設 定し、GetRecordSet 関数を使用して ADO Recordset を返します。 次の例では、既存の データストア オブジェクトから、ResultSet オブ ジェクトに結果集合を生成しています。ResultSet オブジェクトを使用 し て、新 し い ADOResultSet オ ブ ジ ェ ク ト に デ ー タ を 設 定 し ま す。 ADOResultSet オブジェクト上の GetRecordSet 関数を使用して、ADO Recordset を OLEObject として返し、この OLEObject を ADO Recordset メソッドで使用します。 ResultSet lrs_resultset ADOresultset lrs_ADOresultset OLEObject loo_ADOrecordset // 既存のデータストアから結果集合を生成する ds_source.GenerateResultSet(lrs_resultset) // 新しい ADOResultSet オブジェクトを作成し、生成された // 結果集合をそのオブジェクトに設定する lrs_ADOresultset = CREATE ADOResultSet lrs_ADOResultset.SetResultSet(lrs_resultset) // ADOResultSet オブジェクト内のデータを // OLEObject に渡し、ADO Recordset として使用できるようにする loo_ADOrecordset = CREATE OLEObject lrs_ADOResultset.GetRecordSet(loo_ADOrecordset) // OLEObject 上のネイティブな ADO Recordset メソッドを // 呼び出す loo_ADOrecordset.MoveFirst() アプリケーション テクニック 581 トランザクションのサポート COM および COM+ コンポーネントから結 果集合を返す COM または COM+ に配布される PowerBuilder ユーザ オブジェクトと の間で結果集合を受け渡しするには、関数の引数または戻り値のデー タ型に ResultSet を指定します。GenerateResultSet 関数を呼び出して、 COM または COM+ 内のデータストア オブジェクトから結果集合を作 成すると、結果集合はマーシャリングされて、ADO Recordset としてク ライアントに返されます。 次の例では、データストア オブジェクトを作成し、その中にあるデー タを取り出し、続いて GenerateResultSet 関数を使用して、クライアン トに返す結果集合を作成しています。 datastore ds_datastoreresultset lrs_resultset integer li_rc ds_datastore = create datastore ds_datastore.dataobject = "d_empdata" ds_datastore.SetTransObject (SQLCA) IF ds_datastore.Retrieve() = -1 THEN // エラーを返して復帰 END IF li_rc = ds_datastore.generateresultset(lrs_resultset) IF li_rc <> 1 THEN // エラーを返して復帰 END IF return lrs_resultset トランザクションのサポート コンポーネントがトランザクションをサポートする場合、COM+ は、 コンポーネントのデータベース操作がトランザクションの一部として 実行されるようにします。 トランザクション サービス コンテキス ト オブジェクトの使 い方 582 COM+ で動作する PowerBuilder コンポーネントは、トランザクション コンテキスト サービスを使用して、トランザクションを制御できま す。PowerBuilder COM オブジェクトが作成するコンテキスト オブジェ クトによって、PowerBuilder コンポーネントは Microsoft DTC を利用す ることができます。TransactionServer オブジェクトによって、COM+ で動作する COM オブジェクトは、オブジェクトに関連付けられてい るコンテキストにアクセスできるため、トランザクションとアクティ ブ化をより厳しく管理できます。また、セキュリティ コンテキストに 関しても部分的に制御が可能です。 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 TransactionServer オブジェクトとそのメソッドのについての詳細は、 『オブジェクトとコントロール』マニュアルおよび『PowerScript リファ レンス』マニュアルを参照してください。 トランザクション コンテキスト サービスを使用するには、その前に、 TransactionServer 型の変数を宣言し、GetContextService 関数を呼び出し てサービスのインスタンスを作成する必要があります。 TransactionServer txninfo_base this.GetContextService("TransactionServer", & txninfo_base) コンポーネントのトランザクション コンテキストに関する情報にア クセスしてトランザクションを制御するには、たとえば、次のように、 TransactionServer オブジェクトのインスタンス上のメソッドを呼び出 します。 IF txninfo_base.IsInTransaction() THEN txninfo_base.DisableCommit() END IF ... txninfo_base.SetComplete() サービスへの参照が不要になったら、次のように破棄してください。 DESTROY txninfo_base COMMIT と ROLLBACK の動作 PowerBuilder コンポーネントが COM+ で動作しており、 UseContextObject DBParm パラメータに Yes が設定されている場合に は、TransactionServer インタフェースを使用してトランザクションを 制御します。UseContextObject の DBParm パラメータに Yes が設定さ れていると、COMMIT 文と ROLLBACK 文でデータベース エラーが発生 します。このトランザクションは、TransactionServer コンテキスト オ ブジェクトのインスタンスを介して SetComplete または SetAbort が発行 されるまでは、アクティブ状態を保ちます。 アプリケーション テクニック 583 トランザクションのサポート PowerBuilder 6 コンポーネントの移行 PowerBuilder 6 で作成したコンポーネントは、 COM+ に対する SetComplete または SetAbort 呼び出しの発行を、PowerBuilder のデータベース ドラ イバで行っています。これらのコンポーネントを現行のバージョンの PowerBuilder に移行する場合には、TransactionServer インタフェースを 使 用 す る よ う に、コ ー ド を 修 正 し な け れ ば な り ま せ ん。ま た は、 UseContextObject DBParm に No を設定する方法もあります。この場合、 COMMIT は SetComplete と等しくなり、ROLLBACK は SetAbort と等しく なります。この方法は、PowerBuilder のオブジェクトをコードを修正 せずに移行する場合にだけお勧めします。 コンポーネントがトラ ンザクションをサポー トするかどうかの指定 各 COM+ コンポーネントには、コンポーネントのトランザクションへ の参加方法を指示するトランザクション プロパティがあります。 COM+ におけるコンポーネント トランザクション プロパティに[新規 が必要]を設定すると、PowerBuilder COM オブジェクトは、新規のコ ンテキスト オブジェクトを作成します。PowerBuilder COM オブジェク トのコンポーネント トランザクション プロパティに、[必要]または [サポート]を設定すると、既存のオブジェクトからトランザクション を継承するか、または新規トランザクションを作成します。 このプロパティは、COM/COM+ プロジェクト ウィザードまたはプロ ジェクト ペインタで設定します。設定可能な値は、表 26-4 のとおりで す。 表 26-4: コンポーネント トランザクション プロパティの値 トランザクションの 種類 [サポートなし] [サポート] 584 説明 コンポーネントはトランザクションの一部として実 行されない。コンポーネントが、トランザクション 内部で実行中の別のコンポーネントによってアク ティブにされた場合には、その新しいインスタンス の作業は既存のトランザクションの外部で行われる コンポーネントは COM+ トランザクションのコンテ キスト内で実行できるが、コンポーネントのメソッ ドを実行するために接続は必要ない。コンポーネン トがクライアントによって直接インスタンス化され た場合には、COM+ はトランザクションを開始しな い。コンポーネント A がコンポーネント B によって インスタンス化され、コンポーネント B はトランザ クション内部で実行されている場合には、コンポー ネント A は同じトランザクション内で実行される PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 トランザクションの 種類 説明 [必要] コンポーネントは常にトランザクション内で実行さ れる。コンポーネントがクライアントによって直接 インスタンス化された場合には、新しいトランザク ションが始まる。コンポーネント A がコンポーネン ト B によってアクティブにされ、しかも B はトラン ザクション内で実行されている場合には、A は同じ トランザクション内で実行される。B がトランザク ション内で実行されていない場合には、A は新しい トランザクション内で実行される [新規が必要] コンポーネントがインスタンス化されるたびに、新 しいトランザクションが始まる。コンポーネント A がコンポーネント B によってアクティブにされ、B がトランザクション内部で実行されている場合に は、A は B のトランザクションの結果に影響されな い新しいトランザクションを開始する。B がトラン ザクション内で実行されていない場合には、A は新 しいトランザクション内で実行される 別のサーバ コンポーネントのメソッドの呼び出し COM+ では、あるサーバ コンポーネントのメソッドが、別のサーバ コ ンポーネントのメソッドを呼び出すことができます。この別のサーバ コンポーネントは、PowerBuilder コンポーネントである必要はなく、 COM+ によってサポートされている任意の言語で実装できます。 OLEObject オブジェ クトの使い方 別のコンポーネントのメソッドにアクセスするには、クライアントか らコンポーネントを呼び出す場合と同様に、OLEObject 型の変数を宣 言し、ConnectToNewObject 関数を呼び出して、コンポーネントに接続 します。ConnectToNewObject は、サーバ オブジェクトのトランザクショ ン コンテキストを自動的に継承します。 TransactionServer オ ブジェクトの使い方 現行のサーバ内の別のコンポーネントのメソッドにアクセスするには、 PowerBuilder が提供する、TransactionServer というトランザクション サービス コンテキスト オブジェクトを使用できます。TransactionServer インタフェースが提供する CreateInstance というメソッドを使用すれ ば、ローカルで使用するほかのコンポーネントにアクセスできます。 CreateInstance は、呼び出し元のコンポーネントに適用されるのと同じ ユーザ情報とパスワード情報を使用します。 アプリケーション テクニック 585 セキュリティ問題 セキュリティ問題 COM+ に配布するコンポーネントを開発するときには、ロールを定義 して、特定のトランザクションの実行を許可されるユーザまたはユー ザのグループを決定することができます。コンポーネントを配布する ときには、COM+ Component Services ツールで特定のユーザにロールを 割り当てます。 プロジェクト ペイン タまたはウィザードで の権限の設定 ウィザードを使用して COM/COM+ プロジェクトを作成した場合に は、コンポーネントを呼び出すクライアントのセキュリティ資格を チェックするよう、COM+ に指示することができます。プロジェクト ペインタでは、[COM+ コンポーネント]と[COM+ パッケージ]の プロパティ ページで、コンポーネントとパッケージの 2 つのレベルで のチェックを指定することができます。 セキュリティを有効にするには、Microsoft Management Console 内で COM アプリケーションにロールを追加し、ユーザをそのロールに割り 当て、そのロールをコンポーネントに与えます。 プログラムによるセ キュリティ PowerBuilder がトランザクション サービス オブジェクトで提供してい る関数をコンポーネント内で使用すれば、呼び出し側に特定のメソッ ドを呼び出す権限があるかどうか、プログラムで判定することができ ます。IsSecurityEnabled は、コンポーネントのセキュリティが有効であ るかどうかを判定します。IsCallerInRole は、コンポーネントのメソッド を呼び出すクライアント プロセスまたはサーバ プロセスが、呼び出し 権限を持つロールに含まれるどうかを判定します。 偽装 IsCallerInRole は、現行のメソッドの直接の呼び出し側のロールを調べ ます。クライアントがコンポーネント上のメソッドを呼び出し、その メソッドがデータベースにアクセスする場合には、データベースへの アクセス権は、クライアントではなく、コンポーネントのセキュリティ コンテキストによって決定されます。PowerBuilder がトランザクショ ン サービス オブジェクトに提供する追加関数によって、コンポーネン トは、クライアントに権限のない操作を実行する前に、クライアント のセキュリティ コンテキストを判断することができます。 ImpersonateClient は、クライアントのセキュリティ コンテキストを判断 します。IsImpersonating は、コンポーネントがそのクライアントのセ キュリティ コンテキスト内で動作しているかどうかを判断します。ま た、RevertToSelf は、コンポーネントのセキュリティ コンテキストを復 元します。 586 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 プロジェクト ペインタでの COM/COM+ コンポーネント の構築 PowerBuilder COM サーバは、プロジェクト ペインタで構築します。 ユーザ オブジェクトの作成時にプロジェクトを作成しなかった場合 には、COM/COM+ プロジェクト ウィザードを使用して作成できます。 [プロジェクト]タブの[COM/COM+ コンポーネント]アイコンを選 択すれば、プロジェクト ペインタで COM コンポーネントを直接作成 するプロジェクトを設定できます。 COM サーバに組み込みたい 1 つまたは複数のオブジェクトに対して、 COM/COM+ プロジェクトをすでに作成している場合には、プロジェク ト ペインタで修正し、必要に応じてオブジェクトを追加します。 プロジェクト ペインタのワークスペースは読み取り専用の領域であ り、ウィザードで選択したオプション、またはペインタのオブジェク トの選択 ダイアログボックスおよびプロパティ ダイアログボックス で選択したオプションが表示されます。PowerBuilder COM サーバを構 築する際、このワークスペースには、構築プロセスの各ステップのス テータスとオブジェクト検査レポートも表示されます。 v PowerBuilder COM サーバ プロジェクトを定義および構築するには 1 新規作成 ダイアログボックスの[プロジェクト]タブから [COM/COM+ コンポーネント ウィザード]を選択します。 2 プロジェクトの名前と位置を含む、プロジェクト プロパティを指 定します。 3 サーバに組み込みたい 1 つまたは複数のオブジェクトを選択しま す。 4 各オブジェクトのプロパティを指定し、必要なら COM+ の配布オ プションも指定して、[完了]をクリックします。 プロパティを指定する際には、ウィザードの状況依存ヘルプまた は以下の項目を参考にしてください。 プロパティ インタフェース オプ ション 構築オプション コンポーネントの登録 アプリケーション テクニック 参照箇所 589 ページの「カスタム インタフェースと デュアル インタフェースの選択」と 574 ペー ジの「インスタンス変数」 590 ページの「埋め込み PBD の設定」 589 ページの「コンポーネントの自動登録」 587 プロジェクト ペインタでの COM/COM+ コンポーネントの構築 プロパティ COM+ の配布オプショ ンとパッケージ オプ ション COM+ トランザクショ ンの設定 COM+ セキュリティ 参照箇所 589 ページの「COM+ にコンポーネントを配 布」 584 ページの「コンポーネントがトランザク ションをサポートするかどうかの指定」 586 ページの「セキュリティ問題」 5 [ファイル|開く]を選択し、作成したばかりのプロジェクトを選 択して、プロジェクト ペインタを開きます。 正しいオブジェクトが選択されていることを確認するには、メ ニューバーから[編集|オブジェクトの選択]を選択します。 6 [編集|プロパティ]を選択してウィザードで設定したプロパティ を確認し、必要なら修正します。 一部の高度な COM+ パッケージ プロパティは、プロジェクト ペイ ンタでのみ設定できます。 7 プロジェクト ペインタで[配布]ボタンをクリックして、 PowerBuilder COM サーバを構築します。 こ の 構 築 プ ロ セ ス で は、選 択 し た 各 ユ ー ザ オ ブ ジ ェ ク ト の PowerBuilder COM オブジェクトを含む PowerBuilder COM サーバ (DLL)と IDL ファイルが作成されます。COM+ への配布を指定 し、COM+ がコンポーネントを生成するコンピュータ上にインス トールされ動作している場合、コンポーネントはサーバに直接配 布されます。このとき、追加の配布ファイルが作成されることも あります。 PowerBuilder COM サーバに含まれる埋め込み型 PBD ファイルに は、カスタム クラス ユーザ オブジェクトと、それらのオブジェク トが参照する補助オブジェクトに加えて、埋め込みのタイプ ライ ブラリも含まれています。 オブジェクト呼び出し後のプロジェクトの構築 開発環境で COM オブジェクトを呼び出すと、COM オブジェクトは PowerBuilder と同じプロセスで管理されるので PowerBuilder が終了す るまでメモリに残ります。オブジェクトを呼び出してから変更し、プ ロジェクト ペインタで再生成しようとすると、コンパイル エラーとリ ンク エラーが発生します。プロジェクトを構築する前に、PowerBuilder をシャットダウンして再起動し、メモリからオブジェクトを解放して ください。 588 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 コンポーネントの自動登録 プロジェクト ウィザードまたはプロジェクト ペインタでは、構築に成 功したときに、生成されたすべての PowerBuilder COM オブジェクトを 自動登録するように指定できます。これによって、使用コンピュータ でのコンポーネントのテストが簡単になります。使用コンピュータ上 で不必要なレジストリ エントリが作成されるのを避けるため、このオ プションを選択するのは、PowerBuilder COM サーバのテスト準備が完 了してからにしてください。 COM+ にコンポーネントを配布 正常に構築されたコンポーネントは、COM+ に自動的に配布できます。 アプリケーションを Microsoft Windows Installer(MSI)ファイルにエク スポートし、これを使って別のコンピュータ上の COM+ サーバにパッ ケージをインポートできます。次にアプリケーション プロキシを MSI ファイルとしてエクスポートし、それをクライアント コンピュータ上 にインストールすると、リモートの COM+ サーバにアクセスできるよ うになります。 カスタム インタフェースとデュアル インタフェースの選択 COM オブジェクトを生成するときには、クライアントにカスタム イ ンタフェースとデュアル インタフェースのどちらを公開するのかを 選択する必要があります。PowerBuilder COM オブジェクトでは、現在、 どちらのインタフェース タイプでも、標準の OLE オートメーション データ型しか使用できません。 カスタム インタ フェース カスタム インタフェースは、サーバ オブジェクトの仮想関数テーブル (VTBL)へのアクセスを通じて、ディスパッチベースのインタフェー スより高いパフォーマンスと、デュアル インタフェースよりすっきり した使用モデルを提供します。クライアントを C++ などのコンパイル 言語で記述する場合、または Visual Basic などのツールでカスタム イ ンタフェースのサポートを活用する場合には、カスタム インタフェー スの使用を考えてください。 カスタム インタフェースを使用する PowerBuilder COM オブジェクト は、COM によって提供される標準のマーシャル処理を使用します。 アプリケーション テクニック 589 PowerBuilder COM オブジェクトの実行 デュアル インタ フェース デュアル インタフェースを使用すれば、プログラマは、仮想関数テー ブルとディスパッチ インタフェースのどちらを使用しても、COM オ ブジェクト内のメソッドを呼び出すことができます。デュアル インタ フェースは、広範囲のクライアントをサポートし、メソッドへの高速 アクセスを提供します。 埋め込み PBD の設定 COM サーバに含まれる埋め込み PowerBuilder 動的ライブラリ(PBD) ファイルには、選択したコンパイル済みのすべてのカスタム クラス ユーザ オブジェクトとその依存オブジェクトが含まれています。追加 の未参照オブジェクトを PBD に組み込むには、[ライブラリ]プロパ ティ ページで、そのオブジェクトを含むライブラリを選択します。選 択したライブラリ内のすべてのオブジェクトが PBD に含められます。 ライブラリに関連付けられた PowerBuilder リソース(PBR)ファイル の名前を指定できます。PBR ファイルは、ビットマップなどの動的に 割り当てられたリソースのリストを含むテキスト ファイルです。詳細 については、715 ページの「リソースについて」を参照してください。 PowerBuilder COM オブジェクトの実行 PowerBuilder COM オ ブ ジ ェ ク ト の イ ン ス タ ン ス を 設 定 す る た め、 PowerBuilder 仮想マシン(PBVM115.dll)は、COM サーバ DLL に埋め 込まれた PBD からカスタム クラス オブジェクトをロードし、適切な セッション情報とインスタンス情報を作成します。クライアントが PowerBuilder COM オブジェクトのメソッドを呼び出すと、そのメソッ ドは PowerBuilder 仮想マシンをコールバックし、適切な PowerScript コードを実行します。 PowerBuilder COM サーバは、COM の single-threaded apartment(STA) モデルを使用しています。実行時セッションは、同じスレッド上に作 成されたオブジェクト間で共有できます。クライアントが PowerBuilder COM オブジェクトのインスタンスを要求すると、PowerBuilder COM サーバは実行時セッションを確立し、その実行時セッション中にカス タム クラス ユーザ オブジェクトのインスタンスを作成します。サー バが同じスレッドから COM オブジェクトのインスタンスに対する新 しいリクエストを受け取ると、既存の実行時セッションを使用して、 オブジェクトをインスタンス化します。 590 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 いずれの場合も、個々のクライアントは異なる PowerBuilder 仮想マシ ン セッションを使用します。 メモリの割り当て クライアントが PowerBuilder COM サーバから PowerBuilder COM オブ ジェクトのインスタンスを初めて要求すると、サーバは PowerBuilder 仮想マシンをロードし、メモリ ブロックを割り当て、実行時セッショ ンを開始します。PowerBuilder 仮想マシン、キャッシュ メモリ、およ び実行時セッションに約 4 MB のメモリが割り当てられます。 オブジェクトが同じ実行時セッションを共有できる場合には、それ以 降のリクエストでは追加のメモリ割り当てが不要になります。 それ以降のリクエストにおいて、リクエストが別のクライアントまた はスレッドから作成されたなどの理由で、PowerBuilder COM オブジェ クトを別の COM アパートメントで作成する必要がある場合、オブジェ クトは新しい実行時セッションでインスタンス化されます。新しい各 セッションは、PowerBuilder 仮想マシンのインスタンスとキャッシュ メモリを共有するため、約 200 KB のメモリを消費するだけで済みま す。 PowerBuilder COM サーバの配布 PowerBuilder COM サーバを生成したら、COM 対応のクライアント ア プリケーションを使用して、PowerBuilder COM オブジェクトを作成 し、それらのメソッドにアクセスすることができます。COM 対応の任 意のアプリケーションでサーバを使用したり、サーバをパッケージと して COM+ に配布したりすることができます。 COM 対応のアプリケーションによる PowerBuilder COM サーバの使い方 v COM 対応のアプリケーションで PowerBuilder COM サーバを使用するには 1 アプリケーション テクニック PowerBuilder COM サーバをユーザのコンピュータに配布します。 591 PowerBuilder COM サーバの配布 2 PowerBuilder 仮想マシン(PBVM115.dll)とそのほかの必要なモ ジュール(PBCOMRT115.DLL、PBDWE115.DLL、あるいは必要な データベース ソフトウェアなど)を、PowerBuilder COM サーバ をインストールしたコンピュータに配布します。 3 PowerBuilder COM サーバをユーザのコンピュータに登録します。 4 PowerBuilder COM サーバ内の PB オブジェクト関数を呼び出すク ライアント アプリケーションを記述します。 593 ページの「クライアントから PowerBuilder COM サーバへのア クセス」を参照してください。 PowerBuilder COM サーバの登録 PowerBuilder COM サーバを配布する ときには、レジストリに情報を追加して、COM がサーバ オブジェクト のインスタンスを作成できるようにする必要があります。PowerBuilder COM サーバは自己登録型なので、登録ファイルを別に作成する必要は ありません。PowerBuilder COM サーバを登録するには、次のように REGSVR32 ユーティリティを使用します。 regsvr32.exe path_to_server\mycomserver.dll リモート クライアントからサーバにアクセスする場合には、レジスト リをさらに変更する必要があり、サーバへのリモート アクセス用にク ライアントの設定が必要になる場合もあります。詳細については、597 ページの「DCOM での PowerBuilder COM サーバとオブジェクトの使 い方」を参照してください。 テスト用の自動登録 テスト目的の場合には、 [全般]プロパティ ページにあるチェックボッ クスをオンにします。これにより、サーバが生成されるとそのサーバ は開発コンピュータに自動登録されます。使用コンピュータ上で不必 要なレジストリ エントリが作成されるのを避けるため、このオプショ ンを選択するのは、PowerBuilder COM サーバのテスト準備が完了して からにしてください。 592 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 クライアントから PowerBuilder COM サーバへのアクセス COM 準拠のツールで作成したクライアントは、PowerBuilder COM コ ンポーネント上のメソッドにアクセスできます。COM+ の場合、クラ イアントは Microsoft Windows Installer を必要とします。COM サーバが クライアント マシンに登録されているか、COM+ アプリケーション プ ロキシ ファイルがインストールされていなければなりません。 リモート クライアントから PB COM サーバにアクセスする方法につ いては、597 ページの「DCOM での PowerBuilder COM サーバとオブ ジェクトの使い方」を参照してください。 以下の例では、Visual Basic または C++ から PowerBuilder COM オブ ジェクトにアクセスする方法を示します。これらの例では、ccuo_employee というユーザ オブジェクトから生成され、PB115.employee というプロ グラム ID を持つ PowerBuilder COM オブジェクトを使用します。 PowerBuilder クライアントの作成方法と、同じ COM オブジェクトの使 用例については、第 27 章「COM/COM+ クライアントの構築」を参照 してください。 クライアントとしての Visual Basic Visual Basic では、そのプログラム ID を使用して登録オブジェクトに 接続できます(実行時バインド)。Visual Basic 5 以降では、そのクラス 名も使用できます(事前バインド)。 v Visual Basic で PowerBuilder COM オブジェクトにアクセスするには 1 次のどちらかを実行します。 • オブジェクトを宣言し、そのプログラム ID を使用して接続し ます。 Dim EmpObj As Object Set EmpObj = CreateObject("PB115.employee") • PowerBuilder COM オブジェクトに対して生成されたタイプ ラ イブラリへの参照をプロジェクトに追加し、そのクラス名を使 用してオブジェクトのインスタンスを宣言します(Visual Basic 5 以降) 。 Dim EmpObj As New CoEmployee 2 接続が確立されたことを確認します。 Dim response アプリケーション テクニック 593 クライアントから PowerBuilder COM サーバへのアクセス If EmpObj Is Nothing Then response = MsgBox("Employee オブジェクトの作成 ", vbOKOnly, " エラー ") End If 3 オブジェクトの関数またはプロパティにアクセスします。 Dim units, time as Long Dim DoubleReturn as Double Dim StringReturn As String DoubleReturn = EmpObj.f_calcdayavg units, time StringReturn = EmpObj.f_teststring EmpObj.ll_hours = 37 4 オブジェクトを破棄します。 Set EmpObj = Nothing クライアントとしての C++ C++ では、COM ライブラリ関数を使用して、PowerBuilder COM オブ ジェクトのインスタンスを作成します。クライアントを作成するとき には、PowerBuilder COM オブジェクトの C/C++ 定義も使用する必要が あります。Microsoft IDL(MIDL)コンパイラは、PowerBuilder COM ジェネレータによって作成された IDL ファイルから、これらの定義を 生成します。 たとえば、PowerBuilder COM オブジェクト Employee に対して生成さ れた IDL ファイルを使用する場合は、次のようになります。 midl.exe employee.idl MIDL コンパイラは、IDL ファイル内の全オブジェクトのインタフェー スの定義を含んでいるヘッダ ファイル(employee.h)、およびオブジェ クトに関連付けられた CLSID とインタフェース ID(IID)を定義する C ファイル(employee_i.c)を生成します。 そのほかのファイル MIDL コンパイラはプロキシ/スタブ コードも(employee_p.c と dlldata.c に)生成します。ただし、C++ クライアント実行ファイルを作成した り、PowerBuilder COM オブジェクトにアクセスするのに、プロキシ / スタブ コードを使用したりする必要はありません。 594 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 PowerBuilder COM オブジェクト内のメソッドに アクセスできる C++ クライアント実行ファイルを作成するには、生成 されたヘッダ ファイルを組み込む C++ ソース ファイルを作成し、 MIDL コンパイラによって生成された C ファイルと C++ クライアント ソース ファイルの両方をコンパイルし、それによって得られるオブ ジェクト ファイルをリンクして実行ファイルを作成します。 クライアントの作成 Employee の例では、次のようになります。 1 client.cpp という C++ ソース ファイル(下記参照)を作成します。 2 client.cpp をコンパイルします。 3 employee_i.c をコンパイルします。 4 client.obj と employee_i.obj をリンクして、実行ファイル(たとえ ば、employee_ecl.exe)を作成します。 Employee.h 以下のコードは、MIDL コンパイラによって生成された employee.h ヘッダ ファイルの一部で、C++ クライアントによって使用 される定義を表します。 typedef interface DIEmployee DIEmployee; EXTERN_C const IID IID_DIEmployee; interface DECLSPEC_UUID("A2F59F71-D5FB-11D1-92B900A0247712F1") DIEmployee :public IDispatch { public: virtual /* [id] */ HRESULT STDMETHODCALLTYPE f_calcdayavg( /* [in] */ long units, /* [in] */ long time, /* [retval][out] */ double __RPC_FAR *retval) = 0; virtual /* [id] */ HRESULT STDMETHODCALLTYPE f_teststring( /* [retval][out] */ BSTR __RPC_FAR *retval) = 0; }; EXTERN_C const CLSID CLSID_CoEmployee; 次のサンプル クライアント ファイルでは、MIDL によって 生成された、PowerBuilder COM オブジェクトの C/C++ 定義を使用して います。client.cpp に示されている COM API 呼び出しについての詳細 は、Microsoft ソフトウェア開発キットの資料を参照してください。 Client.cpp アプリケーション テクニック 595 クライアントから PowerBuilder COM サーバへのアクセス #include <windows.h> // employee.h I( MIDL.EXE から ) #include "employee.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { HRESULT hr; DIEmployee *pDIEmployee = 0; // COM を初期化する CoInitialize(0); hr = CoCreateInstance(CLSID_CoEmployee,NULL, CLSCTX_INPROC_SERVER, IID_DIEmployee, (void **)&pDIEmployee); if (FAILED(hr)) ErrorMessage("CoCreateInstance", hr); // メソッドの変数 long units, time; double dReturn; BSTR strReturn = NULL; // メソッドを呼び出す hr = pDIEmployee->f_calcdayavg(units, time,&dReturn); if (FAILED(hr)) ErrorMessage("f_calcdayavg",hr); hr = pDIEmployee->f_teststring(&strReturn); if (FAILED(hr)) ErrorMessage("f_teststring",hr); // インタフェース ptr を解放 pDIEmployee->Release(); CoFreeUnusedLibraries(); // 完了 CoUninitialize(); return 0; } 596 PowerBuilder 第 26 章 COM/COM+ コンポーネントの構築 DCOM での PowerBuilder COM サーバとオブジェクトの使い方 DCOM を使用すれば、リモート クライアントから PowerBuilder COM オブジェクトをアクティブにすることができます。オブジェクトは、 指定されたホスト コンピュータ上のサーバ プロセスでアクティブに する必要があります。アウト オブ プロセス サーバ(EXE ファイル) はサーバ プロセスを作成しますが、インプロセス サーバ(DLL ファ イル)は代理プロセス下で動作させる必要があります。 COM は、PowerBuilder COM サーバ DLL のホストとして使用できる汎 用の代理ホスト(DLLHOST.EXE)を提供しています。代理ホストを 使用するように、PowerBuilder COM サーバにマークを付けることは、 PowerBuilder COM オブジェクトをリモート クライアントからアクセ スを可能にするための最も重要なステップです。DCOM 環境設定ユー ティリティ(DCOMCNFG.EXE)を使用して、位置、セキュリティ、お よび識別情報の値を変更できますが、多くの場合にはデフォルトのま まで十分です。詳細については、DCOMCNFG ユーティリティのオンラ イン ヘルプを参照してください。 PowerBuilder COM サーバが代理ホストを使用できるようにするには、 2 つの方法があります。 PowerBuilder COM サーバが代理ホストを 使用できるようにする • レジストリ エディタ(REGEDIT32.EXE)を使用して、PowerBuilder COM サーバのレジストリ エントリ AppID を編集する • Microsoft Visual C++ 5.0 以降に付属する OLE/COM オブジェクト ビューア(OLEVIEW.EXE)を使用する コンピュータのレジストリを手作業で編集すると、コンピュータの構 成の一部または全部が動作不能になることがあるため、一般には OLEVIEW の使用をお勧めします。 v レジストリ エディタを使用して、COM サーバが代理プロセスを使用できる ようにするには 1 サーバの生成に使われたプロジェクトを開き、 [全般]プロパティ ページから PowerBuilder COM サーバの AppID 値をコピーします。 2 REGEDIT.EXE を実行し、 マイ コンピュータ \HKEY_CLASSES_ROOT\AppID の位置にある サーバの AppID キーを探して選択します。 3 メニューバーから[編集|新規作成|文字列の値]を選択します。 4 名前に DllSurrogate を入力し、データ フィールドは空のままに しておきます。 アプリケーション テクニック 597 クライアントから PowerBuilder COM サーバへのアクセス データ フィールドが空である場合、COM はデフォルトの代理ホス ト(DLLHOST.EXE)を使用します。AppID 値のキーは次のように なります。 名前 (デフォルト) DllSurrogate v データ PowerBuilder 11.5 が生成したサーバ :servername.dll "" OLE/COM オブジェクト ビューアを使用して、COM サーバが代理プロセス を使用できるようにするには 1 OLEVIEW.EXE を実行します。 2 リストビューでオートメーション オブジェクトを展開し、 PowerBuilder COM サーバのオブジェクトを選択します。 3 PowerBuilder COM サーバに関連付けられたオブジェクトを選択し ます。 4 [Implementation]タブを選択します。 5 [Inproc Server]タブを選択し、[Use Surrogate Process]チェック ボックスをオンにします。 クライアント コン ピュータを設定して、 リモート PowerBuilder COM オ ブジェクトをアクティ ブにする リモート コンポーネントをアクティブにするには、クライアント アプ リケーションが、オブジェクトのクラス識別子(CLSID)を、リモー ト ホストに対するアクティブ化リクエストに指定して渡す必要があ ります。 PowerBuilder や C++ で作成されたクライアントなど、一部のクライア ントは、リモート オブジェクトのインスタンスを作成するときに、メ ソッド呼び出しでオブジェクトの CLSID を使用できます。これらのク ライアント アプリケーションは、クライアント側の環境設定を必要と しません。 多くのクライアントは、オブジェクトの CLSID ではなく、オブジェク トの名前(ProgID)によってオブジェクトを参照します。このような 場合、リモート アクティブ化リクエストを行うためには、クライアン ト コンピュータのレジストリに、ProgID を CLSID にマップするため に必要な情報が含まれていなければなりません。必要なレジストリ情 報をクライアント コンピュータに追加するには、次のどちらかの方法 を使用します。 • リモート アクセスを必要とするクライアント コンピュータごとに、 PowerBuilder COM サーバを登録します。 この方法を使用するには、適切なバージョンの PBVMn0.dll がイン ストールされていなければなりません。 598 PowerBuilder 第 26 章 • COM/COM+ コンポーネントの構築 PowerBuilder COM サーバが登録されているホスト上で、 REGEDIT.EXE を使用して、必要なレジストリ情報を .REG ファイ ルにエクスポートし、続いてリモート アクセスを必要とする各ク ライアント コンピュータのレジストリに、これらのファイルをコ ピーおよびインポートします。 PowerBuilder COM オブジェクトごとに、以下のレジストリ キーを エクスポートします。 HKEY_CLASSES_ROOT\PB115.objectname HKEY_CLASSES_ROOT\PB115.objectname.version_number HKEY_CLASSES_ROOT\CLSID\{objects_clsid} PowerBuilder COM サーバには、以下のレジストリ キーが必要なこ ともあります。 HKEY_CLASSES_ROOT\TypeLib\{comserver_typelib_id} HKEY_CLASSES_ROOT\AppID\{comserver_application_id} PowerBuilder を使用 してリモート オブ ジェクトに接続する PowerBuilder クライアントは、ConnectToNewRemoteObject 関数を使用し てリモート オブジェクトをアクティブにすることができます。この部 分のコードは次のようになります。 OLEObject remobj remobj = CREATE OLEObject remobj.ConnectToNewRemoteObject("myremotehostname", "PB115.employee") & リモート オブジェクトの CLSID 文字列を classname パラメータに指定 することもできます。 remobj.ConnectToNewRemoteObject("myremotehostname", "clsid:0EA53FED-646A-11D2-BF8E-00C04F795006") & classname パラメータにオブジェクトの CLSID を指定すると、クライ アント側での環境設定は不要になります。 C++ を使用したリ モート オブジェクト に接続 生成された PowerBuilder COM サーバの IDL ファイルから作成された ヘッダ ファイルを使用する C++ クライアントは、アクティブ化リクエ ストで、リモート オブジェクトの CLSID を使用できます。 COSERVERINFO ServerInfo; MULTI_QI mqi[1]; OLECHAR wszHostName[MAXFILE]; LPTSTR pszHost=NULL; memset(&ServerInfo,0,sizeof(ServerInfo)); pszHost =GetUserRequestedHostName(); mbstowcs(wszHostName,pszHost,MAXFILE); アプリケーション テクニック 599 クライアントから PowerBuilder COM サーバへのアクセス ServerInfo.pwszName = wszHostName; mqi[0].pIID = &IID_Iemployee; mqi[0].pItf = NULL; mqi[0].hr = S_OK; // 目的のサーバに employee オブジェクトを作成する hr = CoCreateInstanceEx(CLSID_Employee,NULL, CLSCTX_REMOTE_SERVER,&ServerInfo,1,mqi); 600 PowerBuilder 第 2 7 章 COM/COM+ クライアントの構築 この章について この章では、COM または COM+ サーバ コンポーネントにアクセ スする PowerBuilder クライアントの構築方法について説明しま す。 内容 項目 COM/COM+ クライアントの構築について COM サーバへの接続 COM コンポーネントとのやり取り クライアントからのトランザクション制御 ページ 601 602 603 604 COM/COM+ クライアントの構築について PowerBuilder アプリケーションは、COM サーバのクライアントと して機能できます。COM サーバは、PowerBuilder またはそのほか の COM に準拠したアプリケーション開発ツールを使用して作成 できます。また、リモート コンピュータ上でインプロセス サーバ として、または COM+ 環境でローカルに実行できます。 アプリケーション ウィザードを使用すれば、COM および COM+ クライアントを簡単に構築できます。 クライアント コンピュー タを設定してリモート コ ンポーネントにアクセス アプリケーション テクニック COM コンポーネントがリモート コンピュータ上で動作している 場合、クライアント コンピュータは、そのメソッドに透過的にア クセスできなければなりません。そのためには、クライアント側 にサーバに対応するローカルのプロキシ DLL を用意し、クライア ント コンピュータのレジストリにリモート サーバを識別するエ ントリを登録する必要があります。クライアント コンピュータは、 Windows 2000 または Windows XP 上で動いていなければなりませ ん。 601 COM サーバへの接続 コンポーネントが COM+ にインストールされている場合は、COM+ コ ンポーネント サービス ツールを使用して 、クライアント コンピュー タ 上 に ア プ リ ケ ー シ ョ ン プ ロ キ シ を イ ン ス ト ー ル す る Microsoft Windows インストーラ(MSI)ファイルを作成します。 サーバが COM+ にインストールされていない場合は、クライアント ファイルとプロキシ ファイルをクライアントにコピーし、サーバを代 理プロセスで動作させるように設定する必要があります。 レジストリに書き込まれたリモート サーバ名 COM サーバを別のコンピュータに移動した場合には、クライアント上 のレジストリ エントリを更新する必要があります。 COM サーバへの接続 COM サーバ内のコンポーネントに関連付けられたメソッドにアクセ スするために、PowerBuilder クライアントは、コンポーネントのプロ グラム識別子(ProgID)またはクラス識別子(CLSID)を使用して、コ ンポーネントに接続します。 プログラム ID または CLSID、および登録した PowerBuilder COM オブ ジェクトのメソッドを表示するには、PowerBuilder オブジェクト ブラ ウザの OLE タブや OLEVIEW などのツールを使用します。 COM サーバへの接続を確立するには、以下の操作を実行するために必 要な PowerScript 文を実行する必要があります。 1 OLEObject 型の変数を宣言し、Create 文を使用してその変数をイン スタンス化します。 2 オブジェクトの ProgID または CLSID を使用して、オブジェクトに 接続します。 3 接続が確立されたことを確認します。 例 次のスクリプトでは、OLEObject オブジェクト EmpObj をインスタ ンス化し、PowerBuilder COM オブジェクト PBcom.Employee に接続し て、エラーをチェックしています。 OLEObject EmpObj Integer li_rc EmpObj = CREATE OLEObject li_rc = EmpObj.ConnectToNewObject("PBcom.employee") 602 PowerBuilder 第 27 章 COM/COM+ クライアントの構築 IF li_rc < 0 THEN DESTROY EmpObj MessageBox("COM オブジェクトへの接続に失敗 ", " エラー :" + String(li_rc)) Return END IF & COM コンポーネントとのやり取り コンポーネント メ ソッドの呼び出し COM コンポーネントへの接続が確立されると、クライアント アプリ ケーションはコンポーネント メソッドを使用できるようになります。 出力パラメータには REF キーワードを使用する 出力パラメータを持つ COM オブジェクト上のメソッドを呼び出すと きには、REF キーワードを使用しなければなりません。たとえば、 of_add( arg1, arg2, REF sum ) のように指定します。 前の例で作成した EmpObj オブジェクトを使用して、次の例では、 コンポーネント上の 2 つのメソッドを呼び出し、続いてサーバとの接 続を切断し、インスタンスを破棄しています。 例 Long units, time Double avg, ld_retn String ls_retn ld_retn = EmpObj.f_calcdayavg(units, time, REF avg) ls_retn = EmpObj.f_teststring() EmpObj.DisconnectObject() DESTROY EmpObj 結果集合の受け渡し PowerBuilder は、3 つのシステム オブジェクトを提供することによっ て、トランザクション サーバ環境で動作しているコンポーネントから 結果集合を取得したり、トランザクション サーバ コンポーネントとし て動作している PowerBuilder ユーザ オブジェクトから結果集合を返し たりする操作に対処します。これらのシステム オブジェクト(ResultSet、 ResultSets、および ADOResultSet)は、データストア オブジェクトと の間でトランザクション サーバの結果集合の変換を簡単にするため に設計されたものであり、状態情報を含んでいません。 アプリケーション テクニック 603 クライアントからのトランザクション制御 実行時エラー処理 OLE オートメーション オブジェクト、COM オブジェクト、または COM+ コンポーネントとして実行されているカスタム クラス ユーザ オブジェクトからの実行時エラー情報は、オブジェクトを保持するコ ンテナに例外として(オートメーション オブジェクトの場合は、例外 または機能エラーとして)レポートされます。PowerBuilder SignalError 関数への呼び出しも、コンテナにレポートされます。PowerBuilder オ ブジェクトによって生成された実行時エラーを処理するには、OLE ク ライアントの ExternalException イベントを記述します。 OLE オブジェクトまたは COM オブジェクトにおける実行時エラー処 理についての詳細は、390 ページの「エラー処理」を参照してください。 クライアントからのトランザクション制御 PowerBuilder クライアントは、OLEObject 型ではなく、OleTxnObject 型 の変数を使用して COM オブジェクトに接続することによって、COM+ サーバ上のトランザクションを明示的に制御できます。 COM+ のインストールが必要 COM+ がクライアント コンピュータにインストールされていないと、 OleTxnObject での ConnectToNewObject 呼び出しは失敗します。 OLEObject オブジェクトから派生した OleTxnObject オブジェクトに は、クライアントがトランザクション制御に参加するための 2 つの関 数(SetComplete と SetAbort)が追加定義されています。クライアント が SetComplete を呼び出すと、そのトランザクションは、トランザク ションの別の参加者が SetAbort を呼び出していなければコミットされ ますが、そうでない場合は失敗します。クライアントが SetAbort を呼 び出すと、トランザクションは常に中断します。 例 次の例では、 ボタンの Clicked イベントによって OleTxnObject 型の 変数を作成し、サーバ上の PowerBuilder COM オブジェクトに接続し、 オブジェクト上のいくつかのメソッドを呼び出しています。すべての メソッドが復帰すると、クライアントは SetComplete を呼び出して、 サーバとの接続を切断します。 604 PowerBuilder 第 27 章 COM/COM+ クライアントの構築 integer li_rc OleTxnObject lotxn_obj lotxn_obj = CREATE OleTxnObject li_rc = lotxn_obj.ConnectToNewObject("pbcom.n_test") IF li_rc <> 0 THEN MessageBox(" 接続が失敗しました ", string(li_rc) ) HALT END IF lotxn_obj.f_dowork() lotxn_obj.f_domorework() lotxn_obj.SetComplete() lotxn_obj.DisconnectObject() サーバの PowerBuilder COM オブジェクトに定義されている f_dowork 関数は、トランザクション コンテキスト サービスのインスタンスを作 成し、その DisableCommit メソッドを呼び出すことによって、次のメ ソッド呼び出しまでの間にトランザクションが早期にコミットされる のを防止します。そして何らかの作業を行った後、その作業が正しく 完了しなかった場合には SetAbort を、正しく完了した場合には、SetComplete を呼び出します。 TransactionServer txninfo_one integer li_rc li_rc = GetContextService( "TransactionServer", txninfo_one ) txninfo_one.DisableCommit() & // 処理を実行し、リターン コードを返す IF li_rc <> 0 THEN txninfo_one.SetAbort() return -1 ELSE txninfo_one.SetComplete() return 1 END IF トランザクション内のすべてのメソッドが SetComplete または EnableCommit を呼び出すと、クライアント上の SetComplete 呼び出し によってトランザクションがコミットされます。 アプリケーション テクニック 605 クライアントからのトランザクション制御 606 PowerBuilder 第 2 8 章 EJB クライアントの構築 この章について この章では、J2EE 準拠のアプリケーション サーバ上で動作する Enterprise JavaBeans コンポーネント用の PowerBuilder クライアン トの構築方法について説明します。この章で説明するオブジェク トの関連情報については、 『PowerBuilder エクステンション リファ レンス』マニュアルおよびオンライン ヘルプを参照してください。 内容 項目 EJB クライアントの構築について アプリケーションへの pbejbclient115.pbx の追加 EJB プロキシ オブジェクトの生成 Java VM の作成 サーバへの接続 コンポーネント メソッドの呼び出し 例外処理 クライアント管理のトランザクション クライアントのデバッグ ページ 607 609 610 618 621 622 627 629 630 EJB クライアントの構築について PowerBuilder アプリケーションは、J2EE 準拠のアプリケーション サーバ上で実行する EJB 1.1 または 2.0 コンポーネントに対するク ライアントとして動作することが可能です。この機能は、Sybase が 提供する PowerBuilder エクステンション ファイルに依存します。 PowerBuilder エクステンション ファイルは、PowerBuilder Native Interface(PBNI)を使用して開発されたものです。EJB クライアン ト を 作 成 す る た め に PBNI に 関 す る 知 識 は 必 要 あ り ま せ ん。 PowerBuilder エクステンションについての詳細は、 『PowerBuilder エクステンション リファレンス』マニュアルに記載されていて、 また、PBNI についての詳細は、『PowerBuilder ネイティブ インタ フェース プログラマーズ ガイドとリファレンス』マニュアルに記 載されています。 アプリケーション テクニック 607 EJB クライアントの構築について EAServer 用 EJB クライアント EAServer 用の EJB クライアントを開発する場合、この章で説明するテ クニックを使用することができます。また、PowerBuilder 接続オブジェ クトと EAServer プロキシ オブジェクトを使用するクライアントを作 成することもできます。 EJB クライアント エクステンションは Java 対応のラッパーであるた め、より柔軟に EJB と通信できます。たとえば、EJB クライアントは、 EJB プロキシを介して EJB メソッド呼び出しから返された Java クラス を操作できます。 EJB クライアントが存在するコンピュータ上に JRE をインストールす る必要がないので、PowerBuilder 接続オブジェクトはより小さくなり、 配備しやすくなります。また、PowerBuilder 接続オブジェクトを使用 すると、JRE ロードによる遅滞が生じないために、サーバへの接続も 速くなります。 PowerBuilder 接続オブジェクトを使用した EAServer 上で動作する EJB コンポーネント用の EJB クライアント構築についての詳細は、第 24 章 「EAServer クライアントの構築」を参照してください。 pbejbclient115.pbx と pbejbclient115.pbd サーバに接続して EJB コンポーネントと通信するためには、クライア ントは接尾辞 PBX を持つ DLL ファイル、pbejbclient115.pbx に実装さ れているクラスのセットを使用します。この PBX ファイル内のクラス を使用するには、クライアント アプリケーション内のライブラリにク ラスの定義をインポートする必要があります。pbejbclient115.pbd ファ イルをターゲットのライブラリ探索パスに追加することもできます。 このファイルは、PBX ファイルのラッパーとして機能します。 EJB プロキシ オブ ジェクトについて PowerBuilder クライアントは、リモート EJB コンポーネントのメソッ ド呼び出しを EJB コンポーネントのローカル プロキシ オブジェクト に任せます。各 EJB コンポーネントは最小限、クライアント アプリ ケーション内で、ホーム インタフェース用プロキシとリモート インタ フェース用プロキシによって表されます。たとえば、Cart という EJB コンポーネントには、CartHome と Cart の 2 つのプロキシがあります。 それぞれのプロキシには、これらのインタフェースのパブリック メ ソッドのシグネチャのみが含まれます。 さらに、ホーム インタフェースとリモート インタフェースによって使 用される例外と補助クラスに対しても、プロキシが生成されます。詳 細については、610 ページの「EJB プロキシ オブジェクトの生成」を 参照してください。 608 PowerBuilder 第 28 章 EJB クライアントの構築 EJB クライアントを構築するには、以下の手順をすべて実行する必要 があります。 プロセスの概要 1 ワークスペースと PowerScript ターゲットを作成します。 2 pbejbclient115.pbx をアプリケーションに追加します。 3 プロキシ オブジェクトの構築のためのプロジェクトを作成します。 4 プロキシ オブジェクトを生成するためにプロジェクトを作成します。 5 クライアント アプリケーションのユーザ インタフェースを実装 するために必要なウィンドウを作成します。 6 Java VM をインスタンス化します。 7 サーバへの接続を確立し、EJB を検索します。 8 EJB コンポーネントのインスタンスを作成し、クライアントから コンポーネント メソッドを呼び出します。 9 クライアントのテストとデバッグを行います。 アプリケーションへの pbejbclient115.pbx の追加 PBEJBClient クラスを PowerBuilder ターゲットに追加する最も簡単な 方法は、pbejbclient115.pbx PBX ファイル内のオブジェクト ディスクリ プションを PowerBuilder システム ツリー内のライブラリにインポート することです。 PowerBuilder をインストールするときに、Shared\PowerBuilder ディレ ク ト リ に pbejbclient115.pbx と pbejbclient115.pbd フ ァ イ ル が イ ン ス トールされます。EJB クライアント アプリケーションを作成する場合、 pbejbclient115.pbx を別の場所にコピーする必要はありませんが、アプ リケーションの探索パス内のディレクトリに、クライアント実行ファ イルとともにこのファイルを配布する必要があります。 v エクステンション内のディスクリプションをライブラリにインポートするには 1 2 アプリケーション テクニック システム ツリーでエクステンションを使用したいターゲットを展 開し、ライブラリを右クリックして、ポップアップ メニューから [PB エクステンションのインポート]を選択します。 PBX ファイルの位置まで移動し、[開く]をクリックします。 609 EJB プロキシ オブジェクトの生成 PBX 内の各クラスがシステム ツリーに表示されます。そのため、 クラスを展開し、そのプロパティ、イベント、およびメソッドを 表示して、それらをスクリプトに追加するためにドラッグアンド ドロップできます。 pbejbclient115.pbx をインポートすると、システム ツリーには以下のオ ブジェクトが表示されます。 オブジェクト EJBConnection EJBTransaction JavaVM 説明 EJB サーバに接続し、EJB を配置するために使用す る javax.transaction.UserTransaction インタフェースに マップする。EJB クライアントからトランザクショ ンを制御するために使用する Java VM のインスタンスを作成するために使用す る EJB プロキシ オブジェクトの生成 EJB プロキシ オブジェクトを生成するには、EJB クライアント プロキ シ プロジェクトを作成する必要があります。EJB クライアント プロキ シ プロジェクトの作成には、プロジェクト ペインタかウィザードを使 用します。 EJB プロキシ プロジェクトの使い方 EJB クライアント プロキシ プロジェクトを新規に作成するには、新規 作成 ダイアログボックスの[プロジェクト]ページから次のいずれか を選択します。 • [EJB クライアント プロキシ]アイコン • [EJB クライアント プロキシ ウィザード]アイコン [EJB クライアント プ ロキシ]アイコン 610 [EJB クライアント プロキシ]アイコンを選択すると、EJB プロキシ用 のプロジェクト ペインタが開きます。このプロジェクト ペインタを使 用すると、プロジェクトの作成、オプションの指定、およびプロキシ ライブラリの構築ができます。 PowerBuilder 第 28 章 v EJB クライアントの構築 プロジェクト ペインタで EJB クライアント プロキシ プロジェクトを作成す るには 1 新規作成 ダイアログボックスの[プロジェクト]ページで、 [EJB クライアント プロキシ]アイコンをダブルクリックします。 2 EJB を指定するには、 [編集|オブジェクトの選択]を選択し、テ キストボックスに、com.sybase.jaguar.sample.svu.SVULogin や portfolio.MarketMaker など、コンポーネントのリモート インタフェー スの完全修飾名を入力します。 3 [クラスパス]ボックスに、EJB のスタブを含むディレクトリまた は JAR ファイルのパスを入力し、[OK]をクリックします。 スタブ ファイルがディレクトリに格納され、EJB の完全修飾名が packagename.beanname である場合、packagename を含むディレクト リを入力します。 4 プロキシ オブジェクトを格納する PBL を指定するには、[編集| プロパティ]を選択し、ターゲットのライブラリ リスト内のライ ブラリの格納場所を指定します。 生成された各プロキシ名の先頭に追加する接頭辞を任意に指定で きます。接頭辞を追加すると、指定した EJB に関連付けられたプ ロキシの特定が容易になり、クラス名と PowerBuilder 予約語の衝 突を避けることができます。ただし、例外のプロキシ、ストリーム オ ブジェクトのプロキシ、および EJBHome、EJBObject、EJBMetaData、 Handle、HomeHandle のプロキシなど、この EJB 固有でないプロキ シ名には、接頭辞は追加されません。 5 ダイアログボックスを閉じて、 [ファイル|すべて保存]を選択し てプロジェクトを保存します。 新規プロジェクトは、プロキシが生成される EJB コンポーネントを一 覧にし、生成されたプロキシ オブジェクトを格納する出力ライブラリ 名を指定します。 EJB クライアント プロキシ ウィザードを使用すると、プロジェクトを 容易に作成できます。 [EJB クライアント プ ロキシ ウィザード] アイコン v ウィザードを使用して EJB クライアント プロキシ プロジェクトを作成するには 1 新規作成 ダイアログボックスの[プロジェクト]ページで[EJB クライアント プロキシ ウィザード]アイコンをダブルクリック し、ウィザードの最初のページで[次へ]をクリックします。 2 プロジェクト オブジェクトを格納するライブラリを選択し、 [次へ] をクリックします。 アプリケーション テクニック 611 EJB プロキシ オブジェクトの生成 3 プロジェクト名を指定し、必要に応じてプロジェクトの説明を指 定して、[次へ]をクリックします。 4 次に示すように、テキストボックスに、cocoPortfolio.Portfolio など、コンポーネントのリモート インタフェースの完全修飾名を 入力します。 コンポーネントのホーム インタフェース名は、標準の命名規約に 従って自動的に入力されます。必要であれば、ウィザードでこの 名前を変更できます。 5 EJB スタブを格納した JAR ファイル、または EJB スタブ パッケー ジを格納したディレクトリを参照して選択します。 スタブ ファイルがディレクトリに格納され、EJB の完全修飾名が packagename.beanname である場合、packagename を含むディレクト リを入力します。 6 生成された各プロキシ名の先頭に追加する任意の接頭辞を指定 し、[次へ]をクリックします。 接頭辞を追加すると、指定した EJB に関連付けられたプロキシの 特定が容易になり、クラス名と PowerBuilder 予約語の衝突を避け ることができます。ただし、例外のプロキシ、サポートしている クラスのプロキシ、および EJBHome、EJBObject、EJBMetaData、 Handle、HomeHandle のプロキシなど、この EJB 固有でないプロキ シ名には、接頭辞は追加されません。 7 612 既存のライブラリを参照して選択し、 [次へ]をクリックし、 [完了] をクリックします。 PowerBuilder 第 28 章 EJB クライアントの構築 プロキシ オブジェクトが生成され、このライブラリに格納されま す。このライブラリをターゲットのライブラリ リストに追加する 必要があります。 ウィザードを使用してプロジェクトを作成した後、プロジェクト ペイ ンタを使ってプロジェクトの設定を変更できます。 プロキシの作成 EJB プロキシ プロジェクトの作成にウィザードまたはペインタのいず れを使用する場合も、最後にプロキシ オブジェクトを作成します。プ ロキシ オブジェクトを作成するには、ペインタ バーで[配布]アイコ ンをクリックするか、メニュー バーから[デザイン|プロジェクトの 配布]を選択します。 プロキシの生成には javap.exe が必要 PowerBuilder は、javap.exe ユーティリティを使ってプロキシ オブジェ クトを生成します。この実行ファイルは、システム パスに置く必要が あります。デフォルトでは、EJB クライアントの開発に PowerBuilder とともにインストールされる Sun JDK 1.4 を使用します。Java VM に必 要なパスとクラスパスは、現在のセッションで使用するパスとクラス パスに自動的に追加されます。 別の JDK を使用する場合は、[ツール|システム オプション]を選択 し、システム オプション ダイアログボックスの[Java]ページで[JDK ロケーションの設定]をクリックします。WebSphere を使用する場合 は、IBM JDK のパスを使用します。 EJB のホーム インタフェースとリモート インタフェースのプロキシ に加え、EJB が参照するすべての Java クラス、先祖クラス、EJB とそ のサポートするクラスから送出されるすべての例外、および以下のイ ンタフェースに対してもプロキシが生成されます。 オブジェクト EJBHome EJBMetaData EJBObject アプリケーション テクニック 説明 すべての EJB ホーム インタフェースの基本クラスであ る、javax.ejb.EJBHome インタフェースのプロキシ javax.ejb.EJBMetaData インタフェースのプロキシ。 EJBMetaData を使用すると、クライアントは、EJB の ホーム インタフェース、EJB のホーム インタフェース とリモート インタフェースのクラス オブジェクト、お よびエンティティ Bean の主キー クラスを取得し、Bean がセッション オブジェクトまたはステートレス セッ ション オブジェクトかどうかが判断可能になる すべての EJB リモート インタフェースの基本クラスで ある、javax.ejb.EJBObject インタフェースのプロキシ 613 EJB プロキシ オブジェクトの生成 オブジェクト Handle 説明 HomeHandle javax.ejb.HomeHandle インタフェースのプロキシ。ホーム javax.ejb.Handle インタフェースのプロキシ。EJB への堅 牢で永続的な参照を提供する オブジェクトへの堅牢で永続的な参照を提供する これらのインタフェースについての詳細は、javax.ejb package のサイト http://java.sun.com/j2ee/sdk_1.3/techdocs/api/index.html に掲載のマニュアル を参照してください。 プロジェクトは、Java クラスのプロキシ名へのマッピングを格納する 構造体も生成します。この構造体は内部的に使用されるものなので、 変更しないでください。 ejb2pb115 ツールの使い方 プロキシの生成には、ejb2pb115 コマンドライン ツールを使用する方法 もあります。このツールを使用した場合、以下が生成されます。 • 指定した EJB のホーム インタフェースとリモート インタフェー スのプロキシ、および EJB が依存するクラスのプロキシ(.srx ファ イル) • ejbname_ejb_pb_mapping.srs という名前の PowerBuilder 構造体オブ ジェクト。この場合、ejbname は EJB 名。この構造体は、Java クラ ス名と PowerBuilder プロキシ名との間のマッピング テーブルをホ ストする • ejbproxies.txt という名前のテキスト ファイル。エラーが発生した 場合は、ejbproxies.err という名前のテキスト ファイル これらのファイルは、コマンドの呼び出し元のディレクトリ内に生成 されます。構文は次のとおりです。 ejb2pb115 [ -classpath pathlist ] EJBName [EJBHomeName][ prefix ] D:\Program Files のように、pathlist 引数にスペースが含まれる場合は、 pathlist を引用符で囲む必要があります。EJBName は、完全修飾リモー ト インタフェース クラス名です。標準の命名規約に従ったホーム イ ンタフェース名を使用する場合、完全修飾ホーム インタフェース名の 引数 EJBHomeName はオプションです。オプションの prefix を指定す ると、生成されたプロキシ名の先頭に接頭辞が追加されます。 614 PowerBuilder 第 28 章 EJB クライアントの構築 たとえば、次のステートメントは、EAServer 上の cocoPortfolio パッケー ジ内の Portfolio クラスのプロキシを生成します。Portfolio クラスの ホーム インタフェースとリモート インタフェースのプロキシには、接 頭辞として pf_ が追加され、生成されたファイルは D:\work\proxies ディレクトリに書き込まれます。 cd D:\work\proxies ejb2pb115 -classpath "D:\Program Files\Sybase\EAServer\ html\classes" cocoPortfolio.Portfolio pf_ EJB のホーム クラスとリモート クラス、およびそれに従属するクラス は、指定したクラス パスに置く必要があります。 プロキシを生成した後に、生成したプロキシをターゲットにインポー トするには、クライアントを含むライブラリを選択し、ポップアップ メニューから[インポート]を選び、表示されたダイアログボックス から .srx ファイルを選びます。.srx ファイルをインポートする順序に は注意が必要です。ほかのクラスに従属するプロキシは、その従属す るクラスのプロキシをインポートした後でないとインポートできませ ん。 生成されたプロキシの表示方法 生成されたプロキシはシステム ツリーに表示されます。プロキシ ノー ドを展開すると、EJB コンポーネントのホーム インタフェースとリ モート インタフェースのメソッドのシグネチャ、およびプロキシを生 成したほかのすべてのオブジェクトのメソッドのシグネチャが表示さ れます。 アプリケーション テクニック 615 EJB プロキシ オブジェクトの生成 予約語との衝突 616 コンポーネントのメソッド名が PowerBuilder の予約語と衝突する場 合、メソッドを PowerBuilder にインポートできるように、プロキシ内 のメソッド名に文字列 _j が追加されます。たとえば、Java Iterator クラ スには Next メソッドがあり、このメソッドは、PowerBuilder の予約語 NEXT と衝突します。プロシキ内で、このメソッドには next_j という 名前が付けられます。 PowerBuilder 第 28 章 EJB クライアントの構築 データ型マッピング EJB プロキシ ジェネレータは、次の表に示すように Java と PowerBuilder の間でデータ型をマップします。 Java のデータ型 PowerBuilder のデータ型 short Integer int Long long LongLong float Real double Double byte Int char(16 ビット、符号なし) Char java.lang.String String boolean Boolean java.util.Date Datetime プリミティブ型の配列 パラメータ : プリミティブ型の配列 戻り値 :Any パラメータ :String または DateTime の配列 戻り値 :Any java.lang.String または java.util.Date オブジェクトの配列 配列の配列 Java クラスの引数または戻り値 その他 Any Java クラスの PowerBuilder プロキシ Any double 型の精度の相 違 PowerBuilder の double 型は 15 桁の精度(1.79769313486231E+308)を 持ち、Java の double 型は 17 桁の精度(1.7976931348623157e+308)を 持ちます。EJB クライアント アプリケーションの場合、double 型の精 度は、PowerBuilder の範囲(2.2250738585073E-308 ~ 1.79769313486231E+308)に制限されます。 配列の配列 PowerBuilder は、Java とは異なり、可変長多次元配列をサポートしてい ません。Java メソッドがパラメータとして配列の配列を受け取る場合、 これに対応する PowerBuilder プロキシ メソッドは Any 型のパラメータ を受け取ります。PowerBuilder 内でメソッドを呼び出すには、Java 配 列と同じ次元で PowerBuilder 配列を宣言し、その配列をパラメータと して渡します。 アプリケーション テクニック 617 Java VM の作成 Java VM の作成 EJB コンポーネントを呼び出す場合、事前に JavaVM クラスの CreateJavaVM メソッドを使用して Java VM を作成する必要があります。 最初の引数は、Java VM によって使用されるクラスパスの先頭に追加 するクラスパスを指定する String 型です。 Java VM がすでにロードされている場合 Java VM がすでに実行されている場合、クラスパス引数は無視されま す。 createJavaVM の第 2 引数は、デバッグ情報をテキスト ファイルに書き 出すかどうかを指定する Boolean 型の引数です。630 ページの「クライ アントのデバッグ」を参照してください。 これ以外に、JavaVM クラスには、Java VM の作成に使用可能な以下の メソッドがあります。 • CreateJavaInstance メソッド。このメソッドは、プロキシ名から Java オブジェクトのインスタンスを作成する • IsJavaVMLoaded メソッド。このメソッドは、Java VM がすでにロー ドされているかどうかを判断する。Java VM がすでにロードされ ているかどうかによって、アプリケーションの一部の機能を有効 または無効にする場合には、CreateJavaVM を呼び出す前にこのメ ソッドを使用する。これにより、CreateJavaVM に渡されるクラス パス引数は無視される • GetJavaVMVersion メソッド。このメソッドは、実行中の Java VM の バージョンを判断する • GetJavaClasspath メソッド。このメソッドは、Java VM のランタイ ム クラスパスを判断する CreateJavaVM を使用して作成する JavaVM は、クライアント アプリ ケーションのグローバル変数またはインスタンス変数でなければなら ず、明示的に破棄されないようにします。 開発環境における Java VM クラスパス PowerBuilder が Java VM を起動すると、Java VM は内部パスとクラス パス情報を使って、必要な Java クラスが常に使用できる状態にします。 開発環境では、JVM が実行されているかどうか、実行されている場合 は JVM がどのクラスパスを使用しているかをシステム オプション ダ イアログボックスの[Java]ページで確認できます。クラスパスは、以 下のパスを結合して作成されます。 618 PowerBuilder 第 28 章 ランタイム Java VM クラスパス EJB クライアントの構築 • Java VM の起動時にプログラムによって追加されるクラスパス。た とえば、CreateJavaVM メソッドに渡すクラスパス • PowerBuilder ランタイム スタティック レジストリ クラスパス。こ のパスは、pbjvm115.dll に組み込まれる。このパスには、実行時に EJB クライアント、 および Java VM を使用するそのほかの PowerBuilder 機能に必要なクラスが含まれる • PowerBuilder システム クラスパス。このパスは、PowerBuilder のイ ンストール時にインストールされる Windows レジストリ キー内 に保存される。このパスには、設計時に JDBC 接続などの Java 関 連の PowerBuilder 機能に必要なクラスが含まれる • PowerBuilder ユーザ クラスパス。このパスは、システム オプション ダイアログボックスの[Java]ページで指定するパス • システムの CLASSPATH 環境変数 • 現行ディレクトリ 実行時に、GetJavaClasspath メソッドを使用すると、Java VM が使用し ているクラスパスを判断できます。Java VM は、実行時に以下のクラ スパスを使用します。 • Java VM の起動時にプログラムによって追加されるクラスパス • PowerBuilder ランタイム スタティック レジストリ クラスパス • システムの CLASSPATH 環境変数 • 現行ディレクトリ 実行時の Java クラスパスについての詳細は、759 ページの「Java サポー ト」を参照してください。 サーバが必要とするク ラス クラスパスには、EAServer 用の EJB クライアントが必要とするクラス が含まれます。別の J2EE サーバを使用する場合、アプリケーション サーバが必要とするクラスをシステムの CLASSPATH にさらに追加す る必要があります。たとえば、次のようになります。 • WebLogic の場合、weblogic.jar。このファイルは、サーバ上の wlserver6.1\lib または weblogic700\server\lib にインストールされる • WebSphere の場合、JAR ファイルが、サーバ上の websphere\appserver\lib にインストールされる クライアント上での各アプリケーション サーバに対して必要なファ イルについての詳細は、サーバのマニュアルを参照してください。 アプリケーション テクニック 619 Java VM の作成 例 この例では、EAServer インストール内の html\classes フォルダをクラ スパスとして指定する Java VM のインスタンスの作成を示します。 // グローバル変数 javavm g_jvm、 // boolean gb_jvm_started boolean isdebug string classpath if NOT gb_jvm_started then //JAVAVM を作成します。 g_jvm = create javavm // EJB の Java パッケージは、 // EAServer html/classes フォルダにあります。 classpath = & "D:\Program Files\Sybase\EAServer\html\classes;" isdebug = true choose case g_jvm.createJavaVM(classpath, isdebug) case 0 gb_jvm_started = true case -1 MessageBox(" エラー ", "Java VM のロードに失敗 ") case -2 MessageBox(" エラー ", "EJBLocator のロードに失敗 ") end choose end if 使用する Java VM バージョンとクラスパスのレコードを作成するに は、上記の例に次のコードを追加します。 integer li_FileNum string ls_classpath, ls_version, ls_string li_FileNum = FileOpen("C:\temp\PBJavaVM.log", & LineMode!, Write!, LockWrite!, Append!) ls_classpath = i_jvm.getjavaclasspath() ls_version = i_jvm.getjavavmversion() ls_string = String(Today()) + " " + String(Now()) ls_string += " Java VM Version:" + ls_version ls_string += " ~r~n" + ls_classpath + "~r~n" FileWrite(li_FileNum, ls_string) FileClose(li_filenum) 620 PowerBuilder 第 28 章 EJB クライアントの構築 サーバへの接続 EJB サーバに接続し EJB を検索するには、EJBConnection クラスを使用 します。EJBConnection クラスには、次の 4 つのメソッドがあります。 ConnectToServer、DisconnectServer、Lookup、および GetEJBTransaction で す。 サーバへの接続を確立するには、以下の操作を行うために必要な PowerScript ステートメントを実行する必要があります。 1 EJBConnection クラスのインスタンスを宣言します。 2 EJBConnection オブジェクトのプロパティを設定します。 3 CREATE 文を使用して、EJBConnection オブジェクトをインスタン ス化します。 ConnectToServer メソッドを呼び出して、サーバへの接続を確立し 4 ます。 エラーの有無をチェックします。 5 クラスパス要件 アプリケーション サーバに接続し、EJB オブジェクトを作成するには、 システムの CLASSPATH 環境変数または createJavaVM の classpath 引 数に、EJB スタブ ファイルの格納場所(ディレクトリまたは JAR ファ イル)を含める必要があります。また、使用するアプリケーション サー バが、クライアントコンピュータ上でクラスまたは JAR ファイルを利 用できるようにし、それらをクラスパスに追加することが必要な場合 もあります。詳細については、618 ページの「開発環境における Java VM クラスパス」を参照してください。 初期コンテキストの設 定 初期コンテキストの設定に使用される文字列は、EJB サーバに依存し ます。次の表に、サンプル文字列値を示します。詳細については、サー バのマニュアルを参照してください。 サーバ EAServer WebLogic WebSphere 例 INITIAL_CONTEXT_FACTORY 値 com.sybase.ejb.InitialContextFactory weblogic.jndi.WLInitialContextFactory com.ibm.websphere.naming.WsnInitialContextFactory 次のスクリプトは、EAServer への接続を示しています。このスクリプ トでは、接続プロパティを設定して、初期コンテキストの作成、サー バのホスト名とポート番号の識別、ユーザ ID とパスワードの識別を行 います。 アプリケーション テクニック 621 コンポーネント メソッドの呼び出し IIOPS IIOPS 接続は、現時点ではサポートされていません。 続いて、このスクリプトでは、EJBConnection オブジェクトのインスタ ンスを作成し、ConnectToServer メソッドを呼び出してサーバへの接続 を確立し、エラーをチェックします。 ejbconnection conn string properties[] properties[1]="javax.naming.Context.INITIAL_CONTEXT_FACTORY= com.sybase.ejb.InitialContextFactory" properties[2]="javax.naming.Context.PROVIDER_URL=iiop://myejbserver:9000" properties[3]="javax.naming.Context.SECURITY_PRINCIPAL=admin" properties[4]="javax.naming.Context.SECURITY_CREDENTIALS=" conn = CREATE ejbconnection TRY conn.connectToServer(properties) CATCH (exception e) MessageBox(" 例外 ", e.getmessage()) END TRY サーバとの接続解除 EJB サーバを使用してアプリケーションを終了したら、サーバとの接続を 解除する必要があります。 conn.disconnectserver() コンポーネント メソッドの呼び出し サーバへの接続が確立され、プロキシ オブジェクトかオブジェクトが 作成された後ではじめて、クライアント アプリケーションは EJB コン ポーネントを使用できます。EJB コンポーネント メソッドを呼び出す には、以下の操作に必要な PowerScript ステートメントを実行する必要 があります。 1 622 EJBConnection の lookup メソッドを使用して、コンポーネントの ホーム インタフェースにアクセスします。 PowerBuilder 第 28 章 EJB クライアントの構築 2 ホーム インタフェース上で create または findByPrimaryKey メソッド を呼び出して、コンポーネントのインスタンスを作成または検索 し、コンポーネントのリモート インタフェースへの参照を取得し ます。 3 リモート インタフェースでビジネス メソッドを呼び出します。 このプロシージャは、pbejbclient115.jar ファイルを使用します。この ファイルは、設計時および実行時に pbjvm115.dll によって自動的に Java VM クラスパスに追加されます。 lookup メソッドの使 い方 lookup メソッドは、ホーム インタフェースのプロキシ名、EJB コンポー ネントの JNDI 名、EJB コンポーネントの完全修飾ホーム インタフェー ス名の 3 つの文字列引数を受け取ります。 ホーム インタフェース名は、EJB ホーム インタフェースの完全修飾ク ラス名です。たとえば、クラスの Java ネーミング コンテキストからの 相対格納場所が ejbsample である場合、ホーム インタフェース名は ejbsample.HelloEJBHome になります。 次の例では、WebLogic 上の HelloEJB に対する、lookup メソッドの呼び 出しを示します。 HelloEJBHome homeobj homeobj = conn.lookup("HelloEJBHome", "ejbsample.HelloEJB", "ejbsample.HelloEJBHome") Lookup の大文字と小文字の区別 EJB サーバの Lookup では大文字と小文字が区別されます。lookup メ ソッドの引数に指定する文字列の大文字と小文字は、サーバの大文字 と小文字に一致させる必要があります。 EJB のインスタンス の作成や検索 セッション Bean は、クライアントのリクエストに応答して作成されま す。クライアントは、通常の場合、そのクライアント セッションの持 続中はセッション Bean を排他的に使用します。エンティティ Bean は、 データベースに保存される永続情報を表します。クライアントは、ほ かのクライアントと同時にエンティティ Bean を使用します。エンティ ティ Bean は、クライアントの有効期限が終了しても持続するため、エ ンティティ Bean のインスタンスが存在する場合は主キーのクラス名 を使用してこれを検索し、エンティティ Bean のインスタンスが存在し ない場合は新規に作成する必要があります。 アプリケーション テクニック 623 コンポーネント メソッドの呼び出し セッション Bean の場合、プロキシ オブジェクトの create メソッドを使用 して、 EJB のインスタンスを作成します。 create メソッドは、 CreateException と RemoteException を送出します。homeobj 内のホーム インタフェース への参照を取得していることを前提とした場合、すべての EJB サーバ では同じ方法で create が使用されます。 HelloEJB beanobj try beanobj = homeobj.create() catch (remoteexception re) MessageBox(" リモート例外 ", re.getmessage()) catch (createexception ce) MessageBox(" 作成例外 ", ce.getmessage()) end try エンティティ Bean の場合、主キーを提供します。FindByPrimaryKey メ ソッドは、FinderException と RemoteException を送出します。この例で は、キーは関数に引数として渡す特定の顧客 ID です。 try beanobj = homeobj.findByPrimaryKey(customerID) catch (remoteexception re) MessageBox(" リモート例外 ", re.getmessage()) catch (finderexception fe) MessageBox(" 検索例外 ", fe.getmessage()) end try EJB コンポーネント メソッドの呼び出し Bean のインスタンスの作成または検索が完了したら、そのメソッドを 呼び出すことができます。たとえば、次のようになります。 string msg msg = beanobj.displaymessage() Java クラスのインス タンスの作成 Bean に引数として Java クラスを受け取るメソッドがある場合、JavaVM オブジェクトの CreateJavaInstance メソッドを使用して Java クラスのイ ンスタンスを作成します。たとえば、findByPrimaryKey メソッドへの呼び 出し内の主キーが Java クラスである場合は、CreateJavaInstance メソッド を使用してそのクラスを作成し、PowerBuilder プロキシを使用してそ れと通信します。 この例では、create メソッドは Java の Integer 型のクラス引数を受け取 り ま す。PowerBuilder は java_integer と い う プ ロ キ シ を 作 成 し ま す (PowerBuilder integer 型との衝突を避けるために、接頭辞 java_ が必要 です)。CreateJavaInstance への呼び出しがその変数の値を設定し、EJB create メソッドを呼び出せるようにします。 CustomerRemoteHome homeobj CustomerRemote beanobj 624 PowerBuilder 第 28 章 EJB クライアントの構築 java_integer jint_a try homeobj = conn.lookup("CustomerRemoteHome", & "custpkg/Customer", "custpkg.CustomerRemoteHome" ) catch (Exception e) MessageBox( "Lookup 例外 ", e.getMessage() ) return end try try g_jvm.createJavaInstance(jint_a, "java_integer") jint_a.java_integer("8") beanobj = homeobj.create( jint_a, sle_name.text ) catch (RemoteException re) MessageBox(" リモート例外 ", re.getmessage()) return catch (CreateException ce) MessageBox(" 例外作成 ", ce.getmessage()) return catch (Throwable t) MessageBox(" その他例外 ", e.getmessage()) end try MessageBox( "Info", & " このレコードはデータベースの中に " & + "~r~n 正常に保存されました。" ) 戻り値のダウンキャス ト Java コードから、Java プログラミングで使用するためにダウンキャス トが必要な共通 Java オブジェクトが返されると、Java メソッドは常に Java.lang.Object として戻り値を設定します。PowerBuilder EJB クライア ント プロキシでは、java.lang.Object は any データ型にマップされます。 実行時、PowerBuilder は正しい Java オブジェクトを取得し、生成され たマッピング構造体にインデックスを付けて PowerBuilder プロキシ名 を取得します。any 値は、このプロキシ オブジェクトとして設定され ます。返された Java オブジェクトが PowerBuilder 標準データ型にマッ プ可能な場合は、any 値が PowerBuilder 標準データ型として設定されま す。 リモート インタフェースに次のメソッドが含まれるとします。 java.lang.Object account::getPrimaryKey() また、ホーム インタフェースは次のメソッドを含みます。 account accounthome::findByPrimaryKey(java.lang.String) アプリケーション テクニック 625 コンポーネント メソッドの呼び出し 戻り値 java.lang.Object は、実行時に java.lang.String となります。 PowerBuilder は戻り値を PowerBuilder の string データ型に自動的にダ ウンキャストします。 any nid try account beanobj homeobj = conn.lookup("AccountHome", & ejb20-containerManaged-AccountHome, & examples.ejb20.basic.containerManaged.AccountHome) beanobj = homeobj.create("101", 0, "savings") nid = beanobj.getPrimaryKey() accounts = homeobj.findByPrimaryKey(string(nid)) catch (exception e) MessageBox(" 例外 ", e.getmessage()) end try 動的キャスティング EJB メソッドへの呼び出しから返された Java オブジェクトが、必要な メソッドを提供しないプロキシで表される可能性のあるケースが 2 つ 考えられます。 • EJB メソッドの呼び出しから返される Java オブジェクトのクラス が動的に生成される場合、PowerBuilder は Java クラスによって実 装される最初のインタフェースのプロキシを使用する • someclass を実際に返す EJB メソッドのプロトタイプは、someclass が拡張または実装するクラスを返すように定義できる。たとえば、 実際に java.util.ArrayList 型のオブジェクトを返すメソッドは、 java.util.Collection を返すように定義できる。java.util.ArrayList は、 java.util.AbstractList から継承され、この java.util.AbstractList は、 java.util.AbstractCollection から継承され、この java.util.AbstractCollection が、java.util.Collection を実装する。この場合、PowerBuilder は、 java.util.Collection のプロキシを使用する DynamicCast メソッドを使用すると、返されたプロキシ オブジェクト を、必要なインタフェースのプロキシにキャストするか、実行時に返 されるオブジェクトの実際のクラスのプロキシにキャストし、そのオ ブジェクトのメソッドを使用可能にできます。 オブジェクトの実際のクラスを取得するには、GetActualClass メソッド を使用します。また、DynamicCast メソッドは、Java クラスの直接の親 を返す GetSuperClass メソッドや、クラスによって実装されるインタ フェース リストを文字列配列に書き込む GetInterfaces メソッドととも に使用できます。 たとえば、次のようなクラスがある場合、 626 PowerBuilder 第 28 章 EJB クライアントの構築 public class java.util.LinkedList extends java.util.AbstractSequentialList implements java.util.List, java.lang.Cloneable, java.io.Serializable GetActualClass は java.util.LinkedList を返し、GetSuperClass は java.util.AbstractSequentialList を返し、GetInterfaces は 3 を返し、 java.util.List、java.lang.Cloneable、および java.io.Serializable の 3 つの文字 列を、参照される文字列配列に書き込みます。 Java コレクション ク ラス EJB プロキシの生成では、Enumeration、Iterator、Vector などの Java 共 通コレクション クラスが生成されます。PowerBuilder は、これらのコ レクション クラスを、Java クライアントと同じように操作できます。 たとえば、ホーム インタフェースに戻り値 java.util.Enumeration を持つ 次のメソッドが含まれているとします。 Enumeration accounthome::findNullAccounts () 次のコードは、PowerBuilder EJB クライアントが PowerBuilder プロキ シを介して Enumeration クラスを操作する方法を示しています。 Enumeration enum try enum = homeobj.findNullAccounts() if (not enum.hasMoreElements()) then msg = " アカウントは、NULL アカウント型では見つかりません。" end if catch (exception e) MessageBox(" 例外 ", e.getmessage()) end try 例外処理 EJB コンポーネントのメソッドの実行時に発生したエラーは、例外プ ロキシにマップされ、呼び出し側のスクリプトに送出されます。また、 サーバへの接続に失敗したり、コンポーネントが見つけられなかった り作成できなかったりした場合も、pbejbclient115.pbx 内のすべてのク ラスのメソッドは例外を送出します。 EJB プロキシ プロジェクトを構築すると、ホーム インタフェースとリ モート インタフェースのプロキシ、EJB によって参照される Java クラ スのプロキシ、先祖クラスのプロキシ、および EJB とそのサポートす るクラスによって送出される可能性のある例外のプロキシが生成され ます。次の例外プロキシは、システム ツリー内に表示される例外プロ キシの一部です。 アプリケーション テクニック 627 例外処理 プロキシ名 createexception ejbexception finderexception remoteexception removeexception 例外の捕捉 Java オブジェクト名 javax.ejb.CreateException javax.ejb.EJBException javax.ejb.FinderException java.rmi.RemoteException javax.ejb.RemoveException クライアント アプリケーションは、さまざまな方法で通信エラーを処 理できます。たとえば、クライアントがサーバに接続し、オブジェク トのメソッドを呼び出そうとしたのにそのオブジェクトが存在しな かった場合は、サーバとの接続を解除し、別のサーバに接続して操作 を再試行する方法があります。あるいは、クライアントがユーザにメッ セージを表示して、次に起こることを制御する機会をユーザに与える 方法もあります。 クライアントが操作の再開のために新しいサーバに接続している場 合、エラー発生時には、新しいサーバ上でリモート オブジェクトをイ ンスタンス化してから、リモート オブジェクトのメソッドを呼び出す 必要があります。 次の例では、特定の例外の発生時に、スクリプトはメッセージ ボック スを表示するだけです。 //char getChar() 関数が RemoteException を送出します。 try conn.connectToServer(properties) mappinghome = conn.lookup("pbEjbMappingHome", "pbEjbTest/pbEjbMappingBeanSL", "pbejb.pbEjbMappingHome") mapping = mappinghome.create() ret = mapping.getChar() messagebox("EJB からの文字列 ", ret) catch (remoteexception re) messagebox(" リモート例外 ", re.GetMessage()) catch (createexception ce) messagebox(" 作成例外 ", ce.GetMessage()) end try 処理されない例外 628 例外ハンドラがない場合、または既存の例外ハンドラがその例外を処 理しない場合、アプリケーション オブジェクトの SystemError イベン トが実行されます。SystemError イベントにスクリプトが記述されてい ない場合は、アプリケーション エラーが起きて、アプリケーションは 終了します。 PowerBuilder 第 28 章 EJB クライアントの構築 クライアント管理のトランザクション EJB クライアント アプリケーションは、EJBTransaction オブジェクト を使用してサーバ上のトランザクションを制御します。このオブジェ クトには、クライアントにトランザクションを開始、コミット、また はロールバックさせるメソッドがあります。また、クライアントはト ランザクションの状態を取得したり、そのタイムアウト値を変更した り、コミットできないようにトランザクションを変更したりすること もできます。 EJBTransaction メソッドは、javax.transaction.UserTransaction インタ フェースのメソッドに直接マップします。 javax.transaction.UserTransaction インタフェースについての詳細は、Sun Java Web のサイト http://java.sun.com/products/jta を参照してください。 トランザクションの開 始と終了 クライアントは、EJBConnection クラスの getEJBTransaction メソッドを 呼び出して、EJBTransaction クラスのメソッドへのアクセスを取得でき ます。 ejbconnection conn ejbtransaction trans string properties[] conn = create ejbconnection TRY conn.connectToServer(properties) trans = conn.getEJBTransaction() CATCH (exception e) messagebox(" 例外 ", e.getmessage()) END TRY EJBTransaction のインスタンスを正常に取得した場合、その begin メソッ ドを使ってトランザクションを開始し、その commit メソッドまたは rollback メソッドを使用してトランザクションを終了します。 TRY // トランザクションを開始します。 trans.begin() // コンポーネントを作成し、トランザクション内で実行する // メソッドを呼び出します。 ... // トランザクションをコミットします。 trans.commit(); CATCH (exception e) messagebox(" 例外 ", e1.getmessage()) trans.rollback() END TRY アプリケーション テクニック 629 クライアントのデバッグ トランザクションに関 する情報の取得 GetStatus は、トランザクションがアクティブか、ロールバックのマー クが付いているか、prepare フェーズにあるか commit フェーズにある か、またはコミット済みかロールバック済みかを示す Integer 型の値を 返します。 トランザクションのタ イムアウト時間の設定 呼び出し元スレッドで、トランザクションをロールバックするタイム アウト時間を指定できます。次の例では、タイムアウト時間を 3 分 (180 秒)に設定しています。 trans.SetTimeout(180) trans.Begin() クライアントのデバッグ JavaVM クラスの createJavaVM メソッドは、第 2 引数として Boolean 型 の値を受け取ります。この第 2 引数が Ture の場合、クラスのロードな どの実行情報はアプリケーションが保存されているディレクトリの vm.out ファイルに記録されます。 // グローバル変数 :JavaVM g_jvm string classpath boolean isdebug classpath = "d:\tests\ejbsample;" isdebug = true g_jvm.createJavaVM(classpath, isdebug) 630 PowerBuilder 第 7 部 Web アプリケーションの開発 第 7 部では、PowerBuilder で Web アプリケーションを 開発するためのツールとテクニックについて説明します。 .NET Web フォーム アプリケーションおよび .NET Web サービス コンポーネントの開発についての詳細は『アプ リケーションとコンポーネントの .NET への配布』 マニュ アルを参照してください。 第 2 9 章 PowerBuilder での Web アプリ ケーション開発 この章について この章では、PowerBuidler での Web アプリケーション開発に使え る方法について概要を説明します。 内容 項目 Web アプリケーションの作成 .NET Web フォーム アプリケーションとコンポーネント Web サービス Web データウィンドウ データウィンドウ Web コントロール ActiveX ページ 633 634 634 635 636 Web アプリケーションの作成 PowerBuilder には、Web アプリケーション作成のためのいくつか のツールが用意されています。この節では、これらのツールの概 要を説明し、詳細情報の参照場所を示します。 Appeon for PowerBuilder Appeon for PowerBuilder は、既存の PowerBuilder クライアント / サーバ アプリケーションを Web に配布する製品です。詳細につ いては、ND ソフトウェア のサイト http://www.powerbuilder.jp/ を参照 してください。 アプリケーション テクニック 633 .NET Web フォーム アプリケーションとコンポーネント .NET Web フォーム アプリケーションとコンポーネント PowerBuilder .NET Web フォーム ソリューションは、ASP.NET 技術を 採用しています。それは 3 階層アーキテクチャであり、フロント エン ドとしてブラウザ クライアントを持ち、中間層として IIS サーバ上の PowerBuilder コンポーネントを使用します。データベース層に変更は ありません。 既存のアプリケーションをクライアント サーバ アーキテクチャから 3 階層 Web アーキテクチャへ移す場合、一般的には、アプリケーション コードの変更に多大な労力が必要である一方、Web 環境の制約による 各種の機能制限を許容することが求められます。PowerBuilder .NET Web フォーム ソリューションは、既存のクライアント サーバ アプリ ケーションの Web への配布を非常に簡単に行うこと、新しい Web ア プリケーションを開発するために PowerBuilder のスキルを使用できる ようにすることを目的としています。 PowerBuilder には、PowerBuilder 非ビジュアル オブジェクトから .NET アセンブリと .NET Web サービス アプリケーションを作成するための ターゲットが含まれています。 詳細については、 『アプリケーションとコンポーネントの .NET への配 布』マニュアルを参照してください。 Web サービス Web サービスは、インターネット テクノロジを活用して分散ソフト ウェア コンポーネントが自動で相互にやりとりするサービスと大ま かに定義されます。そうしたソフトウェア コンポーネントを使用する と、株式市況の取得、インターネットでのカタログの在庫検索、航空 会社とレンタカーの予約サービスの統合などのビジネス ロジックを 実行できます。アプリケーション用のコンポーネントを作成しなくて も、インターネット経由で既存のコンポーネントを使用できます。 PowerBuilder アプリケーションは、インターネット経由でアクセスさ れる Web サービスを利用するクライアントとして機能できます。 SOAP と WSDL を利用すると、1 つのエンティティとしてリモートで 発行された関数の集まりを PowerBuilder アプリケーションに含めるこ とができます。Web サービスは、アプリケーションまたはほかの Web サービスから送信されたリクエストを受信して応答します。 634 PowerBuilder 第 29 章 PowerBuilder での Web アプリケーション開発 Web サービスについての詳細は、第 30 章「Web サービス クライアン トの構築」を参照してください。 Web データウィンドウ Web データウィンドウは、Web アプリケーションのシンクライアント データウィンドウの実装です。Web データウィンドウは、クライアン ト上で PowerBuilder DLL を必要とせずに、PowerBuilder データウィン ドウのデータ操作、提示、およびスクリプト作成機能の大部分を提供 します。 Web データウィンドウは、以下のような、個別のコンピュータ上で実 行できるいくつかのソフトウェア コンポーネントのサービスを利用 します。 • アプリケーション サーバかトランザクション サーバで実行され る Web データウィンドウ サーバ コンポーネント • 動的ページ サーバ • Web サーバ • Web ブラウザ • データベース サーバ コンポーネントは非ビジュアル ユーザ オブジェクトであり、 データストアを使用して取得と更新の処理を行い、HTML を生成しま す。開発者は、PowerBuilder かカスタム コンポーネントに付属の汎用 コンポーネントを使用できます。 以下の方法によって、Web データウィンドウの機能を活用できます。 • Web データウィンドウのコンポーネントのコーディング 直接 Web デー タウィンドウのコンポーネントにアクセスするサーバ サイド ス クリプトを記述できます。 • 独自の HTML ジェネレータの記述 PowerBuilder で 提 供 さ れ て い る サンプル PBL を基にして、アプリケーションに必要なメソッドを 提供するユーザ独自の HTML ジェネレータを作成できます。 Web サービスについての詳細は、『データウィンドウ プログラマーズ ガイド』マニュアルを参照してください。 アプリケーション テクニック 635 データウィンドウ Web コントロール ActiveX データウィンドウ Web コントロール ActiveX データウィンドウ Web コントロール ActiveX は、Internet Explorer で使 用できる完全対話形式のデータウィンドウ コントロールです。このコ ントロールは、リッチ テキスト提示様式を除く PowerBuilder データ ウィンドウのすべての機能を実装します。 非推奨のテクノロジ データウィンドウ Web コントロール ActiveX は非推奨のテクノロジで あり、PowerBuilder の今後のリリースではサポートされなくなる可能 性があります。 データウィンドウ Web コントロール ActiveX は、検索引数によるデー タ検索とデータ更新をサポートします。開発者は、編集様式、表示書 式、および入力条件則を使用でき、データウィンドウを操作するため の PowerBuilder メソッドの大部分を利用できます。ファイル システム の対話にかかわるいくつかの関数がサポートされていないため、Web ActiveX は、ActiveX コントロールの中では安全にスクリプト実行でき るコントロールとして分類されています。 データウィンドウ Web コントロールには、いくつかのデータウィンド ウ Web コントロールで共有できるデータベース接続を作成するため の、データウィンドウ トランザクション オブジェクト コントロール が含まれています。 Web ActiveX は CAB ファイルとして提供され、これを使ってクライア ント ブラウザはコントロールをインストールして登録します。ユーザ が CAB ファイルを参照する Web ページをダウンロードすると、ブラ ウザは必要であれば CAB ファイルもダウンロードし、そのファイルを アンパックして、コントロールを登録します。 データウィンドウ Web コントロール ActiveX についての詳細は、 『デー タウィンドウ プログラマーズ ガイド』マニュアルを参照してくださ い。 636 PowerBuilder 第 3 0 章 Web サービス クライアントの構築 この章について この章では、PowerBuilder アプリケーションで Web サービスを使 用する方法について説明します。この章で説明するオブジェクト の関連情報については、 『PowerBuilder エクステンション リファレ ンス』マニュアルおよびオンライン ヘルプを参照してください。 内容 項目 Web サービスについて エクステンション ファイルのオブジェクトのインポート Web サービス プロキシ オブジェクトの生成 SOAP サーバへの接続 Web サービス メソッドの起動 例外処理 UDDI 照会 API の使い方 ページ 637 642 644 649 651 651 652 Web サービスについて Web サービスを使用すると、開発したアプリケーションから呼び 出される一般的なタスクを実行するために、新たにビジネス ロ ジックを作成しなくても、インターネット上かローカル ネット ワーク上の既存のコンポーネントを使用することができます。 Web サービスは、SOAP(Simple Object Access Protocol)が登場し た とき に 生ま れ たも の で す。SOAP は XML(Extensible Markup Language)を利用し、通常は、トランスポートとして HTTP(Hypertext Transfer Protocol)を使用します。SOAP を介して Web サービスを 起動するには、データ型のシリアライズとデシリアライズ、およ び SOAP メッセージの構築と解析が必要です。 アプリケーション テクニック 637 Web サービスについて Web サービスの利点の 1 つとして、WSDL(Web Services Description Language)を使用してサービスをその中に記述できるということがあ ります。WSDL は、XML 文法を使用し、メッセージを交換できる通信 エンドポイントの集まりとして Web サービスを定義します。WSDL サービス定義は、分散システムをドキュメント化し、アプリケーショ ン通信に関連する細部を自動化する方法を示す役割をします。 SOAP および WSDL により、アプリケーション間のインタフェースが、 異なるプラットフォーム間で標準化されるため、サードパーティのコ ンポーネントを簡単に使用できるようになります。 PowerBuilder は以下の Web サービス規格をサポートしています。 • SOAP 1.1 以降 • WSDL 1.1 以降 • HTTP または HTTPS Web サービスの作成 PowerBuilder は、カスタム クラス(非ビジュアル)ユーザ オブジェク トを開発し、EAServer コンポーネントとしてそれらを配布し、Web サービスとして公開するツールを提供します。Windows および UNIX オペレーティング システムで稼働している EAServer ホストにコン ポーネントを配布することができます。詳細については、第 23 章 「EAServer コンポーネントの構築」を参照してください。 Web サービス クライアントの構築について PowerBuilder アプリケーションは、インターネット経由でアクセスさ れる Web サービスを利用するクライアントとして機能します。SOAP と WSDL を利用すると、1 つのエンティティとしてリモートで発行さ れた関数のコレクションを PowerBuilder アプリケーションに含めるこ とができます。Web サービスは、アプリケーションまたはほかの Web サービスから送信されたリクエストを受信して応答します。 638 PowerBuilder 第 30 章 Web サービス クライアントの構築 SOAP を介して Web サービスを起動するには、データ型のシリアライ ズとデシリアライズ、および XML ベースの SOAP メッセージの構築 と解析が必要です。PowerBuilder と一緒にインストールされるエクス テンション ファイルあるいは動的ライブラリのオブジェクトを使用 する場合は、Web サービス クライアント プロキシがこれらの作業を行 います。そのため、SOAP 仕様とスキーマ、XML スキーマ仕様、ある いは WSDL 仕様とスキーマに関する幅広い知識を持つ必要はありま せん。 Web サービス エンジンの選択 PowerBuilder では、SOAP リクエストを作り、Web サービスから返さ れる SOAP メッセージを解析するために .NET Web サービス エンジン と EasySoap Web サービス エンジンのどちらかを選ぶことができます。 .NET Web サービス エンジンの使用 .NET アセンブリの生 成 .NET Web サービスは、最新の Web サービス標準をサポートします。 このエンジンを使用するためには、開発マシンに wsdl.exe Web サービ ス ツールが必要になります。このツールは、WSDL ファイルを解析し、 .NET アセンブリ用の C# コードを生成するために必要です。wsdl.exe ファイルは .NET SDK と一緒にインストールされます。開発マシンで は必要ではありませんが、.NET Web サービス エンジンに依存する Web サービスを利用するために開発マシンに .NET Framework が必要 です。 Web サービス プロキシ ウィザードで .NET Web サービス エンジンを 選択すると、ウィザードはプロキシ オブジェクトに加えて .NET アセ ンブリ(DLL)を生成します。実行時に Web サービスを使用するため には、アプリケーションと一緒にウィザードで生成された DLL を配布 する必要があります。 新しい Web サービス プロキシのためのプロジェクト ペインタで、 .NET Web サービス エンジンを選択することもできます。Web サービ ス プロキシ ジェネレータのプロパティ ダイアログボックスの[Web サービス]タブで[WSDL エンジン]から[.NET]チェックボックス を選択すると、PowerBuilder は[保存]アイコンをクリックした後に アセンブリ DLL を生成しようとします。プロパティ ダイアログボッ クスを使用して、Web サービス プロキシ ウィザードで以前に生成され たプロキシのための Web サービス エンジンを変更することはできま せん。 アプリケーション テクニック 639 Web サービスについて DLL の命名 [アセンブリ名]テキスト ボックスで Web サービス プロキシ ウィザー ドまたはプロジェクト ペインタによって生成された DLL に名前を付 けることができます。DLL 拡張子を含める必要はありません。ウィ ザ ー ド で 生 成 さ れ た ア セ ン ブ リ の 名 前 は、Web_service.DLL で す。 Web_service は[アセンブリ名]フィールドで指定する名前になります。 名前を指定しない場合は、アセンブリは DLL によって利用される Web サービスの名前を受け取ります。アセンブリは現行のターゲットの ディレクトリに生成されます。 DLL の配布 クライアント実行ファイルを配布するディレクトリに、Web サービス プ ロジェクトに作成した DLL を配布する必要があります。さらに、この ディレクトリに Sybase.PowerBuilder.WebService.Runtime.dll システム アセ ンブリおよび Sybase.PowerBuilder.WebService.RuntimeRemoteLoader.dll シ ステムアセンブリをコピーする必要もあります。 エクステンション オ ブジェクト .NET Web サービス エンジンと EasySoap Web サービス エンジンで、同 じ SOAP 接続と例外処理オブジェクトを使用しても、.NET Web サービ ス エンジンを参照するオブジェクトは異なるエクステンション ファ イルあるいはライブラリを要求します。 SoapConnection オブジェクトで使用可能なメソッドは、使用している エクステンション ファイルやライブラリ、および使用している Web サービスに依存します。.NET Web サービス エンジンのメソッドは、 SOAP クライアント ヘッダにセキュリティ情報を含めることができま す。 詳細については、 「エクステンション ファイルのオブジェクトのイン ポート」を参照してください。 テンポラリ ディレク トリ アクセス要件 640 .NET Web サービス エンジンは、クライアント コンピュータ上にある システム定義のテンポラリ ディレクトリへのアクセスをクライアン ト アプリケーションに要求します。クライアントにはこのディレクト リへの読み込みおよび書き込み許可が必要で、許可されていない場合 は「Web サービスを呼び出せません」という内容のエラーが発生しま す。テンポラリ ディレクトリは TEMP ユーザ環境変数で設定されま す。 PowerBuilder 第 30 章 Web サービス クライアントの構築 EasySoap Web サービス エンジンの使用 .NET SOAP エンジンを使用しない場合、PowerBuilder は EasySoap Web サービス エンジンを使用します。PowerBuilder の以前のリリースでは、 EasySoap Web サービス エンジンのみをサポートしていました。.NET Web サービス エンジンと異なり、EasySoap エンジンは XML タイプの 配列データ型および SOAP メッセージ エンベロープのヘッダ セク ションをサポートしません。EasySoap Web サービス エンジンは、下位 互換性および UNIX マシンに配布されるターゲットの使用のために残 されました。 Web サービス プロキシ ウィザードの先頭ページで、あるいは Web サービス プロジェクトのプロパティ シートの[Web サービス]タブ で、使用したい Web サービス エンジンを設定します。新しい Web サー ビス プロジェクトでは、 [.NET]チェック ボックスはデフォルトで設 定解除されます。UNIX マシンに配布する予定の Web サービス アプリ ケーションを開発している場合は、チェック ボックスをオンにしない でください。 Web サービスにアクセスするためのファイアウォール設定の指定 設計時に Web サービスを追加し、開発マシンがファイアウォールの後 ろにあるとき、インターネットに接続するためにプロキシ サーバ設定 を指定する必要があります。 表 30-1 は、PowerBuilder システム オプション ダイアログボックスの [ファイアウォール設定]ページで入力できる、設計時のプロキシ サーバ 設定です。ランタイム プロキシ サーバ設定を入力するには、SoapConnection SetProxyServer メソッドまたは SetProxyServerOptions メソッドを使用す る必要があります。 SetProxyServer および SetProxyServerOptions メソッドの詳細については、 オンライン ヘルプの「PowerBuilder エクステンション リファレンス」を 参照してください。 アプリケーション テクニック 641 エクステンション ファイルのオブジェクトのインポート 表 30-1: 設計時のファイアウォール設定 ファイアウォール設 定 ファイアウォール ホ スト ポート ユーザ名 パスワード 説明 Web ページにアクセスするために使用するプロ キシ サーバ名 プ ロキシ サ ーバに接続するために使用する ポート プロキシ サーバにアクセスするためのユーザ 名 プロキシ サーバにアクセスするユーザのため のパスワード PowerBuilder は、 [ファイアウォール設定]ページの[この設定をシス テムのデフォルトとして使用する]チェック ボックスも選択した場合 にのみ、プロキシ サーバ設定のために入力する値を使用します。Web サービスを利用するために選択したエンジンの種類は、PowerBuilder が設計時にインターネットに接続するために使用する設定にも影響し ます。 開発マシンはファイアウォールの後ろに あるが、 [この設定をシステムのデフォルトとして使用する]チェック ボックスを選択していない場合、PowerBuilder は Internet Explorer ブラ ウザのインターネット オプション ダイアログボックスで入力した設 定を使用してインターネットに接続しようとします。 [ファイアウォー ル設定]ページでの選択は、開発マシンがファイアウォールの後ろに ない場合には影響しません。 .NET Web サービス エンジン EasySoap Web サービス エンジン [この設定をシステムのデフォルトと して使用する]チェック ボックスを選択していない場合、PowerBuilder は開発マシンはファイアウォールの後ろにないとみなし、Internet Explorer ブラウザのインターネット オプション ダイアログボックスの 設定を使用しようとしません。 [この設定をシステムのデフォルトとし て使用する]チェック ボックスを選択しているが、開発マシンがファ イアウォールの後ろにない場合は、Web サービスの呼び出しは失敗し ます。 エクステンション ファイルのオブジェクトのインポート SOAP を介した Web サービスは、データ型のシリアライズとデシリア ライズおよび XML ベースの SOAP メッセージの解析を要求します。 642 PowerBuilder 第 30 章 Web サービス クライアントの構築 pbwsclient115.pbx ファイルは、SOAP 仕様とスキーマ、XML スキーマ 仕様、あるいは WSDL 仕様とスキーマに関する幅広い知識がなくても これらの作業を行える .NET Web サービス エンジンのためのオブジェ クトを含みます。エクステンション ファイルを PowerBuilder Web サー ビス アプリケーションにインポートした後に、これらのオブジェクト を使用することができます。 EasySoap Web サービス エンジンを使用する場合、pbsoapclient115.pbx ファイルまたは pbwsclient115.pbx ファイルを PowerBuilder アプリケー ションにインポートすることができます。しかし、.NET Web サービス エンジンを使用していなくても、pbwsclient115.pbx ファイルは設計マ シンおよび開発マシンに .NET 2.0 Framework を必要とします。両方の エクステンション ファイルは同じオブジェクトを含み、同様の方法で これらのオブジェクトとメソッドを使用します。 PBD ファイルの使用 PowerBuilder の以前のバージョンでは、エクステンション ファイルを インポートするかわりに、PBD ファイルをアプリケーション ライブラ リに追加する必要がありました。しかし、現在これは必要ではなく、 セットアップ プログラムが PBD ファイル(エクステンション ファイ ルとして、同じ SoapConnection オブジェクトと SoapException オブジェ クトを含んでいます)を Sybase\Shared\PowerBuilder ディレクトリにイ ンストールします。pbwsclient115.pbx または pbsoapclient115.pbx ファイ ルからオブジェクト定義をインポートするかわりに、pbwsclient115.pbd あるいは pbsoapclient115.pbd を使用することができます。 PowerBuilder エクステンション ファイルの定義をアプリケーション ラ イブラリに追加するには、システム ツリーでライブラリを右クリック して、ポップアップ メニューから[PB エクステンションのインポー ト]を選択します。Sybase\Shared\PowerBuilder ディレクトリに移動し て、使用したいエクステンション ファイルを選択します。 PBWSClient115.pbx または PBSoapClient115.pbx ファイルをアプリケー ションにインポートすると、以下のオブジェクトがシステム ツリーに 表示されます。 オブジェクト soapconnection 説明 SOAP サーバへの接続に使用される soapexception soapconnection から送出された例外の捕捉のために使 用される アプリケーション テクニック 643 Web サービス プロキシ オブジェクトの生成 Web サービス クライアント アプリケーションを作成する際に、アプリ ケーションの探索パス内のディレクトリに、クライアント実行ファイ ルとともに使用するエクステンション ファイルを配布する必要があ ります。Web サービス アプリケーションが必要とするエクステンショ ン ファイルを自動的に含めるために、ランタイム パッケージャ ツー ルを使用することができます。 Web サービス プロキシ オブジェクトの生成 Web サービス プロキ シ オブジェクトの作 成 Web サービス プロキシを新しく作成するには、新規作成 ダイアログ ボックスの[プロジェクト]ページから[Web サービス プロキシ ウィ ザード]アイコンを選択します。Web サービス プロキシ ウィザードで プロキシを作成することにより、PowerScript で Web サービスを使用で きるようになります。EasySoap Web サービス エンジンを選択した場 合、各ポートに対して 1 つのプロキシが作成されます。 ウィザードで以下の指定を行います。 • 使用する Web サービス エンジン • アクセスする WSDL ファイル • 選択する WSDL ファイル内のサービス • 使用する 1 つまたは複数のポート(EasySoap エンジンのみ) • ポート名に付ける接頭辞(EasySoap)およびプロキシ名に含める 接頭辞(EasySoap と .NET エンジン) • プロキシの配布先の PowerBuilder ライブラリ 新規作成 ダイアログボックスの[プロジェクト]ページから[Web サービス プロキシ]アイコンを選択することもできます。[Web サー ビス プロキシ]アイコンを選択すると、Web サービスのプロジェクト ペインタが開きます。ここからプロジェクトを作成し、オプションを 指定し、プロキシ ライブラリを構築できます。新規プロジェクトは、 Web サービス(および、EasySoap エンジンでは、プロキシを生成する ポート)を一覧にし、生成されるプロキシ オブジェクトを格納する出 力ライブラリの名前を指定します。 Web サービス プロジェクトの作成にウィザードを使用した場合でも ペインタを使用した場合でも、最後のステップとして、ペインタ バー の[配布]アイコンをクリックするか、メニュー バーから[デザイン| プロジェクトの配布]を選択して、プロキシ オブジェクトを構築します。 644 PowerBuilder 第 30 章 Web サービス クライアントの構築 循環参照 循環参照を含む WSDL ファイルからの Web サービス プロキシの生成 は、PowerBuilder ではサポートしません。このような「循環参照」の 例は、子クラス メンバーとしてそれ自身を含んでいる構造です。 生成されたプロキシ 生成されたプロキシはシステム ツリーに表示されます。プロキシ ノー ドを展開すると、メソッドのシグネチャを表示できます。 XML メソッドのエリ アス PowerBuilder は大文字と小文字を区別しませんが、XML、SOAP、C#、 および .NET は大文字と小文字を区別します。そこで、PowerScript コー ドが XML メソッドを正しく呼び出せるように、プロキシの各メソッ ドはエリアスを使用します。alias for の後に、対応する XML メソッ ドまたは SOAP メソッドの名前とシグネチャが大文字小文字を区別し て入ります。 たとえば、次のようになります。 function real getquote(string ticker) alias for getQuote(xsd:string symbol)# return xsd:float StockPrice@urn:xmethods-delayedquotes@SoapAction アプリケーション テクニック 645 Web サービス プロキシ オブジェクトの生成 異なる時間帯の Web サービス アプリケーションが date、time、あるいは datetime データ型を使用する Web サービスを利用する場合、サービス実装が処理し、異なる時間帯 からサービスにアクセスするアプリケーション ユーザに対して異な る値を返すことがあります。これは、通常 Web サービスの設計での問 題で、Web サービスとそれを呼び出すアプリケーション間での精度の 差あるいは変換エラーによるものではありません。 EasySoap Web サー ビス エンジンのデー タ型マッピング Web サービス プロキシ ジェネレータにより、EasySoap Web エンジンを 使用している場合は、XML と PowerBuilder 間で、.NET Web サービス エンジンを使用している場合は、XML、C#、.NET、および PowerBuilder 間でデータ型のマッピングが行われます。XML のデータ 型はすべて World Wide Web Consortium Web のサイト http://www.w3.org/1999/XMLSchema と World Wide Web Consortium Web のサ イト http://www.w3.org/2001/XMLSchema に基づいています。 表 30-2 は、XML と PowerScript 間でのデータ型マッピングを示してい ます。.NET Web サービスを使用する場合は、データ型は C# に変換さ れ、次に .NET データ型に変換されます。 (表 30-3 と 表 30-4 は、.NET Web サービス エンジンで使用されるデータ型マッピングを示してい ます。) 表 30-2: XML と PowerBuilder 間でのデータ型マッピング XML データ型 boolean byte (-128 ~ 127) または short unsignedByte (0 ~ 255) または unsignedShort int unsignedInt long (-9223372036854775808 ~ 9223372036854775807)、 unsignedLong (0 ~ 9223372036854775807)、 integer (-9223372036854775808 ~ 9223372036854775807)、 nonNegativeInteger (0 ~ 9223372036854775807)、 negativeInteger (-1 ~ -9223372036854775808)、 nonPositiveInteger (0 ~ -9223372036854775808)、または positiveInteger (1 ~ 9223372036854775807) decimal (-999999999999999999 ~ 999999999999999999) float double 646 PowerScript データ型 boolean int uint long ulong longlong decimal real double PowerBuilder 第 30 章 Web サービス クライアントの構築 PowerScript XML データ型 データ型 gYear、gYearMonth、gMonthDay、gDay、anyURI、QName、 string NOTATION、string、normalizedSting、token、または token か ら派生するデータ型 normalizedString、token、および派生データ型について normalizedString はキャリッジ リターン、ライン フィード、 あるいはタブ文字を含みません。token は normalizedString に似ていますが、先頭スペースや末尾スペース、あるいは 内部の連続するスペースを含みません。token から派生する デ ー タ 型 は、language、Name、NCName、NMTOKEN、 NMTOKENS、ID、IDREF、IDREFS、ENTITY、ENTITIES を 含みます。 date time dateTime base64、base64Binary、または hexBinary .NET Web サービス エンジンのデータ型 マッピング date time datetime blob .NET Web サービス エンジンを使用する際に、PowerBuilder は WSDL ファイルからの XML を C# コードに変換し、.NET アセンブリ内でそ れをコンパイルします。 注意 DataSet や System.Xml.XmlElement など、マッピングされていな い Microsoft .NET 固有のデータ型を使用する Web サービスには対応し ていません。 表 30-3 は、これらの変換のためのデータ型マッピングを示していま す。 アプリケーション テクニック 647 Web サービス プロキシ オブジェクトの生成 表 30-3: NET Web サービス エンジンのデータ型マッピング XML データ型 int unsignedInt boolean unsignedByte short unsignedShort long unsignedLong Decimal C# データ型 int uint bool Byte short ushort long ulong Decimal .NET データ型 System.Int32 System.UInt32 System.Boolean System.Byte System.Int16 System.UInt16 System.Int64 System.UInt64 System.Decimal Float Double Float Double System.DateTime Byte [ ] System.Float System.Double System.DateTime System.Byte [ ] Datetime、Date、および Time hexBinary および hex64Binary String nonNegativeInteger、 negativeInteger、 nonPositiveInteger、 positiveInteger、gYear、 gMonth、gMonthDay、gDay、 duration、anyURI、QName、 NOTATION、normalizedString、 token、language、NMTOKEN、 NMTOKENS、Name、 NCName、ID、IDREF、 IDREFS、ENTITY、 ENTITIES、および String AnyType Object System.String System.Object 表 30-4 は、C# データ型と PowerBuilder 間のデータ型マッピングを示 しています。 648 PowerBuilder 第 30 章 Web サービス クライアントの構築 表 30-4: C# と PowerBuilder 間のデータ型マッピング 配列の配列 C# データ型 byte sbyte short int long ushort uint ulong float PowerScript データ型 byte int int long longlong uint ulong longlong real double object char string decimal bool System.DateTime double any uint string decimal boolean datetime PowerBuilder は、XML とは異なり、可変長一次元配列のみサポートし ます。WSDL ファイルの配列が固定長の一次元である場合、PowerBuilder は自動的にこれを可変長配列に変換します。WSDL ファイルの配列が 多次元配列の場合、戻り値の型は無効になり、使用できません。 関数プロトタイプで、PowerBuilder は配列型を PowerBuilder any 型とし て表示します。戻り値を保持する適切な型の配列を宣言することが必 要です。 SOAP サーバへの接続 アクセスする Web サービスをホストする SOAP サーバに接続するに は、SoapConnection オブジェクトを使用します。SoapConnection オブ ジェクトの SetOptions メソッドを使用して、HTTPS 接続のユーザ ID およびパスワードなどのオプションを設定できます。.NET Web サー ビスでは、SetBasicAuthentication、SetCertificateFile 、および UseWindowsAuthentication 等の認証メソッドを使用することもできま す。 アプリケーション テクニック 649 SOAP サーバへの接続 同一アプリケーション内での複数の Web サービスの使用 異なる認証要求を持つ複数の Web サービスに接続する場合は、複数の SoapConnection オブジェクトのインスタンスを作成し、SetOptions メ ソッドあるいは各接続オブジェクトのほかの認証メソッドに適切な値 を設定する必要があります。 CreateInstance メソッドを使用して、Web サービスにアクセスするクラ イアント プロキシ インスタンスを作成します。 SoapConnection オブジェクト メソッドの詳細については、オンライン ヘルプの「PowerBuilder エクステンション リファレンス」を参照して ください。 例 以下のスクリプトでは、EasySoap Web サービス エンジンを使用している SOAP サーバ上の Web サービスへの接続が作成されます。CreateInstance メソッドで定義されるエンドポイントを使用して、接続プロパティが設定 されます。エンドポイントが CreateInstance メソッドで定義されない場 合、プロキシに格納されているデフォルト URL が使用されます。この スクリプトでは、SetSoapLogFile メソッドにより、ログ ファイルが指定 されています。戻り値がメッセージ ボックスに表示されます。 SoapConnection conn // SoapConnection を定義 syb_currencyexchangeport proxy_obj // プロキシを宣言 long rVal, lLog real amount // エンドポイントを定義。プロキシ内のデフォルト エンド // ポイントを使用する場合は、省略できる string str_endpoint str_endpoint = "http://services.xmethods.net:80/soap" conn = create SoapConnection // 接続のインスタンス化 lLog = conn.SetSoapLogFile("C:\mySoapLog.log") // SOAP のデータ交換を記録するトレース ファイルを設定 // 文字列を "" にすると、この機能は無効になる rVal = Conn.CreateInstance(proxy_obj, & "syb_currencyexchangeport", str_endpoint) // プロキシ オブジェクトの作成 try amount = proxy_obj.getrate("us","japan") // サービスの起動 messagebox(" 現在の為替レート ", "1 US ドル "& 650 PowerBuilder 第 30 章 Web サービス クライアントの構築 + " = " + string(amount) + " 日本円 ") catch ( SoapException e ) messagebox (" エラー ", "Web サービスを起動できません。") // エラー処理 end try destroy conn Web サービス メソッドの起動 SoapConnection は、SoapConnection オブジェクト メソッドを使って設 定した接続オプションで Soap_proxy オブジェクトを作成するために使 用されます。Web サービスのプロキシ オブジェクトが作成されると、 クライアント アプリケーションは、その Web サービスにアクセスでき るようになります。Web サービス メソッドを起動するには、プロキシ オブジェクトに以下の情報を含めることが必要です。 • サービスのエンドポイント。WSDL ファイルから取得 • SOAP メソッド呼び出しで使用される名前空間定義 • 構造体定義(必要な場合) • 戻される各構造体配列のインスタンス変数。戻される配列がすべ て any 型であるため • 1 つ以上の SOAP メソッドと、対応するエリアス文字列 例外処理 Web サービスのメソッドの実行時に発生するエラーは、SoapException オブジェクトに変換され、呼び出したスクリプトに送出されます。ま た、PBWSClient115.pbx および PBSoapClient115.pbx 内の SoapConnection オブジェクトのメソッドは、サーバへの接続が失敗し たときや Web サービスが検索されなかったり作成できなかったりし たときなどに、SoapException オブジェクトを送出できます。 アプリケーション テクニック 651 UDDI 照会 API の使い方 例外の捕捉 クライアント アプリケーションは、さまざまな方法で通信エラーを処 理できます。たとえば、クライアントがサーバに接続し、オブジェク トのメソッドを呼び出そうとしたときにそのオブジェクトが存在しな かった場合は、サーバとの接続を解除し、別のサーバに接続して操作 を再試行する方法があります。あるいは、クライアントがユーザにメッ セージを表示して、次に起こることを制御する機会をユーザに与える 方法もあります。 エラー発生時にクライアントが操作の再開のために新しいサーバに接 続している場合、新しいサーバ上でリモート オブジェクトをインスタ ンス化してから、リモート オブジェクトのメソッドを呼び出す必要が あります。 処理されない例外 例外ハンドラがない場合、または既存の例外ハンドラがその例外を処 理しない場合、アプリケーション オブジェクトの SystemError イベン トが実行されます。SystemError イベントにスクリプトが記述されてい ない場合は、アプリケーション エラーが起きて、アプリケーションは 終了します。 UDDI 照会 API の使い方 非推奨のテクノロジ UDDI は非推奨のテクノロジであり、PowerBuilder の今後のリリースで はサポートされなくなる可能性があります。 PowerBuilder のエクステンション クラスである UDDIProxy を使用す ると、アクセスする Web サービスを UDDI レジストリから検索できま す。エクス テンシ ョン クラス とその メソッ ドの詳 細につ いては、 『PowerBuilder エクステンション リファレンス』マニュアルまたはオン ライン ヘルプを参照してください。 コード例 次に、UDDIProxy クラスのすべてのメソッドを使用したコード例を示 します。この例では、同じ検索オプション(大文字と小文字を区別し て検索し、最大 5 行の検索結果を取得する)を使用して、IBM の UDDI レジストリをサービス名(Weather)とビジネス名(IBM)で検索します。 uddiproxy proxy int ret proxy = create uddiproxy ret = proxy.setinquiryurl (“http:/www-3.ibm.com/services/uddi/inquiryapi”) 652 PowerBuilder 第 30 章 Web サービス クライアントの構築 ret = proxy.setoption (false, true, 0, 5) int count, count2 string businessName[], businessDescription[] string businessKey [] string servicename[], servicedescription[] string servicekey [], wsdl [ ] ret = proxy.findService(“Weather”,count,serviceName, & serviceDescription, serviceKey, businessName, wsdl) int i, j FOR i = 1 TO count messagebox(servicename[i], & servicedescription[i]+servicekey[i]+wsdl[i]) NEXT proxy.findbusiness(“IBM”, count, businessName, & businessDescription, businessKey) FOR i = 1 TO count messagebox(businessName[i], & businessDescription[i] + businessKey[i]) proxy.getbusinessdetail (businessKey [i], count2, & servicename, servicedescription, servicekey, wsdl) FOR j = 1 TO count2 messagebox(servicename[j], & servicedescription[j]+servicekey[j]+wsdl[j]) NEXT NEXT destroy proxy UDDI API 呼び出しの トラブルシューティン グ ロギングを有効にすると、UDDIProxy オブジェクトのメソッド呼び出 しが失敗した場合に原因を追跡できます。ロギングを有効にするには、 PowerBuilder の Java サービス クラス パスにコンフィグレーション ファイル log4j.properties を追加する必要があります。次に、UDDI 検索 用のログ コンフィグレーション ファイルの例を示します。 #log4j.debug=true #log all level #log4j.rootCategory=DEBUG, lf5 #only log com.sybase.powerbuilder.uddi log4j.category.com.sybase.powerbuilder.uddi=DEBUG, dest2, lf5 #dest1 #log4j.appender.dest1=org.apache.log4j.ConsoleAppender #log4j.appender.dest1.layout= org.apache.log4j.PatternLayout #log4j.appender.dest1.layout.ConversionPattern= %-5p:%-5r:%-5c:%l:%m%n #dest2 アプリケーション テクニック 653 UDDI 照会 API の使い方 log4j.appender.dest2=org.apache.log4j.FileAppender log4j.appender.dest2.layout= org.apache.log4j.PatternLayout log4j.appender.dest2.layout.ConversionPattern= %-5p:%l:%m%n log4j.appender.dest2.File=c:/mylog.txt #lf5 log4j.appender.lf5= org.apache.log4j.RollingFileAppender log4j.appender.lf5.File=c:/mylog.lf5 log4j.appender.lf5.layout= org.apache.log4j.PatternLayout log4j.appender.lf5.layout.ConversionPattern= [slf5s.start]%d{DATE}[slf5s.DATE]%n\ %p[slf5s.PRIORITY]%n%x[slf5s.NDC] %n%t[slf5s.THREAD]%n\%c[slf5s.CATEGORY] %n%l[slf5s.LOCATION]%n%m[slf5s.MESSAGE]%n%n log4j.appender.lf5.MaxFileSize=500KB 654 PowerBuilder 第 8 部 全般的なテクニック 第 8 部では、日本語仕様、印刷処理、アクセシビリティ 要件、および Windows のレジストリを扱うテクニックに ついて説明します。InfoMaker で使用する様式とアクショ ンの作成についても説明します。 第 3 1 章 アプリケーションの国際化 この章について この章では、複数の言語向けのアプリケーションを開発および配 布するときに発生する問題についていくつか説明します。 内容 項目 国際化アプリケーションの開発 Unicode の使い方 ユーザ インタフェースの国際化 ページ 657 658 664 国際化アプリケーションの開発 複 数 の 言 語 で 配 布 す る ア プ リ ケ ー シ ョ ン を 開 発 す る と き は、 PowerBuilder に組み込まれている Unicode サポートを利用できま す。また、開発プロセスの 2 つのフェーズにも注目する必要があ ります。 アプリケーション テクニック • 1 つ目は国際化のフェーズです。ここでは、アプリケーション のコードの作成を始める前にデザインの問題を考慮します。 • 2 つ目はローカライゼーションのフェーズです。このフェーズ は、国際化アプリケーションの開発フェーズが完了したとき から始まり、アプリケーションの翻訳と配布の処理を行いま す。 657 Unicode の使い方 Unicode の使い方 Unicode は、世界のほとんどの言語のテキストを表示できる文字エン コーディング スキームです。PowerBuilder は、Unicode 文字をサポー トしています。したがって、アプリケーションの同一ページに複数の 言語の文字を表示したり、さまざまな国に向けた配布に適した柔軟な ユーザ インタフェースを作成したり、複数の言語のデータを処理した りすることができます。 Unicode について Unicode が開発されるまでは、多数の異なるエンコーディング システ ムがあり、その多くが互いに競合していました。たとえば、エンコー ディング システムが異なるために、同じ数字が別の文字で表示される ことがありました。Unicode は、サポートされているすべての記述言語 で、それぞれの文字に対して固有の番号を提供します。複数のスクリ プトで記述できる言語の場合、Unicode は、サポートされているそれぞ れのスクリプトの個々の文字に固有の番号を提供します。 サポートされている言語およびスクリプトについての詳細は、Unicode Web のサイト http://www.unicode.org/onlinedat/languages-scripts.html を参照 してください。 エンコーディング形式 658 Unicode のエンコーディング形式には、UTF-8、UTF-16、UTF-32 の 3 つがあります。本来、UTF は、Unicode Transformation Format の略でし た。この略語は、現在では、前述のエンコーディング形式の名前とし て使用されています。いずれの形式も、文字セット定義から、データ を表す実際のコード単位およびエンコーディング スキーム(特定のバ イトのシリアル化を含むエンコーディング形式)にマップします。 • UTF-8 は、1 ~ 4 バイトの符号なしのバイト シーケンスを使用し て、個々の Unicode 文字を表します。 • UTF-16 は、文字のスカラ値の範囲に応じて 1 つまたは 2 つの符号 なしの 16 ビット コード単位を使用して、個々の Unicode 文字を表 します。 • UTF-32 は、単一の符号なしの 32 ビット コード単位を使用して、 個々の Unicode 文字を表します。 PowerBuilder 第 31 章 エンコーディング ス キーム アプリケーションの国際化 エンコーディング スキームは、エンコーディング形式内のバイトをシ リアル化する方法を指定します。PowerBuilder で、ファイルの操作、 Blob データと文字列の変換、データウィンドウの保存を行うときは、 ANSI エンコーディング、または 3 つの Unicode エンコーディング ス キームのいずれかを使用するように選択できます。 • UTF-8 は、UTF-8 コード単位のシーケンスを、そのコード単位シー ケンス自体とまったく同じ順序でシリアル化します。 • UTF-16BE は、UTF-16 コード単位のシーケンスを、バイト シーケ ンスとしてビッグ エンディアン形式でシリアル化します。 • UTF-16LE は、UTF-16 コード単位のシーケンスを、バイト シーケ ンスとしてリトル エンディアン形式でシリアル化します。 UTF-8 は、Web リクエストおよび応答でよく使用されます。ビッグ エ ンディアン形式では、バイト シーケンス内の最上位の値が最初の格納 アドレスに格納されます。これは、通常、UNIX システムで使用され ます。リトル エンディアン形式では、シーケンス内の最下位の値が最 初に格納されます。これは Windows で使用されます。 PowerBuilder での Unicode サポート PowerBuilder は、内部的に UTF-16LE エンコーディングを使用します。 PBL のソース コードは、UTF-16LE でエンコーディングされています。 アプリケーションで入力されたテキストは、自動的に Unicode に変換 されます。String 型と Character PowerScript データ型は、Unicode データ だけを保持します。これらのデータ型に割り当てられた ANSI または DBCS 文字は、すべて内部で Unicode エンコーディングに変換されま す。 Unicode データベース のサポート ほとんどの PowerBuilder データベース インタフェースは、ANSI と Unicode の両方のデータベースをサポートしています。 Unicode デ ー タ ベ ー ス は、文 字 セ ッ ト が UTF-8 や UTF-16 な ど の Unicode 形式に設定されているデータベースです。データベース内のす べてのデータは、Unicode 形式であり、データベースに保存されるデー タはすべて明示的または暗黙的に Unicode データに変換されなければ なりません。 アプリケーション テクニック 659 Unicode の使い方 文字セットとして ANSI(または DBCS)を使用するデータベースは、 Unicode データを保存するための特別なデータ型を使用できます。これ らのデータ型は、NChar、NVarChar、および NVarChar2 です。これら のいずれかのデータ型のカラムは Unicode データを保存することがで きますが、そのタイプのカラムに保存されるデータは、明示的に Unicode に変換されなければなりません。 個々のインタフェースについての詳細は、 『データベースとの接続』マ ニュアルを参照してください。 文字列関数 Fill、Len、Mid、Pos などの PowerBuilder の文字列関数は、パラメータま たは戻り値としてバイトではなく文字数を受け取り、すべての環境で 同じ結果を返します。これらの関数には、"W" 付きの関数(FillW など) があります。これらは、"W" が付かない関数と同じ結果を返すので、 現時点では下位互換性のためにだけ残されており将来のバージョンで 削除される予定です。これらの関数の一部には、ANSI 対応の関数(FillA な ど)も あ り ま す。こ の "A" 付 き の 関 数 は、以 前 の バ ー ジ ョ ン の PowerBuilder で、文字数の代わりにバイトを返す文字列関数を使用し ていた DBCS 環境のユーザ向けに下位互換性のために提供されていま す。 GetEnvironment 関数を使用して、環境で使用される文字セットを指定で きます。 environment env getenvironment(env) choose case env.charset case charsetdbcs! // DBCS 処理 ... case charsetunicode! // Unicode 処理 ... case charsetansi! // ANSI 処理 ... case else // その他の処理 ... end choose 660 PowerBuilder 第 31 章 カタログ データ型の エンコーディング アプリケーションの国際化 Blob、BlobEdit、FileEncoding、FileOpen、SaveAs、および String などの関 数には、オプションの encoding パラメータがあります。これらの関数 では、ANSI、UTF-8、UTF-16LE、および UTF-16BE エンコーディング で Blob およびファイルを操作できます。このパラメータを指定しない 場合の SaveAs および FileOpen デフォルト エンコーディングは ANSI です。そのほかの関数のデフォルトは UTF-16LE です。 次の例は、FileOpen を使用してさまざまな種類のファイルを開く方法 を示します。 // ANSI ファイルを読み込みます。 Integer li_FileNum String s_rec li_FileNum = FileOpen("Employee.txt") // または // li_FileNum = FileOpen("Emplyee.txt", & // LineMode!, Read!) FileRead(li_FileNum, s_rec) // Unicode ファイルを読み込みます。 Integer li_FileNum String s_rec li_FileNum = FileOpen("EmployeeU.txt", LineMode!, & Read!, EncodingUTF16LE!) FileRead(li_FileNum, s_rec) // バイナリ ファイルを読み込みます。 Integer li_FileNum blob bal_rec li_FileNum = FileOpen("Employee.imp", Stream Mode!, & Read!) FileRead(li_FileNum, bal_rec) 初期設定ファイル SetProfileString 関数は、Windows システムでは ANSI または UTF16-LE エンコーディングで、また UNIX システムでは ANSI または UTF16-BE エンコーディングで、初期設定ファイルに書き込むことができます。 ProfileInt および ProfileString PowerScript 関数、およびデータウィンドウ 式関数は、これらのエンコーディング スキームのファイルを読み込む ことができます。 ソースのエクスポート とインポート ライブラリ エントリのエクスポート ダイアログボックスでは、エクス ポートされるファイルのエンコーディング タイプを選択できます。選 択肢は ANSI/DBCS(PowerBuilder 9 以前のバージョンにファイルをイ ンポートできます)、HEXASCII、UTF8、または Unicode LE です。 アプリケーション テクニック 661 Unicode の使い方 HEXASCII エクスポート形式は、ソース制御ファイルに使用されます。 Unicode 文字列は、エクスポートされるファイルでは 16 進数 /ASCII 文 字列で表されます。その種の文字列を含んでいるファイルとして識別 す る た め に、ヘ ッ ダ ー の 最 初 に HA と い う 文 字 が 付 い て い ま す。 HEXASCII ファイルを PowerBuilder 9 以前のバージョンにインポート することはできません。 PowerBuilder 9 以前のバージョンからエクスポートされるファイルを インポートする場合、オブジェクトが PBL に追加される前に、ファイ ル内のソース コードが Unicode に変換されます。 外部関数 ANSI 文字列を返す外部関数や、ANSI 文字列引数を持つ外部関数を呼 び出すときは、外部関数宣言で ALIAS 句を使用し、関数名に ;ansi を 追加する必要があります。たとえば、次のようになります。 FUNCTION int MessageBox(int handle, string content, string title, int showtype) LIBRARY "user32.dll" ALIAS FOR "MessageBoxA;ansi" 次の宣言は、Unicode 文字列を使用する “w” 付きの関数用です。 FUNCTION int MessageBox(int handle, string content, string title, int showtype) LIBRARY "user32.dll" ALIAS FOR "MessageBoxW" PowerBuilder 9 以前のバージョンからアプリケーションを移行する場 合、PowerBuilder は、ANSI 文字列を使用する関数宣言を適切な構文に 自動的に置き換えます。 複数の言語をサポート するためのフォントの 設定 システム オプション ダイアログボックスおよびデザイン オプション ダイアログボックスのデフォルト フォントは MS P ゴシックです。 システム オプション ダイアログボックスのフォントを Tahoma に設定 すると、ウィザードのウィンドウ ペインタ、ユーザ オブジェクト ペ インタ、メニュー ペインタのレイアウト ビューおよびプロパティ ビューで、複数の言語を正しく表示できます。 デザイン オプション ダイアログボックスの[エディタ フォント]ペー ジのフォントが Tahoma に設定されていない場合、スクリプト ビュー、 テキスト エディタ、ソース エディタ、データベース ペインタの ISQL セッション ビュー、およびデバッグ ウィンドウで、複数の言語を表示 することはできません。 662 PowerBuilder 第 31 章 アプリケーションの国際化 スクリプト ビュー、テキスト エディタ、ソース エディタ、データベー ス ペインタの ISQL ビューのデザイン オプション ダイアログボックス の[プリンタ フォント]タブ ページで、印刷用に別のフォントを選択 することができます。プリンタのフォントが Tahoma に設定されてお り、Tahoma フォントがプリンタにインストールされていない場合、 PowerBuilder は、多言語文字を検出したときにフォント セット全体を プリンタにダウンロードします。多言語文字を印刷する必要がある場 合は、プリンタにインストールされているプリンタ フォントを指定し ます。 データウィンドウ オブジェクトで複数の言語をサポートするには、す べてのカラムとテキスト コントロールのフォントを Tahoma に設定し ます。 印刷関数のデフォルト フォントはシステム フォントです。PrintDefineFont 関数および PrintSetFont 関数を使用して、ユーザのプリンタで利用で き、複数言語をサポートするフォントを指定します。 PBNI PowerBuilder ネイティブ インタフェースは Unicode ベースです。PBNI エクステンションは、C++ 開発環境で _UNICODE プリプロセッサ擬似 命令を使用してコンパイルする必要があります。 Unicode 環境での正常な動作を保証するため、エクステンションのコード では、char、char*、および const char* の代わりに、TCHAR、LPTSTR、ま たは LPCTSTR を使用する必要があります。または、MultiByteToWideChar 関数を使用して、文字列を Unicode 文字列にマップします。アプリケー ションで Unicode を有効にする方法についての詳細は、使用している C++ 開発環境のマニュアルを参照してください。 Web サービスでの Unicode の有効化 PowerScript ターゲットでは、Web サービス クライアント アプリケー ションによってインスタンス化される PBNI エクステンション クラス は、すべての内部処理で Unicode を使用します。ただし、コンポーネ ント メソッドの呼び出しは、EasySoap による処理のために ANSI に変 換されます。これらの呼び出しから返されるデータは、Unicode に変換 されます。 アプリケーション テクニック 663 ユーザ インタフェースの国際化 XML 文字列のエン コーディング XML パーサは、windows-1253 のように 8 ビット文字コードを使用する 文字列を解析することができません。たとえば、次の宣言を持つ文字 列は解析できません。 string ls_xml ls_xml += '<?xml version="1.0" encoding="windows1253"?>' UTF16-LE などの Unicode エンコーディング値を使用してください。 ユーザ インタフェースの国際化 国際的に配布するアプリケーションを作成するときに、ユーザ インタ フェースのデザインで考慮すべき点は 2 つあります。 物理的デザイン • ユーザ インタフェースの物理的なデザイン • アプリケーションの対象者の文化的基準 ユーザ インタフェースの物理的なデザインには、次のものを含める必 要があります。 • メニュー項目のテキスト、リスト、ラベルが翻訳されたときに文 字列が長くなっても収めることができる柔軟なウィンドウおよび オブジェクト たとえば、元が英語のウィンドウからウィンドウを継承し、ロー カライズする配布用に言語を変更できます。通常は、メニュー項 目、リスト、またはラベルのサイズを英語の文字列の長さの 1.3 倍 にしておけば、ほとんどの言語のテキストを収めることができま す。 • 文化的意識 RightToLeft バージョンの Windows で簡単に使用できるウィンド ウ ユーザ インタフェースの文化的なデザインには、対象者にとって許容 できることとできないこと、または意味があることを認識することが 要求されます。 たとえば、手のひらを表示する手のアイコンは、ある文化では「停止」 を意味しますが、別の文化では、 「拒否」を示します。同様に、黄色は ある文化では「注意」を意味しますが、別の文化では「幸福と繁栄」 を意味します。 664 PowerBuilder 第 3 2 章 利用しやすいアプリケーションの作成 この章について この章では、障害のあるユーザにも利用しやすいアプリケーショ ンを作成するためのガイドラインと要件についての情報を提供し ます。また、利用しやすいアプリケーションの作成を支援するた めに PowerBuilder が提供する機能について説明し、追加情報の入 手先も示します。 内容 項目 アクセシビリティの課題についての理解 ソフトウェアおよび Web アプリケーションのアクセシビリ ティ要件 PowerBuilder を使用した利用しやすいソフトウェア アプリ ケーションの作成 VPAT について 製品のアクセシビリティのテスト ページ 665 668 670 674 674 アクセシビリティの課題についての理解 障害のある人にも利用しやすいソフトウェア アプリケーションお よび Web ページを設計および開発する場合は、一般に 4 種類の障 害について考慮する必要があります。 アプリケーション テクニック • 視覚障害 • 聴覚障害 • 運動障害 • 認知障害または学習障害 665 アクセシビリティの課題についての理解 視覚障害 目の不自由なアプリケーション ユーザには、視覚に問題のないユーザ が利用できるすべてのグラフィック イメージおよびビデオに対応す る同等物をテキストの形式で用意する必要があります。このテキスト は、グラフィック形式で提供されている情報と概念の上で同等の内容 を伝える必要があります。それにより、ユーザは、画面読み上げソフ トウェアや点字リーダなどの補助技術を使用して情報を完全に利用で きます。すべてのユーザ インタフェース(UI)要素には、テキストま たはメニュー形式の同等物が必要です。また、目の不自由なユーザは、 視覚に問題のないユーザがマウスで行うような入力をキーボードから 行う必要があります。 色覚に障害のあるユーザに対応するには、色を情報伝達の唯一の手段 として使用するのを避ける必要があります。色で伝える情報を補完す る手段として、グラフやその他のイメージで色以外に塗りつぶしパ ターンを使用するのも 1 つの方法です。色だけで警告またはその他の 内容を提示する代わりに、音声通知を使用することもできます。 ハイ コントラストのサポートを有効にすると、色覚障害のあるユーザ や弱視ユーザが、デフォルトのシステム カラーおよびフォントを調整 して、ウィンドウまたは Web ページの領域を区別しやすくすることが できます。弱視のユーザは、ハードウェアまたはソフトウェアの拡大 鏡を使用して、ディスプレイ上のピクセルを拡大します。また、代替 テキストを使用して、イメージに表示される情報の一部を取得します。 聴覚障害 耳の聞こえないユーザや難聴のユーザには、音声情報を視覚的に表現 する必要があります。たとえば、音声による警告の代わりに、視覚的 な通知をアプリケーションで提供しなければならない場合がありま す。テキストを点滅させるのも 1 つの方法ですが、点滅速度は一定の 範囲内にする必要があります。これは、発作性疾患のあるユーザに問 題が発生するのを避けるためです。オーディオ トラックは、トランス スクリプトを必要とします。また、場合によってはビデオにクローズ ド キャプションが必要です。 聴覚障害を支援する技術には、音声情報をテキストまたは手話に変換 できる音声認識製品があります。同様に重要なのは、コンピュータと 電話を接続し、入力された ASCII テキスト出力をボー(Baudot)コー ドに変換する TTY/TDD モデムです。ボー コードは、聴覚障害者が電 話での会話に通常使用しているものです。 666 PowerBuilder 第 32 章 利用しやすいアプリケーションの作成 運動障害 運動機能が限られているユーザにとって、ハードウェアおよびメディ アを扱うのはしばしば困難ですが、一般に、最大の課題となるのは入 力です。運動障害のあるユーザは、その障害に応じて、場合によって は音声認識を使用したり、電子スイッチ、トラック ボール、または ジョイ スティックによってオンスクリーン キーボードを使用したり する必要があります。また、入力のペースが遅い可能性があるので、 タイマーおよび応答時間を調整できるようにしなければなりません。 インテリジェント機能が組み込まれているシステムでは、要求される 入力の数を減らすためのキューを提供できます。Windows アプリケー ションの場合、フィルタキー機能を利用して、キー リピートの間隔を 長くすることができます。また、Windows の固定キー機能を使用する と、〔Ctrl〕+〔Alt〕+〔Delete〕などの複数のキー ストロークをキー シーケンスとして入力できます。 認知障害 難読症、視覚または音声情報の処理に関する障害、テキスト入力に関 する障害、および短期記憶における障害は、すべてのソフトウェアお よび Web アプリケーションの内容に対するユーザのアクセスに影響 を与える可能性があります。明確でシンプルな言語を使用したり、一 貫性のあるデザインを採用したり、同じ情報をさまざまな形式(オー ディオとビデオの両方など)で提供したりすることは、いずれも認知 障害のあるユーザが情報にアクセスするのを助けます。また、応答時 間を調整できることは、通常より理解に時間のかかるユーザにとって 重要です。コンテンツを画面読み上げソフトウェアで利用できるよう にして視覚表現を補強するのも、認知障害のユーザの理解を助ける方 法の 1 つです。 一般的なアドバイス Web 表示では、フォント サイズなどのテキスト機能を直接操作するの ではなく、要素を使用してすべてをマークアップすることが重要です。 テキスト要素の機能を、視覚的な表示にだけ頼って示すのは避けてく ださい。要素をマークアップすると、画面読み上げソフトウェアなど の支援技術によって、見出しなどのテキスト要素をその機能ごとに通 知することができます。 適切なアクセシビリティを備えたデザインは、障害のあるユーザだけ でなく、すべてのユーザにとって使いやすいものです。一貫したイン タフェース デザイン、わかりやすい言語表現、簡単なナビゲーション、 同一情報のさまざまな形式での提供により、アプリケーションを誰に とっても使いやすくすることができます。 詳細情報 Web サイトを利用しやすくするための情報については、World Wide Web Consortium Web の サイ ト http://www.w3.org/ お よ び Utah State University WebAim Web のサイト http://www.webaim.org を参照してください。 アプリケーション テクニック 667 ソフトウェアおよび Web アプリケーションのアクセシビリティ要件 ユーザがさまざまなブラウザを調整して識別しやすくする方法、およ び視覚障害に対処する一般的な方法については、Lighthouse International Web のサイト http://www.lighthouse.org/ を参照してください。 ソフトウェアおよび Web アプリケーションのアクセシビ リティ要件 障害を持つユーザにも利用しやすいアプリケーションの作成を目指す 組織が従う必要のある複数の規制やガイドラインは、製品を販売また は使用する国ごとに少し異なります。 リハビリテーション法 :508 条 1998 年に制定された 508 条は、米国リハビリテーション法を修正した ものです。508 条は、米国政府機関が開発、調達、維持、使用するす べての電子情報技術は、障害のある一般市民にも利用しやすいもので なければならないことを求めています。米国の州の多くは、これらの 要件を同様に採択しています。米国連邦政府や多くの州政府にソフト ウェア アプリケーションを納入する組織は、アクセシビリティ支援 ツールを使用または販売する企業と同様に、これらの規制を守って、 自社製品が調達条件を満たすようにしなければなりません。 WCAG 1.0 508 条のガイドラインは、World Wide Web コンソーシアムが 1999 年 3 月に発行したアクセシビリティ ガイドラインを基にしています。これ は、Web Content Accessibility Guidelines (WCAG) version 1.0 として知ら れています。WCAG 1.0 は、現在、ほとんどのアクセシビリティ ガイ ドラインや、多数の国で政府によって施行されている標準の共通の土 台となっています。これらのガイドラインには、3 つの優先度があり ます。優先度 1 は、Web コンテンツへのアクセスに必須の機能を扱い ます。優先度 2 は、Web サイトを一般に、そして特にアクセシビリティ ツールを使う人にとって、使いやすく、またわかりやすくするための 方法を定義しています。優先度 3 は、最新の技術を使用する高度なユー ザビリティ機能について記述しています。 508 条には、優先度 1 の WCAG 勧告のほとんどと、優先度 2 および 3 の一部が含まれています。その他に、WCAG には含まれていない他の 要件もいくつか含まれています。WCAG は、組織が優先度 1 および 2 のガイドラインを満たすように努力することを推奨しています。 668 PowerBuilder 第 32 章 利用しやすいアプリケーションの作成 フランスの法令 フランス政府も、障害のある人向けの Web アクセシビリティを要求す る法令を制定し、その準拠のために AccessiWeb を呼ばれる基準を発行 しています。AccessiWeb には、Bronze、Silver、Gold の 3 つのレベル があります。これは、WCAG の 3 つの優先度レベルにほぼ対応してい ますが、AccessiWeb は、優先度 2 および 3 の多くの要件をより高い優 先度に上げており、WCAG 勧告の一部よりも詳細な内容を含んでいま す。 イギリスの法令 イギリスでは、イギリス住民を対象とする Web サイトは、障害のある 人にとって利用しやすいものでなければならないとする障害者差別禁 止法( Disability Discrimination Act )という法令が通過しています。イ ギリスの法の施行は、現行では WCAG 1.0 優先度 1 および 2 のガイド ラインに基づいています。 その他の国 その他の多くの国は、政府の Web サイトや一般的に使用される Web サ イトが障害のある人にとって利用しやすいものであることを要求する 法を制定しています。これらの国の中は、WCAG 1.0 の優先度 1 およ び 2 に準拠することを明示的に要求している国もありますが、優先度 1 の準拠だけを要求している国も少数あります。法的な要件のないそ の他の多数の国では、実際には WCAG が使用されています。 WCAG 2.0 WCAG 標準は、広く受け入れられる Web アクセシビリティの国際的 なガイドラインとなるように、現在も更新が行われています。WCAG 2.0 では、一般的な概念に焦点を当てて、Web サイトが障害のあるユー ザにとって利用しやすいものであるために保持しなければならない特 性を詳しく説明しています。技術的な要件については、別の文書で規 定されています。これは、一般的な概念を更新しなくても、技術的な 変更だけを簡単に更新できるようにするためです。 詳細情報 ソフトウェア アプリケーションおよび Web サイトについての米国連 邦政府のアクセシビリティ要件については、Electronic and Information Technology のサイト http://www.access-board.gov/sec508/guide/ および Electronic and Information Technology Accessibility Standards のサイト http://www.access-board.gov/sec508/standards.htm を参照してください。 Web アクセシビリティについて広く受け入れられている国際的な推奨 事項については、WCAG guidelines のサイト http://www.w3.org/TR/WCAG10/ を参照してください。開発中の新しいガイドラインについては、WCAG 2.0 guidelines のサイト http://www.w3.org/TR/WCAG20/ を参照してくださ い。 フランス政府が採択している Web アクセシビリティの基準について は、AccessiWeb criteria のサイト http://www.accessiweb.org/fr/Label_Accessibilite/ を参照してください。 アプリケーション テクニック 669 PowerBuilder を使用した利用しやすいソフトウェア アプリケーションの作成 PowerBuilder を使用した利用しやすいソフトウェア アプ リケーションの作成 MSAA 標準 PowerBuilder は、Windows および Web アプリケーションにアクセシビ リティ機能を組み込むために必要なインフラストラクチャおよびプロ パティを提供します。この機能を使用すると、アプリケーションを Microsoft Active Accessibility(MSAA)バージョン 2 に一般的に準拠さ せることができます。MSAA は、Windows 標準で、アクセシビリティ 支援ツールがユーザ インタフェース要素についての情報を取得する 方法、およびプログラムがアクセシビリティ支援ツールに情報を公開 する方法を定義します。 PowerBuilder の標準コントロールは、次の表に示すように、必要な Microsoft Active Accessibility のプロパティをすべてサポートしています。 表 32-1: MSAA プロパティと PowerBuilder サポート Microsoft Active Accessibility プロパティ サポートする PowerBuilder のプロパティ Name objectname.AccessibleName Role State Location Parent ChildCount Keyboard Shortcut DefaultAction Value 一部のコントロールは、Text プロパティまたは Title プロパティで Name 設定をサポートします。 すべてのコントロールで、Name は、 AccessibleName プロパティを通じてカスタマイズ できます。 objectname.AccessibleRole AccessibleRole プロパティを通じてカスタマイズ できます。 デフォルトの Active Accessibility をサポートする デフォルトの Active Accessibility をサポートする デフォルトの Active Accessibility をサポートする デフォルトの Active Accessibility をサポートする Text プロパティの "&" アクセス キーに対して、 デフォルトの Active Accessibility をサポートする また、そのコントロールに適用できる場合は PowerBuilder Accelerator プロパティを設定 デフォルトの Active Accessibility をサポートする (たとえば、チェック ボックスにはチェックがな いときのデフォルトのアクションがあります) デフォルトの Active Accessibility をサポートする (たとえば、チェック ボックスはオンのときの値 を持ちます) 670 PowerBuilder 第 32 章 Microsoft Active Accessibility プロパティ Children ビジュアル コント ロール 利用しやすいアプリケーションの作成 サポートする PowerBuilder のプロパティ デフォルトの Active Accessibility をサポートする Focus Selection Description (たとえば、リスト ボックス内の項目) デフォルトの Active Accessibility をサポートする デフォルトの Active Accessibility をサポートする objectname.AccessibleDescription Help HelpTopic AccessibleDescription プロパティを通じてカスタ マイズできます。 未サポート 未サポート DragObject から継承される PowerBuilder のビジュアル コントロールの 場合、PowerBuilder ドット表記またはペインタのプロパティ ビューの [その他]ページを使用して、各コントロールの IAccessible Name、Role、 および Description プロパティを操作できます。また、テキスト プロパ ティおよびアクセラレータ プロパティでアンパサンドがサポートさ れている箇所では、PowerBuilder プロパティを使用して、IAccessible プ ロパティの KeyboardShortcut を操作することもできます。その他の IAccessible プロパティは、Active Accessibility のデフォルト サポートを 使用して自動的に設定されます(たとえば、場所は、実行時に画面上 の Windows コントロールの絶対座標で自動的に更新されます)。 次の表は、DragObject から継承される PowerBuilder ビジュアル コント ロールと、そのデフォルトのアクセシブル ロール(AccessibleRole)の リストです。 表 32-2: PowerBuilder ビジュアル コントロールとそのデフォルト ロール AccessibleRole カタログ データ PowerBuilder ビジュアル コントロール (列挙体)値 animationrole! アニメーション checkbuttonrole! チェックボックス pushbuttonrole! コマンドボタン clientrole! データウィンドウ comboboxrole! ドロップダウン リストボックス ドロップダウン ピクチャ リストボックス comboboxrole! textrole! エディットマスク diagramrole! グラフ groupingrole! グループボックス progressbarrole! 水平プログレスバー、垂直プログレス バー アプリケーション テクニック 671 PowerBuilder を使用した利用しやすいソフトウェア アプリケーションの作成 AccessibleRole カタログ データ PowerBuilder ビジュアル コントロール (列挙体)値 scrollbarrole! 水平スクロールバー、垂直スクロール バー sliderrole! 水平トラックバー、垂直トラックバー listrole! リストボックス listrole! リストビュー clientrole! 月表示カレンダ textrole! マルチライン エディット graphicrole! ピクチャ pushbuttonrole! ピクチャボタン linkrole! ピクチャ ハイパーリンク listrole! ピクチャ リストボックス radiobuttonrole! ラジオボタン clientrole! リッチテキスト エディット textrole! シングルライン エディット linkrole! スタティック ハイパーリンク statictextrole! スタティック テキスト clientrole! タブ コントロール clientrole! タブ ページ outlinerole! ツリービュー OLEControl コントロールは、デフォルトで pushbuttonrole! に設定され ます。内容に応じてこのロールを設定する必要があります。 データウィンドウ コ ントロール PowerBuilder は、データウィンドウ カスタム コントロールとその子に ついて MSAA 標準を実装します。 AccessibleName プロパティと AccessibleDescription プロパティは文字 列値を取ります。AccessibleRole プロパティは、AccessibleRole カタロ グ データ型変数の値を取ります。 データウィンドウでのアクセシビリティ サポートには、いくつか制限 があります。 • 672 ナビゲーション関数 accNavigate では、Spatial Nabigation(画面上の 場所を起点にしたキーボードによるナビゲーション)はサポート されていません。キーボード ナビゲーションが論理タブのシーケ ンスに従う論理的なナビゲーションは、詳細区域のカラムについ てのみサポートされています。タブ値が 0 に設定されているカラ ムはユーザによる更新ができないので、キーボードからはアクセ スできません。 PowerBuilder 第 32 章 利用しやすいアプリケーションの作成 • コンポジット、ラベル、段組み、OLE 2.0、およびリッチテキスト データウィンドウ スタイルはサポートされていません。 • データウィンドウでの OLE オブジェクト、OLE データベース カ ラム、ネスティッド レポートのサポートは限られています。 PowerBuilder では、コントロールのコンテンツのアクセシビリティを 提供することはできません。これは、コントロールのベンダが提供す る必要があります。 例 次のステートメントは、ウィンドウ内のコマンド ボタンの IAccessible プロパティを設定します。 cb_1.accessiblename = " 削除 " cb_1.accessibledescription = " 選択したテキストを削除します " cb_1.accessiblerole = pushbuttonrole! 次のステートメントは、データウィンドウ オブジェクトのボタンの AccessibleName プロパティを設定します。 dw_1.Object.b_1.accessiblename = " 更新 " 次のステートメントは、データウィンドウ オブジェクトの AccessibleRole プロパティを 43(PushButtonRole! に関連付けられている数)に設定し、 プロパティを文字列変数に返します。 string ls_data dw_1.Object.b_1.AccessibleRole = 43 ls_data = dw_1.Describe("b_1.AccessibleRole") 配布 アクセシブル アプリケーションを配布する場合には、pbacc115.dll ファ イルを必ず配布する必要があります。 詳細情報 詳細については、Microsoft の Accessibility Web のサイト http://www.microsoft.com/japan/enable を参照してください。また、 WebAim Web のサイト http://www.webaim.org も参照してください。 アプリケーション テクニック 673 VPAT について VPAT について 自主的製品アクセシビリティ テンプレート(VPAT)は、米国連邦政 府の調達用に提供される製品がアクセシビリティ要件に準拠している かを連邦政府職員が事前に評価するのに役立つように設計されたリス トです。VPAT は、さまざまなタイプの製品についてアクセシビリティ 要件に準拠するための基準を示します。また、自社製品が VPAT の基 準を満たしているかについて、企業がチェックしたりコメントを追加 したりできるカラムがあります。 VPAT は、ソフトウェア アプリケーションとオペレーティング システ ム、Web ベースのインターネット情報とアプリケーション、およびそ の他のタイプの製品で利用できます。VPAT に記入する必要がない場 合でも、自社製品のタイプについてのテンプレートを参照することで、 ソフトウェアおよび Web アプリケーションに対する 508 条の要件を明 確に理解することができます。 詳細情報 さまざまな VPAT を確認するには、Information Technology Industry Council Web のサイト http://www.itic.org を参照してください。 IT 製品の全 VPAT のサンプルを確認するには、Sybase accessibility のサ イト http://www.sybase.com/accessibility を参照してください。 製品のアクセシビリティのテスト MSAA 2.0 ソフトウェア開発キット(SDK)には、アプリケーション が MSAA に準拠していることを確認するためのツールが複数含まれ ています。たとえば、AccExplorer、Accessible Event Watcher、Object Inspector などがあります。これらのツールは、Microsoft Web のサイト http://www.microsoft.com/downloads/details.aspx?familyid=3755582A-A707460A-BF21-1373316E13F0&displaylang=en から利用できます。 障害のあるユーザにとってのアプリケーションの動作を直接テストす るには、さまざまな方法を使用できます。たとえば、テキストのみの ブラウザを使用したり、キーボードだけを使って入力したり、JAWS、 Window-Eyes、Hal、または Supernova などの画面読み上げソフトウェ アを使ってアプリケーションを使用したりすることができます。 Web サイトが 508 条および WCAG 1.0 に準拠しているかどうかをテス トするために使用できる商用アプリケーションもいくつかあります。 674 PowerBuilder 第 32 章 詳細情報 利用しやすいアプリケーションの作成 WCAG 1.0 の準拠についてテストするためのチェックリストについて は、W3C Web のサイト http://www.w3.org/TR/1999/WAI-WEBCONTENT19990505/full-checklist を参照してください。W3C Web サイトにも、ア クセシビリティをテストするためのリストと評価ツールがあります。 アプリケーション テクニック 675 製品のアクセシビリティのテスト 676 PowerBuilder 第 3 3 章 印刷 この章について この章では、PowerScript の組み込み関数を使用して、リストやレ ポートを印刷する方法について説明します。 内容 項目 印刷関数 印刷の基礎 ジョブの印刷 タブの使い方 印刷ジョブの停止 高度な印刷技法 ページ 677 679 679 680 681 682 印刷関数 PowerScript 言語では、帳票やレポートの作成のための組み込み関数 を用意しています。わずか 3 つの関数(PrintOpen、Print、PrintClose) を用いるだけで、使用プリンタのデフォルトのフォントで表(タ ブラ)形式のレポートを印刷できます。ほかの関数を用いると、複 数のテキストフォント、文字サイズ、スタイルが使用できるだけ でなく、罫線やピクチャを用いた帳票やレポートが作成できます。 表 33-1 は印刷用の関数のリストです。 表 33-1: PowerScript 印刷関数 関数 Print PrintBitMap PrintCancel PrintClose PrintDatawindow アプリケーション テクニック 説明 Print 関数には 5 種類の構文がある。タブを 1 個指 定できる構文が 3 つ、タブを 2 個指定できる構文が 1 つある 指定されたビットマップを印刷する 指定された印刷ジョブを取り消す 印刷ジョブの現行ページをプリンタ(またはスプー ラ)に送り、印刷ジョブを終了する 指定されたデータウィンドウを印刷ジョブとして 印刷する 677 印刷関数 関数 PrintDefineFont PrintGetPrinter PrintGetPrinters PrintLine PrintOpen PrintOval PrintPage PrintRect PrintRoundRect PrintScreen PrintSend PrintSetFont PrintSetPrinter PrintSetSpacing PrintSetup PrintSetupPrinter PrintText PrintWidth PrintX PrintY 説明 印刷ジョブに使用できる 8 種類のフォントから 1 つのフォントを定義する 現在のプリンタ名を取得する 使用可能なプリンタのリストを取得する 指定の太さの線を指定された位置に印刷する 印刷ジョブを開始し、その印刷ジョブに印刷ジョブ 番号を割り当てる 指定サイズの楕円(または円)を指定された位置に 印刷する 現行ページを印刷し、新しいページを設定する 指定サイズの長方形を指定された位置に印刷する 指定サイズ丸長方形を指定された位置に印刷する 画面のイメージを印刷ジョブの一環として印刷す る 指定された文字列をプリンタに直接送信する 現行フォントに、現行ジョブの定義済みフォントの 1 つを設定する 次に呼び出される印刷関数のためにプリンタを使 用するよう設定する。この関数は開いているジョブ には影響しない 行間隔を決定する係数を設定する プリンタの設定 ダイアログボックスを呼び出し、 エンド ユーザが行う設定をプリンタ ドライバに対 して保存する プリンタの設定 ダイアログボックスを表示する 指定テキスト文字列を指定された位置に印刷する 現行印刷ジョブの現行フォントで、指定された文字 列の長さ(単位 : 1/1000 インチ)を返す 印刷カーソルの X 値を返す 印刷カーソルの Y 値を返す 印刷関数についての詳細は、 『PowerScript リファレンス』マニュアル を参照してください。 678 PowerBuilder 第 33 章 印刷 印刷の基礎 印刷処理は、すべて印刷領域に基づいて定義されます。印刷領域とは、 物理的な印刷ページから余白を除いた領域のことです。たとえば、ペー ジのサイズが 8.5 × 11 インチで、上下左右の余白がすべて 1/2 インチ の場合には、印刷領域は 7.5 × 10 インチとなります。 測定単位 印刷領域の測定単位は 1/1000 インチです。たとえば、印刷領域が 7.5 × 10 インチの場合、その四隅の座標は以下のようになります。 左上隅の座標は 0,0 右上隅の座標は 7500,0 左下隅の座標は 0,10000 右下隅の座標は 7500,10000 印刷カーソル 印刷処理の際、PowerBuilder は、印刷カーソルを使用して印刷位置を 制御します。印刷カーソルは、印刷が開始される左上隅の座標を保持 します。PowerBuilder は、PrintBitmap 関数、PrintLine 関数、PrintRectangle 関数、PrintRoundRect 関数以外の印刷処理の後で、印刷カーソルを(必 要であればタブ位置も)更新します。複雑なレポートの作成時にテキ スト、オブジェクト、罫線、およびピクチャの位置を指定するには、 各印刷関数の呼び出し時にカーソル位置を指定します。 ジョブの印刷 印刷ジョブを開始するには、まず最初に PrintOpen 関数を呼び出す必要 があります。PrintOpen 関数は、新しいページをメモリ上に定義し、す べての印刷がプリンタのデフォルト フォントで行われるように指定 して、整数値を返します。この整数値は、ほかのすべての関数呼び出 しで印刷ジョブの識別に用いられるジョブ番号です。 PrintOpen 関数の後に 1 つまたは複数のほかの印刷関数を呼び出し、最 後に PrintClose 関数(または PrintCancel 関数)を呼び出してジョブを終 了します。通常、PrintOpen 関数と PrintClose 関数の間には、タブ付きま たはタブなしで文字列を印刷する単純な印刷関数、あるいはレポート に罫線、オブジェクト、ピクチャーなどを加える複雑な印刷関数が呼 び出されます。 アプリケーション テクニック 679 タブの使い方 タイトルの印刷方法 各ページの上部にタイトルを印刷するときには、印刷される行数をカ ウントし、一定の行数(たとえば 50)になったら PrintPage 関数を呼び 出し、カウンタをリセットしてタイトルを印刷するようにします。 以下の例は、単純な印刷リクエストです。 Int PrintJobNumber // 印刷ジョブを開始し、PrintJobNumber に // PrintOpen の戻り値の整数を設定します。 PrintJobNumber = PrintOpen() // Atlanta の文字列を印刷します。 Print(PrintJobNumber,"Atlanta") // 印刷ジョブを閉じます。 PrintClose(PrintJobNumber) タブの使い方 Print 関数には、いくつかの構文があります。前出の例の構文では、印 刷領域の左端から文字列が印刷され、次に新しい行が印刷されます。 Print 関数のほかの構文で、タブを用いて印刷処理の前または後、ある いは前後で印刷カーソルの位置を指定できます。 タブ値の指定 タブ値は、1/1000 インチの単位で、印刷領域の左端からの相対位置に よって指定します。タブ値が Print 関数の呼び出し文字列の前にあり、 その文字列の後にはない場合、PowerBuilder はタブを設定し、印刷し て、新 し い 行 を 開 始 し ま す。タ ブ 値 が 文 字 列 の 後 に あ る 場 合、 PowerBuilder は印刷後にタブを設定し、新しい行を開始せずに次のス テートメントを待ちます。 以下の例では、Job は整数の印刷ジョブ番号です。 以下のステートメントは、印刷領域の左端から 1 インチの位置にタブ を設定し、Atlanta と印刷して、新しい行を開始します。 Print(Job,1000,"Atlanta") 以下のステートメントは、現行印刷位置に Boston と印刷し、印刷領域 の左端から 3 インチの位置にタブを設定して、その次のステートメン トを待ちます。 Print(Job,"Boston",3000) 680 PowerBuilder 第 33 章 印刷 以下のステートメントは、印刷領域の左端から 1 インチの位置にタブ を設定し、Boston と印刷し、印刷領域の左端から 3 インチの位置にタ ブを設定して、その次のステートメントを待ちます。 Print(Job,1000,"Boston",3000) タブと印刷カーソル PowerBuilder がタブを設定するときには、印刷カーソルの X 座標に印 刷カーソル値(指定された値と現行カーソル位置との大きい方の値) を設定します。したがって、指定された値が印刷カーソルの現行 X 座 標より小さい場合には、カーソルは移動しません。 以下に示す最初の Print 文は、印刷領域の左端から 1 インチの位置にタ ブを設定し、Sybase と印刷しますが、次のタブには移動しません(印 刷領域の左端から 0.5 インチは、現行カーソル位置より左側にあるた めです)。タブは最後の引数として指定されたので、タブを無視して も、最初の Print 文は新しい行を開始しません。2 番目の Print 文は、 Sybase の e の直後に Inc. を印刷し(つまり Sybase Inc.) 、新しい行を開始 します。 Print(Job,1000,"Sybase",500) Print(Job," Inc.") 印刷ジョブの停止 印刷ジョブを中断するには、以下の 2 つの方法があります。通常では、 印刷ジョブの終わりに PrintClose 関数を呼び出してジョブを終了しま す。もう 1 つは、PrintoCancel 関数を呼び出してジョブを取り消す方法 です。 PrintClose 関数の使い 方 PrintClose 関数は、現行ページをプリンタまたはプリント スプーラに送 り、印刷ジョブを終了して、印刷を開始したウィンドウをアクティブ 状態にします。PrintClose 関数呼び出しを実行した後では、そのジョブ 番号を参照する関数呼び出しがすべて無効となります。 PrintCancel 関数の使 い方 PrintCancel 関数は、印刷ジョブを終了し、印刷されずに残った出力を すべて破棄します。PrintCancel 関数は、処理が終了する前にエンド ユー ザに対して印刷を取り消す手段を提供します。通常この関数は、グロー バル変数を定義して、印刷ジョブの処理中にその変数の値を定期的に チェックすることによって呼び出されます。 StopPrint が Boolean 型のグローバル変数であるものとします。以下の ステートメントは、StopPrint グローバル変数をチェックし、StopPrint 変数の値が TRUE になったらジョブを取り消します。 アプリケーション テクニック 681 高度な印刷技法 IntJobNbr JobNbr = PrintOpen() // グローバル変数の初期値を設定します。 StopPrint = FALSE // 印刷処理を行います。 Do While ... . . . // グローバル変数をテストします。 // 値が TRUE の場合、印刷ジョブをキャンセルします。 // スクリプトの実行を止めます。 If StopPrint then PrintCancel(JobNbr) Return End If Loop 高度な印刷技法 PowerBuilder で複雑なレポートを作成するときには、これまでに紹介 した以外の関数も必要となりますが、比較的簡単に作成できます。 PowerScript 関数を使用して、ジョブに対するフォントの定義、フォン ト間隔と行間隔の指定、ページ上へのオブジェクトの配置、テキスト やオブジェクトを配置する正確な位置の指定を行うことができます。 フォントの定義と設定 これまでの例では、プリンタのデフォルト フォントを使用しました が、各印刷ジョブにつき最大 8 つのフォントを定義することや、その ジョブの実行中にフォントを切り替えることが可能です。 さらに、印刷ジョブの実行中は、必要に応じて何度でもフォントの再 定義ができます。このため、使用プリンタで使用可能なフォントをす べて、印刷ジョブにおいて使用できます。ただし、フォントを再定義 するとパフォーマンスが多少低下するので、PrintOpen 関数を呼び出し た時点でフォントを定義し、印刷ジョブの実行中にフォントを変更し ないようにしてください。 フォントを定義するには、Integer 型変数に PrintDefineFont 関数が返した 値を設定し、次に PrintSetFont 関数を使用してフォントを変更します。 682 PowerBuilder 第 33 章 印刷 JobNum は整数の印刷ジョブ番号で、現行プリンタは Helv という フ ォ ン ト を 持 っ て い る も の と し ま す。以 下 の ス テ ー ト メ ン ト は、 Helv18BU(Helv フォント、18 ポイントの太字、下線付き)を定義して います。定義は、JobNum のフォント 2 に保存されています。社名は フォント 2 で印刷されます。 例 IntJob, Helv18BU JobNum = PrintOpen() Helv18BU = PrintDefineFont(JobNum,2,"Helv",250,700, & Variable!,Swiss!,FALSE,TRUE) PrintSetFont(JobNum,2) Print(JobNum,"Sybase, Inc.") PrintDefineFont 関数と PrintSetFont 関数についての詳細は、 『PowerScript リファレンス』マニュアルを参照してください。 行間隔の設定 Print 関数を使用すると、行間隔は自動的に設定されます。たとえば、 18 ポイントのフォントで印刷して新しい行を開始すると、印刷カーソ ルの Y 座標に文字の高さの 1.2 倍が加えられます。 この行間隔係数 1.2 は、固定されているわけではありません。行間隔 は、PrintSetSpacing 関数を使用して設定できます。 以下のステートメントを実行すると、行と行が密着した 1 行間隔 で印刷されます(フォントやプリンタによっては、最も低い文字の最 下部と最も高い文字の最上部が接触する可能性があります)。 例 PrintSetSpacing(JobNum,1) 以下のステートメントは、1.5 行間隔で印刷します。 PrintSetSpacing(JobNum,1.5) 以下のステートメントは、2 行間隔で印刷します。 PrintSetSpacing(JobNum,2) 描画オブジェクトの印 刷 印刷ジョブでは、以下の描画オブジェクトが使用できます。 • 直線 • 長方形 • 丸長方形 • 楕円 • ピクチャ アプリケーション テクニック 683 高度な印刷技法 印刷ジョブで描画オブジェクトを配置するときには、まず最初に描画 オブジェクトを配置し、次にテキストを加えます。たとえば、印刷領 域内に長方形を描き、次にその長方形の内部に罫線とテキストを加え ます。オブジェクトは輪郭線だけのように見えますが、実際には塗り つぶされています(空白が入っています)。したがって、オブジェクト をテキストや別のオブジェクトの上に重ねて配置すると、そのテキス トや別のオブジェクトは覆い隠されてしまいます。 注意 :PowerBuilder は、すべてのテキストやオブジェクトが印刷領域内 に配置されているかどうかを確認しません。印刷領域内にあるものを 印刷するだけです。 例 以下のステートメントは、1 × 3 インチの長方形を描き、次にその 長方形の内部に会社の住所を印刷します。長方形はページの上端の中 央に描かれます。 IntJob JobNum = PrintOpen() PrintRect(JobNum,2500,0,3000,1000,40) Print(JobNum,2525,"") Print(JobNum,2525,"25 Mountain Road") Print(JobNum,2525,"Milton, MA 02186") PrintClose(JobNum) 684 PowerBuilder 第 3 4 章 初期設定ファイルと Windows レジ ストリの管理 この章について この章では、PowerBuilder アプリケーションの環境設定とデフォ ルト設定を管理する方法について解説します。 内容 項目 環境設定とデフォルト設定について 初期設定ファイルでの情報の管理 Windows レジストリでの情報の管理 ページ 685 686 687 環境設定とデフォルト設定について PowerBuilder アプリケーションは、セッションをまたがってエン ド ユーザの環境設定とデフォルト設定を保存できます。たとえば、 アプリケーションはそのアプリケーションの表示と動作の形態を 管理する設定や、データベースに接続するためにデフォルトのパ ラメータを格納する設定を保持しています。PowerBuilder アプリ ケーションは、初期設定ファイルや Windows レジストリでこのよ うな情報を管理できます。 データベース接続パラメー タ トランザクション オブジェクトの値は、通常の場合、外部ファイ ルから値を取得して設定する必要があります。たとえば、アプリ ケーションを開発しているときは PowerBuilder 初期設定ファイル から、またアプリケーションを配布するときはアプリケーション 固有の初期設定ファイルから値を設定できます。 初期設定ファイル内のデータベース接続パラメータについての詳 細は、182 ページの「外部ファイルからの値の読み込み」を参照し てください。 Windows レジストリにデータベース接続パラメータを登録したり 取得したりする方法については、687 ページの「Windows レジス トリでの情報の管理」を参照してください。 アプリケーション テクニック 685 初期設定ファイルでの情報の管理 ツールバーの設定 PowerBuilder では、ツールバーの設定に関する情報の取得や修正を行 うための関数が用意されています。これらの関数を使用して、現行の ツールバーの設定情報の保存と復元ができます。 詳細については、80 ページの「ツールバー設定の保存と復元」を参照 してください。 保存可能なほかの設定 データベース接続パラメータとツールバーの設定情報のほかに、アプ リケーション特有の設定情報を保存できます。たとえば、色、フォン トの表示設定やエンド ユーザの環境設定情報などを保持できます。 初期設定ファイルでの情報の管理 初期設定ファイルにア クセスする関数 PowerBuilder には、初期設定ファイルを使用してアプリケーション設 定を管理するための関数が用意されています。 表 34-1: PowerBuilder 初期設定ファイル関数 関数 ProfileInt ProfileString SetProfileString 説明 プロファイル ファイルの設定値を Integer 型で取得する プロファイル ファイルの設定値を String 型で取得する プロファイル ファイルに値を書き込む これらの関数についての詳細は、 『PowerScript リファレンス』マニュ アルを参照してください。 レジストリでの ProfileString 関数の使い方については、687 ページの 「Windows レジストリでの情報の管理」を参照してください。 APP.INI の書式 以下の例では、APP.INI という名前のプロファイルで、アプリケーショ ンの情報を管理しています。このファイルは、アプリケーションの表 示形態を管理するための環境設定の情報が記述されています。ファイ ルには、4 つのカラー設定が記述された [Preferences] セクションがあり ます。 [Preferences] WindowColor=Silver BorderColor=Red BackColor=Black TextColor=White 686 PowerBuilder 第 34 章 以下のスクリプトでは、APP.INI ファイルのカラー設定を取得します。 値の取得 wincolor brdcolor bckcolor txtcolor 初期設定ファイルと Windows レジストリの管理 = = = = ProfileString("app.ini", ProfileString("app.ini", ProfileString("app.ini", ProfileString("app.ini", 値の設定 "Preferences", "Preferences", "Preferences", "Preferences", "WindowColor", "") "BorderColor", "") "BackColor", "") "TextColor", "") 以下のスクリプトでは、APP.INI ファイルにカラー設定を保存します。 SetProfileString("app.ini", SetProfileString("app.ini", SetProfileString("app.ini", SetProfileString("app.ini", "Preferences", "Preferences", "Preferences", "Preferences", "WindowColor", wincolor) "BorderColor", brdcolor) "BackColor", bckcolor) "TextColor", txtcolor) Windows レジストリでの情報の管理 レジストリにアクセス する関数 PowerBuilder には、Windows レジストリを使用してアプリケーション 設定を管理するための関数が用意されています。 表 34-2: PowerBuilder レジストリ設定関数 関数 RegistryDelete RegistryGet RegistryKeys RegistrySet RegistryValues 説明 Windows レジストリのキーまたはキーの値を削除する Windows レジストリから値のデータを取得する Windows レジストリのキーの 1 つ下位レベルにあるサブ キーのリストを取得する Windows レジストリに、キー、値の名前、値のデータを設 定する。キーまたは値の名前が存在しない場合は、新しい キーまたは値の名前を作成する キーに関連付けられた値の名前のリストを取得する これらの関数についての詳細は、『PowerScript リファレンス』マニュ アルを参照してください 。 初期設定ファイルを無 効にする ProfileString 関数を使用すると、初期設定ファイルからではなく、レジ ストリから情報を取得できます。次の位置に INIFILEMAPPING という 名の新しいキーを作成します。 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion WIN.INI ファイルを無効にするには、WIN.INI という名の INIFILEMAPPING に次の値を持つサブキーを作成します。 #usr:software\microsoft\windows\currentversion\extensions アプリケーション テクニック 687 Windows レジストリでの情報の管理 この後の例では、データベース接続パラメータの情報を管理するため にレジストリを使用します。接続パラメータは、レジストリの HKEY_CURRENT_USER\Software キーの下の MyCo\MyApp\database サブキーで管理されています。 レジストリからの値の 取得 以下のスクリプトは、デフォルトのトランザクション オブジェクトの 値をレジストリから取得します。 RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "dbms", sqlca.DBMS) RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "database", sqlca.database) RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "userid", sqlca.userid) RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "dbpass", sqlca.dbpass) RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "logid", sqlca.logid) RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "logpass", sqlca.logpass) RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", “"servername", sqlca.servername) RegistryGet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "dbparm", sqlca.dbparm) レジストリへの値の登 録 & & & & & & & 以下のスクリプトは、トランザクション オブジェクトの値をレジスト リに登録します。 RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "dbms", sqlca.DBMS) RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "database", sqlca.database) RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "userid", sqlca.userid) RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "dbpass", sqlca.dbpass) RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "logid", sqlca.logid) RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "logpass", sqlca.logpass) RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "servername", sqlca.servername) RegistrySet("HKEY_CURRENT_USER\Software\MyCo\MyApp\database", "dbparm", sqlca.dbparm) 688 & & & & & & & & & PowerBuilder 第 3 5 章 InfoMaker の様式とアクションの作成 この章について この章では、PowerBuilder で様式を作成して InfoMaker ユーザに提 供する方法について説明します。 内容 項目 フォーム様式について フォーム様式でのデータウィンドウ コントロールの命名 フォーム様式の作成および使用 既存の様式の修正 最初からの様式の作成 様式の完成 様式の使い方 ページ 689 693 694 694 697 698 702 フォーム様式について InfoMaker には、ユーザが洗練されたフォームを作成できるよう に、組み込みフォーム様式があります。PowerBuilder を使用する と、開発者は独自のフォーム様式を作成して、InfoMaker ユーザに 提供できます。このようなカスタム フォーム様式を使うと、フォー ム内で特定の標準を使うように指定して、InfoMaker ユーザに対し て機能を追加できます。たとえば、以下のように指定できます。 • 各フォーム内の開発者の組織のロゴ表示 適当な位置にロゴを配置したカスタム フォーム様式を作成で きる • 組み込みフォーム様式で提供されるツールバーの再構成 組み込みフォーム様式を修正してカスタム フォーム様式とし て保存できる アプリケーション テクニック • フォーム内でのドラッグ アンド ドロップ • フォーム内でのピクチャボタン、編集コントロール、および そのほかのコントロールの配置 689 フォーム様式について PowerBuilder ウィンドウ内でできることは、ほとんどすべてカスタム フォーム様式内でもできます。 フォーム様式 フォーム様式が構成さ れる方法 InfoMaker のユーザはデータを管理するのにフォームを使用します。 フォーム内でデータを表示、追加、削除、および更新できます。各 フォームはフォーム様式を基礎としており、以下の項目を指定します。 • たとえば、フリーフォーム、グリッド、またはマスタ / 詳細提示様 式などデータを提示する方法 • フォームを実行するときに使用可能なメニューとツールバー • そのフォーム内でユーザがコマンドボタンにアタッチできるアク ション PowerBuilder でフォーム様式を作成します。フォーム様式は次の 2 つ のもので構成されています。 • ウィンドウ • メニュー 図 35-1: PowerBuilder フォーム様式 ウィンドウについて ウィンドウはフォームの土台の役割を果たしま す。ウィンドウには特別な名前をもつ 1 つまたは複数のデータウィン ドウ コントロールがあります。フォーム様式の中心となるのはこの データウィンドウ コントロールです。ユーザはこの特別なデータウィ ンドウ コントロールを通じて、データをフォーム内で表示または変更 します。 この章では、この特別なデータウィンドウ コントロールをセントラル データウィンドウ コントロールと呼ぶことにします。セントラル デー タウィンドウ コントロールには、サポートされている名前のセットか ら名前を付けなければなりません。 セントラル データウィンドウに加えて、ウィンドウには PowerBuilder 上のウィンドウ内に配置できるコマンドボタン、ラジオボタン、ユー ザ オブジェクト、およびピクチャなどすべてのコントロールを配置で きます。 メニューについて フォームを実行する場合、メニューから項目を取り 除けます。メニューをメニュー ペインタで作成して、そのフォーム様 式が基礎としているウィンドウにそのメニューを関連付けます。 690 PowerBuilder 第 35 章 InfoMaker の様式とアクションの作成 メニューを作成する場合、フォームが実行されているときにツール バーに表示するメニュー項目を指定できます。このツールバーは PowerBuilder ツールバーと同じように動作します。 フォーム様式には、フォーム内でコマンドボタン にアタッチできたり、スクリプト内で呼び出させたりするアクション があります。 アクションについて フォーム様式のウィンドウ内で定義する各パブリック ウィンドウ関 数を、そのフォーム様式のユーザはアクションとして使用できます。 例 たとえば、組み込み様式であるフリーフォームは以下のもので構成さ れています。 • w_pbstyle_freeform ウィンドウ • m_pbstyle_freeform メニュー w_pbstyle_freeform について w_pbstyle_freeform ウィンドウには dw_freeform という名前のデータウィンドウ コントロールがあります。 その他のコントロールはありません。 PowerBuilder ウィンドウは、以下のようにウィンドウレベルの関数を 多く定義しています。 フリーフォーム フォーム様式のユーザは、これらのウィンドウ関数を それぞれ、InfoMaker 内でアクションとして使用できます。 アプリケーション テクニック 691 フォーム様式について m_pbstyle_freeform について m_pbstyle_freeform メニューでは、フリー フォーム様式を基礎とするフォームの実行時に、メニュー項目および ツールバー項目が使用できます。 たとえば、m_pbstyle_freeform には、 [検索条件の指定]項目が[行]メ ニューにあり、この項目はツールバーにも表示されます。 InfoMaker ユーザがフォームを実行するとき、フォーム内で行を検索す るのに使用する選択条件を入力するために、 [検索条件の指定]を選択 できます。 692 PowerBuilder 第 35 章 InfoMaker の様式とアクションの作成 フォーム様式でのデータウィンドウ コントロールの命名 フォーム様式には、組み込み InfoMaker フォーム様式のいずれかのデー タウィンドウ コントロールを基礎とする 1 つまたは複数のセントラル データウィンドウ コントロールが含まれています。 これらのデータウィンドウ コントロールの動作を理解する一番良い 方法は、InfoMaker 内で各組み込み様式を使用してフォームを作成する ことです。そして、フォーム様式を作成するとき、組み込み様式の中 からフォーム様式内で表示したい提示様式の型に一致するものを選択 します。 たとえば、基本フリーフォームをデータ入力フォームとするためには、 w_pbstyle_freeform にあるデータウィンドウ コントロールの dw_freeform を基礎としてフォームを作成します。 フォーム様式を作成するときは、セントラル データウィンドウ コント ロールに以下の名前の内 1 つを割り当てなければなりません。 • dw_freeform • dw_grid • dw_master_12many • dw_detail_12many • dw_master_many21 • dw_detail_many21 有効な組み合わせ . フォーム様式内では、表 35-1 の 4 つのデータウィン ドウの組み合わせの内 1 つを使用しなければなりません。 表 35-1: PowerBuilder データウィンドウ コントロール 使用するデータウィンドウ コントロール名 dw_freeform のみ dw_grid および dw_freeform dw_master_12many および dw_detail_12many dw_master_many21 および dw_detail_many21 アプリケーション テクニック 基礎となる組み込み様式 フリーフォーム提示様式 グリッド提示様式 dw_grid はセントラル データウィンドウ コン トロール。dw_freeform は結果集合を共有して バックグラウンドで動作し、フォーム内のどこ でもユーザは計算フィールドを配置できる マスタ詳細 /1 対多 マスタ詳細 / 多対 1 693 フォーム様式の作成および使用 フォーム様式の作成および使用 v フォーム様式を作成および使用するには 1 次のどちらかを実行します。 • 既存のフォーム様式からウィンドウとメニューをコピーする • 新規にウィンドウを作成して、サポートされている名前を持つ 1 つか 2 つのデータウィンドウ コントロールをその中に配置 する 2 ウィンドウがフォーム様式の基礎としての役割を果たしているこ とを示す特別なコメントをつけて保存します。 3 ウィンドウにコントロールを追加したり、メニューを修正したり、 アクションとして動作するウィンドウ関数を定義したりなどし て、フォーム様式を拡張します。 4 フォーム様式の中で使用するすべてのオブジェクト(ウィンドウ、 ユーザ オブジェクト、およびメニューなど)を、InfoMaker ユーザ に対して様式ライブラリとして定義するライブラリにコピーしま す。 5 InfoMaker ユーザに対する探索パスを様式ライブラリに追加します。 InfoMaker ユーザが新たにフォームを作成する場合は、開発者の定 義したフォーム様式が新規フォーム ダイアログボックスに表示さ れます。ユーザは開発者が作成した様式を基礎としてフォームを 作成できます。 この章の後の箇所では、これらの操作手順について説明します。 既存の様式の修正 フォーム様式を作成する一番簡単な方法は、既存のフォーム様式をコ ピーして、作業することです。構造を調べて多少の変更を加えると、 短時間でフォーム様式の働きを理解できます。 v 既存のフォーム様式の修正を始めるには 1 694 PowerBuilder 上でライブラリ ペインタを開きます。 PowerBuilder 第 35 章 2 InfoMaker の様式とアクションの作成 フォーム様式の土台としての役割を果たすウィンドウとメニュー を開発者のアプリケーションのライブラリ探索パスにあるライブ ラリにコピーします。 組み込みフォーム様式から始める 組み込みのフォーム様式の基礎としての役割を果たすウィンドウ とメニューは、IMSTYLE115.PBL にあります。このファイルは InfoMaker に同梱されて、InfoMaker 11.5 ディレクトリにインストー ルされます。この PBL のコピーを作成して、独自のフォーム様式 の基礎として使用することができます。 3 4 ウィンドウ ペインタ上でウィンドウを開き、メニュー バーから [ファイル|名前を付けて保存]を選択して新しい名前でウィンド ウを保存します。 そのウィンドウに新しい名前を付けます。 名前は自由に設定できますが、フォーム様式を定義するウィンド ウ名は、InfoMaker ユーザが使用するすべての様式ライブラリに 渡って固有の名前をつける必要があります。 5 ウィンドウに対して特別なコメントを定義します(方法について は、696 ページの「様式の基礎としてのウィンドウの識別」を参照 してください)。 6 [OK]をクリックしてウィンドウを保存します。 7 メニュー ペインタ上でメニューを開き、メニュー バーから[ファ イル|名前を付けて保存]を選択してメニューを新しい名前で保 存します。 8 新しい名前と任意のコメントを付け、 [OK]をクリックしてメ ニューを保存します。 メニューに対してはコメントを付ける必要はありませんが、作成 しているフォーム様式内で使用するときと同様に識別できるよう にしたほうがよいでしょう。 9 アプリケーション テクニック フォーム様式を拡張します(方法については、698 ページの「様式 の完成」を参照してください)。 695 既存の様式の修正 様式の基礎としてのウィンドウの識別 InfoMaker に、ライブラリ内のウィンドウがフォーム様式の基礎として の役割を果たしていることを認識させるには、次のテキスト Style: で 始まるコメントをそのウィンドウに対して指定しなければなりませ ん。 Style: 様式を説明するテキスト Style: に続くテキストは InfoMaker の新規フォーム ダイアログボック ス内のフォーム様式のアイコンの下に表示されます。 たとえば、コメント「Style: 企業データ管理」付きの w_pbstyle_freeform ウィンドウを様式ライブラリに保存する場合には、InfoMaker ユーザが 新しいフォームを作成するときに、次のような画面が表示されます。 最初にウィンドウを保存するときとライブラリ ペインタ上のどちら の場合もコメントを指定できます。 詳細については、PowerBuilder の『ユーザーズ ガイド』マニュアルを 参照してください。 696 PowerBuilder 第 35 章 InfoMaker の様式とアクションの作成 最初からの様式の作成 フォームの動作を一度理解すると、最初からフォームを作成できるよ うになります。 v フォーム様式を最初から作成するには 1 新しいウィンドウを作成します。 2 そのウィンドウにデータウィンドウ コントロールを配置します。 3 コントロールのプロパティ ビューで、そのコントロールに特別な 名前を付けます。 特別な名前のリストについては、693 ページの「フォーム様式での データウィンドウ コントロールの命名」を参照してください。 4 必要に応じて、コントロールのプロパティを変更します。 たとえば、垂直および水平のスクロールバーを追加できます。 コントロールにデータウィンドウ オブジェクトを関連付けない 新しいフォームを作成するときに、InfoMaker ユーザがコントロー ルのデータを指定します。 5 作成するフォーム様式が 2 つのデータウィンドウ コントロールを 使用する場合は、ウィンドウ上にもう 1 つ データウィンドウ コン トロールを配置して、その名前を有効な組み合わせに合致させま す。 有効な組み合わせのリストについては、693 ページの「フォーム様 式でのデータウィンドウ コントロールの命名」を参照してくださ い。 6 ウィンドウを保存して、コメントを指定します。 方法については、696 ページの「様式の基礎としてのウィンドウの 識別」を参照してください。 アプリケーション テクニック 697 様式の完成 様式の完成 様式を完成するには、ウィンドウとメニューを拡張して必要な処理を 提供するようにします。たとえば、以下のことが可能です。 • セントラル データウィンドウ コントロールに対して作業する • ウィンドウにコントロールを追加する • アクション(フォーム様式にアクションとして表示される関数)を 定義する • メニューと関連するツールバーを修正する • ウィンドウ、コントロール、およびメニュー項目用にスクリプト を書く • ドラッグ アンド ドロップなどその他の機能をウィンドウに追加 する セントラル データウィンドウ コントロールに対する作業 特別な名前をもつデータウィンドウ コントロールは、フォームの中心 です。これらのコントロールにおいてユーザがフォーム上でデータを 操作します。 次の事柄を理解する必要があります。 フリーフォームのデー タウィンドウのサイズ を指定する方法 • フォーム上でフリーフォームのデータウィンドウのサイズを指定 する方法 • フォーム上でコントロールに対してデータを検索する方法 組み込み様式と同じように、作成するフォーム様式はすべて、フリー フォームのデータウィンドウを含んでいます。PowerBuilder のウィン ドウ ペインタ上でフリーフォームのデータウィンドウ コントロール にどのようなサイズを指定するかに関係なく、フリーフォームのデー タウィンドウは InfoMaker のフォーム ペインタ上のフォーム全体を占 めます。InfoMaker がフリーフォームのデータウィンドウを拡大して、 フォーム上のどこにでも計算フィールドなどのデータを配置できるよ うにします。 これは、PowerBuilder 上で指定するウィンドウの背景色はフォーム上 では無視されるということです。 698 PowerBuilder 第 35 章 セントラル データ ウィンドウ コント ロールに対する行の検 索 InfoMaker の様式とアクションの作成 InfoMaker ユーザがフォームを実行するとき、InfoMaker は自動的に SQLCA トランザクション オブジェクトに正しい値を与えるので、開 発者がそのためのスクリプトを書く必要はありません。セントラル データウィンドウに対して行を検索するのに必要なのは、コントロー ルのトランザクション オブジェクトを設定して、行を検索することだ けです。 たとえば、dw_freeform という名前のコントロールに対してデータを検 索するには、次のようにスクリプトを書きます。 dw_freeform.SetTransObject(SQLCA) dw_freeform.Retrieve() フォームが開くときにデータを提示するには、そのウィンドウの Open イベント内にこのスクリプトを書いてください。 トランザクション オブジェクトの詳細については、第 12 章「トラン ザクション オブジェクトの使い方」を参照してください。 コントロールの追加 フォーム様式の基礎としての役割を果たすウィンドウはすべて、少な くとも 1 つの データウィンドウ コントロールを持っています。それに 加えて、標準の PowerBuilder ウィンドウに追加できるコマンドボタン、 ユーザ オブジェクト、テキスト、編集ボックス、ピクチャ、および描 画オブジェクトなど、そのほかすべてのコントロールを追加できます。 フォームのユーザは、開発者がウィンドウ内に配置したコントロール を移動できますが、削除はできません。 同様に、ユーザはフォーム ペインタ上でフォームにコントロールを追 加できます。アクションを関連付けて、コマンドボタンおよびピクチャ ボタンを作成します。アクションを以下に説明します。 アプリケーション テクニック 699 様式の完成 アクションの定義 ユーザはカスタム フォーム様式を使用して作成されたフォームに、コ マンドボタンまたはピクチャボタンを追加したい場合があります。開 発者は、フォーム様式を作成するとき、フォーム様式にアクションを 定義して、追加したボタンで可能な動作を指定します。ユーザがボタ ンを配置するとき、リストから行いたいアクションを選択します。 アクションはパブリックなウィンドウレベル関数として実装されてい ます。 v アクションを定義するには 1 2 ウィンドウ ペインタのスクリプト ビューで、メニューバーから [挿入|関数]を選択します。 ウィンドウレベル関数を定義します(方法については、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください)。 ウィンドウ関数をアクションとしてフォーム ユーザが使用できる ようにするには、関数をパブリック(public)として定義してくだ さい。定義した関数の引数はアクションのパラメータとして使用 されます。定義した各パブリック ウィンドウ関数は、フォーム ペ インタのアクションの選択 ダイアログボックス内でアクションと して一覧表示されます。 アクションとして使用できない関数の定義 フォーム内でアクションとして使用できないウィンドウ関数を定 義および使用する場合は、その関数をプライベート(private)とし て定義してください。 700 PowerBuilder 第 35 章 InfoMaker の様式とアクションの作成 メニューの使い方 開発者は、ユーザがフォームを実行するときに表示されるメニューと ツールバーを指定します。メニュー ペインタでメニューを定義し、 フォーム様式の土台として役割を果たすウィンドウに関連付けます。 フォームが実行されるとき、定義したメニュー内の各メニュー項目が 表示されます。加えて、InfoMaker は[ウィンドウ]および[ヘルプ] メニューを追加して、InfoMaker 環境下でフォームを実行するときに、 ユーザがウィンドウを操作したり、オンライン ヘルプを参照したりで きるようにします。 オンライン ヘルプの提供 [ヘルプ]項目をメニューバー上で定義して、[ヘルプ]ドロップダウ ン メニュー内で表示されるメニュー項目を定義できます。InfoMaker 上 でフォームを実行するときには、この[ヘルプ]項目は表示されませ んが、実行ファイルからフォームを実行するときには表示されます。 InfoMaker 実行ファイルの詳細については、InfoMaker の『ユーザーズ ガイド』マニュアルを参照してください。 ツールバー上の項目 MDI アプリケーションの場合と同様、フォームの実行時に、ツール バーにメニュー項目を表示するように指定できます。 スクリプト フォームで使用するメニューには、標準ウィンドウで使用するメ ニューに対してと同じスクリプト技術を使用します。通常、ウィンド ウとそのメニューとの間で通信するには、ウィンドウに対してユーザ イベントを定義し、メニュー オブジェクトの親ウィンドウ プロパティ を使用してフォーム ウィンドウに照会し、メニューからそのイベント を発生させます。この技術は組み込みフォーム様式で使用されます。 詳細情報 メニューとユーザ イベントの使い方の詳細については、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 メニューに対するツールバーの関連づけの詳細については、第 5 章 「MDI アプリケーションの構築」を参照してください。 アプリケーション テクニック 701 様式の使い方 スクリプトの記述 ウィンドウ、コントロール、およびメニュー オブジェクトに対するス クリプトは、標準ウィンドウおよびメニューに対してと同じ方法で書 きます。データウィンドウ コントロールで作業する場合は、SQLCA ト ランザクション オブジェクトのプロパティを設定する必要はありま せん。これは、ユーザがフォームを実行するときに、InfoMaker が自動 的に設定するからです。 開発者が書くスクリプトをサポートするために、ユーザ定義のグロー バル関数およびグローバル構造体を定義できます。しかし、InfoMaker にはアプリケーション オブジェクトがないので、フォーム様式はグ ローバル変数またはグローバル外部関数宣言を使用できません。 その他の機能の追加 フォームは開発者の必要に応じて洗練されたものにできます。たとえ ば、ドラッグ アンド ドロップ機能を実装したり、フォームでメールを 使用したりできるようにします。 ウィンドウに対して作成できる機能の詳細については、PowerBuilder の『ユーザーズ ガイド』マニュアルを参照してください。 様式の使い方 フォーム様式を完成、または少なくともテストできるバージョンを完 成すると、そのフォームを使用できます。 v InfoMaker ユーザが様式を使用できるようにするには 1 フォーム様式を定義するウィンドウとメニューが InfoMaker のア クセス可能なライブラリ(スタイル ライブラリ)内にあることを 確認します。 2 ウィンドウ、ユーザ オブジェクト、グローバル ユーザ定義関数な どフォーム様式内で使用するその他の PowerBuilder オブジェクト を同じライブラリに追加します。 3 InfoMaker ユーザのパスに、スタイル ライブラリを追加します。 詳細については、InfoMaker の『ユーザーズ ガイド』マニュアルを 参照してください。 702 PowerBuilder 第 35 章 InfoMaker の様式とアクションの作成 カスタム フォーム様式を使用したフォームの作成 スタイル ライブラリを使用する InfoMaker ユーザが新しいフォームを 作成するときには、新規フォーム ダイアログボックスの[フォーム様 式]ボックス上にすべてのカスタム フォーム様式が表示されます。 カスタム様式と汎用アイコンが表示されます。 InfoMaker ユーザはデータ ソースとカスタム様式を選択するだけで、開 発者の作成したフォーム様式を基礎としたフォームの作成を開始でき ます。開発者は作成したフォーム様式について説明を提供しなければ なりません。 継承の理解 ユーザがフォームを作成するときは、開発者がフォーム様式に対して 作成したウィンドウの子孫ウィンドウに対して作業します。つまり、 開発者が PowerBuilder で作成したフォーム様式ウィンドウは先祖ウィ ンドウであり、InfoMaker で使用するフォーム ウィンドウは子孫ウィ ンドウということです。フォーム様式を変更した場合、その変更はユー ザがその様式を使用して次に作業するときに反映されます。 たとえば、フォーム様式にコントロールを追加した場合、ユーザが後 でその様式を使用して既存のフォームを開くときにそのコントロール が自動的に表示されるように設定できます。 注意 様式を使用してすでに作成されたフォームを無効にする変更はしない でください。 アプリケーション テクニック 703 様式の使い方 フォーム様式の使用の管理 ネットワーク上に様式ライブラリを格納して、InfoMaker ユーザ全員が 簡単にそれらを使用できるように設定できます。ネットワーク上に様 式ライブラリをセットアップするには、ネットワーク上で初期設定 ファイルを共有した状態で行います。共有様式ライブラリを参照する InfoMaker 初期設定ファイルをネットワーク上に配置してから、InfoMaker ユーザが初期設定ファイルにアクセスできるように InfoMaker ユーザ を設定します。 v 組織全体でスタイルライブラリを使用できるようにするには 1 InfoMaker ユーザがアクセスできるネットワーク上のディレクトリに 様式ライブラリを配置します。 2 InfoMaker を開き、ライブラリ ペインタに移動し、探索パスにすべ ての様式ライブラリがリストされていることを確認します。 3 InfoMaker を閉じます。 4 InfoMaker 初期設定ファイルを InfoMaker ユーザ全員がアクセスで きるネットワーク上のディレクトリにコピーします。 これが共有初期設定ファイルです。このファイルは[Application] セクションの StyleLib 変数にスタイル ライブラリすべてを記録し ます。 5 InfoMaker ユーザが共有初期設定ファイルにアクセスできるように セットアップします。 各 InfoMaker ユーザが InfoMaker 内で共有初期設定ファイルの位置 を指定する必要があります。 詳細については、次の「InfoMaker 上での共有 InfoMaker 初期設定 ファイルの位置の指定」を参照してください。 InfoMaker 上での共有 InfoMaker 初期設定 ファイルの位置の指定 一度共有初期設定ファイルがユーザの InfoMaker 初期設定ファイルで 定義されると、ユーザの様式ライブラリ探索パスはユーザのローカル InfoMaker 初期設定ファイルに加えて、共有初期設定ファイルで定義さ れた様式ライブラリ全部から成りたちます。ユーザが新しいフォーム を作成する場合、様式ライブラリ全部で定義されたフォーム様式が新 規フォーム ダイアログボックスに表示されます。 各 InfoMaker ユーザは、共有初期設定ファイルの位置を InfoMaker に知 らせる必要があります。 704 PowerBuilder 第 35 章 v InfoMaker の様式とアクションの作成 共有 InfoMaker 初期設定ファイルの位置を指定するには 1 InfoMaker メニューバーの[ツール|システム オプション]を選択 します。 2 [全般]プロパティ ページ内で、共有 InfoMaker 初期設定ファイル へのパスを入力します。 3 [OK]をクリックします。 InfoMaker は、InfoMaker 初期設定のパスをレジストリに保存しま す。 InfoMaker ユーザが組み込みフォーム様式を使用しないようにしたい 場合もあります。つまり、開発者の組織のユーザ定義様式を基礎とす るフォームのみをユーザに使用させたいという場合です。このような 場合、新規フォーム ダイアログボックスに表示されないようにして、 組み込み様式を使用しないようにします。 組み込み様式の使用を 防ぐ v 組み込み様式の表示を禁止するには 1 ネットワーク上の共有初期設定ファイルを前節で説明したように 設定します。 2 共有初期設定ファイルの [Window] セクションに次の行を追加し ます。 ShowStandardStyles = 0 共有初期設定ファイルでこの行を指定すると、新しいフォームを作成 するときに、ユーザはユーザ定義フォーム様式からのみ選択できるよ うになります。InfoMaker はユーザのローカル InfoMaker 初期設定ファ イルにある ShowStandardStyles 行を無視することに注意してください。 アプリケーション テクニック 705 様式の使い方 706 PowerBuilder 第 9 部 配布のテクニック 第 9 部では、アプリケーションを配布するためのパッ ケージ化の方法と、配布に必要なファイルについて説明 します。 第 3 6 章 配布用アプリケーションのパッケー ジ化 この章について この章では、完成した実行アプリケーションをユーザに配布する ための準備方法について説明します。 内容 項目 アプリケーションの配布について アプリケーションの実行版の作成 エンド ユーザへのアプリケーションの配布 ページ 709 710 726 アプリケーションの配布について PowerBuilder を使用すると、数多くのアプリケーション アーキテ クチャ用に、アプリケーションを開発および配布できます。 従来型のクライアント / サーバ アプリケーション この章の主なねらいは、実行ファイルを作成して、単層または 2 階層のアプリケーションを配布用にパッケージ化することです。 この章の内容は、コンパイル済みコードを使用するか擬似コード を使用するか、動的ライブラリ(PBD または DLL)を使用するか どうかとその編成方法、ビットマップやアイコンなどのリソース を別々に配布するのか、それとも PowerBuilder リソース ファイル (PBR)を使用するのか、といった決定をする際に役立ちます。 インターネットと分散アプ リケーション 多層アプリケーションでクライアントを構築する場合には、従来 のクライアント / サーバ アプリケーションの場合と同じ選択を行 う必要があります。EAServer または COM コンポーネントを作成 している場合、711 ページの「パッケージに含まれる要素」で後述 する PowerBuilder 動的ライブラリ(PBD)と PBR について知る必 要があります。 詳細情報 クライアント / サーバ アプリケーション、多層アプリケーション、 および Web アプリケーションで配布しなければならないファイ ルについての詳細は、第 37 章「アプリケーションとコンポーネン トの配布」を参照してください。 アプリケーション テクニック 709 アプリケーションの実行版の作成 アプリケーションの実行版の作成 以下の節では、パッケージ化のプロセスについて詳しく説明し、最終 的に作成されるアプリケーションのさまざまな選択事項について、ア ドバイスします。以下のことについて説明します。 • コンパイラの基本事項 • パッケージに含まれる要素 • パッケージ化モデルの選択 • パッケージ化モデルの実装 • 実行アプリケーションのテスト コンパイラの基本事項 アプリケーションを計画するとき、基本的に考慮する事項の 1 つとし て、ア プ リ ケ ー シ ョ ン を 生 成 す る コ ン パ イ ラ 形 式 が あ り ま す。 PowerBuilder では、Pcode とマシン コードのいずれかを選択できます。 Pcode マシン コード Pcode(中間コード)は、PowerBuilder のすべてのプラットフォームで サポートされているインタプリタ言語です。Pcode は、PowerBuilder が 個々のオブジェクトを実行可能な状態で格納する際にライブラリ (PBL ファイル)内で使用する形式と同じです。Pcode の利点は、サイ ズ、信頼性、移植性です。 PowerBuilder は、コードを生成およびコンパイルして、マシン コード の実行ファイルまたは動的ライブラリを作成します。マシン コードの 最大の利点は、実行速度の速さにあります。 PowerBuilder DLL の呼び出しはできない PowerBuilder マシン コード DLL をほかのアプリケーションから呼び 出すことはできません。 使用するコードの決定 710 自分のプロジェクトにとって Pcode とマシン コードのどちらが適切か を決めるためのガイドラインを以下に示します。 PowerBuilder 第 36 章 • 配布用アプリケーションのパッケージ化 作成したアプリケーションでスクリプト処理を集中的に行 う場合は、マシン コードを使用することを検討します。コード内 でループ構造、浮動小数点演算、整数演算、または関数の呼び出 しを使う頻度が非常に高い場合は、Pcode よりも優れた処理能力を 発揮します。アプリケーションに前述のような特徴がない場合は、 マシン コードによる処理が Pcode よりも目に見えて優れているこ とはありません。作成するアプリケーションでマシン コードを使 用するとメリットがあると考えられる場合は、ベンチマーク テス トをいくつか実行して効果を調べます。 速度 Pcode はマシン コードより速く生成されます。マシン コードを 使ってアプリケーションを配布する予定であっても、アプリケー ションのテスト用実行モジュールをすばやく作成したいときには Pcode を使用できます。 • サイズ Pcode を使って生成されるファイルは、マシン コードを 使って生成されるファイルよりサイズが小さくなります。ファイ ルのサイズが大きな問題であるコンピュータにアプリケーション を配布する場合、または Web のダウンロードまたはファイル転送 を使って配布する場合は、マシン コードの速度をあきらめ、Pcode を選択したほうがよいでしょう。 パッケージに含まれる要素 どちらのコンパイラ形式を選択した場合でも、PowerBuilder で作成す るアプリケーションは、以下の要素のいずれか 1 つまたは複数で構成 されます。 • 実行ファイル • 動的ライブラリ • リソース 特定のプロジェクトに必要な要素を決めるには、まず、各要素に関す る知識が必要です。 実行ファイルについて サーバ コンポーネントまたは Web アプリケーションとして配布する のではなく、実行ファイルとしてユーザに配布する単層または 2 階層 のアプリケーションを作成している場合には、必ず実行(EXE)ファ イルを作成することになります。 アプリケーション テクニック 711 アプリケーションの実行版の作成 この実行ファイルは、最低でもアプリケーションをターゲット プラッ トフォームでネイティブに実行するためのコードを含みます。たとえ ば、ユーザが配布されたアプリケーションを起動するときに、実行ファ イルのアイコンをデスクトップでダブルクリックすれば起動できるこ とを意味します。 実行ファイルでのその他の要素 アプリケーション用に選択したパッケー ジ化モデルの種類によって、実行ファイルは以下の要素のいずれか 1 つまたは複数を含みます。 • アプリケーションのライブラリに入っているコンパイル済みオブ ジェクト 配布するファイルが 1 つで済むように、すべてのオブジェクトを 実行ファイルに入れたり、1 つの実行ファイルと 1 つまたは複数の 動的ライブラリにアプリケーションを分割したりできます。詳細 については、712 ページの「動的ライブラリについて」を参照して ください。 • アプリケーション用にパッケージ化した任意の動的ライブラリに 含まれるオブジェクトとリソースを検索するために、PowerBuilder の実行システムが使用する実行ライブラリ リスト • ビットマップなど、アプリケーションが使用するリソース 図 36-1: 実行ファイルの内容 動的ライブラリについ て 712 アプリケーション全体を 1 つの大きな実行ファイルに収める代わり に、そのオブジェクトの一部またはすべてを 1 つまたは複数の動的ラ イブラリで配布できます。PowerBuilder が動的ライブラリを実装する 方法は、選択するコンパイラ形式によって異なります。 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 表 36-1: PowerBuilder 動的ライブラリ 作成コード マシン コード 実装される動的ライブラリ DLL ファイル(ダイナミック リンク ライブラリ) Pcode マシン コードの動的ライブラリは、Windows では拡張子 .dll が付加される。これらの動的ライブラリは、オペレー ティング環境における、ほかの標準的な共有ライブラリ と同様に動作する。これらの動的ライブラリは、外部の プログラムから呼び出せない点に注意する PBD(PowerBuilder 動的ライブラリ)ファイル これらの動的ライブラリは、実行時にアプリケーション にリンクされるという点で、DLL ファイルに似ている。 ただし、PBD は内部形式が異なるため、DLL とは互換性 がない 2 種類の動的ライブラリ(DLL と PDB)を 1 つのアプリ ケーション内に混在させることはできない 実行ファイルと同様、動的ライブラリに格納できるのは、オブジェク トのソースではなく、コンパイル済みのオブジェクトだけです。 図 36-2: 動的ライブラリ内のコンパイル済みオブジェクト 実行ファイルとは異なり、動的ライブ ラリにはスタートアップ コードが含まれません。動的ライブラリは、 独立して実行することはできません。動的ライブラリは、アプリケー ションを実行したときに、実行ファイル内に必要なオブジェクトが見 つからない場合にアクセスされます。 動的ライブラリ内のその他の要素 アプリケーション テクニック 713 アプリケーションの実行版の作成 動的ライブラリにはビットマップなどのリソースが含まれる場合があ ります。動的ライブラリのオブジェクトに必要なリソースを、その DLL ファイルまたは PBD ファイルに含めることができます。これによって、 動的ライブラリを、再利用可能な、独立したユニットにすることがで きます。ただし、処理効率の視点から考えると、リソースは実行ファ イル内に格納されているときの方が、実行時に速くロードされます。 図 36-3: 動的ライブラリ内のリソース 動的ライブラリを使う理由 表 36-2 に示すように、動的ライブラリの使 用を推奨する理由がいくつかあります。 表 36-2: 動的ライブラリを使用する理由 理由 モジュール性 保守性 再利用性 柔軟性 効率性 詳細 アプリケーションを、管理のしやすい、より小さく、より 多くのモジュール型ファイルに分割できる アプリケーション コンポーネントの個別配布ができる。 ユーザにバグ修正ファイルを提供するために、影響のある 特定の動的ライブラリを配布できる 動的ライブラリは、ユーザ間だけでなく、アプリケーショ ン間でも共有できるため、複数のアプリケーションで同じ コンポーネントを再利用できる 文字列変数のみによって参照されるウィンドウ オブジェク トなど、実行時にアプリケーションによって動的にのみ参 照されるオブジェクトを提供できる このようなオブジェクトは、データウィンドウの場合を除 いて、実行ファイルに含めることはできない 以下の理由により、大規模なアプリケーションでもメモリ を効率的に使用できる • PowerBuilder では、動的ライブラリ全体をメモリ内に一 度にロードしない。その代わり、必要に応じて、動的ラ イブラリから個々のオブジェクトをロードする • 実行ファイルのサイズを小さく抑えることができるた め、ロード時間が速く、扱いやすい 714 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 動的ライブラリの編成 動的ライブラリの利用を決めたら、どのライブ ラリ(PBL ファイル)から作成するかを、PowerBuilder に指示する必 要があります。PowerBuilder は、選択した PBL ファイルからコンパイ ル済みの全オブジェクトを、DLL ファイルまたは PBD ファイル内に配 置します。 アプリケーションで一部のオブジェクトしか使用しない場合は、余分 なオブジェクトを動的ライブラリに含めてもファイルが大きくなるだ けです。その解決法は以下のとおりです。 リソースについて 1 新しい PBL ファイルを作成し、必要なオブジェクトだけをその中 にコピーする 2 動的ライブラリのソースとして、作成した新しい PBL ファイルを 使用する ウィンドウやメニューなどの PowerBuilder オブジェクトに加えて、ア プリケーションではさまざまなリソースを使います。リソースの例に は以下のものがあります。 • ピクチャ コントロールまたはピクチャボタン コントロールで表 示するビットマップ • ウィンドウに割り当てるカスタム ポインタ リソースを使うときは、PowerBuilder オブジェクトとともに、アプリ ケーションの一部として配布する必要があります。 PowerBuilder のアプリケーションでは、複数の異なる リソースを使用できます。表 36-3 は、リソースを、使用できるオブ ジェクトごとにリストしています。 リソースの種類 表 36-3: PowerBuilder オブジェクトおよびリソース オブジェクト ウィンドウ オブジェクト とユーザ オブジェクト データウィンドウ オブ ジェクト MDI アプリケーションに おけるメニュー オブジェ クト 使用されるリソースの種類 アイコン(ICO ファイル) ピクチャ(BMP、GIF、JPEG、PNG、RLE、 および WMF の各ファイル) ポインタ(CUR ファイル) ピクチャ(BMP、GIF、JPEG、PNG、RLE、 および WMF の各ファイル) ピクチャ(BMP、GIF、JPEG、PNG、RLE、 および WMF の各ファイル) アプリケーションといっしょに配布するリソースの パッケージ方法を決めるときは、以下のアプローチから選択できます。 リソースの配布 アプリケーション テクニック 715 アプリケーションの実行版の作成 • リソースを実行ファイルに含める PowerBuilder では、実行ファイルの作成時、そのファイルに配置す るオブジェクトについて、リソース(アイコン、ピクチャ、ポイ ンタ)を明示的に参照しているかどうかが自動的に調べられます。 次に、そのようなリソースをすべて、実行ファイル内に直接コピー します。 文字列変数などを介して動的に参照されるリソースは、自動的に コピーされません。そのようなリソースを実行ファイル内にコ ピーするには、リソース(PBR)ファイルを使わなければなりま せん。これは単純なテキスト ファイルで、既存の ICO、BMP、GIF、 JPEG、PNG、RLE、WMF、および CUR の各ファイルをこの中に一 覧表示します。 PBR ファイルが完成したら、実行ファイルを作成するときは、PBR ファイルを読み込むよう PowerBuilder に指示することによって、 追加するリソースを指定します。処理効率上の理由で、ほとんど またはすべてのリソースを実行ファイルに含める場合、PBR ファ イルには、動的ライブラリ内のオブジェクトによって使用される リソースも含めることができます。 • リソースを動的ライブラリに含める 1 つまたは複数の動的ライブラリにリソースを直接含めたい場合 がありますが、PowerBuilder は、リソースがそのファイル内のオブ ジェクトにより明示的に参照されるときでも、作成される動的ラ イブラリ内にそのリソースを自動的にコピーしません。この特定 の DLL ファイルまたは PBD ファイル内にどのリソースを入れる かを PowerBuilder に対して指定する PBR ファイルを作成する必要 があります。 リソースを入れる動的ライブラリごとに、個別の PBR ファイルを 使用します。適切であれば、このアプローチを使って、リソース だけを含み、オブジェクトを含まない動的ライブラリを生成する こともできます。空の PBL ファイルをソースとして作業を始める だけです。 • リソース ファイルを個別のファイルで配布する これは、アプリケーションの配布時に、アプリケーションの実行 ファイルおよび動的ライブラリに加えて、さまざまな画像ファイ ルをユーザに提供することを意味します。多くのファイルを配布 することに問題がなければ、一部のファイルを修正する予定があ る場合に便利な方法です。 716 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 この方法は、実行時に必要な検索作業が多くなるため、もっとも 速い方法ではないことに注意してください。アプリケーションで リソースが必要なとき、アプリケーションは最初に実行ファイル を、次に動的ライブラリを検索します。リソースが見つからない 場合、アプリケーションは別個のファイル内で検索します。 これらの個々のファイルがどこに格納されているかを、アプリ ケーションがわかるようにしておく必要があります。そうでない 場合は、対応するリソースが表示されません。 特定のアプリケーションをパッケージ化するときは、以上のアプロー チのいずれか 1 つまたは組み合わせを利用できます。 PBR ファイルを使って、動的に参照されるデータウィンドウ オブジェクト を含める 作成中の実行ファイルの中に、アプリケーションが文字列変数を介し てのみ動的に参照するデータウィンドウ オブジェクトを入れたい場 合があります。そのためには、PowerBuilder によって実行ファイル内 にコピーしたいリソースの名前とともに、そのデータウィンドウ オブ ジェクトの名前を、PBR ファイル内に一覧表示しなければなりません。 動的ライブラリを作成するときは、その必要はありません。PowerBuilder によって、ソース ライブラリ(PBL ファイル)のすべてのデータウィ ンドウ オブジェクトが、新しい DLL ファイルまたは PBD ファイル内 に自動的に含まれます。 PowerBuilder リソース ファイルの作成 PBR ファイルは、リソース名(BMP、CUR、ICO など)とデータウィ ンドウ オブジェクトが一覧で表示されている ASCII テキスト ファイ ルです。PBR ファイルを作成するには、テキスト エディタを使用しま す。各リソースの名前を 1 行に 1 つずつ記述し、そのリストに拡張子 PBR を付けてファイルとして保存します。以下は、PBR ファイルのサ ンプルです。 ct_graph.ico document.ico codes.ico button.bmp next1.bmp prior1.bmp アプリケーション テクニック 717 アプリケーションの実行版の作成 v PowerBuilder リソース ファイルを作成して使用する手順 1 テキスト エディタを使用して、アプリケーションで動的に参照さ れるリソース ファイルをすべて一覧表示するテキスト ファイル を作成します(ファイルの作成については、以下を参照してくだ さい)。 動的ライブラリのリソース ファイルを作成するときは、スクリプ トで動的に割り当てられたリソースだけでなく、動的ライブラリ によって使用されるすべてのリソースを一覧表示します。 2 プロジェクト ペインタで、リソース ファイルを指定します。動的 ライブラリと同様、実行ファイルにリソース ファイルが添付され ていることもあります。 PowerBuilder がプロジェクトを構築するときは、実行ファイルまた は動的ライブラリの PBR ファイルに指定されているすべてのリ ソースを含めます。動的に割り当てられたリソースを個別に配布 する必要はありません。リソースはアプリケーションに含まれて います。 リソースを指定する リソース ファイルが現行ディレクトリにある場合は、以下のように ファイルを一覧表示するだけです。 FROWN.BMP リソース ファイルが別のディレクトリにある場合は、以下のように ファイルへのパスを指定します。 C:\BITMAPS\FROWN.BMP PBR ファイルとスクリプトのパスの一致 PBR ファイルに指定するファイル名は、スクリプトにおけるリソース の参照方法と正確に一致していなければなりません。 スクリプト内の参照にパスが使用される場合は、PBR ファイルに同じ パスを指定する必要があります。スクリプトのリソース ファイルがパ スで修飾されていない場合は、PBR ファイルでも修飾しないようにし ます。 たとえば、次のようなスクリプトがあります。 p_logo.PictureName = "FROWN.BMP" この場合、PBR ファイルは次のように記述する必要があります。 FROWN.BMP PBR ファイルの記述が下記のように異なる場合について説明します。 718 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 C:\MYAPP\FROWN.BMP この場合、スクリプトでパスが指定されていないと、PowerBuilder は 実行時にリソースを見つけることはできません。これは、PowerBuilder が実行時には単純な文字列の比較を行うためです。先ほどの例では、 スクリプトを実行するとき、PowerBuilder は実行ファイルに文字列 「FROWN.BMP」で指定されているオブジェクトを探します。実行ファイ ルでは、リソース「C:\MYAPP\FROWN.BMP」として識別されているため、 PowerBuilder はオブジェクトを見つけることができません。 この場合、実行時にはピクチャが表示されず、ウィンドウのコントロー ルは空白になります。 データウィンドウ オ ブジェクトを PBR ファイルに含める データウィンドウ オブジェクトをリストに含めるには、ライブラリ名 (拡張子 PBL)の後にカッコで囲んだデータウィンドウ オブジェクト 名を付けます。たとえば、次のようになります。 sales.pbl(d_emplist) 実行ファイル作成時の現行ディレクトリにデータウィンドウ ライブ ラリがない場合は、PBR ファイルに完全修飾の参照を指定します。た とえば、次のようになります。 c:\myapp\sales.pbl(d_emplist) パッケージ化モデルの選択 前述したとおり、アプリケーションの実行版をパッケージ化するには、 たくさんのオプションがあります。もっとも一般的なパッケージ化モ デルを以下に示します。 スタンドアロンの実行 ファイル このモデルでは、オブジェクトとリソースがすべて実行ファイル内に 含まれているため、配布するファイルは 1 つだけになります。 説明図 図 36-4 に、このモデルの構造のサンプルを示します。 図 36-4: スタンドアロン実行モデル アプリケーション テクニック 719 アプリケーションの実行版の作成 このモデルは、小規模で、簡単なアプリケーションに適してお り、管理をそれほど必要としないアプリケーションの場合には特に適 しています。そのようなプロジェクトに、このモデルを使用すると、 最高の処理効率ともっとも簡単な配布方法が保証されます。 用途 実行ファイルと外部リ ソース このモデルでは、すべてのオブジェクトと大部分のリソースが実行 ファイルに含まれていますが、特定のリソースについては、別個のファ イルを配布します。 説明図 図 36-5 に、このモデルの構造のサンプルを示します。 図 36-5: 外部リソースを含む実行モデル このモデルも小規模で、簡単なアプリケーションに適していま すが、変更の可能性のあるリソースの管理をサポートしているという 点で、前のモデルとは異なります。つまり、実行ファイルの修正コピー を配布しないで特定のリソースの修正コピーをユーザに配布できま す。 用途 このモデルを使うと、ほかのアプリケーションと共有しなければなら ないリソース、または、大規模で使用頻度の低いリソースを扱うこと も可能です。 実行ファイルと動的ラ イブラリ 720 このモデルでは、アプリケーションを 1 つの実行ファイルと 1 つまた は複数の動的ライブラリ(DLL または PBD)に分割します。アプリ ケーションを分割するときは、オブジェクトとリソースをさまざまな 方法で編成できます。表 36-4 に、いくつかの方法を示します。 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 表 36-4: 動的ライブラリを含むオブジェクトとリソースの編成 編成の対象 オブジェクト リソース 行えること 実行ファイルにオブジェクトが含まれないようにし、すべ てのオブジェクトを動的ライブラリに配置して、管理を容 易にする。または、 アクセス頻度の高い一部のオブジェクトを実行ファイル に配置して、これらのオブジェクトへのアクセスを最適化 し、残りのオブジェクトすべてを動的ライブラリ内に配置 する 大部分またはすべてのリソースを、それらを使用するオブ ジェクトとともに、動的ライブラリ内に配置して、再利用 を簡単にする。または、 大部分またはすべてのリソースを実行ファイルに配置す る。これによって、リソースへのアクセスが最適化される 説明図 図 36-6 に、このモデルの構造のサンプルを示します。 図 36-6: 動的ライブラリを含む実行モデル アプリケーション テクニック 721 アプリケーションの実行版の作成 このモデルは、アプリケーションの編成および管理において柔 軟に作業を行えるため、多くの大規模なプロジェクトに適しています。 たとえば、このモデルを使用すると、1 つの動的ライブラリで、アプ リケーションの特定部分に修正を加えることができます。 用途 注意 アプリケーションを修正する場合は、その度にフル再構築を行 い、実行ファイルとアプリケーションのすべての動的ライブラリを配 布することをお勧めします。たとえば、以下のオブジェクトへの変更 は、他のオブジェクトに影響を及ぼす場合があります。 実行ファイル、動的ラ イブラリ、および外部 リソース • プロパティの名前とタイプ • 関数の名前 • 関数の引数と戻り値 • オブジェクトまたはグループ内の関数またはプロパティのシーケ ンス • 他の PBL の継承オブジェクトに影響する可能性のあるもの このモデルは、実行ファイルと動的ライブラリにすべてのリソースを 含めるかわりに、特定のリソースについて個別のファイルを配布する という点以外は、直前のモデルと同じです。 説明図 722 図 36-7 に、このモデルの構造のサンプルを示します。 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 図 36-7: 動的ライブラリと外部リソースを含む実行モデル このモデルは、大規模なアプリケーションに適しており、特に、 特定のリソースを処理するための柔軟性が必要なアプリケーションの 場合に適しています。柔軟性が求められるのは、以下のようなリソー スです。 用途 • 修正する可能性がある • ほかのアプリケーションと共有しなければならない • 大規模で、使用頻度が低い パッケージ化モデルの実装 アプリケーションについて適切なパッケージ化モデルを決定したら、 PowerBuilder に付属のパッケージ化機能を利用して、パッケージ化モ デルを実装できます。この作業のほとんどは、プロジェクト ペインタ で行います。プロジェクト ペインタを使用すれば、実行アプリケー ションと同様に、コンポーネント、プロキシ ライブラリ、HTML ファ イルが作成できます。 実行アプリケーション 用にプロジェクト ペ インタを使用する 実行アプリケーション用のプロジェクト ペインタは、以下の操作を可 能にすることによって、パッケージ化ジョブのすべての局面を編成し ます。 アプリケーション テクニック 723 アプリケーションの実行版の作成 • 作成する実行ファイルを指定します。 • 作成する動的ライブラリ(DLL ファイルまたは PBD ファイル)を 指定します。 • 実行ファイルまたは特定の動的ライブラリに含めるリソースを指 定します。リソースの取得場所を示す適切な PBR ファイルを利用 します。 • 生成するコンパイラ形式として、マシン コードまたは Pcode を選 択します。 マシン コードでは、最適化、トレース情報、およびエラー コンテ キスト情報などの、さまざまなコード生成オプションも指定でき ます。 • 構築オプションを選択します。実行アプリケーションの生成時に、 プロジェクト ペインタを使用してアプリケーションのオブジェク トのフル構築を行うか、インクリメンタル構築を行うかどうかの 指定も含まれます。 • パッケージ全体を再構築するときにいつでも利用できるプロジェ クト オブジェクトとして、上記の仕様を保存します。 プロジェクト ペインタの使い方の詳細については、PowerBuilder の 『ユーザーズ ガイド』マニュアルを参照してください。 個別の動的ライブラリ の構築 既存のアプリケーションに修正を加えても、そのすべての動的ライブ ラリが影響を受けるわけではありせん。システム ツリーまたはライブ ラリ ペインタのポップアップ メニューから、個別の動的ライブラリを 再構築できます。 変更が限定的で、ほかの PBL の継承オブジェクトに影響しない場合 は、更新またはバグ修正用に個別の PBD をユーザに配布できます。し かし、アプリケーションを修正するたびにフル再構築して、実行ファ イルとアプリケーションのすべての動的ライブラリを配布することを お勧めします。 実行アプリケーションのテスト アプリケーションの実行版を作成したら、配布する前に、その動作を テストしてください。PowerBuilder の開発環境においては、すでにア プリケーションを何度も実行しているかもしれませんが、エンド ユー ザの立場になって独立したアプリケーションの実行版を実行すること は、非常に重要なことです。 724 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 アプリケーションを実行する手順は次のとおりです。 1 PowerBuilder を終了して、オペレーティング システム環境に戻り ます。 2 アプリケーションが PowerBuilder ランタイム ライブラリにアクセ スできるようにしておいてください。 そのためには、PowerBuilder 仮想マシンおよびそのほかのランタイ ム ファイルの位置が PATH 環境変数に設定されていること、また は、アプリケーションのレジストリ エントリを作成して、パスを 指定できることを確認します。 3 アプリケーションの実 行をトレースする 任意のネイティブ アプリケーションの場合と同じように、アプリ ケーションの実行ファイルを実行します。 問題を見つけやすくするため、PowerBuilder では、トレースとプロファ イルの機能を提供しています。これらの機能は開発環境で利用でき、 アプリケーションの実行版を実行するときにも利用できます。アプリ ケーションの実行ファイルに問題がなくても、この機能を利用して、 アプリケーションの動作に関する監査証跡を生成することをお勧めし ます。実行のトレースの詳細については、PowerBuilder の『ユーザー ズ ガイド』マニュアルを参照してください。 アプリケーション テクニック 725 エンド ユーザへのアプリケーションの配布 エンド ユーザへのアプリケーションの配布 アプリケーションの実行版をユーザに配布する場合には、各種のファ イルとプログラムをすべてコンピュータやネットワーク上の適切な位 置にインストールする必要があります。 配布プロセスを自動化 する 配布プロセスを自動化する場合、InstallShield などのソフトウェア配布 アプリケーションを利用することもできます。通常、そのようなアプ リケーションでは、ユーザがアプリケーションを実行するときに必要 となる実行ファイル、リソース ファイル、データ ソース、およびコン フィグレーション ファイルがすべてインストールされます。また、 ユーザの初期設定(INI)ファイルとレジストリも更新されます。 インストール チェックリスト 以下のチェックリストを使用すると、必要なものをすべてインストー ルしたかどうか確認できます。読みやすくするために、チェックリス トは以下の項目に分類されています。 環境要素をインストー ルする • 環境要素をインストールする • アプリケーション要素をインストールする チェックリスト項目 PowerBuilder のランタイ ム DLL のインストール 詳細 PowerBuilder の実行システムを含む、すべての DLL ファイルを、各ユーザのコンピュータにイ ンストールする。DLL ファイルは、PowerBuilder アプリケーションを、開発環境の外で、独立し て実行するために必要になる。これは、Pcode で 生成されたアプリケーションだけでなく、マシ ン コードで生成されたアプリケーションにも該 当する ランタイム DLL のインストールについての詳細 は、746 ページの「PowerBuilder ランタイム ファ イル」を参照 管理リリースの処理。 開発環境で PowerBuilder の管理リリースを使っている場合は、その管理 リリースのランタイム DLL をユーザに提供して おく必要がある 726 PowerBuilder 第 36 章 チェックリスト項目 データベース インタ フェースのインストール インストールする ODBC ドライバの設定 配布用アプリケーションのパッケージ化 詳細 各ユーザのコンピュータには、ODBC インタ フェースおよびその他のネイティブなデータ ベース インタフェースなど、アプリケーション が必要とするデータベース インタフェースをイ ンストールする データベース インタフェースのインストールに ついての詳細は、第 37 章「アプリケーションと コンポーネントの配布」を参照。データベース インタフェースについての詳細は、 『データベー スとの接続』マニュアルを参照 ODBC インタフェースおよび 1 つまたは複数の ODBC ドライバをユーザのコンピュータにイン ストールする場合、ODBC ドライバも設定しな ければならない。ドライバの設定作業には、各 ドライバを介してアクセスされる特定のデータ ソースの定義も含まれる ODBC ドライバの設定についての詳細は、 『デー タベースとの接続』マニュアルを参照 必要に応じたネットワー アプリケーションがサーバのデータベースまた ク アクセスの設定 はその他のネットワーク サービスにアクセスす る必要がある場合は、各ユーザのコンピュータ を正しく接続しておく必要がある オペレーティング システ 特定のアプリケーションでは、処理効率上また ムまたはウィンドウ シス はその他の理由により、オペレーティング シス テムまたはウィンドウ システムの側で特別な調 テムの設定 整が必要になる場合がある。そのようなアプリ ケーションに該当する場合は、各ユーザのコン ピュータを調整しておく必要がある アプリケーション テクニック 727 エンド ユーザへのアプリケーションの配布 アプリケーション要素 をインストールする チェックリスト項目 実行アプリケーションの コピー 詳細 実行アプリケーションを構成するファイルのコ ピーを作成し、それを各ユーザのコンピュータ にインストールする。インストールするファイ ルには、以下のものがある • 実行(EXE)ファイル • 動的ライブラリ(DLL ファイルまたは PBD ファイル) • 個別に配布するリソース ファイル(ICO、 BMP、GIF、JPEG、PNG、RLE、WMF、ま たは CUR など) 管理リリースの処理。 これらのファイルを定 期的に修正する計画がある場合は、それらの最 新バージョンをネットワーク上のサーバからコ ピーして、ユーザのコンピュータにコピーする プロセスを自動化することもできる 追加ファイルのコピー このロジックをアプリケーション内で直接構築 することも考えられる。また、PowerBuilder のラ ンタイム DLL の更新ファイルをユーザのコン ピュータにコピーすることも考えられる アプリケーションが使用する追加ファイルのコ ピーを作成し、各ユーザのコンピュータにイン ストールする。インストールするファイルには、 以下のものがある • 初期設定(INI)ファイル • ヘルプ(HLP)ファイル • ほかに、テキスト ファイルやサウンド ファイ ルなど、さまざまなファイルが考えられる アクセスするローカル データベースのコピー ファイルの使用法によっては、特定のファイル をローカルではなく、サーバにインストールす る場合もある アプリケーションがローカル データベースにア クセスする必要がある場合は、そのデータベー スを構成するファイルをコピーし、各ユーザの コンピュータにインストールする その場合は、適切なデータベース インタフェー スもインストールし、正しく設定しておく必要 がある 728 PowerBuilder 第 36 章 配布用アプリケーションのパッケージ化 チェックリスト項目 詳細 アクセスするほかのプロ アプリケーションが任意の外部プログラムにア グラムのインストール クセスする必要がある場合、各外部プログラム を、すべてのユーザのコンピュータかサーバに インストールする また、プログラムを正常に動作させるために必 要な設定も行う。たとえば、ActiveX コントロー ルの登録が必要な場合もある。詳細については、 735 ページの「ActiveX コントロールの配布」を 参照 アプリケーションに必要 アプリケーションが使用するさまざまなファイ なファイルを検索できる ルは、アプリケーションが検索できるパス上に ようにする インストールしておく必要がある • アプリケーションが特定のパスによってファ イルを参照する場合は、そのパス上にファイ ルをインストールする • アプリケーションが名前のみによってファイ ルを参照する場合は、現行のパスなど、アプ リケーションが検索できるパスにファイルを インストールする アプリケーションの値に Windows レジストリを利用して、アプリケー よる、システム レジスト ション パスなどアプリケーションで必要な情報 リの更新 を管理する場合は、アプリケーションの値でレ ジストリを更新する アプリケーションのアイ ユーザがアプリケーションを起動できるよう コンの設定 に、各ユーザのコンピュータのウィンドウ シス テムを使って、実行ファイルのアイコンを希望 の場所に表示する 代替方法として、ユーザはウィンドウ システム 下で、ネイティブ アプリケーションと同じその ほかの方法で、アプリケーションを起動するこ ともできる アプリケーション テクニック 729 エンド ユーザへのアプリケーションの配布 配布済みアプリケーションの起動 ユーザは、配布されたアプリケーションを、ほかの Windows アプリ ケーションと同じ方法で実行できます。たとえば、エクスプローラで 表示される実行ファイルをダブルクリックしたり、アプリケーション のショートカットをデスクトップに作成して、そのショートカット ア イコンをダブルクリックしたりできます。 ユーザがショートカットを作成する場合は、 [ショートカット]プロパ ティ ページの[リンク先]テキスト ボックスで実行ファイルへのパス が指定され、 [作業フォルダ]テキスト ボックスで Powersoft ランタイ ム DLL の場所が指定されている必要があります。 730 PowerBuilder 第 3 7 章 アプリケーションとコンポーネント の配布 この章について この章では、ユーザのコンピュータやサーバにアプリケーション とコンポーネントを配布する際に必要な情報について説明しま す。PowerBuilder ランタイム ファイルのパッケージ化に使用する ツールについて説明し、さまざまなターゲットに対して配布が必 要なファイルをリスト表示します。 これらのファイル リストは、新しいデータベース インタフェース が使用可能になったときなど、場合によっては更新する必要があ ります。これらの変更についての詳細は、PowerBuilder の使用し ているバージョンの『リリース ノート』マニュアルを参照してく ださい。 内容 アプリケーション テクニック 項目 ページ アプリケーション、コンポーネント、およびサポート ファイルの配布 PowerBuilder ランタイム パッケージャ サードパーティ製コンポーネントと配布 PowerBuilder ランタイム ファイル データベース接続 Java サポート PowerBuilder エクステンション PDF と XSL-FO のエクスポート データウィンドウ Web コントロール ActiveX EAServer 上の PowerBuilder コンポーネント EAServer 上の Web データウィンドウ 732 737 742 746 749 759 761 762 765 766 769 731 アプリケーション、コンポーネント、およびサポート ファイルの配布 アプリケーション、コンポーネント、およびサポート ファイルの配布 配布するアプリケーションの種類に関わらず、動的ライブラリ、BMP ファイルや ICO ファイルのようなリソース、オンライン ヘルプ ファ イル、初期設定ファイルなどの任意のサポート ファイルも一緒に配布 しておく必要があります。アプリケーションの種類によって、必要な サポート ファイルのセットが違います。pbvm115.dll と pbdwe115.dll な どの PowerBuilder ランタイム ファイル、pbsnc115.dll と pbo10115.dll な どの PowerBuilder データベース インタフェースは、アプリケーション を使用して自由に配布できます。ライセンス費用もかかりません。 配布の計画 第 36 章「配布用アプリケーションのパッケージ化」には、動的ライブ ラリ、Pcode(中間コード)またはマシン コード、リソース ファイル の使い方など、PowerBuilder 実行アプリケーションを配布する際の決 定に役立つ情報が含まれています。また、必要な要素がすべてインス トールされているか確認するためのチェックリストも用意されていま す。 Web アプリケーションまたはトランザクション サーバのコンポーネ ントを配布する場合には、上記章の中の PowerBuilder 動的ライブラリ (PBD)および PowerBuilder リソース ファイル(PBR)についての情報 を参照してください。また、このマニュアルまたは表 37-1 に記載され ているマニュアルの、アプリケーション、コンポーネント、またはプ ラグインの特定の種類に関する記述も参考にしてください。 732 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 表 37-1: 追加配布されるマニュアル アプリケーションの種類 EAServer コンポーネント 参照先 515 ペ ー ジ の「EAServer へ の コ ン ポーネントの配布」 アプリケーション サーバ コン ポーネント PowerBuilder Application Server Plug-in の マニュアル セットの『User’s Guide』マ ニュアル .NET ア プ リ ケ ー シ ョンとコン 『アプリケーションとコンポーネントの ポーネント .NET への配布』マニュアル Web データウィンドウおよび 『データウィンドウ プログラマーズ ガイ データウィンドウ Web コント ド』マニュアル ロール ActiveX この章での情報の見つ け方 この章は、インストール環境を作成するサードパーティのソフトウェ ア パッケージによるインストール プログラムのプログラミングを支 援する目的で作成されています。ここでは、各コンピュータに必要な ファイル、そのファイルの保存場所、インストール先、作成しなけれ ばならないレジストリ設定を説明します。また、PowerBuilder Enterprise には、アプリケーションに必要なファイルのパッケージ化に役立つツー ルが用意されています。このツールについての詳細は、737 ページの 「PowerBuilder ランタイム パッケージャ」を参照してください。 アプリケーションと一緒に配布する必要のあるファイルの情報につい ては、表 37-2 を参考にしてください。 アプリケーション テクニック 733 アプリケーション、コンポーネント、およびサポート ファイルの配布 表 37-2: 配布に必要な PowerBuilder ファイル シナリオ すべての PowerBuilder クライ アント アプリケーション データベース サーバ上のデー タにアクセスする PowerBuilder クライアント ア プリケーション EJB、SOAP Web サービス、お よび XML サービス用 PowerBuilder クライアント PDF または XSL-FO 形式で データを保存する PowerBuilder クライアント データウィンドウ Web コント ロール ActiveX を使用する Web アプリケーション PowerBuilder 内に作成される EAServer コンポーネント EAServer と Web データウィン ドウを使用する Web アプリ ケーション インストール先パスと 配布先パス 参照節 746 ページの「PowerBuilder ランタイ ム ファイル」 749 ページの「データベース接続」 761 ページの「PowerBuilder エクステ ンション」 762 ページの「PDF と XSL-FO のエク スポート」 765 ページの「データウィンドウ Web コントロール ActiveX」 766 ページの「EAServer 上の PowerBuilder コンポーネント」 769 ページの「トランザクション サー バに必要なファイル」 770 ページの「動的ページ サーバに必 要なファイル」 この章で、いくつかの表の後に記載されているインストール先パスは、 デフォルトのインストール先を選択して PowerBuilder をインストール したときに、ファイルがインストールされる場所を示しています。ア プリケーションのインストール プログラムを作成する場合は、この場 所から目的とする場所にファイルをコピーできます。 配布先パスは、作成したアプリケーションまたはコンポーネントをイ ンストールする際に、コンピュータ上でこれらのファイルをインス トールすることができる場所を示しています。 App Path レジストリ キー 表によっては、レジストリ エントリのリストが後ろに記載されていま す。このレジストリ エントリは、アプリケーションまたはコンポーネ ントが必要なファイルを見つけられるように、インストール プログラ ムを使用して作成する必要があります。Windows 上で実行されるとき、 アプリケーションは、以下の場所で以下の順序に従ってサポート ファ イルを探します。 1 734 実行ファイルがインストールされているディレクトリ PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 2 Windows システムおよび Windows ディレクトリ(たとえば、 C:\WINDOWS\system32、C:\WINDOWS\system、および C:\WINDOWS) 3 レジストリに指定されているアプリケーション パス 4 システム パス アプリケーション パスは必ずしも指定する必要はありませんが、指定 することをお勧めします。 アプリケーション パ スの指定 アプリケーションがサポート ファイルを見つけるためのパスを指定 するには、インストール プログラムで、次のレジストリ位置にアプリ ケーションのための App Path キーを作成する必要があります。 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\ CurrentVersion\App Paths アプリケーションがインストールされるディレクトリの(デフォルト) 文字列値にデータ値を設定し、共有ファイルの保存場所を指定する Path という新しい文字列値を作成します。以下の例は、SQL Anywhere を使用する myapp.exe というアプリケーションの一般的なレジストリ エントリを示します。レジストリ キーは大カッコで囲まれ、後ろに " 名前 "=" 値 " の形式でキーの文字列値が記述されています。 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\ CurrentVersion\App Paths\myapp.exe] "Default"="C:\Program Files\myapps\myapp.exe" "Path"="C:\Program Files\myapps;C:\Program Files\ sybase\shared\PowerBuilder;c:\program files\ SQL Anywhere 11\win32\;" REG ファイルについて .REG 拡張子を持つレジストリ更新ファイルを使用すると、情報をレジ ストリにインポートできます。この章のレジストリ キーの例で使用し ている形式は、レジストリ更新ファイルの形式とよく似ていますが、 これらの例は更新ファイルとしての使用を意図したものではありませ ん。レジストリ更新ファイルのデータ値文字列のパス名には、一般に、 円記号が 1 つではなく 2 つ組み合わされて使用され、 「デフォルト」の 文字列値はアット マーク(@)で表されます。 例を参考にして、インストール プログラムで追加または更新するレジ ストリ キーを決定してください。 ActiveX コントロール の配布 アプリケーションが ActiveX コントロール、OLE コントロール、また は OCX コントロールを使用する場合には、以下の作業が必要です。 アプリケーション テクニック 735 アプリケーション、コンポーネント、およびサポート ファイルの配布 • アプリケーションと一緒にコントロール ファイルを配布する • 各コントロールを登録しておく • 必要なファイルをターゲット コンピュータのシステム ディレクトリ に配置しておく 自己登録を行わないコントロールを使用するアプリケーションの場合 は、セットアップ プログラムによって各ユーザのコンピュータに手動 で登録する必要があります。自己登録を行うコントロールかどうかを 調べるには、コントロールに付属のマニュアルを参照してください。 開発プラットフォーム、配布プラットフォーム、および配布するコン トロールの種類によっては、配布先となるコンピュータの WINDOWS システム ディレクトリに、追加の DLL ファイルまたはライセンス ファイルをコピーする必要がある場合もあります。 736 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 PowerBuilder ランタイム パッケージャ PowerBuilder ランタイム パッケージャは、アプリケーションが実行時 に必要 な PowerBuilder フ ァイル を Microsoft Windows イン ストー ラ (MSI)パッケージ ファイルにパッケージ化するツールです。Windows インストーラは、最新の Microsoft Windows オペレーティング システ ムとともにインストールされる、インストールおよび環境設定サービ スです。 ランタイム パッケージャがインストール パッケージの一部として生 成した MSI ファイルを使用できます。このパッケージには、アプリ ケーションで必要な他のファイルも含まれています。 ランタイム パッケージャを正常に実行するには、システム上に Microsoft Windows インストーラが必要です。インストーラは、Windows XP と Windows 2003 で使用できます。 最新版 Windows インストーラの詳細および入手方法については、 Microsoft ドキュメンテーション のサイト http://msdn.microsoft.com/jajp/default.aspx を参照してください。 ランタイム パッケージャは、Windows システムにインストールされた クライアント アプリケーションおよび .NET Framework に配布された アプリケーションで使用できます。ランタイム パッケージャは、アプ リケーションがデータウィンドウ Web コントロール ActiveX を使用す る場合に必要なファイルをパッケージ化しません。また、ほとんどの サードパーティ コンポーネントをインストールすることもありませ ん。詳細については、742 ページの「サードパーティ製コンポーネン トと配布」を参照してください。 また、734 ページの表 37-2 内の該当する箇所を参照して、インストー ルが必要なファイルであるが、ランタイム パッケージャによってはイ ンストールされないファイルを確認してください。 アプリケーション テクニック 737 PowerBuilder ランタイム パッケージャ v PowerBuilder ランタイム パッケージャを使用するには 1 Windows の[スタート]メニューから[プログラム| Sybase | PowerBuilder 11.5 | PowerBuilder ランタイム パッケージャ]を 選択するか、Shared\PowerBuilder ディレクトリの pbpack115 実行 ファイルを起動します。 2 生成された MSI ファイルの保存場所を選択します。 3 .NET ターゲットを配布する場合は、[PowerBuilder .NET コンポー ネント]を選択します。それ以外の場合は、[PowerBuilder 標準コ ンポーネント]を選択します。 4 アプリケーションに必要なデータベース インタフェースを選択し ます。 選択したデータベースの DLL がパッケージに追加されます。ODBC および OLE DB の場合、pbodb115.ini ファイルも追加されます。 JDBC の場合、pbjdbc12115.jar と pbjvm115.dll ファイルも追加され ます。Java Runtime Environment(JRE)は追加されません。詳細に ついては、742 ページの「サードパーティ製コンポーネントと配 布」を参照してください。 738 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 そのほかの ODBC または OLE DB ファイルをアプリケーションが 必要とする場合がありますが、これらのファイルは追加されませ ん。これらのファイルの配布方法についての詳細は、751 ページの 「ODBC データベース ドライバとサポート ファイル」および 756 ページの「OLE DB データベース プロバイダ」を参照してくださ い。 5 アプリケーションがデータウィンドウ XML のエクスポートまた はインポート、あるいは XML Web データウィンドウを使用する場 合、[XML サポート]チェックボックスをオンにします。 ランタイム パッケージャは、PBXerces115.dll、xerces-c_2_6.dll、お よび xerces-depdom_2_6.dll を追加します。 6 アプリケーションが、PowerBuilder Document Object Model が提供 する XML サービスを使用する場合、またはアプリケーションが EJB または SOAP Web サービス クライアントである場合は、それ に該当するチェックボックスをオンにします。 ランタイム パッケージャは、必要な DLL、PBX、および JAR ファ イルをパッケージに追加します。ランタイム パッケージャは、 [SOAP クライアント(Web サービス)]チェックボックスが選択 されると、必要なファイルを EasySoap と .NET Web サービス エン ジンの両方に追加します。これらのサービスに必要なファイル情 報については、761 ページの「PowerBuilder エクステンション」を 参照してください。 Web サービス データウィンドウ アプリケーションで Web サービス データウィンドウを使用する 場合は、[SOAP クライアント(Web サービス)]ボックスもオン にします。このボックスをオンにすると、 Sybase.PowerBuilder.WebService.Runtime.dll と Sybase.PowerBuilder.WebService.Runtime.RemoteLoader.dll の 2 つの ファイルが追加されます。これらファイルも、Web サービス デー タウィンドウで必要なファイルです。 7 アプリケーションでリッチテキスト コントロールやデータウィン ドウを使用する場合は、[リッチ テキスト サポート]チェック ボックスをオンにします。 ランタイム パッケージャは、748 ページの表 37-5 にリストされて いるリッチテキスト サポート用のファイルをインストールしま す。 8 [生成]をクリックします。 アプリケーション テクニック 739 PowerBuilder ランタイム パッケージャ ランタイム パッケージャは、選択したコンポーネントに必要な ファイルと、PowerBuilder の標準アプリケーション用のランタイム DLL、または、表 37-3 に示した、PowerBuilder の .NET アプリケー ション用のランタイム DLL および .NET アセンブリを格納した MSI ファイルを作成します。 表 37-3: 基本コンポーネント 選択した基本コンポーネント ファイル PowerBuilder 標準コンポーネ libjcc.dll ント libjutils.dll pbacc115.dll pbcomrt115.dll pbdbl115.dll pbdwe115.dll pbdwr115.dll pbdwr115.pbd pbjag115.dll pbjvm115.dll pbshr115.dll pbtra115.dll pbtrs115.dll pbvm115.dll 740 PowerBuilder 第 37 章 選択した基本コンポーネント PowerBuilder .NET コンポーネ ント アプリケーションとコンポーネントの配布 ファイル pbdbl115.dll pbshr115.dll pbrth115.dll pbdwm115.dll PowerBuilder .NET アセンブリ : Sybase.PowerBuilder.ADO.dll Sybase.PowerBuilder.Common.dll Sybase.PowerBuilder.Core.dll Sybase.PowerBuilder.Datawindow.Web.dll Sybase.PowerBuilder.DataWindow.Win.dll Sybase.PowerBuilder.Datawindow.Interop.dll Sybase.PowerBuilder.Db.dll Sybase.PowerBuilder.DBExt.dll Sybase.PowerBuilder.EditMask.Win.dll Sybase.PowerBuilder.EditMask.Interop.dll Sybase.PowerBuilder.Graph.Web.dll Sybase.PowerBuilder.Graph.Win.dll Sybase.PowerBuilder.Graph.Core.dll Sybase.PowerBuilder.Graph.Interop.dll Sybase.PowerBuilder.RTC.Win.dll Sybase.PowerBuilder.RTC.Interop.dll Sybase.PowerBuilder.Interop.dll Sybase.PowerBuilder.Web.dll Sybase.PowerBuilder.Web.WebService.dll Sybase.Powerbuilder.WebService.Runtime.dll Sybase.PowerBuilder.WebService.RuntimeRemoteLoader.dll Sybase.PowerBuilder.Win.dll MSI ファイルは、あらゆる Windows プラットフォーム上で直接実行可 能な圧縮ファイルです。MSI ファイルは、自己登録 DLL を登録し、 Windows レジストリにインストール先のパスを追加し、システムの PATH 環境変数を設定し、さらに、Windows のコントロール パネルの [アプリケーションの追加と削除]ページに情報を追加します。また、 サードパーティのインストール ソフトウェア パッケージの中には MSI ファイルを使用できるものもあります。 アプリケーション テクニック 741 サードパーティ製コンポーネントと配布 .NET アプリケーションでは、MSI ファイルは .NET アセンブリをグ ローバル アセンブリ キャッシュ(GAC: Global Assembly Cache)内に インストールします。.NET Framework 2.0 を対象コンピュータにイン ストールする必要があります。インストールしていない場合はインス トール処理が停止しエラー メッセージが表示されます。.NET Web フォーム ターゲットで必要な IE Web Controls がインストールされて いない場合は、警告メッセージが表示されますが、インストール処理 は続行されます。.NET Web フォーム アプリケーションや Web サービ ス用の本稼動サーバ、または .NET Windows フォームやスマート クラ イアント アプリケーション用のクライアント コンピュータで MSI ファイルを実行したあとは、対象システムを再起動する必要がありま す。 .NET ターゲットの配布の詳細については、『アプリケーショとコン ポーネントの .NET への配布』マニュアルの最初の章を参照してくだ さい。 サードパーティ製コンポーネントと配布 PowerBuilder アプリケーションは、PowerBuilder とともにインストール されるサードパーティ製のコンポーネントへの依存性を持つ場合があ ります。依存性を持つコンポーネントの多くは、PowerBuilder ランタ イム パッケージャではインストールされません。これらのコンポーネ ントの一部は、アプリケーションと一緒に再配布できる場合もありま すが、別途ベンダーから入手する必要がある場合もあります。 無償でダウンロードが可能なコンポーネントの詳細については、無償 ダウンロード規約に関するドキュメントを参照してください。このド キュメントは、DVD の Support ディレクトリに収録されています。ま た、Sybase Web のサイト http://www.sybase.com/softwarelicenses/third_party_legal でも参照できます。 Apache ファイル PowerBuilder に含まれる Apache ファイルをユーザに再配布できます。 PowerBuilder 11.5 に含まれる Apache コードを使用したり再配布したり する場合は、Apache ライセンスに従う必要があります。このライセン スについては、PowerBuilder 11.5 の無償ダウンロード規約に関するド キュメントを参照してください。 742 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 ファイルを PDF として保存するためにアプリケーションで XSL-FO を 使用するには、Apache Formatting Objects Processor(FOP)のバージョ ン 0.20.4 が必要です。FOP についての詳細は、Apache FOP Web のサイ ト http://xmlgraphics.apache.org/fop/ を参照してください。 XML Web データウィンドウのサポート、また、データウィンドウと データストアの XML サポート、PBDOM、Web サービスの SOAP クラ イアントには、Apache Xerces ファイルである xerces-c_2_6.dll および xerces-depdom_2_6.dll が必要です。Xerces についての詳細は、Xerces C++ Parser Web のサイト http://xml.apache.org/xerces-c/ を参照して ください。 Microsoft ファイル Visual C++ ランタイ ム、Active Template、 GDI+ ライブラリ PowerBuilder のコア ランタイム ファイルを配布する場合は、ユーザの コンピュータまたはサーバに、Microsoft Visual C++ ランタイム ライブ ラ リ msvcr71.dll お よ び msvcp71.dll、お よ び Microsoft .NET Active Template Library(ATL)モジュール atl71.dll が存在していることを確 認します。PowerBuilder ランタイム ファイルは、これらのファイルに 実行時依存するため、PowerBuilder ランタイムを必要とするすべての アプリケーションおよびコンポーネントで必要です。これらの DLL ファイルは、DLL アーカイブ のサイト http://dlldump.com で入手でき ます。また、DLL アーカイブ のサイト http://driverskit.com からも入手 できます。 PowerBuilder ランタイム ファイルは、Microsoft Windows GDI+ (gdiplus.dll) にも実行時依存します。システムで gdiplus.dll を使用できない場合は、 PowerBuilder .NET ターゲットは起動できません。GDI+ は、Windows XP または Windows Server 2003 オペレーティング システムのサブシス テムであり、画面やプリンタでの高度な画像処理を行います。GDI+ は Windows Vista にも組み込まれていますが、Windows 2000 では使用で きないため、PowerBuilder アプリケーションを Windows 2000 に配布す る場合は、gdiplus.dll が対象のコンピュータのシステム パスで使用で きることを確認する必要があります。GDI+ は、Microsoft Web のサイト http://www.microsoft.com/downloads/details.aspx?FamilyID=6A63AB9C-DF124D41-933C-BE590FEAA05A&displaylang=en からダウンロードできます。 アプリケーション テクニック 743 サードパーティ製コンポーネントと配布 MSI ファイルの実行前にインストールするファイル PowerBuilder ランタイム パッケージャで生成した MSI ファイルにより インストールされる一部のファイルは、これらのファイルに依存して います。たとえば、atl71.dll および gdiplus.dll は、pbjvm115.dll を登録 する前にユーザのコンピュータにインストールしておく必要がありま す。PowerBuilder ランタイム パッケージャで生成した MSI ファイルを 実行する前に、これらのファイルが対象のコンピュータにあることを 確認してください。 インクピクチャ ライ ブラリ アプリケーションで InkEdit および InkPicture コントロールを使用する 場合は、Microsoft.Ink、Microsoft.Ink.dll、および Microsoft.Resources.dll が 必 要 で す。こ れ ら の フ ァ イ ル は Microsoft Windows XP Tablet PC Edition の Software Development Kit 1.7 の 一 部 で す。こ の SDK は、 Microsoft Web のサ イト http://www.microsoft.com/downloads/details.aspx?FamilyId=B46D4B83-A82140BC-AA85-C9EE3D6E9699&displaylang=en からダウンロードできます。 これらの DLL と .NET Framework 2.0 との間には、互換性の問題がある ことが Microsoft で確認されています。この問題に対処するための更 新プログラムは、Microsoft Web のサイト http://www.microsoft.com/downloads/details.aspx?familyid=84BBEFA4-704741DF-8583-E3BDBF9D805F&displaylang=ja からダウンロードできます。 DirectX ランタイム PowerBuilder アプリケーションでは、DirectX 3D レンダリングを使っ て 3D グラフ(Pie3D、Bar3D、Column3D、Line3D、Area3D)に洗練さ れた概観を与えることができます。データ項目や連続した透明性を DirectX グラフ スタイルと合わせて使用することで、効果的なデータ 提示が可能になります。 DirectX 3D によるレンダリングは、DirectX ランタイムに依存します。 3D グラフのプロパティ ビューの[全般]タブで[3D レンダリング] チェック ボックスを初めて選択すると、DirectX のインストーラが起 動します。インストールの実行を選択しなかった場合、3D レンダリン グ プロパティは無視されます。また、PowerBuilder アプリケーション の エ ン ド ユ ー ザ は、DirectX グ ラ フ ス タ イ ル を 表 示 さ せ る た め に DirectX ランタイムをコンピュータにインストールする必要がありま す。DirectX ランタイムを含む再配布可能なパッケージは、Microsoft Web の サ イ ト http://www.microsoft.com/downloads/details.aspx?FamilyId=822640AB-09834C41-9C70-632F6F42C557&displaylang=en から入手できます。 744 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 コンピュータが古いグラフィック ドライバを使用している場合、 DirectX がサポートされているかどうかを確認するには、dxdiag.exe を 実行します。通常、この .exe ファイルは Windows\System32 ディレク トリにインストールされています。dxdiag.exe を実行すると DirectX 診 断ツールが表示されます。このツールの[ ディスプレイ]タブで Direct3D が有効であるかどうかを確認できます。 AJAX エクステンショ ン PowerBuilder で は、Web フ ォ ー ム ア プ リ ケ ー シ ョ ン に、AJAX (Asynchronous JavaScript and XML)更新機能を使用します。ASP.NET AJAX を使用して、ページの特定の領域を非同期にリフレッシュして ページを更新します。 PowerBuilder .NET Web フォームと .NET Web サービス コンポーネント ターゲットは .NET Framework 3.5 で動作しますが、どちらも .NET Framework 3.5 でインストールされる AJAX のバージョンを使用しませ ん。このため、これらの .NET ターゲットの種類を使用するためには、 AJAX Extensions バージョン 1.0(build 61025.0)のインストールが必要 です。 PowerBuilder はデフォルトで AJAX 更新機能を使用するため、Web フォーム アプリケーションの場合、すべての開発マシンと配布マシン 上に AJAX Extensions が必要です。Microsoft ASP.NET AJAX Extensions バージョン 1.0 は、ASP.NET のサ イト http://www.asp.net/ajax/downloads/archive か ら ダ ウ ン ロ ー ド し て イ ン ス トールすることができます。 Sun Microsystems ファイル EJB クライアント、JDBC 接続、および XSL-FO を使用した PDF の保 存には、Java Runtime Environment(JRE)が必要です。JRE のサード パーティ条項については、無償ダウンロード規約に関するドキュメン ト を 参 照 し て く だ さ い。JRE は、 Sun Developer Network のサ イト http://java.sun.com/javase/downloads/index.jsp からダウンロードできます。 Web サービスの SOAP クライアントで使用するソフトウェア PowerBuilder では、EasySoap115.dll 内に実行可能形式の EasySoap++ ラ イブラリが含まれており、PBSoapClient115.pbx に動的にリンクされて います。EasySoap++ ライ ブラリ とその 使用は、GNU Lesser General Public License(LGPL)の適用範囲です。このライセンスについては、 無償ダウンロード規約に関するドキュメントを参照してください。 アプリケーション テクニック 745 PowerBuilder ランタイム ファイル また、EasySoap++ ライブラリは、LGPL の規定に従ってサードパーティ に配布することができます。配布の前には、LGPL を確認してくださ い。 EasySoap++ ライブラリのコンピュータが読取可能なソース コードは、 DVD の Support\WSExtn フォルダ内の EasySoap.zip ファイルにありま す。さらに、PBSoapClient115.pbx のオブジェクト コードと Microsoft Visual C++ プロジェクト ファイル は、同じディレクトリの soapclient.zip ファイルにあります。 これらのファイルは LGPL の規定に基づいて提供されているものであ り、EasySoap++ ライブラリを変更したり、変更した EasySoap115.dll を生 成するために再リンクしたりすることができます。また、PBSoapClient115.pbx と変更した EasySoap++ インポート ライブラリを再リンクすることも できます。LPGL では、EasySoap++ ライブラリで変更した定義を使用 するために、PBSoapClient115.pbx の再コンパイルが必ず必要なわけで はないということがわかります。 PBSoapClient115.pbx を構築するには、soapclient.zip ファイルに含まれ る Readme.txt ファイルに従います。 Web フォーム アプリケーションの Telerik コントロール PowerBuilder は Telerik RadControls for ASP.NET をインストールし、こ れらのコントロールを Web フォーム アプ リケーションと一緒に配布 し ま す。RadControls は、Web フ ォ ー ム の ツ ー ル バ ー と メ ニ ュ ー、 DatePicker(日付ピッカー)コントロールと MonthCalendar(月表示カ レンダ)コントロール、および TreeView(ツリービュー)コントロー ルのための拡張機能を提供します。Web フォーム アプリケーションの エンド ユーザは、RadControls をコンピュータにインストールする必要 はありません。 PowerBuilder ランタイム ファイル データベースの接続 データベースの接続に必要なファイルについては、749 ページの「デー タベース接続」に個別に一覧表示されています。 746 PowerBuilder 第 37 章 主なランタイム ファ イル アプリケーションとコンポーネントの配布 表 37-4 は、PowerBuilder の主なランタイム ファイルです。 表 37-4: 主な PowerBuilder ランタイム ファイル 名前 pbvm115.dll pbshr115.dll libjcc.dll libjutils.dll pbdwe115.dll Microsoft ファイル 必要とする対象 すべて すべて。pbvm115.dll は、このファイルへの依存性を 持つ すべて。pbvm115.dll は、このファイルへの依存性を 持つ すべて。libjcc.dll は、このファイルへの依存性を持つ データウィンドウおよびデータストア(.NET アプリ ケーションの場合は、かわりに pbdwm115.dll を使用) 基本的な PowerBuilder ランタイム ファイルを配布する際に、ユーザの マシンに msvcr71.dll と msvcp71.dll Microsoft Visual C++ ランタイム ラ イブラリおよび Microsoft .NET Active Template Library(ATL)モジュー ル atl71.dll が存在しない場合は、これらのファイルも配布する必要が あります。PowerBuilder ランタイム ファイルは、実行時はこれらのファ イルに依存します。詳細については、742 ページの「サードパーティ 製コンポーネントと配布」を参照してください。 Microsoft Windows GDI+ は、スクリーンおよびプリンタ用の拡張グラ フィック機能を実装する Windows XP オペレーティング システムや Windows Server 2003 オペレーティング システムのサブシステムです。 PowerBuilder ランタイム ファイルは、実行時は gdiplus.dll に依存しま す。Windows 2000 プラットフォームに PowerBuilder アプリケーション を配布する場合は、対象のコンピュータで gdiplus.dll が利用できるこ とを確認する必要があります。 ほかのランタイム ファイル 表 37-5 に、アプリケーションがさらに必要とする可能性があるランタ イム ファイルを示します。たとえば、pbvm115.dll はすべての配布アプ リケーションに必要ですが、pbrtc115.dll および関連するランタイム ファイルは、リッチテキスト コントロールまたはリッチテキスト デー タウィンドウ オブジェクトを使用するアプリケーションでのみ必要 になります。 Java サポート対応の pbjvm115.dll を使用する配布アプリケーションに ついての詳細は、759 ページの「Java サポート」を参照してください。 アプリケーション テクニック 747 PowerBuilder ランタイム ファイル 表 37-5: 追加の PowerBuilder ランタイム ファイル 名前 pbacc115.dll 必要とする対象 アクセシビリティのサポート(米国リハビリ テーション法 508 条) pbdpl115.dll データ パイプラインのサポート PBDWExcel12Interop115.dll、 Excel 2007 のサポート Sybase.PowerBuilder.DataWin dow.Excel12.dll pbdwr115.dll、 pbdwr115.pbd Web データウィンドウのサポート PBXerces115.dll、 xerces-c_2_6.dll、 xerces-depdom_2_6.dll XML Web データウィンドウのサポートおよ びデータウィンドウとデータストアの XML サポート Web サービス データウィンドウ Sybase.PowerBuilder.WebServ ice.Runtime.dll、 Sybase.PowerBuilder.WebServ ice.RuntimeRemoteLoader.dll pbjvm115.dll pbrth115.dll pbrtc115.dll、tp13.dll、 tp13_bmp.flt、tp13_css.dll、 tp13_doc.dll、tp13_gif.flt、 tp13_htm.dll、tp13_ic.dll、 tp13_ic.ini、tp13_jpg.flt、 tp13_obj.dll、tp13_pdf.dll、 tp13_png.flt、tp13_rtf.dll、 tp13_tif.flt、tp13_tls.dll、 tp13_wmf.flt、tp13_wnd.dll、 tp4ole13.ocx pblab115.ini pbtra115.dll、pbtrs115.dll Java サポート .NET Web フォームおよび ADO.NET リッチテキストのサポート データウィンドウのラベル提示様式の定義 済みフォーマット データベース接続のトレース インストール先パス \Program Files\Sybase\Shared\PowerBuilder また は、リッチ テキストに必要なファイルの多くは \Program Files\Sybase\shared\PowerBuilder\RTC アプリケーションと同じパス、システム パスのディレクト リ、または App Path レジストリ キー 配布先パス レジストリ エントリ 734 ページの「App Path レジストリ キー」を参照 してください。 748 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 データベース接続 データベースにアクセスする実行ファイルまたはコンポーネントを配 布する場合、ユーザは DBMS およびアプリケーションが使用するデー タベースにアクセスする必要があります。 データベース接続ファイルのインストール先 別のコンピュータの中間層コンポーネントを使用してデータベース トランザクションを実行するクライアント アプリケーションでは、 データベース接続ファイルを配布する必要はありません。データベー ス接続ファイルは、データベース サーバと対話するコンピュータに配 布しなければなりません。 以下の作業を行う必要があります。 • 必要であれば、DBMS ランタイム(クライアント)ファイルを、ア プリケーション ディレクトリかシステム パス上のディレクトリ にインストールする スタンドアロンの SQL Anywhere データベースを使用するアプリ ケーションの場合には、ユーザのコンピュータに SQL Anywhere ラ ンタイム エディション ファイルをインストールできます。詳細に ついては、752 ページの「SQL Anywhere ファイル」を参照してく ださい。それ以外の場合は、ベンダによって明示された指示およ びライセンス規約に従ってください。 • アプリケーションが使用するデータベースに各ユーザがアクセス できるようにしておく アプリケーションがローカル データベースを使用する場合は、 データベースとログ ファイルなどの関連ファイルをユーザのコン ピュータにインストールします。 アプリケーションがデータベース サーバを使用する場合は、ユー ザのコンピュータからアクセスできるようにセットアップしてお きます。この作業は、データベース管理者が行います。 • ユーザのコンピュータ上でアプリケーションが使用するデータ ベース インタフェースをインストールする • アプリケーションが ODBC インタフェースを使用する場合は、754 ページの「ODBC データ ソースとドライバの環境設定」の説明に 従って、ODBC データベース ドライバとデータ ソースを設定する データベース ドライバとインタフェースの詳細については、以下を参 照してください。 アプリケーション テクニック 749 データベース接続 • 次の「ネイティブ データベース ドライバ」 • 751 ページの「ODBC データベース ドライバとサポート ファイル」 • 756 ページの「OLE DB データベース プロバイダ」 • 757 ページの「ADO.NET データベース インタフェース」 • 758 ページの「JDBC データベース インタフェース」 ネイティブ データベース ドライバ 表 37-6 は、PowerBuilder で提供されるネイティブ データベース ドライ バのリストを示します。アプリケーションまたはコンポーネントが、 指定のデータベースを使用する場合、コンピュータ上にそのファイル が必要です。ネイティブ データベース ファイル名の最初の 2 つの文字 は PB であり、次の 3 つの文字でデータベースを識別し、最後の 2 つ の文字で PowerBuilder のバージョンを識別します。 表 37-6: PowerBuilder ネイティブ データベース ドライバ 名前 pbin9115.dll pbo90115.dll pbo10115.dll pbora115.dll pbsnc115.dll pbdir115.dll pbase115.dll pbsyc115.dll pbsyj115.dll 必要とする対象 INFORMIX I-Net 9 Oracle9i Oracle 10g Oracle 11g SQL Native Client for Microsoft SQL Server Sybase DirectConnect Sybase Adaptive Server Enterprise CT-LIB(Adaptive Server 15 のみ) Sybase Adaptive Server Enterprise CT-LIB Sybase Adaptive Server Enterprise CT-LIB(EAServer 配布 の場合のみ) インストール先パス \Program Files\Sybase\Shared\PowerBuilder アプリケーションと同じパス、システム パスのディレクト リ、または App Path レジストリ キー 配布先パス レジストリ エントリ 734 ページの「App Path レジストリ キー」を参照 してください。 750 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 注意 PowerBuilder カスタム クラス ユーザ オブジェクトを EAServer に配布するときは、SYC ではなく SYJ データベース インタフェースを 使用して Adaptive Server Enterprise データベースに接続する必要があり ます。PowerBuilder の開発環境で SYJ を使用することはできませんが、 SYJ DB プロファイル設定 ダイアログボックスを使用して、該当する 接続パラメータを設定することができます。その後、 [プレビュー]タ ブからトランザクション オブジェクトのスクリプトに構文をコピー できます。 ODBC データベース ドライバとサポート ファイル この節では、PowerBuilder アプリケーションまたは InfoMaker アプリ ケーションからのすべての ODBC データベース接続に必要なファイル と、特定のデータベース インタフェースまたは DBMS に必要なファイ ルを一覧します。 PowerBuilder ODBC インタフェース ファ イル アプリケーションが ODBC を使用する場合は、以下の PowerBuilder ODBC インタフェース ファイルが必要です。 表 37-7: PowerBuilder ODBC インタフェース ファイル 名前 pbodb115.dll pbodb115.ini インストール先パス 説明 PowerBuilder ODBC インタフェース PowerBuilder ODBC 初期設定ファイル \Program Files\Sybase\Shared\PowerBuilder 配布先パス アプリケーションと同じパス、 システム パスのディレクト リ、または App Path レジストリ キー レジストリ エントリ 734 ページの「App Path レジストリ キー」を参照 してください。 注意 PBODB115.INI フ ァ イ ル の 場 所 は、 HKEY_CURRENT_USER\Software\Sybase\PowerBuilder\11.5\InitPath レジストリで設定されているディレクトリか、このキーがない場合は DLL ファイルと同じディレクトリになります。多くの場合、ターゲッ トの配布マシンではこのレジストリ設定が行われないため、INI ファイ ルは DLL と同じファイルに格納されることになります。 Microsoft ODBC ファ イル 表 37-8 に、アプリケーションが ODBC を使用する場合に必要な Microsoft ODBC ファイルを一覧します。 アプリケーション テクニック 751 データベース接続 表 37-8: Microsoft ODBC ファイル 名前 DS16GT.dll DS32GT.dll ODBC32.dll ODBC32GT.dll ODBCAD32.exe ODBCCP32.cpl ODBCCP32.dll ODBCCR32.dll ODBCINST.cnt ODBCINST.hlp ODBCINT.dll ODBCTRAC.dll 説明 Microsoft ODBC ドライバ マネージャ、DLL、およびヘ ルプ ファイル インストール先パス Windows システム ディレクトリ 配布先パス Windows システム ディレクトリ レジストリ エントリ なし 通常、Microsoft ODBC ドライバ マネージャ(ODBC32.dll)とサ ポート ファイルは、すでにユーザの Windows システム ディレクトリ にインストールされています。 注意 SQL Anywhere ファイ ル SQL Anywhere データベースを使用する PowerBuilder アプリケーショ ンの場合には、SQL Anywhere の ODBC データベース ドライバだけで なく、SQL Anywhere DBMS も配布する必要があります。 制約 PowerBuilder には、開発プロセスで使用する SQL Anywhere が含まれて います。ただし、この製品を特許権使用料なしでユーザに配布するこ とはできません。 データ定義言語(DDL)、トランザクション ログ、ストアド プロシー ジャ、またはトリガがアプリケーションに必要な場合は、サイベース 社におたずねください。 アプリケーションがスタンドアロンのデータベースを使用する場合 は、ユーザのコンピュータに SQL Anywhere デスクトップ ランタイム システムを配布することができます。この場合、追加のライセンス料 金はかかりません。ランタイム システムを使うことによって、ユーザ はデータベース内のデータの取り出しや変更を行えますが、データ ベース スキーマの変更はできません。また、トランザクション ログ、 ストアド プロシージャ、およびトリガはサポートしていません。 752 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 SQL Anywhere ドライバ、ランタイム エンジン、およびサポート ファ イルの完全インストールは、DVD の Support\SA11Runtime ディレクト リから行えます。表 37-9 に、インストールされるファイルを示します。 詳細については、インストール ディレクトリの RuntimeEdition.html ファイルを参照してください。 表 37-9: SQL Anywhere ファイル 名前 dbodbc11.dll dbbackup.exe dbcon11.dll dbisqlc.exe dblgen11.dll dblib11.dll dbtool11.dll dbunlspt.exe dbvalid.exe rteng11.exe rteng11.lic dbctrs11.dll dbserv11.dll dbelevate11.exe *1 dblgja11.dll *2 dbicu11.dll *2 dbicudt11.dll *2 rteng11.lic *3 説明 SQL Anywhere ODBC ドライバ SQL Anywhere バックアップ ユーティリティ 接続 ダイアログボックス。開発者が独自のダイアログ ボックスを提供せず、エンド ユーザが独自のデータ ソースを作成する場合、データベースに接続するとき にユーザ ID とパスワードの入力が必要な場合、あるい はそのほかの目的で接続 ダイアログボックスを表示す る必要がある場合に必要 対話型 SQL ユーティリティ 言語固有の文字列ライブラリ(EN は英語版を示す) インタフェース ライブラリ SQL Anywhere データベース ツール SQL Anywhere アンロード ユーティリティ SQL Anywhere 検証ユーティリティ 制限つきのランタイム エンジン 制限つきのランタイム エンジンのライセンス ファイ ル パフォーマンス ユーティリティ サーバ ユーティリティ 昇格された権限が必要な操作を実行するためのユー ティリティ 言語固有の文字列ライブラリ(JA は日本語版を示す) データベースの文字セットがマルチバイトであるか、 UCA 照合順が使用されている場合のみ必要 データベースの文字セットがマルチバイトであるか、 UCA 照合順が使用されている場合のみ必要 制限つきのランタイム エンジン ライセンス ファイル *1 Windows Vista に配布する場合必要です。 *2 日本語環境に配布する場合必要です。 *3 すべての環境で必要です。 インストール先パス \Program Files\Sybase\SQL Anywhere 11\bin32(ま たは bin64) アプリケーション テクニック 753 データベース接続 アプリケーションと同じパス、システム パスのディレクト リ、または App Path レジストリ キー 配布先パス 734 ページの「App Path レジストリ キー」および 次の「ODBC データ ソースとドライバの環境設定」を参照してくださ い。 レジストリ エントリ Vista の特権要件 ユーザ アカウント制御下で実行される場合、SQL Anywhere はランタイム エンジン (rteng11.exe)を制限し、他の SQL Anywhere 実行ファイルは特権の昇格を要求します。Windows Vista お よびそれ以降の Windows では、SQL Anywhere 昇格操作エージェント (dbelevate11.exe)を使用して、これらの実行ファイルを実行するユー ザの特権の昇格と、非昇格クライアント プロセスの昇格サーバまたは データベース エ ン ジ ン の 自 動 起 動 の 許 可 を 行 え ま す。ま た、 dbcon11.dll、 dbctrs11.dll、 dbodbc11.dll、 dboledb11.dll、お よ び dboledba11.dll も、登録および登録解除時に特権の昇格が必要です。 サポート ファイルは、dbodbc11.dll と同じディレクトリにインス トールしなければなりません。英語版の文字列ライブラリを使用しな い場合は、使用言語固有の文字列ライブラリの該当するバージョンを 配布しておく必要があります。 注意 ODBC データ ソース とドライバの環境設定 ODBC.INI ユーザが特定のデータ ソースに接続できるようにするには、 インストール プログラムによって、データ ソースにアクセスするコン ピュータのレジストリにある ODBC.INI キーに、そのデータ ソースの 定義を提供する必要があります。ユーザ DSN の場合は HKEY_CURRENT_USER、システム DSN の場合は HKEY_LOCAL_MACHINE になります。データ ソース定義では、デー タベース ドライバの名前と保存場所だけでなく、データベース エンジ ンの起動に必要なコマンドも指定します。ODBC Data Sources キーの データ ソースも、ODBC.INI に一覧表示する必要があります。 以下の例では、SQL Anywhere を使用する MyApp DB というデータ ソースの一般的なレジストリ エントリを示します。レジストリ キーは 大カッコで囲まれ、後ろに " 名前 "=" 値 " の形式でキーの文字列値が記 述されています。 [HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI\MyApp DB] "Driver"="C:\Program Files\Sybase\SQL Anywhere 11\ bin32\dbodbc11.dll" "Start"="c:\program files\sybase\SQL Anywhere 11\bin32\ rteng11.exe -c9m" "UID"="dba" "PWD"="sql" "Description"="Database for my application" "DatabaseFile"="C:\Program Files\myapps\myapp.db" "AutoStop"="Yes" 754 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 [HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI\ ODBC Data Sources] "MyApp DB"="SQL Anywhere 11.0" ODBCINST.INI インストール プログラムは、 HKEY_LOCAL_MACHINE\SOFTWARE\ODBC の ODBCINST.INI キー に、配布するアプリケーションが使用する各ドライバについて以下の 2 種類のエントリを作成する必要があります。 • ODBCINST.INI の ODBC DRIVERS キーにドライバ名を指定した 文字列値と "Installed" を指定したデータ値を追加します。 • ODBCINST.INI キーに Driver および Setup という文字列値を使用 したドライバごとの新しいキーを追加します。 ドライバによっては、ODBCINST.INI にさらに文字列値が必要な 場合があります。 ODBC データベース ドライバ ファイルがシステム パスのディレクト リ内に保存されていない場合は、その保存場所も実行ファイルの App Paths キーに追加する必要があります。 ベンダから提供された ODBC ドライバを使用している場合は、ドライ バのセットアップ プログラムを使用して、ドライバをインストールし てレジストリ エントリを作成することができます。 以下の例は、SQL Anywhere の一般的なレジストリ エントリを示しま す。レジストリ キーは大カッコで囲まれ、後ろに " 名前 "=" 値 " の形 式でキーの文字列値が記述されています。 [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ SQL Anywhere 11.0] "Driver"="c:\program files\sybase\SQL Anywhere 11\ bin32\dbodbc11.dll" "Setup"="c:\program files\sybase\SQL Anywhere 11\ bin32\dbodbc11.dll" ODBC ドライバとデータ ソースのレジストリ エントリの内容につい ての詳細は、 『データベースとの接続』マニュアルを参照してください。 アプリケーション テクニック 755 データベース接続 OLE DB データベース プロバイダ OLE DB を使用してデータにアクセスするアプリケーションの場合、 各ユーザのコンピュータに Microsoft の Data Access Components ソフト ウェアがインストールされていない場合はインストールしなければな りません。 PowerBuilder OLE DB インタフェースには、Microsoft Data Access Components(MDAC)バージョン 2.8 以降のソフトウェアの機能が必 要です。バージョン 2.8 は、Windows XP Service Pack 2 および Windows Server 2003 に同梱されて配布されています。 コンピュータの MDAC のバージョンを確認するには、MDAC ダウンロー ド ページ のサイト http://msdn2.microsoft.com/en-us/data/aa937730.aspx から MDAC Component Checker ユーティリティをダウンロードして実行し てください。 Windows Vista オペレーティング システムに対しては、Windows Data Access Components(DAC)バージョン 6.0 に、Vista 対応の変更がいく つか含まれていますが、それ以外の機能は MDAC 2.8 に相当します。 MDAC とともにインストールされる OLE DB データ プロバイダ SQL Server(SQLOLEDB)用および ODBC(MSDASQL)用を含む、い くつかの Microsoft OLE DB データ プロバイダが MDAC とともに自動 的にインストールされます。 PowerBuilder OLE DB インタフェース ファ イル アプリケーションで OLE DB を使用する場合は、PowerBuilder OLE DB インタフェース ファイルが必要です。ODBC 初期設定ファイルを使用 して OLE DB 設定をカスタマイズした場合は、ODBC 初期設定ファイ ルが必要です。 表 37-10: PowerBuilder OLE DB インタフェース ファイル 名前 pbole115.dll pbodb115.ini 説明 PowerBuilder OLE DB インタフェース PowerBuilder ODBC 初期設定ファイル インストール先パス \Program Files\Sybase\Shared\PowerBuilder アプリケーションと同じパス、システム パスのディレクト リ、または App Path レジストリ キー 配布先パス 詳細については、734 ページの「App Path レジス トリ キー」を参照してください。 レジストリ エントリ 756 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 INI ファイルと DLL ファイルは、同しディレクトリにあること か必要です。pbodb115 初期設定ファイルを修正した場合には、修正 したバーションを配布してくたさい。 注意 ADO.NET データベース インタフェース PowerBuilder ADO.NET イ ン タ フ ェ ー ス は、OLE DB、Microsoft SQL Server .NET、Oracle ODP.NET、および Sybase ASE データ プロバイダ をサポートしています。ADO.NET を使用する場合は、pbado115.dll、 pbrth115.dll、Sybase.PowerBuilder.Db.dll、Sybase.PowerBuilder.DbExt.dll、 および OLE DB のための OLE DB データ プロバイダを配布しなければ なりません。 pbado115.dll および pbrth115.dll ファイルは標準 DLL ファイルであり、 ほかの PowerBuilder DLL と同じ方法で配布することができます。しか し、Sybase.PowerBuilder.Db.dll および Sybase.PowerBuilder.DbExt.dll は、 .NET アセンブリです。そのファイルを配布するためには、以下の 3 つ の方法のうち 1 つを使用します。 • ADO.NET ドライバを呼び出す実行ファイルと同じディレクトリ に、Sybase.PowerBuilder.Db.dll および Sybase.PowerBuilder.DbExt.dll ファイルを配布する • Sybase.PowerBuilder.Db.dll および Sybase.PowerBuilder.DbExt.dll の パスを割り当てるために、.NET アプリケーションの構成ファイル を使用する。そのファイルは、アプリケーションが読みこむ環境 設定と共通言語ランライム(CLR)が読み込む環境設定を含む。実 行ファイルの場合、構成ファイル名は実行ファイルと同じ名前に、 拡張子 .config をつけたものである。見本の pb115.exe.config ファイ ルが PowerBuilder 11.5 ディレクトリにある 構成ファイルの詳細については、Microsoft Visual Studio SDK のマ ニュアルを参照してください。 • アプリケーション テクニック グローバル アセンブリ キャッシュ(GAC:Global Assembly Cache ) に Sybase.PowerBuilder.Db.dll お よ び Sybase.PowerBuilder.DbExt.dll アセンブリを追加する。GAC の詳細については、Microsoft Visual Studio SDK マニュアルのグローバル アセンブリ キャッシュに関す る資料を参照してください。ランタイム パッケージャを使用する 場合は、アセンブリを GAC にインストールする 757 データベース接続 JDBC データベース インタフェース PowerBuilder JDB イ ン タ フ ェ ー ス は、Sun Java Runtime Environment (JRE)バージョン 1.2 以降をサポートしています。 アプリケーションまたはコンポーネントが JDBC 接続を使用する場合 は、使用する Java VM に対応する Java パッケージだけでなく、JDB ド ラ イ バ を 配 布 し な け れ ば な り ま せ ん。Java 仮 想 マ シ ン と、Sybase jConnect® for JDBC などベンダ提供の JDBC 準拠ドライバも、データ ソースにアクセスするコンピュータ上にインストールして設定する必 要があります。 Java VM の詳細については、次の「Java サポート」を参照してください。 表 37-11: PowerBuilder JDB ファイル 名前 pbjdb115.dll pbjdbc12115.jar 説明 JRE 1.2 以降対応 PowerBuilder JDBC ドライバ(JDB) PowerBuilder JDB ドライバおよび JRE 1.2 以降対応 Java パッケージ インストール先パス \Program Files\Sybase\Shared\PowerBuilder アプリケーションと同じパス、システム パスのディレクト リ、または App Path レジストリ キー 配布先パス CLASSPATH 環境変数には、PowerBuilder pbjdbc12115.jar ファイルを含めておいてください。たとえば、次のよ うになります。 レジストリ エントリ [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control \Session Manager\Environment] "CLASSPATH"="C:\Program Files\sybase\shared\ PowerBuilderbjdbc12115.jar;... 注意 766 ページの「EAServer 上の PowerBuilder コンポーネント」お よび 769 ページの「EAServer 上の Web データウィンドウ」を参照して ください。 758 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 Java サポート Java Runtime Environment(JRE)を使用するアプリケーションまたはコ ンポーネントとともに PowerBuilder pbjvm115.dll ファイルを配布し、さ らにターゲット コンピュータに JRE をインストールしておく必要が あります。JRE は、EJB クライアント、JDBC 接続、および XSL-FO を 使用した PDF での保存をする場合に必要になります。PowerBuilder と ともにインストールされている JRE を、ターゲット コンピュータ上の PowerBuilder ランタイム ファイルと同じディレクトリにコピーする か、ユーザの PATH システム環境変数で定義された場所に保存されて いる既存の JRE を使用します。 Java VM の検索 PowerBuilder アプリケーションで Java VM が必要になると、PowerBuilder ランタイムは、ユーザ コンピュータ上で pbjvm115.dll がインストール されているディレクトリのサブディレクトリ内の jvm.dll ファイルを 探します。jvm.dll ファイルは、JDK 1.4 以降のインストール ディレク トリ JRE\bin\client と、JDK 1.2 および 1.3 インストール ディレクトリ JRE\bin\classic にインストールされます。 PowerBuilder は、PowerBuilder アプリケーションが使用する現在のパス の先頭に jvm.dll の保存場所を追加します。このパスは、ユーザの PATH システム環境変数で定義されているパスです。PowerBuilder は、Windows レジストリに保存されている環境変数を変更しません。 jvm.dll を探すために、PowerBuilder は、まず pbjvm115.dll がインス トールされている場所を確認します。pbjvm115.dll が、 C:\Sybase\Shared\PowerBuilder にインストールされていると仮定しま す。次に、PowerBuilder はこの検索プロシージャを使って、現在使用 しているパスに jvm.dll の保存場所を追加します。 1 C:\Sybase\Shared\PowerBuilder\ 内でディリクトリ構造 JRE\bin\client(JDK 1.4 以降の場合)を検索し、見つかったらこ れをパスの先頭に追加します。 2 見つからなかった場合、JRE\bin\client を含む JDK ディリクトリ構 造を C:\Sybase\Shared\PowerBuilder\ 内で検索し、見つかったらこ れをパスの先頭に追加します。 3 見つからなかった場合、C:\Sybase\Shared\PowerBuilder\ 内でディ リクトリ構造 JRE\bin\classic(JDK 1.2 または 1.3 の場合)を検索 し、見つかったらこれをパスの先頭に追加します。 上記のディレクトリ構造がいずれも見つからなかった場合、PowerBuilder はユーザの PATH 環境変数で定義された場所にある最初の jvm.dll を 使用します。jvm.dll が見つからないと、Java VM は起動されません。 アプリケーション テクニック 759 Java サポート ランタイム Java VM クラスパス ランタイム スタ ティック レジストリ クラスパスの上書き PowerBuilder が Java VM を起動すると、Java VM は内部パスとクラス パス情報を使って、必要な Java クラスが常に使用できる状態にします。 実行時、Java VM は以下のパスを結合して作成されたクラス パスを使 用します。 • システム JAVA_HOME 環境変数 • Java VM の起動時にプログラムによって追加されるクラス パス。た とえば、EJB クライアント アプリケーションは、CreateJavaVM メ ソッドにクラス パスを渡すことができます。 • PowerBuilder ランタイム スタティック レジストリ クラスパス。これ は、PowerBuilder でアプリケーションを配布するときに使用される、 Windows レジストリ内のパスに対応する pbjvm115.dll ファイルに 組み込まれるパスです。このパスには、Java VM を使用する機能 が実行時に必要とするクラスが含まれます。 • システムの CLASSPATH 環境変数 • 現行ディレクトリ 必要に応じて、スタティック レジストリ内でランタイムの使用のため に定義された JVM 設定およびプロパティを上書きできます。 PowerBuilder は、次のアルゴリズムを使用して設定情報を探します。 1 JVM に対して最初のリクエストが発生すると、PowerBuilder は、 JVM を作成する関数に渡す設定情報およびプロパティのレジスト リ エントリを探します。 2 PowerBuilder が設定情報のレジストリエントリを見つけた場合、ス タティック レジストリのかわりにこのレジストリ エントリを使 用します。レジストリ エントリが見つからない場合、PowerBuilder はスタティック レジストリを使用します。 3 PowerBuilder が JVM に渡すカスタム プロパティのレジストリ エ ントリを見つけた場合、スタティック レジストリのかわりにこの レジストリを使用します。レジストリ エントリが見つからない場 合、PowerBuilder はスタティック レジストリ エントリを使用しま す。 デフォルト設定を上書きするには、 HKEY_LOCAL_MACHINE\Software\Sybase\PowerBuilder\11.5\Java キー内に、PBRTConfig という名前の新しいキーを作成した後、 PBJVMconfig および PBJVMprops のどちらか一方または両方のサブ キーを作成したキーに追加します。 スタティック レジストリ エントリを複製するには、PBIDEConfig キー 内に表示される次のサブキーに同じ文字列値を追加します。 760 PowerBuilder 第 37 章 サブキー PBJVMconfig PBJVMprops アプリケーションとコンポーネントの配布 文字列値名 Count 0 java.compiler 文字列値データ 1 -verbose:jni,class なし 環境設定またはプロパティ エントリのどちらか一方または両方を上 書きできます。エントリを誤って指定すると、PowerBuilder はスタ ティック レジストリのデフォルト設定に戻します。ただし、これらの エントリを正しく設定しないと JVM 内で正しく動作しなくなるので、 エントリを変更する際は注意が必要です。 PowerBuilder エクステンション PowerBuilder 11.5 には、複数の PowerBuilder エクステンション ファイ ルが備えられています。アプリケーションがこれらのエクステンショ ンを使用する場合、表 37-12 に示すファイルを配布する必要がありま す。 表 37-12: PowerBuilder の組み込みのエクステンションを使用する場合に 必要なファイル エクステンション PowerBuilder Document Object Model ファイル EJB クライアント Web サービス用 SOAP クライアン ト pbejbclient115.pbx、pbejbclient115.jar pbdom115.pbx、PBXerces115.dll、xerces-c_2_6.dll、 xerces-depdom_2_6.dll ExPat115.dll 、libeay32.dll、ssleay32.dll、 xerces-c_2_6.dll、xerces-depdom_2_6.dll、 EasySoap115.dll、pbnetwsruntime115.dll、 pbsoapclient115.pbx、pbwsclient115.pbx、 Sybase.PowerBuilder.WebService.Runtime.dll、 Sybase.PowerBuilder.WebService.RuntimeRemoteLoader.dl l EJB クライアントに関しては、表に示したファイルに加えて、EJB サーバ の JDK と互換性のある Java Runtime Environment(JRE)をクライアン トで使用できるようにし、CLASSPATH に追加する必要があります。 詳細については、759 ページの「Java サポート」を参照してください。 アプリケーション テクニック 761 PDF と XSL-FO のエクスポート PDF と XSL-FO のエクスポート PowerBuilder は、データウィンドウのデータと提示様式を 2 つのテクニッ クを使って Portable Document Format(PDF)ファイルとして保存できま す。PowerBuilder は PDF ファイルとして保存する場合に、デフォルトで distiller を使用します。PowerBuilder では Apache XML Formatting Objects プロセッサを使用して、PDF または XSL Formatting Objects(XSL-FO) 形式に保存することもできます。 Ghostscript distiller の使い方 SaveAs メソッドを使って distiller でデータを PDF として保存するには、 まず、次の手順に従って Ghostscript をダウンロードし、コンピュータ にインストールする必要があります。 GPL Ghostscript の使用に際しては、GNU General Public License(GPL) の規定に従う必要があります。GPL Ghostscript をコンピュータにイン ストールする前に、 GPL を読んでください。 GPL は GNU Project Web server のサイト http://www.gnu.org/licenses/gpl.html から入手できます。 AFPL Ghostscript の使用に際しては、Aladdin Free Public License(AFPL) の規定に従う必要があります。AFPL Ghostscript の商用配布は通常商用 のライセンスを必要とします。詳細については、Ghostscript Web のサイ ト http://www.ghostscript.com/awki を参照してください。 v Ghostscript をインストールするには 1 コンピュータの一時ディレクトリに、Ghostscript Web のサイト http://www.ghostscript.com/awki にあるサイトの 1 つから必要な Ghostscript のバージョンの自己解凍型実行ファイルをダウンロー ドします。 テスト用に使用した Ghostscript のバージョンについては『リリー ス ノート』マニュアルを参照してください。 2 実行ファイルを実行して、Ghostscript をシステムにインストールし ます。 デフォルトのインストール ディレクトリは C:\Program Files\gs で す。別のディレクトリを選択したり、Ghostscript コンソールと readme ファイルへのショートカットを作成したりすることもでき ます。 762 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 Ghostscript をインストールした後で、Ghostscript の使い方およびアプ リケーションでそれを配布することについて調べるために、Ghostscript インストレーション ディレクトリの doc サブディレクトリにある readme.htm ファイルを読む必要があります。 名前を付けて行を保存に失敗 データウィンドウ ペインタで PDF として保存するには、[ファイル| 名前を付けて行を保存]を選択して、ファイルの種類として「PDF」を 選択します。Ghostscript をインストールしないで、デフォルトのエク スポート プロパティを使用する場合は、PowerBuilder は名前を付けて 行を保存することに失敗したことを知らせるポップアップ ウィンド ウを表示します。Ghostscript をインストールし、Ghostscript をインス トールしたディレクトリ名を変更すると、PDF 形式での行の保存はエ ラーを通知することなく失敗します。 ファイルの場所 distill メソッドを使ってデータウィンドウ オブジェクトを PDF として 保存する場合、PowerBuilder は、次の場所からインストールされた GPL または AFPL Ghostscript を探します。 • • • Windows レジストリ pbdwe115.dll ファイルの相対パス (通常は Sybase\Shared\PowerBuilder) システムの PATH 環境変数 GPL または AFPL Ghostscript を Ghostscript 実行ファイルを使ってイン ストールした場合は、Windows レジストリにパスが追加されます。 Ghostscript ファイルが pbdwe115.dll ファイルの相対パスにある場合、 Ghostscript は次のディレクトリ構造でインストールされています。 dirname\pbdwe115.dll dirname\gs\gsN.NN dirname\gs\fonts dirname はランタイム DLL を含むディレクトリ、N.NN は Ghostscript の リリース バージョン番号です。 すべてのフォントを配布する必要はないかもしれません。フォントに ついての詳細は、Fonts and font facilities supplied with Ghostscript のサイト http://www.ghostscript.com/doc/current/Fonts.htm を参照してください。 アプリケーション テクニック 763 PDF と XSL-FO のエクスポート PostScript プリンタ ドライバ 使用しているコンピュータに PostScript プリンタがすでにインストー ルされている場合は、PDF ファイルの作成に必要な PostScript ドライ バ ファイルである PSCRIPT5.DLL、PS5UI.DLL、および pscript.ntf も インストールされています。通常、これらのファイルは、Windows XP の場合は C:\WINDOWS\system32\spool\drivers\w32x86 に、また、 64 ビット Vista システムの場合は C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_1a216484\ Amd64 にあります。ユーザは PDF の作成に使用するオペレーティン グシステムに適したドライバ ファイルを使用する必要があります。 これらのファイルは dirname\drivers ディレクトリにコピーします。 Sybase\Shared\PowerBuilder\drivers に イ ン ス ト ー ル さ れ て い る 関 連 ファイルも配布する必要があります。これらのファイルはユーザのコ ンピュータにコピーまたはインストールできます。次のディレクトリ 構造で配置する必要があります。 dirname\pbdwe115.dll dirname\drivers PostScript プリンタ プロファイル 各ユーザのコンピュータに、Sybase DataWindow PS という PostScript プ リンタ プロファイルがなければなりません。このプロファイルは、 データウィンドウ ペインタで PDF ファイルにデータウィンドウの行 を保存する際に、自動的に開発コンピュータに追加されます。この方 法を使用すると、PowerBuilder がインストールされているコンピュー タに Sybase DataWindow PS プリンタを追加できます。 ユーザは、次のいずれかの方法で、プリンタの追加ウィザードを使用 して手動でプロファイルを追加することもできます。 • ウィザードの[プリンタ ソフトウェアのインストール]ページで [ディスク使用]ボタンをクリックし、 (Shared\PowerBuilder\drivers デ ィ レ ク ト リ に、PowerBuilder と と も に イ ン ス ト ー ル さ れ た) Adist5.inf ファイルまたは別の PostScript ドライバ ファイルを検索 し、 [プリンタ名]ページでプリンタ名を「Sybase DataWindow PS」 に変更します。 • ウィザードの[プリンタ ソフトウェアのインストール]ページ で、一覧表示されているプリンタから、名前に「PS」が含まれる プリンタ([Apple Color LW 12/660 PS]など)を選択し、[プリン タ名]ページでプリンタ名を「Sybase DataWindow PS」に変更し ます。 アプリケーションで IIS サーバから PDF ファイルまたは XSL ファイル を印刷する場合、 『アプリケーションとコンポーネントの .NET への配 布』マニュアルのプリント マネージャの章を参照してください。 764 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 Apache FO プロセッサの使い方 Apache プロセッサを使用して PDF または XSL-FO 形式で保存するア プリケーションの場合には、アプリケーションとともに fop-0.20.4 ディ レクトリと Java Runtime Environment(JRE)を配布する必要がありま す。 これらのディレクトリは、PowerBuilder ランタイム ファイルと同じ ディレクトリに配布する必要があります。たとえば、MyApplication と いうディレクトリにアプリケーションと pbvm115.dll とそのほかの PowerBuilder ランタイム ファイルを配布する場合、Apache プロセッサ を MyApplication\fop-0.20.4 および MyApplication\jre の JRE に配布し ます。ただし、ターゲット コンピュータ上に JDK をフル インストー ルし、クラスパスに追加してある場合は、その場所に JRE のコピーを 置く必要はありません。 ユーザのクラスパスに、次の JAR ファイルが必要です。 fop-0.20.4\build\fop.jar fop-0.20.4\lib\batik.jar fop-0.20.4\lib\xalan-2.3.1.jar fop-0.20.4\lib\xercesImpl-2.1.0.jar fop-0.20.4\lib\xml-apis.jar fop-0.20.4\lib\avalon-framework-cvs-20020315.jar JRE についての詳細は、759 ページの「Java サポート」を参照してく ださい。 Windows DBCS プラットフォームでは、 ターゲット コンピュータの Windows フォント ディレクトリ(C:\WINDOWS\fonts など)に、DBCS 文字を サポートするファイルも配布する必要があります。フォントの設定に ついての詳細は、Apache Web のサイト http://xml.apache.org/fop/fonts.html を 参照してください。 データウィンドウ Web コントロール ActiveX データウィンドウ Web コントロール ActiveX を使用している場合は、 Web サーバに以下のファイルを配布する必要があります。 アプリケーション テクニック 765 EAServer 上の PowerBuilder コンポーネント 表 37-13: データウィンドウ Web コントロール ActiveX 用の PowerBuilder ファイル 名前 psdwc115.cab pbjdbc12115.jar 必要とする対象 Open Software Distribution 情報ファイル、Web ActiveX およびトランザクション コントロール用 DLL を含む CAB ファイル 必要な Java クラスを含む JAR ファイル 配布先システムに Sun JRE がインストールされていない場合は、Sun Java Web サイトから JRE をダウンロードする必要があります。クライ アント ブラウザで Web ActiveX およびトランザクション コントロー ルを使用できるようにするには、配布された HTML ページの Object 要 素に CODEBASE 属性を記述します。 CODEBASE 属性につ いて CODEBASE 属性は、CAB ファイルまたは OCX ファイルの保存場所を 識別します。この属性によってブラウザは、CAB ファイルまたは OCX ファイルをダウンロードし、CAB ファイルの場合はアンパックして、 それをユーザのコンピュータに登録することができます。CODEBASE の一般的な値は、CAB または OCX ファイルの保存場所を識別する相 対 URL の後に、# 記号と、カンマで 4 つに区切られたバージョン番号 とが記述されます。バージョン番号は、PowerBuilder のバージョン番 号と同じです。たとえば、次のようになります。 CODEBASE="cabs/psdwc115.cab#11,5,0,1049" 追加ファイルが必要になる場合もあります。詳細については、PowerBuilder オンライン ブックの「データウィンドウ Web コントロールの配布」ま たは『データウィンドウ プログラマーズ ガイド』マニュアルを参照し てください。 EAServer 上の PowerBuilder コンポーネント EAServer で PowerBuilder コンポーネントを実行するには、コンポーネ ントを開発した時の PowerBuilder のバージョンとビルド番号のランタ イム ライブラリが、サーバ上で使用できるようにします。PowerBuilder のメンテナンス リリースをインストールし、EAServer に新しいコン ポーネントまたはアップデートしたコンポーネントを配布するときに は、サーバ上の PowerBuilder VM もアップデートする必要があります。 766 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 PowerBuilder で生成されたコンポーネントを実行する EAServer ホスト では、表 37-14 のファイルが必要です。PowerBuilder コンポーネントが 表に一覧表示されている機能またはデータベース インタフェースを 使用しない場合は、サーバにファイルをインストールする必要はあり ません。PowerBuilder VM には、EAServer libjcc ファイルとその関連 ファイルも必要です。表の UNIX の列にある ext は、ライブラリ名に 対応するプラットフォーム固有の拡張子を表します。たとえば Solaris では、このファイル名は libpbvm115x.so になります。 表 37-14: EAServer ホストに必要な PowerBuilder ファイル Windows UNIX 説明 pbvm115.dll libpbvm115x.ext PowerBuilder 仮想マシン (すべての PowerBuilder コ ンポーネントに必要) pbshr115.dll pbshr115.ext PowerBuilder 仮想マシンに 必要 pbdwe115.dll libpbdwe115x.ext データストアのサポート pbjag115.dll libpbjag115x.ext、 EAServer での PowerBuilder pbjag115.ext のサポート pbdwr115.pbd pbdwr115.pbd Web データウィンドウの サポート(PBDWE が必 要) htmldw.js htmldw.js Web データウィンドウの サポート リッチテキストのサポー pbRTC115.dll お よ び 表 — 37-5 に記載の追加のラ ト ンタイム ファイル PBXerces115.dll、 libxerces115x.ext、 XML サポート libxerces-c_2_1_0.ext xerces-c_2_6.dll、 xerces-depdom_2_6.dll pbdom115.pbx libpbdom115x.ext PBDOM サポート アプリケーション テクニック 767 EAServer 上の PowerBuilder コンポーネント Windows UNIX 説明 EasySoap115.dll、 ExPat115.dll、 libeay32.dll、 ssleay32.dll、 pbsoapclient115.pbx、 pbwsclient115.pbx、 pbnetwsruntime115.dll、 xerces-c_2_6.dll、 xerces-depdom_2_6.dll、 Sybase.PowerBuilder.We bService.Runtime.dll、 Sybase.PowerBuilder.We bService.RuntimeRemote Loader.dll pbo90115.dll — EasySoap のための SOAP クライアントおよび .NET Web サービス( .NET Web サービスでは 2 つの Sybase.PowerBuilder DLL ファイルが EAServer\Bin ディレクトリに配布され る必要がある) pbo10115.dll pbora115.dll pbodb115.ini 768 libpbo90115x.ext (Solaris と Linux の み) libpbo10115x.ext (Solaris と Linux の み) libpbora115x.ext (Solaris と Linux の み) pbodb115.ini pbodb115.dll libpbodb115x.ext pbsnc115.dll libpbsnc115x.ext pbsyj115.dll libpbsyj115x.ext pbjdb115.dll libjdb115x.ext — libpbwfr115.ext pbjdbc12115.jar pbjdbc12115.jar Oracle9i データベース ドラ イバ Oracle 10g データベース ド ライバ Oracle 11g データベース ド ライバ PowerBuilder ODBC 初期設 定ファイル PowerBuilder ODBC インタ フェース SQL Native Client ネイティ ブ データベース インタ フェース Adaptive Server Enterprise ネイティブ データベース インタフェース Sun Java VM JRE 1.1 以降対 応 JDBC データベース ド ライバ PowerBuilder UNIX 拡張ラ イブラリ PowerBuilder JDBC ドライ バ対応 Java クラス(JRE 1.2 以降に必要) PowerBuilder 第 37 章 Windows の場合 アプリケーションとコンポーネントの配布 PowerBuilder VM インストーラを使用できます。このインストーラは、 表 37-14 に記載されているファイルをインストールするために DVD の PBVM フォルダに用意されています。PBVM セットアップ プログラム は、PowerBuilder 11.5 用の Web データウィンドウ サーバ コンポーネン ト (HTMLGenerator115)とリモート デバッグに必要な PBDebugBroker115 コンポーネントもインストールします。 EAServer コンポーネントにほかのデータベース ドライバを使用する こともできますが、トランザクション管理およびインスタンス プーリ ングのための EAServer サポートを活用したい場合は、上の表に記載さ れているいずれかのドライバを使用してください。 UNIX の場合 EAServer をインストールしたときに表 37-14 に記載されているファイ ルがインストールされなかった場合、Sybase Downloads EBFs/Maintenance page のサイト http://downloads.sybase.com/ からご利用の プラットフォームで必要なファイルを入手できることがあります。 UNIX プラットフォームで動作する EAServer に配布される PowerBuilder コンポーネントは、Windows API に依存したり、GUI を使用したりす ることはできません。共有ライブラリは、UNIX サーバ上の EAServer lib ディレクトリにインストールされる必要があります。PowerBuilder JDBC ドライバに必要な Java クラスを、EAServer の html/classes/com/sybase/powerbuilder/jdbc ディレクトリにインストール する必要があります。 UNIX の接続キャッシュ PowerBuilder コンポーネントが接続キャッシュ を使用するためには、表 37-14 に記載のデータベース ドライバが必要 です。PowerBuilder コンポーネントが接続キャッシュを使用するとき は、該当する PowerBuilder ドライバがロードされます。 EAServer 上の Web データウィンドウ EAServer 上で、ページ サーバとして JSP を使用して、Web データウィ ンドウ サーバ コンポーネントを実行できます。コンポーネントのトラ ンザクション サーバとページ サーバは、同一コンピュータ上でも異な るコンピュータ上でも実行できます。 トランザクション サーバに必要なファイ ル トランザクション サーバには、以下の 2 種類のファイルが必要です。 • アプリケーション テクニック データウィンドウ オブジェクトの定義を含む PBL または PBD ファイル 769 EAServer 上の Web データウィンドウ これらのファイルは、サーバのパス内のディレクトリにインス トールしておく必要があります。EAServer がサービスとして実行 されている場合は、これらのファイルがシステム パス上に存在す るか、または完全修飾名で指定されなければなりません。 • PowerBuilder ランタイム ファイル(Windows 上の pbvm115.dll、 pbshr115.dll、pbjag115.dll、および pbdwe115.dll を含む)と pbdwr115.pbd。pbdwr115.pbd ファイルには、データウィンドウ HTMLGenerator115 コンポーネントの実装が含まれる PowerBuilder VM インストーラを使用できます。このインストーラ は DVD の PBVM フォルダに用意されていて、これらのファイル をインストールします。必要なファイルの詳細については、766 ページの「EAServer 上の PowerBuilder コンポーネント」を参照し てください。 さらに、コンポーネントがアクセスするデータベースの接続キャッ シュを作成する必要があります。詳細については、 『データウィンドウ プログラマーズ ガイド』マニュアルを参照してください。 カスタム コンポーネント データウィンドウ コンポーネントのカスタム バージョンを作成し、よ り効率的に再使用できるようにプロパティを構成できます。詳細につ いては、『データウィンドウ プログラマーズ ガイド』マニュアルを参 照してください。 動的ページ サーバに 必要なファイル JSP をページ サーバとして使用し、Java を使って EAServer に接続する には、JSP サーバ コンピュータ上に以下のファイルが必要です。 HTML ページ、テンプレート、およびスクリプト これらは、アプリケー ション用に作成したファイルです。 Java 対応 EAServer クライアント ソフトウェア JSP サーバでは、表 37-15 のファイルが必要です。 表 37-15: JSP サーバに必要な EAServer クライアント ファイル 名前 easclient.jar easj2ee.jar 説明 クライアントに必要な Java クラス J2EE サポートに必要な Java クラス Sun Java 開発キット(JDK) EAServer とともにインストールされた JDK は、どのバージョンも、使用している EAServer のバージョンに応じ て、Sybase\Shared\ または Sybase\Shared\Sun ディレクトリのどちらか に保存されています。PowerBuilder とともにインストールされた JDK は、Sybase\Shared\PowerBuilder ディレクトリに保存されています。 770 PowerBuilder 第 37 章 アプリケーションとコンポーネントの配布 JDK 1.2 または 1.3 を使用する場合、JDK の JRE\bin\classic サブディレ クトリが、システムの PATH 環境変数に追加されていることを確認し ます。 JDK 1.4 以降を使用する場合、JDK の JRE\bin\client サブディレクトリ が、システムの PATH 環境変数に追加されていることを確認します。 アプリケーション テクニック 771 EAServer 上の Web データウィンドウ 772 PowerBuilder 索引 数字 508 条 668 A AccessibleRole カタログ データ(列挙体)値 671 AccessiWeb アクセシビリティ基準 669 Activate イベント、EAServer 内 464 Activate 関数 359, 361 ActiveX コントロール ActiveX のプロパティ、イベント、関数 366 Object プロパティ 381 アクティブ 368 イベント 369 オートメーション 381 概要 347, 349 組合せイベント リスト 369 動作 367 配布 735 表示形態 367 プログラミング 368 プロパティ 366, 367 プロパティ シート 367 Adaptive Server Anywhere(SQL Anywhere 同期を 参照) Adaptive Server Enterprise データベース インタ フェースのプロパティ(トランザクショ ン オブジェクト) 177 AddColumn 関数 158 AddData 関数 277 AddItem 関数 145, 149, 150, 153 AddLargePicture 関数 155 AddPicture 関数 146, 151 AddSeries 関数 277 AddSmallPicture 関数 155 AddStatePicture 関数 155, 156 アプリケーション テクニック ADO.NET、配布要求 757 AJAX Extensions 745 ALIAS FOR キーワード 概要 193 スクリプト記述 194 AncestorReturnValue 変数 33 Any データ型 388 Application Server Plug-in 449 AutoCommit プロパティ(トランザクション オブ ジェクト) COMMIT 文と ROLLBACK 文の実行 179 概要 174 データベース インタフェースごとのリスト 177 B bind.object コンポーネント プロパティ Blob OLE コントロール 365 データウィンドウの同期 481 BMP ファイル リソースとしての配布 715 リソース ファイルでの命名 717 461 C CacheName DBParm 476 Cancel 関数 320, 332 ClassName 関数 388 Clicked イベントとグラフ 283 COM サーバ 571 サーバとオートメーション サーバの比較 データ型 575 COM+ 571 773 索引 クライアントの構築 601 コンポーネントの構築 567 配布 589 COM+ の ImpersonateClient メソッド 586 COM+ の IsCallerInRole メソッド 586 COM+ の IsSecurityEnabled メソッド 586 COM+ の RevertToSelf メソッド 586 COM/COM+ コンポーネントの検証 577 COM/COM+ コンポーネント(COM コンポーネント を参照) COMMIT 文 AutoCommit の設定 179 COM コンポーネント 583 EAServer コンポーネント 472 UseContextObject 469 エラー処理 188 概要 178 接続解除時の自動コミット 179, 185 デフォルト以外のトランザクション オブジェクト 186 COM クライアント 環境設定 601 結果集合 580 構築 601 サーバへの接続 602 トランザクションの制御 604 COM コンポーネント 埋め込み PBD 590 開発プロセス 569 構築 567 セキュリティ問題 586 データベース アクセス 578 登録 589 トランザクション サポート 582 プロジェクト ペインタでの構築 587 メモリの割り当て 591 CONNECT 文 USING TransactionObject 句 183 エラー処理 188 概要 178 スクリプト記述 183 デフォルト以外のトランザクション オブジェクト 186 774 CORBAUserException オブジェクト 549 CreateInstance 関数 527, 528, 585 CreateInstance メソッド、Web サービス プロキシ 649 CreateJavaVM メソッド 618 create メソッド 623 CUR ファイル リソースとしての配布 715 リソース ファイルでの命名 717 C 関数に受け渡す Char 変数 427 D Database プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 DataObject プロパティ(データ パイプライン) 320, 325 dbmlsync 概要 207 プロセス 208 DBMS プロパティ(トランザクション オブジェク ト) 概要 174 データベース インタフェースごとのリスト 177 DBParm MsgTerse パラメータ 336 DBParm プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 DBPass プロパティ(トランザクション オブジェク ト) 概要 174 データベース インタフェースごとのリスト 177 DDE 概要 343 クライアント イベントと関数 345 クライアント関数 345 PowerBuilder 索引 サーバ イベントと関数 346 Deactivate イベント、EAServer 内 464 DeleteLargePictures 関数 157 DeleteLargePicture 関数 157 DeletePicture 関数 146 DeleteSmallPictures 関数 157 DeleteStatePictures 関数 157 DeleteStatePicture 関数 157 DisableCommit メソッド 471 DISCONNECT 文 USING TransactionObject 句 184 エラー処理 188 概要 178 スクリプト記述 184 データベース トランザクションのプール時 189 デフォルト以外のトランザクション オブジェ クト 186 DLL ファイル PBD ファイルとの比較 712 PowerBuilder 配布 726 概要 712 関数の実行 421 作成 723 テスト 724 含まれるリソース 716 例 719 dwprint.ini 511 E EAServer PowerBuilder DLL 516 PowerBuilder との統合 446 Unicode 接続キャッシュ 478 インスタンス プーリング 463 共有コンポーネント 457 クライアント プル 542 コンポーネントの配布 516 接続 521 接続エラー 546 トランザクション サポート 467 アプリケーション テクニック 非同期リクエスト 542 ログ 509 EAServer 環境変数 PB_FOP_SUPPRESSLOG 515 PB_HEAP_LOGFILE_OVERWRITE 52 PB_HEAP_LOGFILENAME 52 PB_POOL_THRESHOLD 51 PBOnFatalError 472 PBRollbackOnRTError 472 EAServer クライアント 構築 519 配布 551 EAServer コンポーネント インタフェース 488 構築 453 データベース更新 480 デバッグ 506 プロパティ 497 メソッドの呼び出し 526 有効期間 466, 473 EAServer プロキシ オブジェクト 概要 524, 525 破棄 532 EAServer プロファイル、作成 455 EAServer プロファイル ダイアログボックス、概要 456 EasySoap Web サービス エンジン 641 EJBConnection オブジェクト 610 EJBTransaction オブジェクト 610 EJB クライアント Java コレクション クラス 627 構築 607 動的キャスティング 626 戻り値のダウンキャスト 625 例外処理 627 EJB コンポーネント、メソッドの呼び出し 528, 622 EJB プロキシ オブジェクト 概要 608 生成 608 EnableCommit メソッド 471 ExternalException イベント 390 775 索引 F FileEncoding 関数 54 FileLength64 関数 54 FileOpen 関数 54 FileReadEx 関数 55 FileSeek64 関数 54 FileWriteEx 関数 55 FindSeries 関数 278 FOR...NEXT 文(ウィンドウ インスタンスを開く / 閉 じる) 95 FUNCTION 宣言 概要 193 スクリプト記述 194 G gdiplus.dll、Windows 2000 への配布に必要 743 GetChanges 関数 480 GetConnectionOption DBParm 478 GetFocus イベントによるマイクロヘルプの提供 GetFullState 関数 480 GetJavaClasspath メソッド 618 GetJavaVMVersion メソッド 618 GetParent 関数 28, 108 78 177 InsertItemFirst 関数 122 InsertItemLast 関数 122 InsertItemSort 関数 122 InsertItem 関数 122, 145, 149, 150, 153 IsInTransaction メソッド 471 IsJavaVMLoaded メソッド 618 IsTransactionAborted メソッド 471 J J2EE アーキテクチャ 447 J2EE サーバへの接続 621 Java VM、実行時に起動 759 JavaVM オブジェクト 610 Java コレクション クラス、EJB クライアント 627 JBoss のサポート(PowerBuilder Application Server Plug-in) 449 JDBC データベース インタフェースのプロパティ (トランザクション オブジェクト) 177 JRE、配布に必要 759 JVM、実行時に起動 759 L H HotLinkAlarm DDE イベント 345 I IAccessible プロパティ 671 ICO ファイル ドラッグ アイコンの指定 163 リソースとしての配布 715 リソース ファイルでの命名 717 imstyle.pbl 690 InfoMaker 様式の作成 690 INFORMIX データベース インタフェース ストアド プロシージャ呼び出しでサポートされる 機能 200 プロパティ(トランザクション オブジェクト) 776 Lock プロパティ(トランザクション オブジェク ト) 概要 174 データベース インタフェースごとのリスト 177 LogID プロパティ(トランザクション オブジェク ト) 概要 174 データベース インタフェースごとのリスト 177 LogPass プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 LUW(論理的な作業単位) 178 PowerBuilder 索引 M MailSession オブジェクト 417 MAPI アプリケーションからのアクセス 417 概要 417 MDI_1 コントロール 73 MDI アプリケーション キーボード操作 87 構築 71 シートの使い方 75 ショートカット キー 89 マイクロヘルプの提供 77 メニューの使い方 74 MDI アプリケーションのキーボード サポート 87 MDI アプリケーションの標準フレーム 73 MDI シート 概要 74 最大化 77 整列 76 閉じる 77 開く 75 マイクロヘルプの提供 77 メニューの使い方 74 リストを開く 76 MDI フレーム カスタムのサイズ変更 84 シートの整列 76 シートを開く 75 マイクロヘルプの使い方 77 MicroHelpHeight 属性 87 Microsoft Active Accessibility 670 Microsoft Active Accessibility プロパティ 670 Microsoft Excel、OLE 382, 386 Microsoft SQL Server ストアド プロシージャの呼び出し 201 プロパティ(トランザクション オブジェク ト) 177 Microsoft Windows インストーラ、ランタイム パッケージャに対して必要 737 Microsoft Word OLE 373, 384, 387 レター フォーム例 375 アプリケーション テクニック MobiLink 同期 dbmlsync 207, 208 PowerBuilder オブジェクト 210 アーティクル 207, 233 ウィザード 210 階層構造 205 概要 203 クライアント 207 サーバ 204 削除の処理 239 サブスクリプション 207, 236 スクリプト 206, 228 スクリプトのデフォルト 225 接続イベント 223 テーブル イベント 224 テクニック 237 統合 204 統合データベース 222 パブリケーション 207, 231 ユーザ 207, 234 リモート 204 リモート データベース 231 リモート マシンで必要なファイル 219 MSAA 670 MSAA プロパティ 670 MsgTerse パラメータ 336 MSI ファイル(Microsoft Windows インストーラ) 737 N .NET Web サービス エンジン 639 .NET ターゲット、配布に必要なファイル 740 O ObjectAtPointer 関数 285 Object プロパティ 概要 38 ドット表記 29 OCI_9U 接続キャッシュ 478 OCX(ActiveX コントロールを参照) 777 索引 ocx_error イベント 391 ODBCU 接続キャッシュ 478 ODBCU_CONLIB データベース パラメータ 479 ODBC インタフェース インストール 726 環境設定 726 ストアド プロシージャ呼び出しでサポートされる 機能 200 プロパティ(トランザクション オブジェクト) 177 OLE アンビエント プロパティ 367 インプレース アクティブ化 358 インプレース アクティブ化のメニュー 359 埋め込み 356 エラー処理 390 オートメーション 371 オートメーションで使用する言語 395 オフサイト アクティブ化 358 オブジェクト 350 オブジェクトと代入 373 オブジェクトのアクティブ化 361 型のない変数 388 括弧 383 コンテナ アプリケーション 347 コンパイラのチェック 381 サーバ アプリケーション 347, 350, 400 サーバ コマンドの修飾子 371, 386 サーバのメソッドとプロパティ 381 サーバ メモリの割り当て 385 処理効率 389 ストリーム 411 挿入可能オブジェクト 348 低レベルのアクセス時のポインタ 396 データウィンドウ オブジェクトの関数 397 データウィンドウのカラム 398 データ ファイル 364 名前のついたパラメータ 384 バーブ 361, 399 引数の参照渡し 383 ブラウザ 400 プロパティの変更通知 393 778 ホット リンク 393 リンク 357 リンク情報の管理 357 リンクと埋め込みの比較 356 レター フォーム例 375 OLE DB データベース インタフェースのプロパ ティ(トランザクション オブジェクト) 177 OLEActivate 関数 399 OLEObject オブジェクト 概要 371 作成 371 接続 371 接続解除と破棄 373 OLEStorage オブジェクト 404 OLEStream オブジェクト 404 OleTxnObject オブジェクト 604 OLE オートメーション Object プロパティ 396, 398 OLEObject 371 構文 381 シナリオ 375 例 375 OLE オブジェクト、ドット表記 29 OLE オブジェクトの埋め込み 364 OLE オブジェクトの挿入 362 OLE オブジェクトの貼り付け 363 OLE オブジェクトのリンク 362, 364 OLE カスタム コントロール(ActiveX コントロー ルも参照) 347 OLE クラス ユーザ オブジェクト 404 OLE 項目のブラウザ 400 OLE コントロール Blob 365 Contents プロパティ 363 ObjectData プロパティ 365 Object プロパティ 381 アクティブ化 361 イベント 365 埋め込み 353, 362 埋め込みデータの保存 364 オートメーション 381 オフサイト アクティブ化とインプレース アク ティブ化の比較 358 PowerBuilder 索引 オブジェクトのアイコン 353 オブジェクトのアクティブ化 353, 354 オブジェクトの削除 355 オブジェクトの挿入 362 オブジェクトの表示 353 オブジェクトの変更 355, 362 概要 347 空の OLE コントロール 350, 359 サーバ アプリケーション 364 定義 350 動作 352, 355 表示形態 352 プロパティ シート 352 メニュー 359 ユーザ インタラクション 355 リンク 353, 362, 364 リンクの更新 354 リンクの中断 359 OLE ストリーム read/write ポインタ 413 概要 402, 411 長さ 413 開く 411 読み込みと書き込み 413 OLE ストレージ 概要 402 構造 403 効率 405 ストレージの構造の記録管理 416 ファイルの構築 408 保存 406 メンバー 407 例 408 Open 関数 96 Open 関数(OLE) 362 OpenSheet 関数 75 ORACLE データベース インタフェース プロパティ(トランザクション オブジェク ト) 177 ストアド プロシージャの使い方 192, 199 ストアド プロシージャ呼び出しでサポートさ れる機能 200 アプリケーション テクニック P Parent 代名詞 28 PB.INI ファイル UserHelpPrefix 169 トランザクション オブジェクト値の読み込み 182 PB_FOP_SUPPRESSLOG 環境変数 515 PB_HEAP_LOGFILE_OVERWRITE 環境変数 52 PB_HEAP_LOGFILENAME 環境変数 52 PB_POOL_THRESHOLD 環境変数 51 PBDOM クラス、概要 244 PBD ファイル DLL ファイルとの比較 712 概要 712 作成 723 テスト 724 含まれるリソース 716 例 719 pbejbclient115.pbd 608 pbejbclient115.pbx 608 pbjvm115.dll、保存場所 759 PBOnFatalError 環境変数 472 PBRollbackOnRTError 環境変数 472 PBR ファイル 716 pbsoapclient115.pbx 643 PBUSR0nn.HPJ ファイル 166 pbwsclient115.pbx 643 PBX、インポート 260, 642 Pcode、実行アプリケーション 710 PipeEnd イベント 320 pipeline システム オブジェクト 320 PipeMeter イベント 320 PipeStart イベント 320 PostEvent 関数 431 Post 関数 430 PowerBuilder 実行時 DLL 726 実行システム 712 パイプライン エラー データウィンドウ 335 PowerBuilder Application Server Plug-in 449 PowerBuilder イベントの発生 431 PowerBuilder ウィンドウ ActiveX 633 PowerBuilder 初期設定ファイル、トランザクショ ン オブジェクト値の読み込み 182 779 索引 PowerBuilder セキュア ウィンドウ プラグイン 633 PowerBuilder 単位系(PBU)と拡張コントロール プロ パティ 349 PowerBuilder の ADO Recordset 581 PowerBuilder 標準ウィンドウ プラグイン 633 PowerBuilder ランタイム パッケージャ 737 PowerScript ドット表記、ストアド プロシージャ呼び 出しのための使い方 197 Powersoft データベース インタフェース インストール 726 ストアド プロシージャ呼び出しでサポートされる 機能 199 PrintCancel 関数 681 PrintClose 関数 681 ProfileString 関数 概要 182, 687 スクリプト記述 182 PropertyChanged イベント 394 PropertyRequestEdit イベント 393 R REF キーワード 383 RegEdit ユーティリティ、サポートされているバーブ の取得 399 RegistryGet 関数 688 RegistrySet 関数 688 ReleaseConnectionOption DBParm 478 RemoteHotLinkStart DDE イベント 346 RemoteHotLinkStop DDE イベント 346 RemoteRequest DDE イベント 346 RemoteSend DDE イベント 346 Repair 関数 320, 336 RLE ファイル リソースとしての配布 715 リソース ファイルでの命名 717 ROLLBACK 文 AutoCommit の設定 179 UseContextObject 469 概要 178 デフォルト以外のトランザクション オブジェクト 186 RowsInError プロパティ(データ パイプライン) 320, 330 780 RowsRead プロパティ(データ パイプライン) 320, 330 RowsWritten プロパティ(データ パイプライン) 320, 330 RPCFUNC キーワード 概要 193 スクリプト記述 194 RTF 287 Run 関数 459 S Save 関数(OLE) 406 SaveAs 関数(OLE) 364, 406 Secure Sockets Layer プロバイダ サービス 434 Send 関数 430 ServerName プロパティ(トランザクション オブ ジェクト) 概要 174 データベース インタフェースごとのリスト 177 SetAbort メソッド 471 SetAutomationLocale 関数 395 SetChanges 関数 480 SetColumn 関数 158 SetComplete メソッド 471 SetFullState 関数 480 SetItem 関数 159 SetMicroHelp 関数 78 SetOptions メソッド、Web サービス プロキシ 649 SetOverLayPicture 関数 156 SetProfileString 関数 687 SetTransPool 関数 189 SOAP 大文字と小文字の区別 645 サーバへの接続 649 例外処理 651 SOAPConnection オブジェクト 643 SoapException オブジェクト 643 Solaris 印刷、設定 511 SQL Anywhere MobiLink 同期 204 ストアド プロシージャ呼び出しでサポートされ PowerBuilder 索引 る機能 202 データ ソース 752 SQL Server、ストアド プロシージャの呼び出し 201 SQLCA SQLCA からのユーザ オブジェクトの継承 191, 196 SQLCA のプロパティとしてのストアド プロ シージャの呼び出し 197 アプリケーション ペインタ プロパティ シート での設定 196 インスタンスの作成と破棄の禁止 185 エラー処理 188 概要 174, 180 ストアド プロシージャ呼び出しのためのカス タマイズ 190 データベース インタフェースごとのプロパ ティのリスト 177 デフォルトのグローバル変数の型の指定 195 プロパティの記述 174 プロパティへの値の設定 181 SQLCode プロパティ(トランザクション オブ ジェクト) 概要 174, 188 スクリプト記述 189 データベース インタフェースごとのリスト 177 SQLDBCode プロパティ(トランザクション オブ ジェクト) 概要 174, 189 スクリプト記述 189 データベース インタフェースごとのリスト 177 SQLErrText プロパティ(トランザクション オブ ジェクト) 概要 174, 189 スクリプト記述 189 データベース インタフェースごとのリスト 177 SQLNRows プロパティ(トランザクション オブ ジェクト) 概要 174 アプリケーション テクニック データベース インタフェースごとのリスト 177 SQLReturnData プロパティ(トランザクション オ ブジェクト) 概要 174 データベース インタフェースごとのリスト 177 SQLSTATE エラー番号の省略 336 SQL 文 SQL 文のセミコロンでの終了 181, 183 エラー処理 188 トランザクション オブジェクトの指定 186 トランザクション処理 179 SQL 文の後のエラー処理 188 SQL 文の終止符のセミコロン 181, 183 SSL EAServer との接続 553 コールバック 562 プロバイダ オブジェクト 559 プロバイダ サービス 434 プロパティ 556 SSLCallback オブジェクトの使い方 562 SSLServiceProvider オブジェクト インスタンスの作成 559 使い方 555 Start 関数 320, 328, 459 Stop 関数 459 SUBROUTINE 宣言 概要 193 スクリプト記述 194 Super 代名詞 32 Sybase Adaptive Server Enterprise データベース イン タフェース ストアド プロシージャの呼び出し 201 トランザクション オブジェクトのプロパティ 182 Sybase EAServer プロファイル EAServer プロファイル ダイアログボックス 456 Sybase SQL Anywhere、ストアド プロシージャの呼 び出し時にサポートする機能 202 Syntax プロパティ(データ パイプライン) 320 SystemError イベント、スクリプト作成 550 781 索引 T TabularResults、PowerBuilder での使い方 486 Tag 属性、マイクロヘルプの使い方 78 This 代名詞 27 thread.safe プロパティ 460 TransactionServer コンテキスト オブジェクト COM+ 582, 585 EAServer 469, 495 TriggerEvent 関数 431 U Unicode EAServer 接続キャッシュ 478 UseContextObject DBParm 472 UserID プロパティ(トランザクション オブジェクト) 概要 174 データベース インタフェースごとのリスト 177 USING TransactionObject 句 CONNECT 文 183 DISCONNECT 文 184 概要 186 V Voluntary Product Accessibility Template(VPAT を参 照) VPAT 674 W WCAG(Web Content Accessibility Guidelines) 668 Web Content Accessibility Guidelines(WCAG を参照) WebLogic のサポート(PowerBuilder Application Server Plug-in) 449 WebSphere のサポート(PowerBuilder Application Server Plug-in) 449 Web サービス EasySoap エンジン 641 .NET エンジン 639 PowerScript クライアント 637 782 概要 634 コンポーネントのエクスポーズ 502 サービスの作成 638 プロキシ オブジェクト 644 メソッドの起動 651 例外処理 651 Windows イベント イベント発生 430 処理 432 Windows メッセージ、送信 429 WMF ファイル リソースとしての配布 715 リソース ファイルでの命名 717 Word 97 オートメーション 386 WordBasic ステートメント 384 WSDL Web サービス プロキシに対する選択 644 概要 638 ア アーキテクチャ J2EE 447 アイコン、配布 715 アクセサ メソッド(COM オブジェクト インタ フェースへの追加) 574 アクセシビリティ 機能 665 データウィンドウのサポート 672 テスト 674 必要な DLL 747 値、引数の受け渡し 35 EAServer 490 アプリケーション MDI 71 外部ファイルからのトランザクション オブジェ クト値の読み込み 182 実行 724 実行のトレース 725 多言語 657 データベース ストアド プロシージャの呼び出 し 190 データベース トランザクションのプール 189 配布 709 PowerBuilder 索引 ユーザ オブジェクトにストアド プロシージャ を実行させるスクリプト 197 ローカライズ 657, 664 アプリケーション、クライアント 構築 601 配布 551 アプリケーション、サーバ COM/COM+ コンポーネントの構築 587 EAServer コンポーネントの構築 453 アプリケーション環境設定、格納 685 アプリケーション管理 アプリケーション管理を容易にする動的ライ ブラリの使い方 714 アプリケーション管理を容易にするリソース のパッケージ化 715 更新された PowerBuilder ランタイム DLL の提 供 726 アプリケーションの実行版 コンパイル オプション 710 テスト 724 トレース 725 パッケージ化モデルの実装 723 パッケージ化モデルの選択 719 パッケージに含まれる要素 711 アプリケーションのテスト 実行のトレース 725 実行版 724 アプリケーションのパッケージ化 コンパイル オプション 710 実行版の処理 711 テスト 724 モデルの実装 723 モデルの選択 719 アプリケーションのユーザ、コンピュータ環境 設定 726 アプリケーション ペインタ アプリケーション プロパティ シート、変数の 型プロパティ ページを使用 196 デフォルトのグローバル変数型の変更 195 アンビエント プロパティ 367 アプリケーション テクニック イ 位置、ウィンドウ 94 位置ポインタ 54 イベント DDE 344 イベント発生 430, 431 グラフ コントロール 276 先祖からの戻り値 33 先祖の呼び出し 32 データ パイプライン 320 ドラッグ アンド ドロップ 163 引数の受け渡し 35 呼び出し 431 イベント発生 430, 431 印刷 EAServer コンポーネントのデータストア 509 Solaris 510 UNIX 510 印刷カーソル 679, 681 印刷領域 679 概要 677 関数 677 行間隔 683 高度な印刷技法 682 ジョブ 679 測定単位 679 タブ 680 停止 681 描画オブジェクト 683 印刷カーソル 679 印刷領域 679 インスタンス、ウィンドウ 参照変数 93 配列 94 インスタンス プーリング 463 インスタンス変数 アクセス 30 名前の重複 32 インターネット サービス 434 インタフェース定義言語(IDL:Interface Definition Language) 488 インデックス、ウィンドウ配列 94 783 索引 ウ オ ウィザード COM/COM+ コンポーネント 568 EAServer コンポーネント 454 EAServer プロキシ オブジェクト 525 EJB プロキシ オブジェクト 611 ウィンドウ MDI アプリケーション 72, 74, 76 実行中の型の選択 37 データ型として定義 91 データ パイプラインの制御 321 表示 91 ウィンドウ インスタンスを複数開く 91 ウィンドウ ペインタ、コントロールのドラッグ モー ドの指定 162 埋め込み SQL でのエラー処理 188 運動障害 667 オートメーション サーバ PowerBuilder COM サーバとの比較 571 オートメーションで使用する言語 395 オブジェクト DLL ファイル 712 PBD ファイル 712 オブジェクトの代名詞 27 共有 457 子孫オブジェクトのインスタンス化 36 子孫オブジェクトの参照 97 実行中の型の選択 36 実行ファイル 712 先祖の関数とイベントの呼び出し 32 動的に参照されるオブジェクトの配布 714, 717 名前の重複 31 オブジェクト、プロキシ EJB に対して生成 608 生成 524, 525 オブジェクト指向概念としての代行 22 オブジェクト指向プログラミング、用語 13 オブジェクトの挿入 ダイアログボックス 350 オペレーティング システム、環境設定 726 親オブジェクト 25 エ エクステンション PowerBuilder で使用 260 エクステンション ファイル pbsoapclient115.pbx 643 pbwsclient115.pbx 642 オブジェクトのインポート 642 エラー EAServer サーバ ログへの書き込み 509 Windows ログへの書き込み 577 データ パイプライン実行時 317, 335 例外処理 39, 627 ログへの書き込み 434 エラー イベントのスクリプト記述 EAServer クライアント 549 OLE サーバ 390 エラー処理 OLE 390 SQL 文の後 188 エラー ロギング サービス COM+ 577 EAServer 509 概要 434 エリアス、XML メソッド 645 784 カ 外部関数 EAServer コンポーネント 428 宣言 422 使い方 421 データベース ストアド プロシージャ呼び出し のための使い方 193 外部ファイル、トランザクション オブジェクト値 の読み込み 182 学習障害 667 拡張属性の概要 317 カスタム クラス ユーザ オブジェクト COM/COM+ コンポーネント 568 EAServer コンポーネント 453 典型的な用途 14 PowerBuilder 索引 カスタム フレーム MDI アプリケーション 73 サイズ変更 84 カッコと OLE オートメーション 383 カプセル化 17, 30 ガベージ コレクション 49 可変長ウィンドウ配列 94 環境変数 PB_FOP_SUPPRESSLOG 515 PB_HEAP_LOGFILE_OVERWRITE 52 PB_HEAP_LOGFILENAME 52 PB_POOL_THRESHOLD 51 PBOnFatalError 472 PBRollbackOnRTError 472 関数 上書き 35 グラフ 276 先祖の呼び出し 32 動的 37 引数の受け渡し 35 関数、PowerScript AddColumn 158 AddItem 145, 149, 150, 153 AddLargePicture 155 AddPicture 146, 151 AddSmallPicture 155 AddStatePicture 155, 156 DDE 344 DeleteLargePicture 157 DeleteLargePictures 157 DeletePicture 146 DeleteSmallPicture 157 DeleteSmallPictures 157 DeleteStatePicture 157 DeleteStatePictures 157 InsertItem 122, 145, 149, 150, 153 InsertItemFirst 122 InsertItemLast 122 InsertItemSort 122 MAPI 417 SetColumn 158 SetItem 159 SetOverlayPicture 156 データ パイプライン 320 ドラッグ アンド ドロップ 164 アプリケーション テクニック ファイル操作 53 ユーティリティ 429 関数、外部 概要 422 宣言 423 データベース ストアド プロシージャ呼び出し のための使い方 193 引数の受け渡し 425 関数の多重定義 20 キ キーワード サービス 434 行、テーブル間のパイプライン処理 行間隔、設定 683 共有オブジェクト、概要 544 共有コンポーネント 457 315 ク クライアント アプリケーション COM/COM+ の構築 601 EAServer の構築 519 同期 207 配布 551 クライアント管理のトランザクション 538 クライアント コンピュータの環境設定の配布 726 クライアント領域 MDI アプリケーション 73 サイズ変更 84 クラス、PBDOM の概要 244 グラフ PowerScript 関数 276 Render 3D プロパティ 276 ウィンドウ内での系列の作成 277 ウィンドウ内でのデータの作成 276 ウィンドウ内でのデータ ポイントの作成 277 実行中の修正 279 情報取得 282, 285 データの保存 283 データ表示の修正 283 785 索引 データ プロパティ 281 内部表現 280 プロパティ 280 グラフ関数 データ アクセス 281 データについての情報取得 282, 285 データの保存 283 データ表示の修正 283 グラフでのデータ保存 283 グラフの grAxis サブオブジェクト 280 グラフの grDispAttr サブオブジェクト 280 クリップボードのアプリケーションでの使い方 グローバル外部関数 422 グローバル変数 ウィンドウ 91 名前の重複 32 グローバル変数型、デフォルト 195 363 ケ 継承 階層構造 95 サービス オブジェクト 15 先祖オブジェクトの仮想関数 16 継承したオブジェクト間の多相性 19 系列、グラフ ウィンドウ内での作成 277 ウィンドウ内での識別 278 ウィンドウ内でのデータ ポイントの追加 277 結果集合 EAServer での受け渡し 485 PowerBuilder によるストアド プロシージャの処理 190, 200 トランザクション サーバ環境での受け渡し 579 言語と OLE オートメーション 395 検証、EAServer コンポーネント 492 コ 更新、EAServer コンポーネント内 480 更新ステータス、分散アプリケーション内 項目の追加 786 480 リストビューへの 153 リストボックスへの 144, 149, 150 コード セット EAServer Manager での変更 518 Management Console での変更 518 国際化アプリケーション 設計 657 コロン(スコープ演算子) 32 コンテキスト情報 434 コンテキスト情報サービス 434 コントロール 種類 364 タブ ページ 104 ツリービュー 117 ドラッグ アンド ドロップ 161 ドロップダウン ピクチャ リストボックス 146, 149, 150 ドロップダウン リストボックス 149 ピクチャ リストボックス 144, 145, 146 マイクロヘルプの使い方 78 リストビュー 152, 154, 155, 157 リストボックス 144 コンパイル オプション 710 スクリプトの記述 53 チェックされない OLE 構文 381 コンポーネント オブジェクト モデル(COM を参 照) コンポーネント管理のトランザクション 538 サ サーバ、MobiLink 同期 204 サーバ データベース、環境設定 726 サーバ アプリケーション、OLE 347 サーバ コンピュータ、環境設定 726 サービス オブジェクト 434 再利用可能な動的ライブラリ 714 削除 リストビュー ピクチャ 157 リストボックス ピクチャ 146 サブスクリプション 概要 207 PowerBuilder 索引 複数サーバとの同期 236 サブルーチン、データベース ストアド プロシー ジャ呼び出しのための使い方 193 参照 EAServer コンポーネントでの引数渡し 489 オブジェクトの動的な参照 714, 717 引数の受け渡し 35, 383 リソースの動的な参照 716 サンプル、コード 5 シ 視覚障害 666 システム例外ハンドラ 547 子孫オブジェクト エンティティの参照 97 概要 36 定義 191 実行 アプリケーションの起動 724 グラフへのアクセス 279 データ パイプライン 328 トレース機能 725 ライブラリ リスト 712 実行アプリケーションのトレース 725 実行ファイル 概要 711 作成 723 スタンドアロン 719 テスト 724 含まれるリソース 716 例 719 [自動的なデマケーション / 不活性化]設定 471 従属関係 23 障害者差別禁止法 669 ショートカット キー、MDI アプリケーション 89 初期設定ファイル アクセス 685 トランザクション オブジェクト値の読み込み 182 ジョブ、印刷 679 処理効率 アプリケーション テクニック 概要 30, 389 リソースの配布モデルの影響 714, 716 ス スクリプト OLE オートメーション 396 OLE オブジェクトの操作 380 OLE カラムのアクティブ化 399 グラフの修正 279 同期 206 ブラウザからの OLE 情報 401 リストビュー カラム値の設定 159 リストビュー カラムの追加 158 リストビュー項目の削除 157 リストビュー項目の追加 153 リストビュー ピクチャの削除 157 リストビュー ピクチャの追加 155 リストボックス項目の追加 145, 149, 150 リストボックス ピクチャの追加 146, 151 スコープ演算子 32 スタンドアロン実行ファイル 719 ステートメント、WordBasic 内(OLE) 384 ストアド プロシージャ、アプリケーションでの呼 び出し DBMS 機能のサポート 199 ORACLE7 の例 192 ORACLE の例 199 SQLCA に対するデフォルトのグローバル変数 の型の指定 195 アプリケーションのスクリプト記述 197 外部関数としての宣言 193 概要 190 基本的な手順 191 結果集合、PowerBuilder による処理 190, 200 標準クラス ユーザ オブジェクトの定義 192 ユーザ オブジェクトの保存 195 ストアド プロシージャ呼び出しでサポートされる DBMS 機能 199 ストリーム モード 53 スペル チェック(リッチテキスト エディット コ ントロール) 302 787 索引 セ 静的呼び出し 22 接続 EAServer 521 EJB サーバ 621 OLE オブジェクト 371 トランザクション オブジェクト 183 複数のデータベースの使用 185 接続オブジェクト ウィザード 523 接続キャッシュ プロキシの使い方 477 利点 475 宣言 外部関数 422 定数 30 トランザクション オブジェクト 185 先祖オブジェクト ウィンドウ 95 概要 36 関数とイベントの呼び出し 32 先祖スクリプトからの戻り値 33 タブ ラベル 106 定義 99 ドット表記 107 表示形態 104 プロパティ シート 104 タブ ページ イベント 114 埋め込み 100 オブジェクトの参照 111 親 107 削除 102 スクリプトで閉じる 111 スクリプトで開く 111 スクリプト内のコントロール 110 定義 99 独立したユーザ オブジェク 100 表示順序の変更 102 プロパティ シート 104 タブ ページの配列の管理 111 チ 聴覚障害 ソ 挿入可能 OLE オブジェクト 666 348 ツ タ ターゲットとなるコントロールのドラッグ アンド ド ロップ 161 代名詞 27 多相性(ポリモフィズム) 18 タブ コントロール Control プロパティ配列 111 CreateOnDemand プロパティ 113 イベント 114 親 107 概要 99 タブの位置 105 タブ ページの管理 102 タブ ページの種類 100 788 通信エラー、処理 546 ツールバー、MDI アプリケーション内 ツリービュー コントロール 概要 117 例 139 74 テ 定数 30 データ ウィンドウのグラフとの関連付け 276 ウィンドウのグラフに追加 277 グラフでの保存 283 データ ソース間のパイプライン処理 315 PowerBuilder 索引 同期 203 データウィンドウ、OLE OLE オブジェクトの関数 397 オートメーション 396, 398 データウィンドウ Web コントロール ActiveX 636 データウィンドウ オブジェクト 概要 287 動的な参照 714, 717 ドット表記 29 リソース ファイルへの組み込み 719 データウィンドウ関数 GetChanges 480 GetFullState 480 GetStateStatus 480 SetChanges 480 SetFullState 480 データウィンドウ コントロール データ共有 306 データ パイプライン エラーの処理 322, 328, 335 リッチテキストと関数 291 データウィンドウ式、最適化 38 データウィンドウの同期 480 データ型 Any 388 COM/COM+ 575 EAServer 526 XML 646 ウィンドウ 95 ウィンドウの定義 91 データ共有、リッチテキスト エディット コント ロール 306 データストア オブジェクト EAServer コンポーネントの使い方 474 ツリービューの値の設定 140 標準クラス ユーザ オブジェクト 24 データ ソース SQL Anywhere 752 配布 752 データ ソース間のデータ転送 315 データ パイプライン PowerBuilder 開発環境での使い方 316 SQLSTATE エラー番号の省略 336 アプリケーション テクニック アプリケーションでの使い方 316 エラー行の修復 336 エラー行の処理 335 エラー行の廃棄 338 エラー処理のデータウィンドウ コントロール 322, 328, 335 概要 316 行解析結果の表示 330 更新のコミット 334 実行時の後処理 339 実行時の処理の準備 325 実行の開始 328 実行の監視 330 実行のキャンセル 332 制御用のウィンドウの提供 321 特性の指定 317 パイプライン処理の指定 325 ユーザ オブジェクトのサポート 320, 325, 330, 339 例 315 データ パイプラインの転送先テーブル 317 データ パイプラインの転送元テーブル 317 データ パイプライン ペインタ 対話的な使い方 316 データ パイプラインの定義 316, 317 データ パイプラインへのコミット 317, 334 データベース COM コンポーネントからのアクセス 578 EAServer コンポーネントからのアクセス 474 OLE データの保存 365 アプリケーションでのストアド プロシージャ の呼び出し 190 インタフェースのプロパティ(トランザクショ ン オブジェクト) 177 環境設定 726 接続 183 接続解除 184 データ パイプラインの転送先 325, 339 データ パイプラインの転送元 325, 339 データベース間のテーブルの移行 315 トランザクションのプール 189 複数のデータベースへの接続 185 789 索引 プロファイル、接続プロパティ 174 リッチテキスト 288 データベース インタフェース インストール 726 環境設定 726 プロパティ(トランザクション オブジェクト) 177 データベースからの接続解除 184 データベース ストアド プロシージャ、データ パイプ ラインの転送元 317 データベース トランザクションのプール 189 データベース内またはデータベース間のテーブルの 移行 315 テーブル データ パイプラインの転送先 317 データ パイプラインの転送元 317 データベース内またはデータベース間の移行 315 テキスト ファイル 関数 53 読み書き 53 デザイン、ユーザ インタフェース 664 デバッグ 実行のトレース 725 実行ファイル 724 デフォルト以外のトランザクション オブジェクト SQL 文での指定 186 値の設定 185 概要 185 作成 185 破棄 187 デフォルト以外のトランザクション オブジェクトの 作成 185 デフォルト グローバル変数型 195 デフォルトのトランザクション オブジェクト (SQLCA) 174, 180 電子メール システム、アクセス 417 ト 同期(MobiLink 同期を参照) 同期サーバ 204 統合データベース 204 790 同時実行コンポーネント プロパティ 460 動的 SQL でのエラー処理 188 動的関数呼び出し 37 動的参照 オブジェクト 714, 717 リソース 716 動的呼び出し 20 動的ライブラリ 概要 712 独立関係 23 独立したオブジェクト間の多相性 18 ドット表記 概要 25 ストアド プロシージャ呼び出しのための PowerScript の使い方 197 ドラッグ アンド ドロップ アイコンの指定 163 関数 164 自動ドラッグ モード 161 使い方 161 ドラッグ コントロールの識別 164 プロパティ 162 トランザクション オブジェクト SQLCA 174, 180 値の設定 181 エラー処理 188 外部ファイルからの値の読み込み 182 概要 173 組み込みシステム型 193 指定 186 ストアド プロシージャ呼び出しのための使い方 190 デフォルト 174, 180 デフォルト以外、SQL 文での指定 186 デフォルト以外、作成 185 デフォルト以外、トランザクション オブジェク トの値の設定 185 デフォルト以外、破棄 187 複数のデータベース接続 185 リモート プロシージャの呼び出しのテクニック 190 トランザクション オブジェクトのインスタンス化 185 PowerBuilder 索引 トランザクション オブジェクトのプロパティ 値の設定 181, 185 外部ファイルからの値の読み込み 182 概要 174 記述 174 ストアド プロシージャの呼び出し 197 データベース インタフェースごとのリスト 177 トランザクション コンテキスト サービス 582 トランザクション処理 COM+ のサポート 582 COM クライアントからの制御 604 EAServer 467 SQL 文 179 エラー処理 188 概要 178 データベース トランザクションのプール 189 トランザクション プール 189 ドロップダウン ピクチャ リストボックス コント ロール 概要 149 項目の追加 149 ピクチャの削除 146 ピクチャの追加 150 例 147 ドロップダウン リストボックス コントロール 概要 149 項目の追加 149 例 147 ナ 名前の修飾 25 ニ 入力条件則、リッチテキスト 入力フィールド 概要 304 スクリプト 305 アプリケーション テクニック 290 テキストへの挿入 編集 314 認知障害 667 288 ネ ネットワーク、ユーザ アクセスの設定 726 ハ バイナリ ファイルの読み書き 53 配布 EAServer コンポーネント 516 概要 709 クライアント アプリケーション 551 ランタイム パッケージャ 737 配布 DLL、PowerBuilder 726 パイプライン エラー データウィンドウ 335 パイプライン オブジェクト データ パイプライン ペインタでの定義 317 配布 328 パイプライン処理の指定 325 配列 EAServer コンポーネントでの受け渡し 489 ウィンドウ インスタンスの 94 配列の 649 パッケージ、COM+ 589 パッケージ化アプリケーションのモデル 概要 719 作成方法 723 テスト 724 パフォーマンス 概要 38 コンパイル時間の短縮 53 変数のスコープ 53 パブリケーション 207, 231 パブリック アクセス 30 汎用的スクリプト記述テクニック 108 791 索引 ヒ 引数 EAServer コンポーネントでの受け渡し 489 OLE 383 受け渡し方法 35 引数の受け渡し EAServer 489 OLE 383 概要 35 ピクチャ、リソースとしての配布 715 ピクチャの高さ 145, 150, 154, 155 ピクチャの追加 リストビューへの 154, 155 リストボックスへの 145, 146, 150 ピクチャの幅 145, 150, 154, 155 ピクチャ マスク 145, 150, 154, 155 ピクチャ リストボックス コントロール 概要 144 項目の追加 144, 145 ピクチャの削除 146 例 147 ビジネス ロジック、概要 445 非同期処理 EAServer 542 描画オブジェクト、印刷 683 表記規則 xviii 標準クラス データ型の選択 ダイアログボックス 193 フ ファイアウォール設定 641 ファイル DLL 712 PBD 712 PBR 716 外部、ファイルからのトランザクション オブジェ クト値の読み込み 182 実行時 747 実行ファイル 711 リソース 715 リッチテキスト 294 ファイル ポインタ 54 792 フォーム様式の作成 690 フォント、定義 682 複数データベース、アクセス 185 プライベート アクセス 30 プロキシ サーバ 641 プロキシ オブジェクト Web サービスに対する生成 644 生成 524, 525 プロジェクト オブジェクト、作成 723 プロジェクト ペインタ 配布アプリケーションのパッケージ化における 使い方 723 プロテクト アクセス 30 プロパティ データ パイプライン 320 ドラッグ アンド ドロップ 162 プロパティ、トランザクション オブジェクト 値の設定 181, 185 外部ファイルからの値の読み込み 182 概要 174 記述 174 ストアド プロシージャの呼び出し 197 データベース インタフェースごとのリスト 177 プロパティの変更通知 393 プロファイル、データベース 174 分散アプリケーション アーキテクチャ 445 エラー処理 546 データストア 474 データベース アクセス 474 データベース更新の実行 480 ヘ ページ余白(リッチテキスト エディット コント ロール) 309 ヘルプ PBUSER115.HLP の名前変更 169 UserHelpFile 169 UserHelpPrefix 169 開発者への提供 167 新規ユーザ ヘルプ ファイル名の指定 169 PowerBuilder 索引 デフォルトの接頭辞の変更 169 ユーザ定義関数のための作成 168 変数 ウィンドウ型の変数 95 型のない 388 宣言、ウィンドウの型 93 デフォルトのグローバル変数 195 トランザクション オブジェクトのための宣言 185 パフォーマンスへの影響 53 変数のアクセサ メソッド(COM オブジェクト イ ンタフェースへの追加) 574 変数の型プロパティ ページ(アプリケーション ペインタ プロパティ シート) 196 ホ ポインタ、リソースとして配布 715 ポイント アンド クリック、グラフ内 283 ポンド記号、EAServer コンポーネント 518 マ マイクロヘルプの MDI アプリケーションでの使 い方 77 マシン コード 710 メ メール関連のオブジェクトと構造体 417 メール システム、アクセス 417 メール マージのリッチテキストの例 306 メッセージ オブジェクト 概要 432 プロパティ 432 メニュー MDI アプリケーション 73, 74 OLE 359 マージ 359 メニュー項目に対するマイクロヘルプの提供 78 アプリケーション テクニック メニュー ペインタでのマイクロヘルプの提供 メモリの管理 49 78 ユ ユーザ、MobiLink 207, 234 ユーザ インタフェース、国際的な配布のためのデ ザイン 664 ユーザ オブジェクト COM+ コンポーネント 567 Control プロパティ配列 112 EAServer コンポーネント 453 概要 99 構造体としての使い方 24 実行中の型の選択 37 データ パイプライン処理のサポートのための 使い方 325, 330, 339 データベース ストアド プロシージャ呼び出し のための使い方 192 ユーザ オブジェクトの保存 ダイアログボックス 195 ユーザ オブジェクト ペインタ カスタム トランザクション オブジェクトを定 義する使い方 192 データ パイプライン処理をサポートするユー ザ オブジェクトの定義 330 ユーザ オブジェクトを構造体として使用する構造 体オブジェクト 24 ユーザ定義関数 上書き 19 状況依存ヘルプの作成 168 多重定義 19 ユーザ定義関数の上書き 19, 35 ユーザ定義関数の多重定義 COM ではサポートされない 576 概要 19, 20 ユーザ ヘルプ ボタン 167 ユーティリティ関数 429 ユーロ記号、EAServer コンポーネント 518 793 索引 ヨ 読み込み専用、引数の受け渡し 35 ラ ライブラリ、動的 712 ライブラリ探索パス、実行アプリケーションでの使 用 712 ライン モード 53 ランタイム パッケージャ 737 リ リストビュー項目 インデックス 152 オーバーレイ ピクチャ インデックス 状態ピクチャ インデックス 152 ピクチャ インデックス 152 ラベル 152 リストビュー コントロール イメージ リスト 154 概要 152 カラム値の設定 159 カラムの設定 158 カラムの追加 158 項目 152 項目の追加 153 詳細表示 158 ピクチャの削除 157 ピクチャの追加 154, 155 リストボックス コントロール 概要 144 項目の追加 144 例 147 リソース DLL ファイル 714, 716 PBD ファイル 714, 716 概要 715 個別のファイルでの配布 716 実行ファイル 712, 716 テスト 724 794 152 動的参照 716 パッケージ化の手順 723 リソース ファイルでの命名 717 例 719 リソース ファイル、作成 717 リソース ファイルでのリソースの探索パス 719 リッチテキスト オブジェクトと書式設定 313 概要 287 作成 288 実装 287 選択 307 ツールバー 293 データベース 294 データベースへの保存 288 入力条件則 290 入力フィールド 288 日付フィールド 305 ページ番号 305 メール マージ例 306 ユーザ操作 311 用途 287 ワード ラップ 292 リッチテキスト エディット コントロール FileExists イベント 297 LoseFocus イベント 296, 308 Modified プロパティとイベント 297 印刷 310 オブジェクト 304, 313 概要 292 書式設定 304 スクロール 307 スペル チェック 302 設定 292 選択 307 挿入ポイント 307 タブ順序 308 ツールバー 293 データ ソース 306 データベースにテキストを保存する例 295 テキストの挿入 293 入力フィールド 304 PowerBuilder 索引 日付フィールド 305 ファイル 294, 296 ファイルを開く例 298 フォーカス 308 プレビュー 309 ページ番号 305 ページ余白 309 変更の取り消し 293 編集キー 314 保存 296 保存の例 298 メール マージ例 306 ワード ラップ 292 リッチテキストが使えるワード プロセッサ 288 リッチテキスト 提示様式 474 リッチテキスト提示様式 新しい行 290 スクリプト 291 スクロール 289 入力条件則エラー 290 編集キー 314 ユーザ操作 290 リモート ストアド プロシージャ ダイアログボッ クス 194 リモート データベース 204 リモート プロシージャの呼び出しのテクニック DBMS 機能のサポート 199 SQLCA に対するデフォルトのグローバル変数 の型の指定 195 アプリケーションのスクリプト記述 197 外部関数としてのストアド プロシージャの宣 言 193 概要 191 ストアド プロシージャの結果集合 190, 200 標準クラス ユーザ オブジェクトの定義 192 ユーザ オブジェクトの保存 195 Web サービス メソッド レジストリ クラス情報 400 情報の格納 685 651 ロ ローカライゼーション 657 ローカル外部関数 423 ログ、EAServer 509 論理的な作業単位 178 レ 例外、処理 39 EAServer クライアント 546 EJB クライアント 627 アプリケーション テクニック 795 索引 796 PowerBuilder
© Copyright 2024 Paperzz