アプリケーション テクニック PowerBuilder® 10.2.1 C2 DOCUMENT ID: DC37774-01-1021-01 LAST REVISED: July 2007 Copyright © 1991-2007 by Sybase, Inc. All rights reserved. 本書に記載されているソフトウェアは、Sybase ライセンス契約に基づいて Sybase, Inc. が提供し、かかる契約の条項に従う 場合にのみ使用が許諾されます。 本書に記載されている内容は、Sybase, Inc. およびその関連会社の書面による許可なく、いかなる形態、または手段、電子 的、機械的、手作業、光学的およびその他にかかわらず、複製、転載および翻訳を禁じます。 Sybase, Sybase(ロ ゴ), AccelaTrade, ADA Workbench, Adaptable Windowing Environment, Adaptive Component Architecture, Adaptive Server, Adaptive Server Anywhere, Adaptive Server Enterprise, Adaptive Server Enterprise Monitor, Adaptive Server Enterprise Replication, Adaptive Server Everywhere, Adaptive Server IQ, Adaptive Warehouse, Anywhere Studio, Application Manager, AppModeler, APT Workbench, APT-Build, APT-Edit, APT-Execute, APT-Translator, APT-Library, AvantGo, AvantGo Application Alerts, AvantGo Mobile Delivery, AvantGo Mobile Document Viewer, AvantGo Mobile Inspection, AvantGo Mobile Marketing Channel, AvantGo Mobile Pharma, AvantGo Mobile Sales, AvantGo Pylon, AvantGo Pylon Application Server, AvantGo Pylon Conduit, AvantGo Pylon PIM Server, AvantGo Pylon Pro, Backup Server, BizTracker, ClearConnect, Client-Library, Client Services, Convoy/DM, Copernicus, Data Pipeline, Data Workbench, DataArchitect, Database Analyzer, DataExpress, DataServer, DataWindow, DB-Library, dbQueue, Developers Workbench, Direct Connect Anywhere, DirectConnect, Distribution Director, e-ADK, E-Anywhere, e-Biz Impact, e-Biz Integrator, E-Whatever, EC Gateway, ECMAP, ECRTP, eFulfillment Accelerator, Embedded SQL, EMS, Enterprise Application Studio, Enterprise Client/Server, Enterprise Connect, Enterprise Data Studio, Enterprise Manager, Enterprise SQL Server Manager, Enterprise Work Architecture, Enterprise Work Designer, Enterprise Work Modeler, eProcurement Accelerator, EWA, Financial Fusion, Financial Fusion Server, Gateway Manager, GlobalFIX, iAnywhere, ImpactNow, Industry Warehouse Studio, InfoMaker, Information Anywhere, Information Everywhere, InformationConnect, InternetBuilder, iScript, Jaguar CTS, jConnect for JDBC, Mail Anywhere Studio, MainframeConnect, Maintenance Express, Manage Anywhere Studio, M-Business Channel, M-Business Network, M-Business Server, MDI Access Server, MDI Database Gateway, media.splash, MetaWorks, My AvantGo, My AvantGo Media Channel, My AvantGo Mobile Marketing, MySupport, Net-Gateway, Net-Library, New Era of Networks, ObjectConnect, ObjectCycle, OmniConnect, OmniSQL Access Module, OmniSQL Toolkit, Open Biz, Open Client, Open ClientConnect, Open Client/Server, Open Client/Server Interfaces, Open Gateway, Open Server, Open ServerConnect, Open Solutions, Optima++, Orchestration Studio, PB-Gen, PC APT Execute, PC DB-Net, PC Net Library, PocketBuilder, Pocket PowerBuilder, Power++, power.stop, PowerAMC, PowerBuilder, PowerBuilder Foundation Class Library, PowerDesigner, PowerDimensions, PowerDynamo, PowerJ, PowerScript, PowerSite, PowerSocket, Powersoft, PowerStage, PowerStudio, PowerTips, Powersoft Portfolio, Powersoft Professional, PowerWare Desktop, PowerWare Enterprise, ProcessAnalyst, Rapport, RepConnector, Replication Agent, Replication Driver, Replication Server, Replication Server Manager, Replication Toolkit, Report-Execute, Report Workbench, Resource Manager, RW-DisplayLib, RW-Library, S-Designor, SDF, Secure SQL Server, Secure SQL Toolset, Security Guardian, SKILS, smart.partners, smart.parts, smart.script, SQL Advantage, SQL Anywhere, SQL Anywhere Studio, SQL Code Checker, SQL Debug, SQL Edit, SQL Edit/TPU, SQL Everywhere, SQL Modeler, SQL Remote, SQL Server, SQL Server Manager, SQL SMART, SQL Toolset, SQL Server/CFT, SQL Server/DBM, SQL Server SNMP SubAgent, SQL Station, SQLJ, STEP, SupportNow, S.W.I.F.T. Message Format Libraries, Sybase Central, Sybase Client/Server Interfaces, Sybase Financial Server, Sybase Gateways, Sybase MPP, Sybase SQL Desktop, Sybase SQL Lifecycle, Sybase SQL Workgroup, Sybase User Workbench, SybaseWare, Syber Financial, SyberAssist, SyBooks, System 10, System 11, System XI(ロゴ), SystemTools, Tabular Data Stream, TotalFix, TradeForce, TransactSQL, Translation Toolkit, UltraLite, UltraLite.NET, UNIBOM, Unilib, Uninull, Unisep, Unistring, URK Runtime Kit for UniCode, VisualWriter, VQL, WarehouseArchitect, Warehouse Control Center, Warehouse Studio, Warehouse WORKS, Watcom, Watcom SQL, Watcom SQL Server, Web Deployment Kit, Web.PB, Web.SQL, WebSights, WebViewer, WorkGroup SQL Server, XA-Library, XAServer および XP Server は Sybase, Inc の登録商標です。 Unicode および Unicode のロゴは Unicode, Inc. の登録商標です。 本書で使用される会社名および製品名はそれぞれの会社の商標および登録商標です。 本書に記載されている内容は、将来予告なしに変更することがあります。また、本ソフトウェアおよび説明書を使用した ことによる損害、または第三者からのいかなる請求についても、サイベース株式会社、その親会社である米国法人 Sybase, Inc. またはその関連会社は、一切の責任を負わないものとします。 目次 本書について ................................................................................................................................ xix 第1部 アプリケーション テクニックの学習 第1章 サンプル アプリケーションの使い方.......................... サンプル アプリケーションについて............................................... Web サイトのサンプル ............................................................. CD 内のサンプル....................................................................... サンプル アプリケーションのインストール .................................... サンプル アプリケーションを開く .................................................. Code Examples アプリケーションの使い方.................................... サンプルの参照 ......................................................................... サンプルの検索 ......................................................................... サンプルの実行と調査 .............................................................. 3 3 4 4 5 5 6 6 7 8 第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 88 ウィンドウ インスタンスの管理 ............................. ウィンドウ インスタンスについて ................................................ ウィンドウ インスタンスの宣言.................................................... ウィンドウ配列の使い方................................................................ 子孫オブジェクトのエンティティの参照 ...................................... 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 同期オブジェクトの使い方.................................... ASA MobiLink 同期ウィザードの使い方 ............................... 生成されるもの ..................................................................... アプリケーションでの同期オブジェクトの使い方 ............... vi 203 203 208 208 210 211 PowerBuilder 目次 同期オプション ウィンドウの使い方.................................... リモート マシンでの同期の実行時要件 ................................ ウィザードを使用する準備 ................................................... 統合データベースの準備.............................................................. 接続イベント......................................................................... テーブル イベント................................................................. Sybase Central でのスクリプトおよびユーザに対する作業 リモート データベースの作成 ..................................................... パブリケーションの作成と変更 ............................................ Mobile Link ユーザの作成...................................................... サブスクリプションの追加 ................................................... 同期のテクニック ........................................................................ 215 217 220 220 221 223 225 228 229 231 233 234 第 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............................... ライブラリ探索パスへの pbdom100.pbd の追加......................... PBDOM の使い方......................................................................... XML の検証 ........................................................................... XML から XML ドキュメントの作成 ..................................... 最初からの XML ドキュメントの作成................................... ノード データへのアクセス .................................................. ノード ツリー階層の操作...................................................... PBDOM 例外の処理 ..................................................................... XML 名前空間 .............................................................................. PBDOM_ATTRIBUTE の名前および名前空間の設定 ........... 237 237 238 239 240 241 243 244 244 247 250 250 251 254 254 255 256 257 258 258 260 261 263 264 265 266 第 15 章 グラフの操作 ............................................ 271 グラフの使い方 ............................................................................ 271 コードにおけるグラフ コントロールの操作 ......................... 272 アプリケーション テクニック vii 目次 グラフへのデータ表示 ................................................................. グラフのプロパティの修正 .......................................................... グラフ要素の表示.................................................................. グラフ要素の参照.................................................................. データのプロパティへのアクセス ............................................... データの情報の取得 .............................................................. グラフのデータの保存 .......................................................... 色や模様、そのほかのデータの修正..................................... ポイント アンド クリックの使い方 ............................................. 273 275 276 276 277 278 279 279 279 第 16 章 リッチテキストの作成方法 ................................. 283 アプリケーションにおけるリッチテキストの使い方 .................. 283 リッチテキストの作成 .......................................................... 284 リッチテキスト データウィンドウ オブジェクトの使い方 ......... 284 リッチテキスト エディット コントロールの使い方 .................... 287 エンド ユーザに制御権を与える ........................................... 287 リッチテキスト エディット コントロールのためのテキスト 289 リッチテキストの書式設定 ................................................... 297 入力フィールド ..................................................................... 298 データベースのデータの使い方 ............................................ 300 リッチテキスト エディット コントロールにおけるカーソル位置 301 プレビューと印刷.................................................................. 302 リッチテキストとエンド ユーザ.................................................. 305 第 17 章 データ ソース間のデータ転送 .............................. データ パイプラインについて ..................................................... 必要なオブジェクトの作成 .......................................................... パイプライン オブジェクトの作成 ....................................... ユーザ オブジェクトの作成 .................................................. ウィンドウの作成.................................................................. パイプライン処理の前準備 .......................................................... パイプライン処理の開始.............................................................. パイプライン処理のモニタ ................................................... パイプライン処理のキャンセル ............................................ 更新処理のコミット .............................................................. エラー行の処理 ............................................................................ エラー行の修復 ..................................................................... エラー行の破棄 ..................................................................... パイプラインの後処理 ................................................................. 第5部 プログラム アクセス テクニック viii 309 310 311 311 314 315 319 322 324 326 328 329 330 332 333 PowerBuilder 目次 第 18 章 DDE の使い方 ........................................... 337 DDE について .............................................................................. 337 DDE 関数とイベント ................................................................... 338 第 19 章 アプリケーションにおける OLE の使い方 ................... 341 PowerBuilder における OLE のサポート ..................................... 341 ウィンドウにおける OLE コントロール ...................................... 343 OLE コントロールと挿入可能なオブジェクト ............................ 346 OLE コントロールの設定...................................................... 346 リンクと埋め込み.................................................................. 350 オフサイト アクティブ化とインプレース アクティブ化 ...... 352 インプレース アクティブ化に対するメニュー ..................... 353 OLE コントロール上でのオブジェクトの修正 ..................... 355 OLE カスタム コントロール ........................................................ 360 OLE カスタム コントロールの設定 ...................................... 360 ActiveX コントロールのプログラミング............................... 362 プログラム可能な OLE オブジェクト.......................................... 364 OLEObject オブジェクト型................................................... 364 OLEControl、OLECustomControl、OLEObject データ型の代入 368 オートメーション.................................................................. 369 スクリプトにおける OLE オブジェクト ...................................... 374 オートメーションのインタフェース..................................... 375 オートメーションと Any 型 .................................................. 382 効率的な OLEObjects 変数の使い方 ..................................... 383 エラー処理 ............................................................................ 384 ホット リンクの作成 ............................................................. 387 OLE サーバで使用できる言語............................................... 389 OLE オブジェクトへの低レベル アクセス............................ 390 データウィンドウ オブジェクトにおける OLE オブジェクト 390 オブジェクト ブラウザでの OLE 情報......................................... 394 OLE オブジェクトの高度な操作 .................................................. 396 OLE ストレージの構造 ......................................................... 397 ストレージとストリームに対するオブジェクト データ型 ... 398 ストレージを開く、保存する................................................ 399 ストリームを開く.................................................................. 405 ストレージを使用する際のストラテジ ................................. 410 第 20 章 PowerBuilder のランタイム オートメーション サーバ ........ 411 ランタイム オートメーション サーバの使い方 ........................... 412 ランタイム オートメーションの用途.................................... 413 3 つのアクセス方法............................................................... 414 ユーザ オブジェクトをオートメーション サーバとして使用する方法 アプリケーション テクニック ix 目次 417 サーバとなるクラス ユーザ オブジェクトの作成................. 417 ユーザ オブジェクトのランタイム ライブラリの構築.......... 418 ユーザ オブジェクトの登録 .................................................. 419 ユーザ オブジェクトにアクセスするクライアント アプリケー ションのコードの記述.................................................... 420 PowerBuilder をオートメーション サーバとして使用する方法 .. 422 アクセスするユーザ オブジェクトの作成............................. 422 ランタイム ライブラリの構築............................................... 423 PowerBuilder とユーザ オブジェクトにアクセスするクライアン ト アプリケーションのコードの記述 ............................. 424 名前付きサーバの作成と使用 ...................................................... 427 ユーザ オブジェクトとレジストリについての詳細 ..................... 429 識別子について ..................................................................... 429 オブジェクトに関する情報の登録場所 ................................. 430 レジストリ情報の作成 .......................................................... 433 オートメーション サーバを使用するアプリケーションの配布 ... 437 複数のバージョンとアップデート ........................................ 438 オートメーション サーバ リファレンス ...................................... 439 PowerBuilder.Application サーバ オブジェクト........................... 439 CreateObject 関数........................................................................ 442 GenerateGUID 関数 ..................................................................... 444 GenerateRegFile 関数.................................................................. 447 GenerateTypeLib 関数 ................................................................. 450 例外コード ................................................................................... 454 レジストリ更新ファイルのサンプル............................................ 455 第 21 章 MAPI の使い方 ........................................... 457 MAPI について ............................................................................. 457 MAPI の使い方 ............................................................................. 458 第 22 章 外部関数とそのほかの拡張処理機能の使い方 ................. 外部関数の使い方 ........................................................................ 外部関数の宣言 ..................................................................... 外部関数の宣言例.................................................................. 引数の受け渡し ..................................................................... UNIX での外部関数とプログラムの呼び出し........................ ユーティリティ関数の使い方 ...................................................... Windows メッセージの送信......................................................... メッセージ オブジェクト............................................................. メッセージ オブジェクトのプロパティ ................................ コンテキスト情報 ........................................................................ コンテキスト情報サービス ................................................... x 461 461 462 463 465 468 468 470 472 472 474 476 PowerBuilder 目次 コンテキスト キーワード サービス ...................................... CORBACurrent サービス ...................................................... エラー ロギング サービス..................................................... インターネット サービス...................................................... Secure Sockets Layer サービス............................................ トランザクション サーバ サービス ...................................... 479 481 481 481 485 485 第6部 分散アプリケーションの開発 第 23 章 PowerBuilder を使った分散アプリケーション開発 ........... 489 分散アプリケーションのアーキテクチャ .................................... 489 サーバのサポート ........................................................................ 490 第 24 章 EAServer コンポーネントの構築........................... EAServer コンポーネントの構築について .................................. ウィザードの使い方について................................................ 開発プロセスについて .......................................................... EAServer プロファイルの作成.............................................. 共有コンポーネントおよびサービス コンポーネントの操作....... 共有コンポーネントについて................................................ サービス コンポーネントについて ....................................... スレッド実行の問題とコンポーネントの種類 ...................... EAServer Thread Manager の使い方 .................................... インスタンス プーリングのサポート........................................... トランザクションのサポート ...................................................... EAServer コンポーネントからデータベースへのアクセス ......... 接続キャッシュの使い方....................................................... 検索操作の実行 ..................................................................... 更新の実行 ............................................................................ 結果集合の受け渡し .............................................................. コンポーネント インタフェースの定義 ....................................... 既存インタフェースの実装 .......................................................... 別のサーバ コンポーネントのメソッドの呼び出し ..................... コンポーネント プロパティへのアクセス ................................... Web サービスとしての NVO のエクスポーズ ............................. コンポーネントのテストとデバッグ............................................ ライブ編集 ............................................................................ リモート デバッグ................................................................. EAServer ログへのメッセージ出力 ...................................... データの印刷................................................................................ Solaris オペレーティング システムでの印刷........................ PDF への印刷........................................................................ アプリケーション テクニック 495 495 496 496 497 499 499 500 501 504 505 510 516 517 521 522 528 530 534 536 539 543 545 545 547 550 550 551 555 xi 目次 EAServer へのコンポーネントの配布.......................................... 556 第 25 章 EAServer クライアントの構築 ............................. EAServer クライアントの構築について ...................................... ウィザードの使い方について................................................ 開発プロセスについて .......................................................... EAServer への接続 ...................................................................... コードを手書きする方法....................................................... ウィザードを使用した接続オブジェクトの作成................... EAServer プロキシ オブジェクトの生成 ..................................... コンポーネント メソッドの呼び出し........................................... コンポーネント メソッドの呼び出し.................................... EJB コンポーネント メソッドの呼び出し ............................ インスタンスの破棄 .............................................................. JaguarORB オブジェクトの使い方 ............................................. String_To_Object を使用したインスタンス化 ...................... ネーミング サービス API によるインスタンス化 ................. クライアントとコンポーネントを区別するトランザクション .... サーバ メッセージ返送の要求 ..................................................... 例........................................................................................... エラー処理 ................................................................................... CORBA 例外の処理............................................................... Error イベントのスクリプト作成 .......................................... SystemError イベントのスクリプト作成 .............................. クライアント アプリケーションの配布 ....................................... 561 561 562 562 563 563 565 566 568 568 570 574 575 576 578 580 583 584 588 590 591 592 593 第 26 章 PowerBuilder クライアントでの SSL の使い方 .............. EAServer とのセキュアな接続 .................................................... PowerBuilder での SSL 接続........................................................ SSL プロパティ..................................................................... ORB プロパティ.................................................................... セキュアな接続の確立 ................................................................. SSL コールバックの使い方 ......................................................... セッション情報の取得 .......................................................... SSLCallback オブジェクトの実装 ........................................ SSLCallback オブジェクトの指定 ........................................ セッション セキュリティ情報の取得........................................... 595 595 597 597 600 601 604 604 605 607 608 第 27 章 COM/COM+ コンポーネントの構築 ......................... COM/COM+ コンポーネントの構築について .............................. ウィザードの使い方について................................................ 開発プロセスについて .......................................................... 609 609 610 611 xii PowerBuilder 目次 コンポーネント オブジェクト モデルについて ........................... 612 PowerBuilder COM サーバについて ..................................... 613 オートメーション サーバと PowerBuilder COM サーバの比較 613 コンポーネント インタフェースの定義 ....................................... 616 メソッドとデータ型 .............................................................. 616 コーディング上の制約 .......................................................... 618 ログ ファイルへのエラー記録............................................... 620 COM コンポーネントからデータベースへのアクセス ................ 620 結果集合の受け渡し .............................................................. 621 トランザクションのサポート ...................................................... 624 別のサーバ コンポーネントのメソッドの呼び出し ..................... 627 セキュリティ問題 ........................................................................ 628 プロジェクト ペインタでの COM/COM+ コンポーネントの構築 629 コンポーネントの自動登録 ................................................... 631 COM+ にコンポーネントを配布 ........................................... 631 カスタム インタフェースとデュアル インタフェースの選択 632 埋め込み PBD の設定............................................................ 632 PowerBuilder COM オブジェクトの実行 ..................................... 633 メモリの割り当て.................................................................. 633 PowerBuilder COM サーバの配布 ................................................ 634 COM 対応のアプリケーションによる PowerBuilder COM サーバ の使い方 ......................................................................... 634 クライアントから PowerBuilder COM サーバへのアクセス ....... 635 クライアントとしての Visual Basic...................................... 635 クライアントとしての C++................................................... 636 DCOM での PowerBuilder COM サーバとオブジェクトの使い方 639 第 28 章 COM/COM+ クライアントの構築........................... COM/COM+ クライアントの構築について.................................. COM サーバへの接続................................................................... COM コンポーネントとのやり取り ............................................. クライアントからのトランザクション制御................................. 第7部 WEB アプリケーションの開発 第 29 章 EJB クライアントの構築 .................................. EJB クライアントの構築について............................................... ライブラリ探索パスへの pbejbclient100.pbd の追加................... EJB プロキシ オブジェクトの生成.............................................. EJB プロキシ プロジェクトの使い方 ................................... ejb2pb100 ツールの使い方 ................................................... アプリケーション テクニック 643 643 644 645 646 651 651 653 655 655 659 xiii 目次 生成されたプロキシの表示方法 ............................................ データ型マッピング .............................................................. Java VM の作成 ........................................................................... サーバへの接続 ............................................................................ コンポーネント メソッドの呼び出し........................................... 例外処理....................................................................................... クライアント管理のトランザクション ........................................ クライアントのデバッグ.............................................................. 660 662 663 666 667 672 674 675 第 30 章 PowerBuilder での Web アプリケーション開発 .............. Web アプリケーションの作成 ..................................................... Web サービス .............................................................................. Web ターゲット........................................................................... JSP ターゲット............................................................................ Web データウィンドウ ................................................................ データウィンドウ Web コントロール ActiveX ............................ データウィンドウ プラグイン ..................................................... PowerBuilder ウィンドウ プラグイン.......................................... PowerBuilder ウィンドウ ActiveX................................................ 677 677 678 678 679 680 681 682 682 683 第 31 章 Web サービス クライアントの構築.......................... Web サービスについて ................................................................ Web サービス クライアントの構築について........................ PBSoapClient100.pbd をライブラリ探索パスに追加する........... Web サービス プロキシ オブジェクトの生成.............................. SOAP サーバへの接続 ................................................................. Web サービス メソッドの起動 .................................................... Web サービスの作成.................................................................... 例外処理....................................................................................... UDDI 照会 API の使い方 .............................................................. 685 685 686 687 688 692 693 694 694 695 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 ............... 699 PowerBuilder ウィンドウ プラグインについて ........................... 700 プラグインとなるアプリケーションの種類 .......................... 702 PowerBuilder ウィンドウ プラグインの機能 ........................ 703 PowerBuilder ウィンドウ プラグインのインストールと設定...... 705 セキュリティ PowerBuilder ウィンドウ プラグインの使い方..... 706 PowerBuilder ウィンドウ プラグイン アプリケーションの開発と配布 707 PowerBuilder アプリケーションの作成 ....................................... 708 プラグイン アプリケーションの設計の選択 ......................... 709 ウィンドウ ペインタでの開始ウィンドウの定義.................. 712 xiv PowerBuilder 目次 PowerBuilder でのアプリーションのテスト ......................... 動的ライブラリの構築 .......................................................... HTML ページの作成 ..................................................................... Embed 要素の属性 ................................................................ サンプル ページ .................................................................... 追加属性を持つ Embed 要素................................................. サーバの設定................................................................................ ユーザのワークステーションの設定............................................ 必要なコンポーネント .......................................................... Web ページとプラグイン アプリケーションの表示 ............. 713 714 717 717 719 719 720 721 721 723 第 33 章 データウィンドウ プラグインの使い方 ...................... データウィンドウ プラグインについて ....................................... データウィンドウ プラグインの機能.................................... データウィンドウ プラグインのインストールと設定........... データウィンドウ プラグインの開発と配布 ......................... Powersoft レポート(PSR)の保存 ............................................ HTML ページの作成 ..................................................................... サンプル ページ .................................................................... Web サーバの設定 ....................................................................... ユーザのワークステーションの設定............................................ 725 725 726 728 728 729 730 731 732 733 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 ................ 735 PowerBuilder ウィンドウ ActiveX について ................................ 735 PowerBuilder ウィンドウ ActiveX で動作するアプリケーションの 種類 ................................................................................ 736 PowerBuilder ウィンドウ ActiveX の機能 ............................. 737 PowerBuilder ウィンドウ ActiveX のインストールと設定.... 738 PowerBuilder ウィンドウ ActiveX アプリケーションの開発と配布 739 PowerBuilder アプリケーションの作成 ....................................... 741 アプリケーションのデザイン................................................ 741 ウィンドウ ペインタでの開始ウィンドウの定義.................. 744 PowerBuilder でのアプリーションのテスト ......................... 745 HTML ページの作成 ..................................................................... 748 Object 要素の属性 ................................................................. 748 基本ページ ............................................................................ 751 クライアント側のスクリプト................................................ 752 PowerBuilder ウィンドウ ActiveX のイベント............................. 761 サーバの設定................................................................................ 762 ユーザのワークステーションの設定............................................ 763 Web ページと PowerBuilder ウィンドウ ActiveX アプリケーショ ンの表示 ......................................................................... 764 アプリケーション テクニック xv 目次 第8部 全般的なテクニック 第 35 章 アプリケーションの国際化 ................................. 国際化アプリケーションの開発................................................... Unicode の使い方......................................................................... Unicode について.................................................................. PowerBuilder での Unicode サポート ................................... ユーザ インタフェースの国際化.................................................. 第 36 章 利用しやすいアプリケーションの作成 ....................... 775 アクセシビリティの課題についての理解 .................................... 775 ソフトウェアおよび Web アプリケーションのアクセシビリティ要件 778 PowerBuilder を使用した利用しやすいソフトウェア アプリケーショ ンの作成 ......................................................................... 780 VPAT について ............................................................................ 784 製品のアクセシビリティのテスト ............................................... 784 第 37 章 印刷 ..................................................... 印刷関数....................................................................................... 印刷の基礎 ................................................................................... ジョブの印刷................................................................................ タブの使い方................................................................................ 印刷ジョブの停止 ........................................................................ 高度な印刷技法 ............................................................................ 787 787 789 789 790 791 792 第 38 章 初期設定ファイルと Windows レジストリの管理 ............. 環境設定とデフォルト設定について............................................ 初期設定ファイルでの情報の管理 ............................................... Windows レジストリでの情報の管理 .......................................... 795 795 796 797 第 39 章 InfoMaker の様式とアクションの作成 ....................... フォーム様式について ................................................................. フォーム様式でのデータウィンドウ コントロールの命名 .......... フォーム様式の作成および使用................................................... 既存の様式の修正 ........................................................................ 様式の基礎としてのウィンドウの識別 ................................. 最初からの様式の作成 ................................................................. 様式の完成 ................................................................................... セントラル データウィンドウ コントロールに対する作業 .. コントロールの追加 .............................................................. 799 799 803 804 805 806 807 808 808 809 xvi 767 767 768 768 769 774 PowerBuilder 目次 アクションの定義.................................................................. メニューの使い方.................................................................. スクリプトの記述.................................................................. その他の機能の追加 .............................................................. 様式の使い方................................................................................ カスタム フォーム様式を使用したフォームの作成 .............. フォーム様式の使用の管理 ................................................... 810 811 812 812 812 813 814 第9部 配布のテクニック 第 40 章 配布用アプリケーションのパッケージ化 .................... アプリケーションの配布について ............................................... アプリケーションの実行版の作成 ............................................... コンパイラの基本事項 .......................................................... パッケージに含まれる要素 ................................................... PowerBuilder リソース ファイルの作成................................ パッケージ化モデルの選択 ................................................... パッケージ化モデルの実装 ................................................... 実行アプリケーションのテスト ............................................ エンド ユーザへのアプリケーションの配布................................ インストール チェックリスト............................................... 配布済みアプリケーションの起動 ........................................ 第 41 章 アプリケーションとコンポーネントの配布 .................. 841 アプリケーション、コンポーネント、およびサポート ファイルの配布 842 PowerBuilder ランタイム パッケージャ ...................................... 846 PowerBuilder ランタイム ファイル ............................................. 849 データベース接続 ........................................................................ 851 ネイティブ データベース ドライバ ...................................... 852 ODBC データベース ドライバとサポート ファイル............. 853 OLE DB データベース プロバイダ........................................ 865 ADO.NET データベース インタフェース.............................. 867 JDBC データベース インタフェース .................................... 868 Java サポート .............................................................................. 869 PowerBuilder エクステンション .................................................. 871 PDF と XSL-FO のエクスポート ................................................. 872 GNU Ghostscript distiller の使い方........................................ 873 Apache FO プロセッサの使い方........................................... 874 データウィンドウ Web コントロール ActiveX ............................ 875 プラグインと PowerBuilder ウィンドウ ActiveX コントロール .. 876 EAServer 上の PowerBuilder コンポーネント ............................. 878 アプリケーション テクニック 819 819 820 820 821 828 830 833 835 836 836 840 xvii 目次 PowerBuilder COM サーバ........................................................... 881 PowerBuilder オートメーション サーバ ...................................... 882 OLE オートメーション オブジェクトのレジストリ情報の作成 .. 883 EAServer 上の Web データウィンドウ ....................................... 883 COM+ または IIS 上の Web データウィンドウ ........................... 885 Index ........................................................................................................................................... 887 xviii PowerBuilder 本書について 対象とする読者 このマニュアルは、PowerBuilder® によるクライアント / サーバ ア プリケーション、分散アプリケーション、または Web アプリケー ション開発に従事している開発者を対象としています。 このマニュアルの使い方 このマニュアルでは、PowerBuilder アプリケーションとコンポー ネントを作成および配布する際に使用するプログラミング テク ニックを紹介します。ここでは、要件に最も適した方法を選択す るためのアドバイスとともに、様々な一般的なアプリケーション 機能を実装するための技術を紹介しています。 PowerBuilder には、このマニュアルで紹介する問題、機能、およ びテクニックを具体例で示すサンプル アプリケーションが付属し ています。PowerBuilder でサンプル アプリケーションのコンポー ネントを調べて、コードのコメントを読み、実践的な作業例を通 じて学習した内容を実際に試してください。 サンプル アプリケーションの使い方については、第 1 章「サンプ ル アプリケーションの使い方」を参照してください。 関連マニュアル PowerBuilder のすべてのマニュアル一覧については、 『PowerBuilder 入門』マニュアルを参照してください。 そのほかの参考資料 製品に関するそのほかの詳細情報については、Sybase の テクニカ ル ライブラリ CD、およびテクニカル ライブラリ製品マニュアル Web サイト(英語)を参照してください。 • ソフトウェア付属の テクニカル ライブラリ CD には、製品マ ニュアルが含まれています。製品マニュアルは、PDF 形式に て提供しています。 テクニカル ライブラリ CD の使い方については、テクニカル ライブラリ CD 内の Readme.txt ファイルを参照してください。 • 表記規則 アプリケーション テクニック テクニカル ライブラリ製品マニュアルの Web サイト(英語) には、Product Manuals のサイト http://www.sybase.com/support/manuals/ からアクセスできます。 このマニュアルでは、以下の表記規則を使用します。 xix 例 説明 Retrieve と Update 左記のフォントが説明文で使用されている場合、 以下を表す • コマンド名、関数名、メソッド名 • キーワード(true、false、null など) • データ型(integer、char など) • データベース カラム名(emp_id、f_name など) 変数(variable)または ファイル名(filename) • ユーザ定義オブジェクト(dw_emp、w_main など) 説明文と構文説明で使用された場合、斜体フォ ントは次のいずれかを表す • 変数(myCounter など) • 代入が必要な入力テキスト部分 (pblname.pbd など) [ファイル|上書き保存] dw_1.Update() • ファイル名とパス名 メニュー名とメニュー項目は単純なテキスト で表示される。 「|」は、選択の移動のしかた メニューを示す。たとえば、 [ファイル|上書 き保存]は、 「[ファイル]メニューから[上書 き保存]を選択する」と同義 左記のフォントは以下のいずれかを示す • ダイアログボックスまたはコマンド ライン に入力する情報 • サンプル スクリプトの一部 • サンプル出力の一部 サポートについて xx 製品に同梱している「サポート ハンドブック」を参照してください。 PowerBuilder 第 1 部 アプリケーション テクニック の学習 第 1 部では、PowerBuilder に添付しているサンプル アプ リケーションの概要と、これらのサンプルを使ってプロ グラミング テクニックを学習する方法について説明しま す。 第 1 章 サンプル アプリケーションの使い方 この章について この章では、PowerBuilder サンプル アプリケーションの使い方に ついて説明します。 内容 項目 サンプル アプリケーションについて サンプル アプリケーションのインストール サンプル アプリケーションを開く Code Examples アプリケーションの使い方 ページ 3 5 5 6 サンプル アプリケーションについて PowerBuilder には、サンプルで使用されているテクニックを学ん で活用できるように、ソース コード付きのサンプル アプリケー ションが用意されています。サンプルには、以下の 2 種類があり ます。 アプリケーション テクニック • Web サイトからダウンロードできるサンプル • CD からインストールできるサンプル 3 サンプル アプリケーションについて Web サイトのサンプル PowerBuilder の最新のサンプル アプリケーションとユーティリティ は、Sybase CodeXchange Web サイト(PowerBuilder Samples and Utilities project のサイト http://powerbuilder.codeXchange.sybase.com/)で利用できま す。このページを開くには、Windows の[スタート|プログラム| Sybase | PowerBuilder 10.0 | PB 10 コード サンプル]を選択します。 MySybase にログインしていない場合、CodeXchange にアクセスするに は[Sybase Account Login]ページでログインする必要があります。 MySybase のアカウントがない場合は、このページ上のリンクを使って サインアップできます。MySybase は、Sybase Web サイトへのパーソナ ライズされたポータルを提供する無料サービスです。 これらのサンプルは Sybase の社員とユーザが作成したものであり、頻 繁に更新されます。PowerBuilder の特定の機能を使うスタンドアロン アプリケーションがあり、PowerBuilder ネイティブ インタフェースを 使った Web サービスの使用、EJB クライアントの作成、ビジュアルお よび非ビジュアル エクステンションの記述などの新機能も使われて います。ほとんどのサンプルには、そこで使われる機能とそのダウン ロード方法および使い方について説明した readme 文書があります。 CD 内のサンプル CD には 2 つのサンプルがあり、PowerBuilder のインストール時にイン ストールできます。 Code Examples PowerBuilder Code Examples アプリケーションには、コーディング テク ニックの学習に活用できる多くのサンプルが含まれています。これら のサンプルは、PowerBuilder の新旧機能を駆使したさまざまなコー ティング テクニックの使い方を示す目的で特別に作成されています。 Web データウィンド ウ Web DataWindow® テクノロジを使用するアプリケーションを開発す るには、EAServer にプリインストールされている汎用サーバ コンポー ネントを使用できます。このコンポーネントは、Microsoft Component Object Model(COM)で使用する DLL として提供されます。また、サ ンプルの Web データウィンドウ PBL をモデルとして、独自の HTML ジェネレータ コンポーネントを作成することもできます。Web データ ウィンドウについての詳細は、『データウィンドウ プログラマーズ ガ イド』マニュアルを参照してください。 4 PowerBuilder 第1章 サンプル アプリケーションの使い方 サンプル アプリケーションのインストール CD からサンプルをインストールするには、PowerBuilder インストール プログラムでセットアップの種類として[カスタム / フル]を選択し、 コンポーネントのリストから「Code Examples」を選択します。Code Examples アプリケーションをインストールするには、 「Example アプリ ケーション」を選択します。Web データウィンドウ PBL をインストー ルするには、「Web データウィンドウ」を選択します。 どちらのサンプルも、PowerBuilder 10.0 ディレクトリの Code Examples サブディレクトリにインストールされます。Code Examples アプリケー ションでは EAS Demo DB というサンプル Adaptive Server Anywhere デー タベースを使用します。 このデータベースは、 Sybase\Shared\PowerBuilder ディレクトリにインストールされています。Code Examples ディレクト リまたは EASDEMO10.DB ファイルが見つからない場合、サンプル ア プリケーションおよびデータベースがインストールされていないこと があります。 サンプル アプリケーションを開く サンプル アプリケーションを開くには、アプリケーション用のワーク スペースを作成し、そのアプリケーションのターゲットをワークス ペースに追加する必要があります。 アプリケーションのターゲット ファイルがない場合は、ワークスペー スに追加することができます。新規作成 ダイアログボックスの[ター ゲット]タブから[既存のアプリケーション]を選択します。起動さ れたウィザードで PowerBuilder 10.0\Code Examples フォルダに移動し、 学習したいアプリケーションが含まれているフォルダと PBL を展開 して、アプリケーションを選択します。 次節では、Code Examples アプリケーションの開き方と実行方法を段階 を追って説明します。 アプリケーション テクニック 5 Code Examples アプリケーションの使い方 Code Examples アプリケーションの使い方 Code Examples アプリケーションは開発環境から実行します。 ❖ Code Example アプリケーションを実行するには 1 メニュー バーから[ファイル|新規作成]を選択し、[ワークス ペース]タブから[ワークスペース]を選択して、 [OK]をクリッ クします。 2 PowerBuilder 10.0\Code Examples\Example App フォルダに移動し、 ワークスペースの名前を入力して、[保存]をクリックします。 3 作成したワークスペースのポップアップ メニューから[ターゲッ トの追加]を選択し、 PowerBuilder 10.0\Code Examples\Example App フォルダに移動し、ターゲット ファイル「PB Examples」を選択し て[開く]をクリックします。 ターゲットを展開すると、PBL にアプリケーションが含まれ、ア プリケーションがサポートする PBL がワークスペースに追加され ていることがわかります。 4 パワーバーの[実行]ボタンをクリックします。 サンプルの参照 Code Examples アプリケーションを開くと、左側のペインに、使用可能 なサンプル項目のツリー ビューが表示されます。このツリー ビュー は、さらに展開することもできます。中には、複数の項目に表示され るサンプルもあります。たとえばビジネス クラス サンプルは、継承と ユーザ オブジェクトの両方の項目にリスト表示されます。データスト アやデータウィンドウなど、特定の機能の使い方を知りたい場合は、 その項目を展開してサンプル名を調べてください。 6 PowerBuilder 第1章 サンプル アプリケーションの使い方 左側のペインでサンプルを選択すると、そのサンプルの説明と使い方 が右側に表示されます。 サンプルの検索 PowerBuilder の特定のオブジェクト クラスまたは機能の使い方を知り たい場合は、[サンプル プログラム]ペインの項目とその説明によっ てサンプルを検索できます。特定のイベント、関数、またはユーザ定 義オブジェクトを使用するサンプルを検索するには、 [検索]ペインを 使用します。 ❖ 関数、イベント、またはオブジェクトを検索するには 1 コード サンプルのメイン ウィンドウにある[検索]タブをクリッ クします。 2 [検索対象]グループボックスのラジオボタンを選択します。 3 アプリケーション テクニック ドロップダウン リストで目的の項目を選択し、 [検索開始]ボタン をクリックします。 7 Code Examples アプリケーションの使い方 検索対象の関数、イベント、またはオブジェクトを使用している サンプルの名前がすべて表示されます。 サンプルの実行と調査 学習したい処理を実行するサンプルが見つかったら、そのサンプルを 実行して動作内容を調べ、コードを参照(必要であればコピーも)で きます。 サンプルの実行 8 ハイライト表示されたサンプルを実行するには、サンプルをダブルク リックするかまたは[実行]をクリックします。サンプルのメイン ウィ ンドウにある[ヘルプ|現在のサンプルのヘルプ]ボタンをクリック すると、そのサンプルの使い方と動作内容に関するヘルプが表示され ます。 PowerBuilder 第1章 コードの調査 サンプル アプリケーションの使い方 サンプルに使用されているすべてのオブジェクトを参照するには、右 側のペインにある[関連オブジェクト]タブをクリックし、プラス記 号をクリックしてさらに詳しい項目を表示します。 スクリプトまたは関数のアイコンをダブルクリックして、コードを参 照します。 開発環境でのサンプル の利用 Code Examples アプリケーションを実行したりサンプルのコードを参 照することによって、多くの情報を得ることができますが、開発環境 でサンプル内のオブジェクトを開けば、さらに詳しい情報を得ること ができます。 たとえば、ペインタでオブジェクトを開く、ブラウザで継承階層を調 べる、デバッガでサンプルをワンステップずつ実行することなどがで きます。さらに、ライブラリ ペインタ内の自分のアプリケーションに オブジェクトをコピーしたり、スクリプト ビューにコード フラグメン トをコピーすることもできます。 Code Examples アプリケーションのライブラリは、オブジェクト型を基準 にして編成されています。たとえば、pbexamd1.pbl および pbexamd2.pbl はデータウィンドウ オブジェクトを含みます。これによって、このマ ニュアルの後半でサンプルとして紹介されているオブジェクトを容易 に見つけることができます。ライブラリ ペインタのリストビューのサ ンプル ライブラリを展開すると、各オブジェクトの用途が表示されま す。 アプリケーション テクニック 9 Code Examples アプリケーションの使い方 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 を参照してください。 分散コンポーネント プロジェクト ペインタで EAServer コンポーネントまたは COM/COM+ コンポーネントを生成すると、生成されたコンポーネントのインタ フェースでパブリック関数を使用できるようになり、パブリック イン スタンス変数を使用可能にするよう選択できます。プライベートとプ ロテクトの関数と変数は、生成されたコンポーネントのインタフェー スにはエクスポーズされません。 詳細については、第 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 イベントに、行選択オブジェクトを呼び出すスクリプト を記述します。 ❖ オブジェクトを従属関係で使用するには 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 つの機能を利用して、構造体とし て機能するユーザ オブジェクトを作成できます。このようなユーザ オ ブジェクトを構造体として使用する利点としては、以下のものがあり ます。 ユーザ オブジェクト の構造体としての使い 方 ❖ • 子孫オブジェクトを作成して拡張できる • 一度にすべての構造体にアクセスする関数を作成できる • 特定のインスタンス変数へのアクセスを制限するためにアクセス 指定子を使用できる 構造体として使用されるカスタムクラス ユーザ オブジェクトを作成するには 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 クライアントは、EAServer コンポーネントで発生した例 外を捕捉し、例外状態から回復することができます。PowerBuilder で 開発したコンポーネントは、独自の例外の種類を定義し送出できます。 これにより、Java などほかの EAServer コンポーネントとの一貫性を高 めることができます。 アプリケーション テクニック 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-CATCH-FINALLY ブロック 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 のエラー処理についての詳細は、588 ページの「エラー処理」 を参照してください。 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 を呼び出すとよいでしょ う。 ガベージ コレクションでは、参照できないオブジェクトとクラスをす べて削除します。これには循環参照(相互に参照し合っているが、ほ かからは一切参照されていないオブジェクト)も含まれます。 ガベージ コレクショ ンの対象にならないオ ブジェクト ガベージ コレクショ ンの発生の制御 次のオブジェクトはガベージ コレクションの対象から除外されます。 • ビジュアル オブジェクト 画面に表示されるオブジェクトは、画面 で作成され表示されるときに内部参照が追加されるため、ガベー ジ コレクションは行われません。ビジュアル オブジェクトは、閉 じるときに明示的に破棄します。 • タイミング オブジェクト • 共有オブジェクト SharedObjectRegister 関数は内部参照を追加する ため、登録された共有オブジェクトにはガベージ コレクションは 行われません。SharedObjectUnregister 関数を呼び出すと、追加され た内部参照が削除されます。 タイミング オブジェクトの Start 関数は そのオブジェクトの内部参照を追加するため、現在実行中のタイ ミング オブジェクトにはガベージ コレクションは行われません。 Stop 関数を呼び出すと追加された参照が削除されます。 ガベージ コレクションは PowerBuilder 内で自動的に行われますが、関数 を呼び出して、ガベージ コレクションを強制実行したり、参照カウント をチェックする間隔を変更することもできます。ガベージ コレクション 発生を制御する関数として、GarbageCollect、GarbageCollectGetTimeLimit、 および GarbageCollectSetTimeLimit の 3 つが用意されています。 これらの関数についての詳細は、 『PowerScript リファレンス』マニュ アルを参照してください。これらの関数の使用例については、第 1 章 「サンプル アプリケーションの使い方」の Code Examples サンプル ア プリケーションを参照してください。 パフォーマンスに関す る考慮点 トレースとプロファイルを使用すると、ガベージ コレクションの実行 間隔を変更することによるパフォーマンスへの影響を調べることがで きます。 トレースとプロファイルの詳細については、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 50 PowerBuilder 第3章 PowerScript についての特別なトピック メモリ管理の設定 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 エンコーディング 54 動作内容 指定されたファイルを閉じる Boolean 指定されたファイルを削除する Encoding カタロ ファイルで使用されているエンコーディン グ データ型 グを返す Boolean 指定されたファイルが存在するかどうかを 判定する Long サイズが 2 GB 以下のファイルの長さを取 得する LongLong 任意のサイズのファイルの長さを取得する Integer 指定されたファイルを開く Integer 指定されたファイルを読み込む(非推奨) Long 指定されたファイルを読み込む Long サイズが 2 GB 以下のファイル内の特定位 置に位置ポインタを設定する FileSeek64 LongLong FileWrite Integer FileWriteEx 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 88 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 つのシート名が表示されています。 開いているシートの一 覧表示 ❖ ドロップダウン メニューに開いているシート名を表示するには • メニュー バー項目の番号を指定する(左端の項目が 1 ) 。OpenSheet 関数を呼び出してシートを開くと、そのシート名がメニュー バー 項目のドロップダウン メニューに表示される 一度に 9 つ以上のシートが開いている場合、最初の 9 シートの名前は 表示されますが、10 番目以降は[その他のウィンドウ]と表示されま す。10 番目以降のシートを表示するには、 [その他のウィンドウ]を 選択します。 シートの整列 ArrangeSheets 関数を使用して、MDI フレーム内で開いてるシートの並 べ方を変更することができます。 シートの並び方の変更 エンド ユーザがシートの並べ方を変更できるように、メニュー項目 (通常は[ウィンドウ]メニューのドロップダウンメニュー項目)を作 成します。エンド ユーザがメニュー項目を選択した時に、ArrangeSheets 関数を使用してシートを並べ替えます。 76 PowerBuilder 第5章 シートの最大表示 シートを閉じる MDI アプリケーションの構築 MDI ウィンドウに開かれているシートがコントロール メニューを持 つ場合、エンド ユーザはそのシートを最大表示することができます。 アクティブなシートが最大表示された場合の動作は以下のようになり ます。 • ほかのシートがアクティブになると、そのアクティブになった シートが最大表示される。アクティブになったシートは、直前の シートの状態を継承する • 新しいシートを開くと、現行シートは直前のサイズに戻り、新し いシートはオリジナルのサイズのまま表示される アクティブなシート 〔Ctrl〕+〔F4〕を押すと、アクティブなウィンド ウ(シート)が閉じます。メニューの親ウィンドウ(シート)を閉じ るスクリプトをメニュー項目に記述することもできます。この場合、 メニューはフレームではなくシートに関連付けます。たとえば、次の ようにスクリプトを記述します。 Close(ParentWindow) すべてのシート 〔Alt〕+〔F4〕を押すと、すべてのシートを閉じてアプ リケーションを終了することができます。開いているシートを配列に 保持しておいて、ループによってすべてのシートを閉じるようにスク リプトを記述することもできます。 マイクロヘルプの使い方 MDI では、フレームの底辺に位置するステータス バーにマイクロヘル プを用意して、エンド ユーザに対して情報を提供することができま す。たとえば、エンド ユーザがメニュー項目を選択するときに、ス テータス バーに選択されたメニュー項目の説明が表示されます。 開発者は、メニュー項目とカスタム フレーム ウィンドウ内のコント ロールに対してマイクロヘルプを定義できます。 メニュー項目に対する マイクロヘルプ メニュー項目に関連付けるマイクロヘルプのテキストは、メニュー ペ インタの[マイクロヘルプ]テキストボックスで指定します。メニュー 項 目 の ス ク リ プ ト で マ イ ク ロ ヘ ル プ の テ キ ス ト を 変 更 す る に は、 SetMicroHelp 関数を使用します。 アプリケーション テクニック 77 MDI アプリケーションにおけるツールバーの使い方 コントロールに対する マイクロヘルプ コントロールの 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 が表示されます。 ❖ フレームが開かれるとき、またはフレームのサイズが変更されるときに、ク ライアント領域のサイズを設定または変更するには • アプリケーション テクニック フレームの 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 プロパティの値はマイクロヘルプの高さになります。 アプリケーション テクニック 87 MDI アプリケーションにおけるキーボード操作について MDI アプリケーションにおけるキーボード操作について PowerBuilder 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 stringwinname = "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 つ作成されます。そのタブ ページを使用することも、削除するこ ともできます。 タブ ページの作成方 法 ❖ ❖ ❖ タブ コントロール内に新しいタブ ページを作成するには 1 タブ コントロール内のタブエリアを右クリックします。タブ ペー ジをクリックしてはいけません。 2 ポップアップ メニューから[タブ ページの挿入]を選択します。 3 新しいタブ ページにコントロールを追加します。 タブ コントロールの独立したタブ ページを定義するには 1 新規作成 ダイアログボックスで、[PB オブジェクト]タブの[カ スタム ビジュアル]を選択します。 2 ユーザ オブジェクト ペインタで、使用するタブ コントロールの表 示領域のサイズに合わせて、ユーザ オブジェクトのサイズを設定 します。 3 タブ ページに表示されるコントロールをユーザ オブジェクトに 追加して、イベントに対するスクリプトを記述します。 4 ユーザ オブジェクトのプロパティ シートで、[タブ ページ]タブ をクリックして、タブ ページで使用される情報を設定します。 タブ コントロールに、タブ ページとしてユーザ オブジェクトを追加するには 1 タブ コントロール内のタブエリアを右クリックします。タブ ペー ジをクリックしてはいけません。 2 ポップアップ メニューから[ユーザ オブジェクトの挿入]を選択 します。 3 ユーザ オブジェクトを選択します。 アプリケーション テクニック 101 タブ ページの定義と管理 タブ ページは、選択したユーザ オブジェクトから継承されます。 タブ コントロール内のタブ ページを定義するのと同じように、継 承されたユーザ オブジェクトのタブ ページにプロパティを設定 し、スクリプトを記述できます。 タブ コントロール内のユーザ オブジェクトに配置されたコントロールの 編集 タブ コントロール内にあるユーザ オブジェクトの内容は編集で きません。ユーザ オブジェクト上のコントロールを編集したり、 スクリプトを記述する場合は、ウィンドウまたはタブ コントロー ルがあるユーザ オブジェクトを閉じてから、ユーザ オブジェクト ペインタに戻って変更を行います 。 タブ コントロール上で、タブ ページの表示、表示順序の変更、削除が できます。 タブ ページの管理 ❖ 別のタブ ページを表示するには • タブ ページのタブをクリックします。 タブ ページは前面に表示され、アクティブなタブ ページとなりま す。タブは、設定したタブ順序に応じて再配置されます。 ❖ ❖ 102 タブ コントロール内のタブの表示順序を変更するには 1 タブ コントロールのプロパティ シートの[タブ順序]タブをクリッ クします。 2 表示したい位置にタブ ページの名前をドラッグします。 タブ コントロールからタブ ページを削除するには 1 タブ ページのタブをクリックします。 2 タブ ページを右クリックし、ポップアップ メニューから[切り取 り]または[削除]を選択します。 PowerBuilder 第7章 ウィンドウにおけるタブ コントロールの使い方 タブ コントロールとタブ ページの選択 タブ コントロール内のさまざまな領域をクリックしてみると、プロパ ティ ビューが変化して、タブ コントロール自身のプロパティ、タブ ページ、またはタブ ページ上のコントロールが表示されることがわか ります。ポップアップ メニューから[切り取り]などの項目を選択す る前に、正しいオブジェクトが選択されていることを確認してくださ い。 タブ コントロールのタブ領域のどこかをクリックすると、そのタブ コ ントロールが選択されます。特定ページのタブをクリックすると、そ のタブ ページはアクティブになりますが、選択されるオブジェクトは 依然としてタブ コントロールです。タブ ページを選択するには、その タブをクリックしてアクティブにしてから、タブ自身を除く、ページ の背景のどこかをクリックします。 タブ ページ上のコン トロール タブ コントロールの本来の目的は、タブ ページにほかのコントロール を表示させることです。タブ ページをウィンドウのミニチュア版とし て考えることができます。ウィンドウに対して行うように、タブ ペー ジにコントロールを追加します。 タブ コントロールで作業しているときは、タブ コントロール内に作成 されたタブ ページにしかコントロールを追加することができません。 タブ コントロール内のユーザ オブジェクトへのコントロールの追加 タブ コントロール内のユーザ オブジェクトにコントロールを追加す るには、ユーザ オブジェクト ペインタでそのユーザ オブジェクトを 開きます。 ❖ 埋め込みタブ ページにコントロールを追加するには • ウィンドウにコントロールを追加する場合と同様に、ツールバー または[挿入]メニューからコントロールを選択して、タブ ペー ジをクリックします。 タブ ページをクリックすると、そのタブ ページがコントロールの 親になります。 ❖ 1 つのタブ ページから別のタブ ページにコントロールを移動するには • アプリケーション テクニック コントロールを切り取るかコピーして、目的のタブ ページに貼り 付けます。 103 タブ コントロールのカスタマイズ 移動元のタブ ページと移動先のタブ ページは、両方とも埋め込みタブ ページでなければなりません。独立したユーザ オブジェクトであって はなりません。 ❖ タブ ページとそのタブ コントロールがあるウィンドウの間でコントロールを 移動するには • コントロールを切り取るかコピーして、目的のウィンドウかタブ ページに貼り付けます。 タブ コントロールの外のウィンドウに、コントロールをドラッグ することはできません。 タブ ページとウィンドウの間でコントロールを移動することは、コン トロールの親を変更することになります。したがって、コントロール を参照するスクリプトに影響を与えます。 タブ コントロールのカスタマイズ タブ コントロールには、タブの表示位置と表示形態を制御する設定が あります。それぞれのタブには、タブ自身のラベル、ピクチャ、背景 色があります。 すべてのタブは、タブのプロパティ シートの[フォント]タブ ページ で設定された、同じフォント設定を共有します。 タブ コントロールと タブ ページのための、 ポップアップ メ ニューとプロパティ シート タブ コントロールにはいくつかの要素があり、それぞれにポップアッ プ メニューとプロパティ シートがあります。プロパティ シートを開 くためには、ポップアップ メニュー上で[プロパティ]を選択します。 アクセスしたい要素の箇所でクリックします。 表 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) Tab データ型の変数の制限事項 PowerBuilder のシステム オブジェクト データ型である Tab 型の変数は、タブ コントロールにあるタブ ページ を認識できません。また、UserObject 型の変数は、タブ ページにある コントロールを認識できません。 以下のタブ ページのイベントに対するスクリプトで記述したローカ ル変数は、親であるタブ コントロールへの参照が代入されています。 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 フォント プロパ ティ 各種ピクチャ プ ロパティ 効果 項目の前にプラス(+)やマイナス(-)ボタンがある場 合は子項目があり、そのボタンをクリックすることに よって分岐を開閉できることを示す 分岐内の項目や、ルート レベルの項目を接続する線を表 示する 状態ピクチャをチェック済みチェックボックスおよび 未チェック チェックボックスに置き換える マウスが上に移動したときに項目の外観を変更する 選択した項目の行全体をハイライト表示する 選択した項目を展開し、前に選択した項目を自動的に折 りたたむ 項目をインデントする量を指定する すべてのラベルのフォントを指定する ピクチャとそのサイズを制御する これらのプロパティの詳細については、『オブジェクトとコントロー ル』マニュアルを参照してください。 ユーザ操作 開発者が特にスクリプトを作成しなくても、ツリービューの基本機能 を利用して、エンド ユーザがラベルの編集、項目の削除、分岐の開閉、 およびアルファベット順のソートを行うことができます。たとえば、 エンド ユーザが選択した項目をもう一度クリックすると、ラベルは編 集状態になります。また、〔Delete〕を押すと項目が削除されます。プ ロパティを設定して、このような操作を実行できないようにすること も可能です。 スクリプトを作成して、このような基本操作をカスタマイズすること ができます。基本操作にイベントを関連付けることにより、操作を実 行可能または実行不可にします。また、項目の追加、項目のドラッグ、 ソート指定のカスタマイズなど、そのほかの機能を実装することもで きます。 カスタム イベントの 使い方 PowerBuilder バージョン 7 以降では、リストビュー コントロールとツ リービュー コントロールに Microsoft のコントロールが使用されてい ます。右クリックしたときに呼び出されるイベントが、以前のリリー スとは異なります。 マウスの右ボタンを放したときに、pbm_rbuttonup イベントは発生しま せん。このボタンが放されると、ツリービュー コントロールの組み込 み RightClicked! イベント pbm_tvnrclickedevent が発生します。 120 PowerBuilder 第8章 ツリービュー コントロールの使い方 選択されていないツリービュー項目を右クリックした場合、その右ボ タンを放すと、以前選択されていた項目にフォーカスが戻ります。新 しい項目を選択するには、次のコードを 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) LOOP データストア インス タンスの破棄 ツリービュー コントロールが表示されているウィンドウを閉じると きに、以下のコードでデータストアのインスタンスを破棄します。 // w_treeview に対する Close イベント DESTROY ids_data DESTROY ids_info アプリケーション テクニック 141 データウィンドウのデータのツリービューへの表示 142 PowerBuilder 第 9 章 ウィンドウでのリストの使い方 この章について この章では、アプリケーションにおいて情報を提示するリストの 使い方について説明します。 内容 項目 リストの提示について リストの使い方 ドロップダウン リストの使い方 リストビュー コントロールの使い方 ページ 143 144 149 152 リストの提示について アプリケーションでリストを提示する複数の方法があります。 アプリケーション テクニック • リストボックスとピクチャ リストボックスは、テキストの表 示とアクションの起動ができます。選択肢を表示して、エン ド ユーザに選択させます。 • ドロップダウン リストボックスとドロップダウン ピクチャ リ ストボックスも、選択肢を表示します。また、エンド ユーザ に表示しているテキストを編集させることもできます。ド ロップダウン リストボックスはテキストだけのリストです。 ドロップダウン ピクチャ リストボックスはテキストとピク チャを一緒に表示します。 • リストビュー コントロールは、ピクチャとテキストの両方を 一 緒 にリ ス ト に し て 提 示し ま す。エ ン ド ユ ー ザ に リス ト ビューの項目を追加、削除、編集、および再配置させること ができます。また、リストビューの項目を使用してアクショ ンを起動させることもできます。 143 リストの使い方 ツリービュー コントロール ツリービュー コントロールも、ピクチャとテキストを一緒にリストに 提示します。リストビュー コントロールとの違いは、ツリービュー コ ントロールは、ツリービュー項目間の階層的な関係を表示することで す。リストビュー コントロールと同じように、エンド ユーザにツリー ビュー項目を追加、削除、編集、および再配置させることができます。 また、アクションを起動させることもできます。 ツリービューの詳細については、第 8 章「ツリービュー コントロール の使い方」を参照してください。 リストの使い方 リストを使用して、エンド ユーザに、スクロールできる簡単なリスト で情報を提示できます。ピクチャ リストボックスは、テキストとピク チャの情報を提示できます。また、リストボックスは、テキストの情 報だけを提示できます。 アプリケーションの設計にもよりますが、エンド ユーザは、1 つまた はそれ以上のリスト項目を選択して、その選択に基づいたアクション を実行できます。 ウィンドウにリストボックス コントロールまたはピクチャ リスト ボックス コントロールを追加するには、ほかのコントロールを追加す るのと同様の方法で行います。つまり、 [挿入|コントロール]メニュー から[リストボックス]または[ピクチャ リストボックス]を選択し て、ウィンドウ上の配置したい位置でクリックします。 ペインタで追加 新規項目を追加するには、コントロールの[項目]プ リスト コントロール への項目の追加 ロパティ ページを使用します。 ❖ リストボックスまたはピクチャ リストボックスに項目を追加するには 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 を設定するか、 [全般]プロパティ ページで[ソート]チェックボックスをオンにします。 ペインタで追加 ピクチャを追加するには、コントロールの[ピクチャ] プロパティ ページと[項目]プロパティ ページを使用します。 ピクチャ リストボッ クス コントロールへ のピクチャの追加 ❖ ピクチャ リストボックスにピクチャを追加するには 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 つの方法です。ドロップダウン リストボックスではテキ ストだけを提示したり、ドロップダウン ピクチャ リストボックスでは テキストとピクチャを提示したりできます。ドロップダウン リスト ボックスおよびドロップダウン ピクチャ リストボックス コントロー ルをウィンドウに追加する方法は、ほかのコントロールを追加する方 法と同じです。つまり、 [挿入|コントロール]メニューから[ドロッ プダウン リストボックス]または[ドロップダウン ピクチャ リスト ボックス]を選択して、ウィンドウ上の配置したい位置でクリックし ます。 項目を追加するには、コントロールの[項目]プロパ ティ ページを使用します。 ドロップダウン リス ト コントロールへの 項目の追加 ペインタで追加 ❖ ドロップダウン リストボックスまたはドロップダウン ピクチャ リストボッ クスに項目を追加するには 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 を設定します。 ペインタで追加 ピクチャを追加するには、リストビュー コントロール ドロップダウン ピク チャ リストボックス コントロールへのピク チャの追加 の[ピクチャ]と[項目]プロパティ ページを使用します。 ❖ ドロップダウン ピクチャ リストボックスにピクチャを追加するには 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章 ウィンドウでのリストの使い方 リストビュー コント ロールの作成 ウィンドウにリストビュー コントロールを追加するには、ほかのコン トロールを追加するのと同様の方法で行います。つまり、 [挿入|コン トロール]メニューから[リストビュー]を選択して、ウィンドウ上 の配置したい位置でクリックします。 リストビュー項目の追 加 ペインタで追加 項目を追加するには、コントロールの[項目]プロパ ティ ページを使用します。 ❖ リストビューに項目を追加するには 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 関数 を使用してリストビューを作成した場合、上記のピクチャをリスト ビュー項目に関連付けることができます。 しかし、リストビュー項目にピクチャを関連付けるには、リストビュー コントロールにリストビュー項目が追加されていなければなりませ ん。 ペインタで追加 ピクチャを追加するには、リストビュー コントロール の[ピクチャ]と[項目]プロパティ ページを使用します。 ❖ リストビュー コントロールにピクチャを追加するには 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!") // 小さいピクチャの高さと幅を設定します。 lv_1.SmallPictureHeight=16 lv_1.SmallPictureWidth=16 アプリケーション テクニック 155 リストビュー コントロールの使い方 // 小さいピクチャを追加します。 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) リストビューの項目と ピクチャの削除 DeleteItem 関数で、リストビューから項目を 1 つずつ削除できます。 DeleteItems 関数は、リストビューからすべての項目を削除します。同 様に、DeleteLargePicture 関数、DeleteSmallPicture 関数、DeleteStatePicture 関数で、特定の種類のピクチャを 1 つずつ削除できます。 DeleteLargePictures 関数、DeleteSmallPictures 関数、DeleteStatePictures 関 数は、特定の種類のピクチャをすべて削除します。 156 PowerBuilder 第9章 ウィンドウでのリストの使い方 以下の例では、リストビューから、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 ❖ 意味 オブジェクトがクリックされると、コントロールは自動的にド ラッグ モードになる オブジェクトがクリックされても、コントロールは自動的には ドラッグ モードにならない。ドラッグ モードにするには、スク リプトで Drag 関数を使用しなければならない ウィンドウ ペインタでコントロールに対する自動ドラッグ モードを指定する には 1 コントロールのプロパティ ビューで[その他]プロパティ ページ を選択します。 2 [自動ドラッグモード]チェックボックスをオンにします。 162 PowerBuilder 第 10 章 ドラッグ アンド ドロップ機能の使い方 DragIcon プロパティ DragIcon プロパティを使用して、コントロールが ドラッグ モードになったときのアイコンを指定します。DragIcon プロ パティは、組み込みアイコン名か、アイコン ファイル(ICO ファイル) 名です。デフォルトのドラッグ アイコンは、コントロールと同じサイ ズの長方形です。 コントロールをドラッグすると、そのコントロールがドロップできる 領域(有効ドロップ領域)上にあるときに、ドラッグ アイコンが表示 されます。コントロールをドロップできない領域(たとえば、ウィン ドウのスクロールバー)ではドロップ禁止アイコンが表示されます。 ❖ ドラッグ アイコンを指定するには 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 とともに インストールされる PBUSR100.HLP ファイルのトピックにあります。 テキストの取り出し方法を以下に示します。 1 PowerBuilder ヘルプを開いて、 [ユーザ]ボタンをクリックします。 2 ユーザ定義ヘルプの下で、トピックの検索 ダイアログボックスの [目次]タブから「ヘルプ プロジェクト ファイルのサンプル」項 目に移動します。 3 ヘルプ トピックを Windows のクリップボードにコピーします。 4 メモ帳などのテキスト エディタを開いて、クリップボードのテキ ストを空のドキュメントに貼り付けます。 5 そのドキュメントを PBUSR100.HPJ としてテキスト形式で保存し ます。 ソース ファイル名やディレクトリ パス名など、ヘルプ開発環境の細部 を反映させるには、プロジェクト ファイルを編集する必要がありま す。そのためには、テキスト エディタを使用したり、ヘルプ ワーク ショップまたはそのほかのヘルプ オーサリング ツールでプロジェク ト ファイルを開いて編集することができます。 166 PowerBuilder 第 11 章 オンライン ヘルプの提供 開発者に対するオンライン ヘルプの提供 ヘルプを提供する 2 つの方法 ユーザ定義関数、ユーザ イベント、およびユーザ オブジェクトのオン ライン ヘルプを PowerBuilder の開発環境に統合するには、2 つの方法 があります。 • • ユーザ定義関数の状況 依存ヘルプの機能 PowerBuilder メイン ヘルプ ウィンドウの[ユー ザ]ボタンをハードコード化して、PBUSR100.HLP というファイ ルを起動します。 [ユーザ]ボタン 状況依存ヘルプ スクリプト ビューで関数名を選択して(または カーソルを関数名に置いて) 〔Shift〕+〔F1〕を押すと、ユーザ定 義関数の状況依存ヘルプを表示できます。 スクリプト ビューで関数の名前を選択するか関数名にカーソルを置 いて、 〔Shift〕+〔F1〕を押すと、以下の動作が行われます。 1 PowerBuilder は、関数名の中から標準の接頭辞(デフォルトは uf_) を探します。 2 標準の接頭辞が見つかった場合には、PowerBuilder は(自身のメイ ン ヘルプ ファイルである PBHLP100.HLP を調べるかわりに)ユー ザ定義関数のヘルプ トピックを含んでいるヘルプ ファイルから ヘルプ トピックを探します。ユーザ定義関数のヘルプのデフォル ト ファイル名は PBUSR100.HLP です。 PowerBuilder は、PB.INI 内の UserHelpFile 変数を読み取ることに よって、調べるヘルプ ファイルの名前を判別します。この変数の 値を変更する方法については、168 ページの「高度な手順」を参照 してください。 3 最も簡単な方法 PowerBuilder が変数を見つけ出した場合には、指定したヘルプ ファ イルから選択した関数の名前を探します。PB.INI に UserHelpFile 変 数が存在しない場合には、PowerBuilder は、PowerBuilder Help ディ レクトリの PBUSR100.HLP ファイルからキーワードを探します。 PowerBuilder のデフォルトを使用する場合には、以下の操作が必要に なります。 • アプリケーション テクニック ユーザ定義関数、ユーザ イベント、およびユーザ オブジェクトの すべてのオンライン ヘルプを、PBUSR100.HLP という 1 つのファ イルにコンパイルします。 167 開発者に対するオンライン ヘルプの提供 オプションでコンテンツ ファイルを提供できます。その名前は PBUSR100.CNT とする必要があります。 • 基本的な手順 作成する各ユーザ定義関数の名前の前に uf_ を付けます(たとえ ば、uf_calculate)。 次に、オンライン ヘルプを PowerBuilder 環境に組み込む方法について 説明します。 ❖ [ユーザ]ボタンから PowerBuilder 開発者用のオンライン ヘルプを起動す るには 1 Microsoft Word および Microsoft ヘルプ ワークショップまたはその ほかのヘルプ オーサリング ツールを使用して、オンライン ヘルプ ファイルを作成します。 2 PowerBuilder とともにインストールされた PBUSR100.HLP と PBUSR100.CNT のファイル名を変更します。独自のコンテンツ ファイルを提供しない場合でも、オリジナルの PBUSR100.CNT ファイルの名前は変更してください。 3 コンパイルしたヘルプ ファイルとオプションのコンテンツ ファ イルを、PowerBuilder の Help ディレクトリに保存します。ヘルプ ファイルの名前は PBUSR100.HLP、コンテンツ ファイルの名前は PBUSR100.CNT とします。 [ユーザ]ボタンをクリックすると、ヘルプ ファイルが表示されま す。 ❖ ユーザ定義関数の状況依存ヘルプを作成するには 1 ユーザ定義関数を作成した場合には、関数の名前には標準の接頭 辞 を 付 け ま す。デ フ ォ ル ト の 接 頭 辞 は uf_ で す(た と え ば、 uf_calculate) 。 2 ユーザ定義関数のヘルプ トピックごとに、関数名と同じ検索キー ワード(脚注として K を使用)を割り当てます。 たとえば、ユーザ定義関数 uf_CutBait のヘルプ項目には、検索キー ワード uf_CutBait を設定します。PowerBuilder は、このキーワード を使用して、ヘルプ ウィンドウに適切なトピックを呼び出します。 3 高度な手順 168 ヘルプ ファイルをコンパイルし、PowerBuilder Help ディレクトリ に保存します。 状況依存ヘルプに別のファイル名を指定するには、PB.INI ファイルの UserHelpFile 変数の値を変更します。この変数を使用するには、ヘル プ ファイルが PowerBuilder Help ディレクトリに存在する必要があり ます。 PowerBuilder 第 11 章 ❖ オンライン ヘルプの提供 状況依存ヘルプに別のファイル名を指定するには 1 テキスト エディタで PB.INI ファイルを開きます。 2 [PB]セクションで、UserHelpFile 変数を追加して、状況依存ト ピックを含むヘルプ ファイルの名前を指定します。変数の書式は 次のとおりです。 UserHelpFile = helpfile.hlp ファイル名だけを指定します。絶対パスで指定しても認識されま せん。 ユーザ定義関数には、デフォルトの uf_ 接頭辞以外の標準の接頭辞を 付けることができます。使用したい接頭辞を定義するには、PB.INI ファ イルに UserHelpPrefix 変数を記述します。 ❖ ユーザ定義関数に別の接頭辞を使用するには 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 の使い方 ❖ 外部関数として WinHelp API を宣言するには 1 2 スクリプト ペインタの最初のドロップダウン リストボックスから [(Declare)]を、2 番目のドロップダウン リストボックスから[Global External Functions]を選択します。 関数宣言をスクリプト ビューに入力します。 次の例では、WinHelp API を宣言します。 FUNCTION boolean WinHelpA(long hWndMain, & string lpszHelp, long uCommand, & long dwData) & LIBRARY "USER32.DLL" WinHelp API の詳細については、Microsoft ヘルプ ワークショップのオ ンライン ヘルプまたはご使用のヘルプ オーサリング ツールの資料を 参照してください。グローバル外部関数の宣言と使用の詳細について は、『PowerScript リファレンス』マニュアルおよび 461 ページの「外 部関数の使い方」を参照してください。 170 PowerBuilder 第 4 部 データ アクセス テクニック 第 4 部では、PowerBuilder によるアプリケーション開発 において、データ アクセス機能を実現するためのテク ニックについて説明します。トランザクション オブジェ クトの使い方、XML の処理、グラフの操作、リッチテキ ストの作成方法、データ ソース間のデータ転送などにつ いて説明します。データウィンドウ オブジェクトおよび データストアでのデータ アクセスの使い方については 『データウィンドウ プログラマーズ ガイド』マニュアル を参照してください。 第 1 2 章 トランザクション オブジェクトの 使い方 この章について この章では、トランザクション オブジェクトと PowerBuilder アプ リケーションにおけるそれらの使い方について説明します。 内容 項目 トランザクション オブジェクトについて トランザクション オブジェクトの使い方 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 ストアド プロシージャを呼び出すときサポートされている DBMS の機能 ページ 173 178 190 199 トランザクション オブジェクトについて PowerBuilder で行うデータベース接続は、トランザクション オブ ジェクトと呼ばれる、PowerBuilder アプリケーションとデータベー スとの通信領域として機能する非ビジュアル オブジェクトを使用し ます。PowerBuilder がデータベースに接続するためには、トランザ クション オブジェクトにパラメータを指定します。なお、トラン ザクション オブジェクトは、図 12-1 に示すように、アプリケー ションからデータベースにアクセスする前に、あらかじめ設定し なければなりません。 図 12-1: データベースにアクセスするためのトランザクション オブジェクト アプリケーション テクニック 173 トランザクション オブジェクトについて PowerBuilder アプリケーションにおいて、データを表示したり、操作 するためには、データベースと通信する必要があります。 データベースとの通信 ❖ 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 JDBC トランザクション オブジェクト のプロパティ DBMS UserID DBPass Database ServerName DBParm Lock AutoCommit SQLReturnData SQLCode SQLNRows SQLDBCode SQLErrText DBMS LogID LogPass DBParm Lock DBMS Database ServerName LogID LogPass DBParm Lock AutoCommit SQLCode SQLNRows SQLDBCode SQLErrText ODBC DBMS #UserID +LogID +LogPass DBParm Lock OLE DB DBMS LogID LogPass DBParm AutoCommit SQLReturnData SQLCode SQLNRows SQLDBCode SQLErrText AutoCommit SQLCode SQLNRows SQLDBCode SQLErrText Microsoft SQL Server アプリケーション テクニック AutoCommit SQLCode SQLNRows SQLDBCode SQLErrText 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 関数と解釈されます。 詳細については、EAServer の場合は 510 ページの「トランザクション のサポート」、COM+ の場合は 624 ページの「トランザクションのサ ポート」を参照してください。 デフォルト トランザクション オブジェクト 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 プロパティ名が各オプションに割り当てられ、必要に 応じて、引用符、カンマ、セミコロンなどの文字が挿入されます。こ の構文は、[プレビュー]タブからスクリプトに直接コピーできます。 ❖ 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 = "Sybase" 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 文 ❖ 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)を使用して Adaptive Server Anywhere データベースに接 続します。また、ASETrans という独自に作成したトランザクション オ ブジェクトを使用して、Adaptive Server Enterprise データベースに接続 します。 // デフォルト トランザクション オブジェクトのプロパティを設定します。 SQLCA.DBMS = "ODBC" SQLCA.DBParm = "ConnectString='DSN=Sample'" // Adaptive Server Anywhere データベースに接続します。 CONNECT USING SQLCA; // ASE トランザクション オブジェクトを宣言します。 transaction ASETrans // ASE トランザクション オブジェクトを作成します。 ASETrans = CREATE TRANSACTION // ASE トランザクション オブジェクトのプロパティを設定します。 ASETrans.DBMS = "Sybase" ASETrans.Database = "Personnel" ASETrans.LogID = "JPL" ASETrans.LogPass = "JPLPASS" ASETrans.ServerName = "SERVER2" // ASE データベースに接続します。 CONNECT USING ASETrans; // Adaptive Server Anywhere データベースに行を挿入 // します。 INSERT INTO CUSTOMER VALUES ( 'CUST789', 'BOSTON' ) USING SQLCA; // ASE データベースに行を挿入します。 INSERT INTO EMPLOYEE VALUES ( "Peter Smith", "New York" ) USING ASETrans; アプリケーション テクニック 187 トランザクション オブジェクトの使い方 // Adaptive Server Anywhere データベースとの接続を解除 // します。 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 プロシージャの 概要 ❖ アプリケーションにおいてデータベースのストアド プロシージャを呼び出す には 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: 標準クラス ユーザ オブジェクトの定義 ❖ 標準クラス ユーザ オブジェクトを定義するには 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 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 ❖ ストアド プロシージャをユーザ オブジェクトの外部関数として宣言するには 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: ユーザ オブジェクトの保存 ❖ ユーザ オブジェクトを保存するには 1 ユーザ オブジェクト ペインタで、[保存]ボタンをクリックする か、メニューバーから [ファイル|名前を付けて保存]を選択し ます。 ユーザ オブジェクトの保存 ダイアログボックスが表示されます。 2 ユーザ オブジェクトの名前を指定し、そのユーザ オブジェクトに ついてのコメントを記述し、ユーザ オブジェクトを保存するライ ブラリを指定します。 3 [OK]ボタンをクリックして、ユーザ オブジェクトを保存します。 ユーザ オブジェクトは、指定した名前で選択したライブラリに保 存されます。 ステップ 4: SQLCA に対するデフォルトのグローバル変数の型の指定 ア プ リ ケ ー シ ョ ン ペ イ ン タ で、定 義 し た ユ ー ザ オ ブ ジ ェ ク ト を SQLCA に対するデフォルト グローバル変数の型として指定しなけれ ばなりません。これにより、アプリケーションを実行すると、組み込 みシステム トランザクション オブジェクトのかわりにその標準クラ ス ユーザ オブジェクトがデフォルト トランザクション オブジェクト として使用されます。 アプリケーション テクニック 195 ストアド プロシージャを呼び出すためのトランザクション オブジェクトの使い方 SQLCA のかわりに独自のトランザクション オブジェクトを使用 このプロシージャでは、アプリケーションでデフォルト トランザク ション オブジェクト SQLCA を使用するものとしていますが、独自の トランザクション オブジェクトのインスタンスを宣言して作成し、そ の後、ユーザ オブジェクトをトランザクション オブジェクトのプロパ ティとして呼び出すことも可能です。詳細については、『PowerBuilder ユーザーズ ガイド』マニュアルの「ユーザ オブジェクト」の章を参照 してください。 ❖ 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) ❖ アプリケーションでユーザ オブジェクトを使用するには 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 の機能 Adaptive Server Anywhere アプリケーションが Adaptive Server Anywhere のデータベースに接続 された場合には、以下の Adaptive Server Anywhere 機能を使用できま す。 • 表 12-8 に IN、OUT、IN OUT の各パラメータを示します。 表 12-8: Adaptive Server 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 同期の使い方 この章について PowerBuilder ASA MobiLink 同期ウィザードは、PowerBuilder アプ リケーションからデータベースの同期を簡単に制御できるように するオブジェクトを作成します。この章では、MobiLink 同期の概 要を説明します。また、ウィザードを使用するための準備と、ウィ ザードによって作成されたオブジェクトの使い方についても説明 します。 内容 項目 MobiLink 同期について PowerBuilder 同期オブジェクトの使い方 統合データベースの準備 リモート データベースの作成 同期のテクニック ページ 203 208 220 228 234 MobiLink 同期について MobiLink は、統合データベースと呼ばれるメイン データベースと 多数のリモート データベース間の双方向の同期を実現できる、 セッションベースの同期システムです。 MobiLink 同期についての詳細は、『Mobile Link 同期ユーザーズ・ ガイド』マニュアルおよび『Mobile Link 同期リファレンス』マ ニュアルを参照してください。これらのマニュアルは、コンパイ ルした SQL Anywhere Studio ヘルプ ファイルに含まれています。こ のファイルは、Sybase Adaptive Server Anywhere (ASA) をインストー ルするときに、デフォルトでインストールされます。また、PowerBuilder のテクニカル ライブラリ CD と Sybase Product Manuals Web のサイ ト http://sybooks.sybase.com/awg0900e.html も参照してください。 すでに MobiLink について理 解している場合は、208 ページの 「PowerBuilder 同 期 オ ブ ジ ェ ク ト の 使 い 方」 の PowerBuilder と MobiLink との統合についての説明に進んでください。 アプリケーション テクニック 203 MobiLink 同期について この節では、MobiLink の用語およびコンセプトの一部を紹介します。 データの移動と同期 データの移動が行われるのは、共有データが複数のノードにある複数 のデータベース上に分散している場合に、あるデータベースのデータ に行われた変更が別のデータベースの対応するデータに適用されると きです。データは、複製または同期によって移動できます。 データの複製では、すべてのトランザクションが一方のデータベース から他方のデータベースに移動されます。データの同期では、トラン ザクションの最終結果だけが移動されます。どちらの方法も、トラン ザクション ログ ファイルをスキャンすることで情報を取得しますが、 同期の場合はログ ファイル全体ではなく、更新されたログ ファイル セ グメントだけを使用するので、データをより高速かつ効率的に移動で きます。 同期の場合は、データをローカルで利用でき、サーバに接続しなくて も変更できます。MobiLink 同期は、ゆるやかな一貫性方式を使用しま す。このモデルは、すべての変更が一貫した方法で徐々に各サイトと 同期を取りますが、特定のタイミングで別のサイトが異なるコピーを 保持している可能性があることを意味します。同期が取られるのは、 成功したトランザクションだけです。 統合データベースとリ モート データベース 統合データベースは、ASA、Sybase Adaptive Server Enterprise、Oracle、 IBM DB2 UDB、または Microsoft SQL Server などのような ODBC 準拠 のデータベースであり、すべてのデータのマスタ コピーを保持しま す。 リモート データベースには、統合データのサブセットが含まれていま す。MobiLink は、ASA および UltraLite データベースと同期を取るこ とができますが、PowerBuilder 10 アプリケーションの場合、リモート データベースは ASA データベースでなければなりません。 MobiLink 同期サーバ MobiLink 同期サーバ dbmlsrv9 は、同期プロセスを管理し、リモート データベースと統合データベース サーバ間のインタフェースを提供 します。MobiLink 同期サーバと統合データベース間の通信はすべて ODBC 接続を介して行われます。統合データベースと同期サーバは、 一般に同一マシン上は配置されますが、別のマシン上でもかまいませ ん。 同期プロセスを開始する前に、MobiLink サーバを起動しておく必要が あります。 204 PowerBuilder 第 13 章 MobiLink 同期の使い方 PowerBuilder アプリケーションの作成およびテストを行うときは、 データベース ペインタのオブジェクト ビューの[Utilities]フォルダ からサーバを起動できます。詳細については、 『PowerBuilder ユーザー ズ ガイド』マニュアルのデータベースの管理についての章を参照して ください。コマンド ラインからサーバを起動する方法については、SQL Anywhere Studio オンライン ブックのインデックスで「dbmlsrv9」を参 照してください。 MobiLink 階層構造 MobiLink は、一般に階層構造の設定を使用します。階層構造内のノー ドは、サーバ、デスクトップ コンピュータ、およびハンドヘルド デバ イスまたは埋め込みデバイスに配置できます。単純な階層構造は、サー バ上の統合データベースと、モバイル デバイス上の複数のリモート データベースで構成できます。もう少し複雑な階層構造には、複数の レベルがあり、各レベルでいくつかのサイトがリモート データベース と統合データベースの両方として機能します。PowerBuilder アプリ ケーションでは、リモート データベースとしても機能する統合データ ベースは、ASA データベースでなければなりません。 たとえば、リモート サイト A1、A2、A3 がローカル サーバ上の統合 データベース A と同期を取り、リモート サイト B1、B2、B3 が別の ローカル サーバ上の統合データベース B と同期を取るとします。A と B は順番にリモート サイトとして機能して、マスタ サーバ上の統合 データベース C と同期を取ります。データベース C には 任意の ODBC 準拠のデータベースを利用できますが、A と B は ASA データベースで なければなりません。 アプリケーション テクニック 205 MobiLink 同期について 図 13-1: MobiLink 階層構造 同期スクリプト MobiLink 同期は、イベント駆動型のプロセスです。MobiLink クライア ントが同期を開始すると、MobiLink サーバ内で多数の同期イベントが 発生します。イベントが発生すると、MobiLink はその同期イベントと 一致するスクリプトを探します。MobiLink サーバで何らかの動作を実 行させるには、イベントに対応するスクリプトを提供する必要があり ます。 接続レベルのイベント、およびリモート データベースの各テーブル レ ベルのイベントに対応する同期スクリプトを記述できます。これらの スクリプトは統合データベースに保存します。 SQL、Java、または .NET を使用してスクリプトを記述できます。イベ ント スクリプト、および Sybase Central での MobiLink 同期プラグイン でのイベント スクリプトの記述についての詳細は、220 ページの「統 合データベースの準備」を参照してください。 206 PowerBuilder 第 13 章 MobiLink 同期クライ アント MobiLink 同期の使い方 リモート サイト上の ASA クライアントは、コマンド ライン ユーティ リティ dbmlsync を実行して同期を開始します。このユーティリティは、 リモート データベース上の 1 つまたは複数のサブスクリプションと MobiLink 同期サーバとの同期を取ります。サブスクリプションについ ては、次の「パブリケーション、アーティクル、ユーザ、サブスクリ プション」で説明します。dbmlsync ユーティリティとそのオプション についての詳細は、SQL Anywhere オンライン ブックのインデックス で「dbmlsync ユーティリティ」を参照してください。 PowerBuilder では、ASA MobiLink 同期ウィザードで作成される同期オ ブジェクトが dbmlsync プロセスを管理します。詳細については、208 ページの「PowerBuilder 同期オブジェクトの使い方」を参照してくだ さい。 パブリケーション、 アーティクル、ユー ザ、サブスクリプショ ン パブリケーションは、リモート データベース上のデータベース オブ ジェクトであり、同期を取るテーブルとカラムを識別します。各パブ リケーションには、1 つまたは複数のアーティクルを含めることがで きます。アーティクルはデータベース オブジェクトであり、テーブル 全体、またはテーブル内のカラムと行のサブセットを示します。 ユーザは、リモート データベース上のデータベース オブジェクトであ り、固有の同期クライアントを記述します。MobilLink システムのリ モート データベースごとに 1 つの MobiLink ユーザ名があります。統 合データベース上の ml_user という MobiLink システム テーブルは、 MobiLink ユーザ名のリストを保持します。これらの名前は認証に使用 されます。 サブスクリプションは、ユーザを 1 つまたは複数のパブリケーション に 関 連 付 け ま す。ま た、同 期 プ ロ ト コ ル(TCP/IP、HTTP、ま た は HTTPS)、アドレス(myserver.acmetools.com など) 、その他の任意の接 続および拡張オプションを指定します。 ユーザ、パブリケーション、サブスクリプションは、リモート データ ベースで作成されます。これらは、Sybase Central で ASA プラグイン (MobiLink 同期プラグインではありません)を使用して作成できます。 ユーザ、パブリケーション、サブスクリプションの作成については、 228 ページの「リモート データベースの作成」を参照してください。 アプリケーション テクニック 207 PowerBuilder 同期オブジェクトの使い方 同期プロセス dbmlsync は、TCP/IP、HTTP、または HTTPS を使用してリモート デー タベースに接続し、統合データベースにアップロードするデータのス トリーム(アップロード ストリーム)を準備します。dbmlsync は、リ モート データベースのトランザクション ログ内の情報を使用して、 アップロード ストリームを作成します。アップロード ストリームに は、MobiLink ユーザ名とパスワード、使用する同期スクリプトのバー ジョン、前回の同期のタイムスタンプ、パブリケーション内のテーブ ルとカラムのスキーマ、および前回の同期以降のすべての挿入、更新、 削除の最終結果が含まれます。 アップロード ストリームを作成した後、dbmlsync は、指定されたパブ リケーションとサブスクリプションに格納された情報を使用して、 MobiLink 同期サーバに接続し、データを交換します。 MobiLink 同期サーバは、データを受信すると、統合データベースを更 新し、関連する変更をすべて含むダウンロード ストリームを作成し て、それをリモート サイトに戻します。それぞれの同期が正常に終了 した時点で、統合データベースとリモート データベースの一貫性が維 持されています。同期は、トランザクション全体について実行される か全く実行されないかのどちらかです。これで、各データベースでト ランザクションの整合性が維持されます。 PowerBuilder 同期オブジェクトの使い方 新規作成 ダイアログボックスの[データベース]ページから ASA MobiLink 同期ウィザードを実行すると、ウィザードによってオブジェ クトが生成されます。これを PowerBuilder アプリケーションからの MobiLink 同期リクエストの開始と制御に使用できます。これらのオブ ジェクトを使用して、同期プロセス中にフィードバックを取得したり、 同期中の特定の時点での PowerScript イベントのコードを作成したり、 プロセスをプログラムによってキャンセルしたりできます。 ASA MobiLink 同期ウィザードの使い方 この節では、サンプル アプリケーションで ASA MobiLink 同期ウィ ザードを使用する方法について説明します。まず、新しいワークスペー スおよびテンプレート アプリケーションを作成します。SQL データ ベース接続を作成する必要はありませんが、プロジェクトは作成して ください。 208 PowerBuilder 第 13 章 MobiLink 同期の使い方 ウィザードを使用してアプリケーションのオブジェクトを生成する前 に、リモート データベースをセットアップして、パブリケーション、 ユーザ、サブスクリプションを少なくとも 1 つずつ追加し、そのリモー ト データベース用の PowerBuilder データベース プロファイルを作成 する必要があります。アプリケーションから同期オブジェクトをテス トするには、統合データベースをセットアップする必要があります。 220 ページの「統合データベースの準備」と 228 ページの「リモート データベースの作成」の説明に従って、独自のデータベースを作成で きます。 同期オブジェクトをテストする手順は次のとおりです。 ウィザードの実行 1 ウィザードの実行 2 アプリケーションからの同期オブジェクトの呼び出し 3 アプリケーションとデータベース ファイルの配布 4 MobiLink サーバの起動 5 アプリケーションの実行 ウィザードは、データベース プロファイルとパブリケーションを入力 するように要求します。ウィザードの指示に従ってデフォルト値を選 択し、 [完了]をクリックして、同期オブジェクトを生成します。 ウィザードの使用については、 『ユーザーズ ガイド』マニュアルのデー タベース管理についての章を参照するか、マウス ポインタをウィザー ドのいずれかのフィールドに置いて〔F1〕を押します。 アプリケーションから の同期オブジェクトの 呼び出し メニュー ペインタでアプリケーションのメニューを開き、 [ファイル] メニューに 2 つのサブメニュー項目[同期化]と[同期オプション] を追 加します。 [同期化]メニュー項目の Clicked イベントに次のコードを追 加します(appname はアプリケーションの名前です)。 s_appname_sync_parms s_opt gf_appname_sync(s_opt) 次のコードを[同期オプション]メニュー項目の Clicked イベントに追 加します。 gf_appname_configure_sync() アプリケーションと データベース ファイ ルの配布 プロジェクト ペインタを使用してアプリケーションをデスクトップ に配布し、これを MobiLink サーバにリモートで接続するすべてのマシ ンにコピーします。リモート データベースをすべてのエンド ユーザ マ シンにコピーし、そのデータベースを ODBC データベースとして登録 するか、データ ソース名(DSN)ファイルに接続パラメータを含めま す。 アプリケーション テクニック 209 PowerBuilder 同期オブジェクトの使い方 エンド ユーザ マシンに必要なその他のファイルとレジストリ エント リについては、217 ページの「リモート マシンでの同期の実行時要件」 を参照してください。 MobiLink サーバの起 動 アプリケーションの実 行 データベース ペインタの[Utilities]フォルダから[MobiLink Synchronization Server]をダブルクリックします。ダイアログボックス で、[ユーザの自動追加]チェックボックスをオンにします。これで、 リモート データベースで作成された MobiLink 名が確実に統合データ ベースによって認識されます。[OK]をクリックしてサーバを起動し ます。 リモート マシンでアプリケーションを実行し、 [ファイル|同期化]と [ファイル|同期オプション]メニュー項目を選択して、動作をテスト します。 次の節では、ウィザードによって生成されるすべてのオブジェクトに ついて説明します。 生成されるもの ウィザードは、2 つのオブジェクト セットを生成します。 同期を開始およびモニ タするオブジェクト 1 つ目のオブジェクト セットは、エンド ユーザによる同期の開始およ びモニタに使用できます。 • nvo_appname_sync – MobiLink クライアントを制御するカスタム クラス ユーザ オブジェクト(appname はアプリケーションの名前) • gf_appname_sync – ユーザ オブジェクトをインスタンス化し、同期 リクエストを開始する関数を呼び出すグローバル関数 • s_appname_sync_parms – MobiLink ユーザの名前とパスワード、お よびリモート データベース ユーザとパスワードを保持する構造 • w_appname_sync – 同期プロセスの進行をレポートするステータス ウィンドウ ウィザードでは、アプリケーションでステータス ウィンドウを使用す るかどうかを選択できます。標準の MobiLink dbmlsync ログ ウィンド ウを表示するか、またはステータス ウィンドウをまったく表示しない かを選択します。生成されるステータス ウィンドウの利点は、ウィン ドウを閉じる前にユーザがステータスを参照できる[OK]ボタンと、 完了前の同期をユーザがキャンセルできる[キャンセル]ボタンがあ ることです。アプリケーションのニーズに合わせてウィンドウをカス タマイズすることもできます。 210 PowerBuilder 第 13 章 同期オプションを変更 するオブジェクト MobiLink 同期の使い方 2 つ目のオブジェクト セットは、ウィザードで[ユーザのパスワード と実行オプションの入力]を選択している場合にだけ生成されます。 これを使用すると、エンド ユーザは同期を開始する前に同期オプショ ンを変更できます。 • w_appname_sync_options – MobiLink ユーザ名とパスワード、 MobiLink サーバのホスト名とポート、および dbmlsync のその他の オプションの変更、およびステータスの表示方法の選択をエンド ユーザが行うことができるオプション ウィンドウ。 • gf_appname_configure_sync – オプション ウィンドウを開くグローバ ル関数。ユーザが[OK]をクリックした場合は、gf_appname_sync を呼び出して同期を開始します。 オプション ウィンドウを使用するほとんどのアプリケーションは、同 期を開始するための 2 つのメニュー項目またはコマンド ボタンを提供 します。1 つは、ユーザが同期をリクエストする前に dbmlsync オプショ ンをセットアップまたは変更できるオプション ウィンドウを開きま す。もう 1 つは、現在のオプションで同期をリクエストします。 アプリケーションでの同期オブジェクトの使い方 生成されたオブジェクトを使用する前に、PowerBuilder のペインタを 使ってオブジェクトの操作方法を理解しておいてください。多数の関 数およびイベント スクリプトに、その用途を説明するコメントが含ま れています。 アプリケーションによる同期の管理を全面的に制御できるように、す べてのソース コードが提供されています。オブジェクトは、そのまま でも、変更しても、または独自オブジェクトのテンプレートとしても 使用できます。 ユーザ オブジェクト のインスタンス変数 nvo_appname_sync ユーザ オブジェクトには、パブリケーション名、 MobiLink サーバのホスト名とポート、リモート データベースに接続す るためのユーザ名とパスワードなどの特定の dbmlsync 引数を示すイン スタンス変数が含まれています。 ウィザードを実行すると、これらのインスタンス変数で指定した値が、 ユーザ オブジェクトの constructor イベントのスクリプトにデフォルト 値として設定されます。また、これらの値は、開発コンピュータの Windows レジストリ HKEY_CURRENT_USER\Software\Sybase\PowerBuilder\10.0\appname \MobiLink にも設定されます。ここで appname はアプリケーションの 名前です。 アプリケーション テクニック 211 PowerBuilder 同期オブジェクトの使い方 実行時に、constructor イベントのスクリプトは、リモート マシンのレ ジストリからインスタンス変数の値を取得します。レジストリから取 得できない場合、またはレジストリ設定を上書きしている場合は、か わりに、スクリプトで提供されているデフォルト値が使用され、レジ ストリに書き込まれます。 イベント スクリプトのデフォルト値は変更できます。また、 w_appname_sync_options ウィンドウを開くメニュー項目を提供するこ とによって、実行時にユーザがレジストリ値を変更できるようにする こともできます。 ユーザ オブジェクトの uf_runsync および uf_runsync_with_window 関数 は、dbmlsync プロセスを開始するときにインスタンス変数を引数とし て使用します。 dbmlsync の開始 ユーザが同期プロセスを開始できるようにするには、gf_appname_sync グローバル関数を呼び出すボタンまたはメニューのイベントスクリプ トを記述します。この関数は、nvo_appname_sync ユーザ オブジェクト のインスタンスを作成します。ユーザ オブジェクトの constructor イベ ント スクリプトは、リモート マシンのレジストリの appname\MobiLink キーを設定します。 ウィザードでステータス ウィンドウを表示するように指定した場合、 グローバル関数はステータス ウィンドウを開き、このウィンドウの ue_postopen イベントが uf_runsync_with_window 関数を呼び出します。そ れ以外の場合、グローバル関数は uf_runsync 関数を呼び出します。両 方の uf_runsync 関数は、PowerBuilder VM の特殊関数を用いて外部プロ セスとして dbmlsync を起動します。 MobiLink ユーザ名お よびパスワードの入力 グローバル関数は、唯一の引数として構造体を受け取ります。ここで は、ウィザードが生成した s_appname_sync 構造体を渡すことができま す。生成された構造体引数には、 String データ型の 4 つの変数 (MobiLink とリモート データベースそれぞれのユーザ名とパスワード)と、リ ターン コード用に Long データ型を取る 5 つ目の変数が含まれていま す。ウィザードによって生成される構造体オブジェクトは、これらの 変数のデフォルト値を設定しないので、通常は開発者が提供する必要 があります。 引数として渡す構造体に有効な値を割り当てる場合、グローバル関数 は、MobiLink サーバとリモート データベースのインスタンス変数の値 に、提供された値を設定します。たとえば、メニュー項目のコードを 作成して、シングルライン エディット ボックスを持つレスポンス ウィ ンドウを開き、[OK]ボタンのスクリプトで、ユーザが入力した値を 関数に渡すことができます。 212 PowerBuilder 第 13 章 MobiLink 同期の使い方 s_appname_sync_parms s_opt s_opt.is_mluser = sle_mlusr.text s_opt.is_mlpass = sle_mlpwd.text s_opt.is_dbuser = sle_dbusr.text s_opt.is_dbpass = sle_dbpwd.text if gf_appname_sync(s_opt)<>0 then MessageBox(" エラー ", "MobiLink エラー ") end if NULL 値または空の文字列を持つ構造体をグローバル関数に渡す場 合、nvo_appname_sync ユーザ オブジェクトの uf_runsync 関数は、レジ ストリに格納されている MobiLink およびデータベースのユーザ名と パスワードの値を探します。オプション ウィンドウ(215 ページの「同 期オプション ウィンドウの使い方」を参照)は、ユーザが初めて同期 を開始するときにこれらの値をレジストリに格納するメカニズムを提 供します。初回以降の同期は、ユーザが情報を再入力しなくても開始 できますが、オプション ウィンドウを使用してレジストリ値を上書き したり再設定したりすることもできます。 同期後のデータの取り 出し 同期の後は、一般に同期エラーについてテストし、新しく同期された データベースからデータを取り出します。たとえば、次のようになり ます。 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 ( ) 次のイベントは、221 ページの「接続イベント」で説明する同期サー バでのイベントに対応しています。 ue_begin_sync ( string user_name, string pub_names) ue_connect_MobiLink ( ) ue_begin_upload ( ) ue_end_upload ( ) アプリケーション テクニック 213 PowerBuilder 同期オブジェクトの使い方 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 ) 次のイベントは、各種のメッセージがサーバから送信されるときに発 生します。 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 イベン ト処理が完了するまで待ってから処理を継続します。 同期のキャンセル 214 ステータス ウィンドウの[キャンセル]ボタンは、uf_cancelsync ユー ザ オブジェクト関数を呼び出して、同期プロセスをキャンセルしま す。アプリケーションがステータス ウィンドウを使用しない場合は、 この関数を、アプリケーションの別のイベント スクリプトで呼び出す ことができます。 PowerBuilder 第 13 章 MobiLink 同期の使い方 同期オプション ウィンドウの使い方 アプリケーションで w_appname_sync_options ウィンドウを使用するに は、メニュー項目またはボタンの Clicked イベントに対して、 gf_appname_configure_sync 関数を呼び出すコードを作成します。この 関数は、s_appname_sync_parms 構造体のインスタンスを作成し、それ をオプション ウィンドウに渡します。 ウィンドウの Open イベントは、nvo_appname_sync ユーザ オブジェク トのインスタンスを作成します。その ue_postopen イベントは、レジス トリから値を取り出してウィンドウのテキスト ボックスに挿入しま す。ただし、レジストリ設定の上書きを選択している場合を除きます。 ユーザは、ウィンドウ内のオプションを確認または変更し、[OK]ま たは[キャンセル]ボタンをクリックします。 ユーザが[OK]をクリックした場合、gf_appname_configure_sync 関数 が gf_appname_sync を 呼 び 出 し て、そ の ウ ィ ン ド ウ か ら 返 さ れ る MobiLink およびリモート データベースのユーザ名とパスワードを使 用して同期を開始します。ユーザの変更もレジストリに書き込まれま す。 ウィンドウの Close イベントは、wf_try_saving ウィンドウ関数を呼び出 します。ユーザが[OK]をクリックした場合は、wf_savesettings ウィ ンドウ関数が開始されます。ユーザが[キャンセル]をクリックした 場合、レジストリに対する変更は行われません。 オプション ウィンドウには、[サブスクリプション]、[接続]、[ML サーバ]、[設定]の 4 つのページがあります。 [サブスクリプション] ページ MobiLink ウィザードを使用したときに、利用可能なパブリケーション のリストから 1 つまたは複数のパブリケーションを選択しています。 選択したパブリケーションは、 [サブスクリプション]ページに表示さ れていますが、実行時に編集することはできません。 各リモート ユーザは、このページで MobiLink 同期ユーザ名を入力す ることができます。この名前は、サブスクリプションでそのページに 表示されているパブリケーションと関連付けられている必要がありま す。アプリケーションを使用する MobiLink ユーザがいつも同じである 場合は、この情報を再入力する必要はありません。名前は、レジスト リに保存され、このデバイスのアプリケーションから同期が起動され るたびにデフォルトで使用されます。 アプリケーション テクニック 215 PowerBuilder 同期オブジェクトの使い方 ユーザが[パスワードを記憶する]チェックボックスをオンにしてい る 場 合、パ ス ワ ー ド は 暗 号 化 さ れ て レ ジ ス ト リ に 保 存 さ れ ま す。 uf_encrypt_pw 関数と uf_decrypt_pw 関数は、シンプルなアルゴリズムを 使用して、暗号化されていないパスワードがレジストリに表示されな いようにしています。このアルゴリズムを、より洗練された暗号化技 術と置き換えることができます。 [接続]ページ リモート ユーザは、このページに DSN ファイル名を入力して、リモー ト データベースとの接続に必要なすべての引数を渡すことができま す。 DSN ファイルが使用されない場合、または DSN ファイルがユーザ名 およびパスワードを含んでいない場合は、各リモート ユーザがリモー ト データベース のユーザ名をオプション ウィンドウの[接続]ペー ジで入力できます。名前は、レジストリに保存され、このデバイスの アプリケーションから同期が起動されるたびにデフォルトで使用され ます。 ユーザは、リモート データベースの追加の接続文字列引数を含めるこ ともできます。それには、 [接続]ページの[追加]テキストボックス に情報を入力します。パラメータと値を追加する場合は次の構文を使 用する必要があります。 param1=value1;param2=value2;paramN=valueN ユーザが[パスワードを記憶する]チェックボックスをオンにしてい る 場 合、パ ス ワ ー ド は 暗 号 化 さ れ て レ ジ ス ト リ に 保 存 さ れ ま す。 uf_encrypt_pw 関数と uf_decrypt_pw 関数は、シンプルなアルゴリズムを 使用して、暗号化されていないデータベース パスワードがレジストリ に表示されないようにしています。このアルゴリズムを、より洗練さ れた暗号化技術と置き換えることができます。 [ML サーバ]ページ サブスクリプションを作成するときは、プロトコル、ホスト、ポート、 その他の接続オプションを指定します。テストを簡単にするために、 デフォルト プロトコルを TCP/IP、デフォルト ホストを localhost にし ます。デフォルト ポートは、TCP/IP の場合は 2439、HTTP の場合は 80、HTTPS の場合は 443 です。 テスト中にこれらのデフォルトの変更が必要になる場合があります。 また、サーバが別のホストに移動されたりポートが変更されたりする 場合は、アプリケーションの使用中にユーザがデフォルトを変更する 必要があります。 ユーザがこのページで何も変更をしない場合、dbmlsync は、開発者が ウィザードで入力した値があればそれを使用します。ウィザードで値 を入力しなかった場合、dbmlsync は、サブスクリプション内の値を使 用します。 216 PowerBuilder 第 13 章 MobiLink 同期の使い方 サブスクリプションについての詳細は、233 ページの「サブスクリプ ションの追加」を参照してください。 [設定]ページ [設定]ページには、ログ オプションと、ウィザードで指定したその 他の dbmlsync オプションが表示されます。また、ユーザが利用できる 3 つの表示オプションが表示されます。このページで、ユーザはこれ らのオプションを変更できます。 拡張オプション 拡張オプションを追加するには、dbmlsync コマンド ラインで -e スイッ チを指定します。テキストボックスに -e スイッチを入力する必要はあ りません。 生成されたオブジェク トの変更 ユーザがオプション ウィンドウで利用できる dbmlsync オプションの 一部(全部ではない)にアクセスできるようにする場合は、必要に応 じてウィンドウを変更するか、ウィンドウを独自のオプション ウィン ドウのテンプレートとして使用します。少なくとも、各ユーザが MobiLink ユーザ名とパスワード、およびリモート データベースのユー ザ名とパスワードを入力する方法を提供する必要があります。 dbmlsync を開始しなくてもユーザがオプションを保存できるようにし たい場合は、gf_appname_configure_sync 内で gf_appname_sync を呼び出 す行をコメントにするか、 [保存]という第 3 のボタンを追加して[OK] ボタンと同じコードを含めます。ただし、このコードはゼロでない値 を戻すようにします。 リモート マシンでの同期の実行時要件 リモート マシンで必 要なサポート ファイ ル PowerBuilder または ASA をリモート マシンにインストールしていな い場合、PowerBuilder アプリケーションとの MobiLink 同期を使用する には、表 13-1 に示されているファイルをコピーする必要があります。 これらのファイルは、リモート マシンのシステム パス、または PowerBuilder アプリケーションをコピーしたディレクトリにコピーしてください。 表 13-1: リモート マシンのシステム パスに必要なランタイム ファイル 必須ファイル PBVM100.DLL、PBDWE100.DLL、 PBSHR100.DLL、PBODB100.DLL、 P B O D B 1 0 0 . I N I、L I B J C C . D L L 、 LIBJLOG.DLL アプリケーション テクニック 説明 開発マシンの Shared\PowerBuilder ディ レ ク ト リ か ら コ ピ ー で き る PowerBuilder ファイル 217 PowerBuilder 同期オブジェクトの使い方 必須ファイル 説明 A T L 7 1 . D L L 、G D I P L U S . D L L 、 PowerBuilder とともに出荷される MSVCP71.DLL、MSVCR71.DLL Microsoft ファイル。クライアント アプ リケーションとこれらのファイルを配 布する際の制限については、『リリー ス ノート』を参照してください。 DBENG9.EXE、DBMLSYNC.EXE、 開発マシンの DBSERV9.DLL、DBTOOL9.DLL、 Sybase\SQL Anywhere 9\win32 ディレクト DBODBC9.DLL、DBMLSOCK.DLL、 リからコピーできる ASA および D B L I B 9 . D L L 、D B G E N 9 . D L L 、 MobiLink ファイル。これらのファイル DBCON9.DLL、DBCTRS.DLL は、PowerBuilder アプリケーションお よびサポート ランタイム ファイルを コピーする場所の「win32」サブディ レクトリにコピーする必要がある リモート マシンのレ ジストリ要件 MobiLink 同期で使用するすべてのリモート マシンに ASA をインス トールする場合は、必要なレジストリ エントリが自動的に割り当て られます。ASA および MobiLink ファイルをリモート マシンにコピー する場合は、 HKEY_CURRENT_USER\SOFTWARE\Sybase\Adaptive Server Anywhere\9.0 レジストリ キーを作成して、ASA および MobiLink ファ イルをコピーした win32 サブディレクトリの親ディレクトリを示す 「Location」文字列値を追加する必要があります(nvo_appname_sync ユーザ オブジェクトの uf_runsync 関数のコードは、このレジストリ値 に割り当てたパスの末尾に「\win32\dbmlsync.exe」を追加します)。 ASA MobiLink 同期ウィザードで生成されたオブジェクトも、リモート ASA 接続の ODBC データ ソースを定義するレジストリ エントリを必 要とします。表 13-2 に、必須レジストリ エントリを示します。これら のレジストリ エントリをインストールする REG ファイルを作成でき ます。 表 13-2: リモート マシンでの必須レジストリ エントリ レジストリ キー HKEY_LOCAL_MACHINE\SOFT WARE\ODBC\ODBCINST.INI\Ad aptive Server Anywhere 9.0 HKEY_LOCAL_MACHINE\SOFT WARE\ODBC\ODBCINST.INI\O DBC Drivers 218 文字列値の名前と割り当てるデータ Driver = DBODBC9.DLL へのフルパス Setup = DBODBC9.DLL へのフルパス Adaptive Server Anywhere 9.0 = “Installed” PowerBuilder 第 13 章 レジストリ キー HKEY_LOCAL_MACHINE\SOFT WARE\ODBC\ODBC.INI\ODBC Data Sources HKEY_LOCAL_MACHINE\SOFT WARE\ODBC\ODBC.INI\dataSou rceName ファイル DSN による レジストリ DSN の代 用方法 MobiLink 同期の使い方 文字列値の名前と割り当てるデータ dataSourceName = “Adaptive Server Anywhere 9.0” Driver = DBODBC9.DLL へのフルパス Userid = リモート データベースのユーザ 名 Password = リモート データベースへの パスワード DatabaseName = remoteDatabaseName DatabaseFile = リモート データベースへ のフルパス ServerName = remoteDatabaseName Start = “dbeng9 -c 8M” CommLinks = “shmem” ASA MobiLink 同期ウィザードで生成された nvo_appname_sync ユーザ オブジェクトの uf_runsync 関数を変更して、レジストリ データ ソース 名(DSN)のかわりにファイル DSN を使用できます。このためには、 次のコード行の「dsn=」を「filedsn=」に変更する必要があります。 connect_string = " -c ~"dsn=" + is_desktop_dsn ファイル DSN を使用する場合は、この行を次のように変更します。 connect_string = " -c ~"filedsn=" + is_desktop_dsn ファイル DSN を使用した MobiLink 同期の場合は、nvo_appname_sync ユーザ オブジェクトの is_desktop_dsn インスタンス変数にファイル DSN へのフルパスを含める必要があります。次に、有効なファイル DSN の内容の例を示します。 [ODBC] DRIVER=Adaptive Server Anywhere 9.0 UID=dba Password=sql Compress=NO DisableMultiRowFetch=NO Debug=NO Integrated=No AutoStop=YES Start=dbeng9 -c 8M EngineName=SalesDB_Remote DBN=SalesDB_Remote DatabaseFile=C:\PB10apps\salesdb\salesdb_remote.db アプリケーション テクニック 219 統合データベースの準備 ウィザードを使用する準備 前の節では、テスト アプリケーションでウィザードを使用する方法と ウィザードによって生成されたオブジェクトを使用する方法を説明し ました。本稼動アプリケーションでウィザードを使用する前に、次の 作業を行う必要があります。 • 220 ページの「統合データベースの準備」に従って、統合データ ベースをセットアップし、同期スクリプトを記述します。 • 228 ページの「リモート データベースの作成」に従って、デスク トップにリモート データベースを作成し、1 つまたは複数のパブ リケーション、ユーザ、サブスクリプションをセットアップしま す。 • PowerBuilder オンライン ヘルプにある『データベースとの接続』マ ニュアルと 219 ページの「ファイル DSN によるレジストリ DSN の代用方法」に従って、すべてのリモート マシンで ODBC マネー ジャにデータベースを登録するか、リモート データベース用の ファイル DSN を作成します。 • 217 ページの「リモート マシンでの同期の実行時要件」に従って、 すべてのリモート マシンに必要なサポート ファイルがあること を確認します。 • (オプション)PowerBuilder オンライン ヘルプにある『データベー スとの接続』に従って、リモート データベースのデータベース接 続プロファイルを作成します。プロファイルを作成すると、ウィ ザードがリモート データベースで、MobiLink サブスクリプション が入力されているパブリケーションのリストを取り出すことがで きます。 統合データベースの準備 新規データベースを設計しているか、既存のデータベースを MobiLink 統合データベースとして使用するように準備しているかにかかわら ず、そのデータベースに MobiLink システム テーブルをインストール す る 必 要 が あ り ま す。SQL Anywhere は、Sybase Adaptive Server Enterprise、Oracle 8 および 9、Microsoft SQL Server、および IBM DB2 用のセットアップ スクリプトを提供します。ASA データベースには セットアップ スクリプトは必要ありません。 220 PowerBuilder 第 13 章 MobiLink 同期の使い方 MobiLink システム テーブルは、MobiLink ユーザ、テーブル、スクリ プト、スクリプトのバージョンについての情報を統合データベースに 格納します。これらのテーブルに直接アクセスすることはおそらくあ りませんが、同期スクリプトを追加するなどの操作を行うとテーブル は変更されます。 ODBC 接続およびド ライバ 同期を実行するために、MobiLink 同期サーバは、統合データベースと ODBC 接続する必要があります。使用するサーバには ODBC ドライバ が必要です。また、MobiLink 同期サーバを実行しているマシン上の データベース用に ODBC データ ソースを作成する必要があります。サ ポートされているドライバのリストについては、Recommended ODBC Drivers for 9.0.0 MobiLink のサイト http://www.sybase.com/detail?id=1025763 を 参照してください。 同期スクリプトの記述 同期中に発生するイベントには 2 つのタイプがあるので、それぞれに ついて同期スクリプトを記述する必要があります。 • 接続イベント – それぞれの同期中に必要な全体的なタスクを実行 します。 • テーブル イベント – 特定のテーブルに関連付けられ、そのテーブ ル内のデータの変更に関連するタスクを実行します。 接続イベント 接続レベルでは、主要なイベントは次の順に発生します。 begin_connection begin_synchronization begin_upload end_upload prepare_for_download begin_download end_download end_synchronization end_connection 同期リクエストが発生すると、begin_connection イベントが発生します。 スクリプトの現行バージョンのすべての同期リクエストが完了する と、end_connection イベントが発生します。通常、これらのイベントの スクリプトに、変数宣言やデータベースのクリーンアップなどの初期 化およびクリーンアップ コードを配置します。 アプリケーション テクニック 221 統合データベースの準備 begin_connection および end_connection 以外のすべてのイベントは、統 合データベースの ml_user テーブルに格納されている MobiLink ユーザ 名をパラメータとして取ります。パラメータ値と置き換えたい場所に 疑問符を配置すると、スクリプトでパラメータを使用できます。 ASA データベースのスクリプトを読みやすくするには、 begin_connection スクリプトで変数を宣言し、それを begin_synchronization スクリプトで ml_username の値に設定します。 たとえば、begin_connection に次の行を挿入します。 CREATE VARIABLE @sync_user VARCHAR(128); begin_synchronization に次の行を挿入します。 SET @sync_user = ? begin_synchronization および end_synchronization イベントは、リモート データベースと統合データベースに変更が適用される前と後に発生し ます。 begin_upload イベントは、アップロード トランザクションの開始を示 します。統合データベースに対する適切な挿入と更新が、すべてのリ モート テーブルについて実行されます。その後すべてのリモート テー ブルで適切に行が削除されます。end_upload の後、アップロードの変 更がコミットされます。 統合データベースから行を削除したくない場合は、upload_delete イベン ト に 対 す る ス ク リ プ ト を 書 か な い か、PowerScript コ ー ド で STOP SYNCHRONIZATION DELETE ステートメントを使用します。詳細につい ては、235 ページの「リモート データベースだけからの行の削除」を 参照してください。 begin_download イベントは、ダウンロード トランザクションの開始を 示します。すべてのリモート テーブルで適切な削除が実行され、その 後 download_cursor で、すべてのリモート テーブルで適切に行が追加さ れます。end_download の後、ダウンロードの変更がコミットされます。 これらのイベントは、最後のダウンロードの日付をパラメータとして 保持します。 handle_error、report_error、synchronization_statistics など、その他の接続レ ベルのイベントが発生することもあります。すべてのイベントとその 使用例については、 『Mobile Link 同期ユーザーズ・ガイド』マニュア ルの同期イベントについての章を参照してください。 222 PowerBuilder 第 13 章 MobiLink 同期の使い方 テーブル イベント begin_download や end_upload な ど、begin_synchronization イ ベ ン ト と end_synchronization イベントの間に発生する接続イベントの多くには、 対応するテーブル イベントもあります。これらのイベントとその他の 全体的なテーブルのイベントは、変更を保持する中間テーブルの作成 やログ ファイルへの情報の出力などのタスクに使用できます。 テーブルの各行に適用するテーブル イベントのスクリプトを記述す ることもできます。行レベルのイベントの場合、スクリプト内のカラ ムの順 序は、それら のカラ ムが リモー ト デ ータベ ースの CREATE TABLE ステートメントで出現する順序と一致していなければなりませ ん。また、スクリプト内のカラム名は、統合データベース上のカラム 名を参照する必要があります。 デフォルト スクリプ トの生成 行レベルのイベントは複数ありますが、ほとんどのテーブルで必要に なるのは、3 つのアップロード イベント(INSERT、UPDATE、DELETE) と 1 つのダウンロード イベントについてのスクリプトです。各テーブ ルに対してこれらの 4 つのスクリプトを作成するタスクを高速化する には、MobiLink 同期サーバを -za スイッチを指定して起動し、dbmlsync の SendColumnNames 拡張オプションを設定する方法で、スクリプトを 自動的に生成できます。 読み出し専用のリモート データベース リモート データベースが読み出し専用である場合、つまりデータの アップロードができないようにしたい場合は、アップロード スクリプ トを実装しないでください。-ze スイッチを使用してサンプル スクリプ トを生成できます。さらに、ダウンロード スクリプトのテンプレート としてダウンロード サンプルを使用できます。 ❖ PowerBuilder で同期スクリプトを自動的に生成するには 1 MobiLink 同期サーバ オプション ダイアログボックスの[自動スク リプト作成]チェックボックスをオンにし、 [OK]をクリックし てサーバを起動します。 このダイアログボックスは、データベース ペインタまたは DB プ ロファイル ダイアログボックスの[Utilities]フォルダから開くこ とができます。 2 アプリケーション テクニック アプリケーションで、w_appname_sync_options ウィンドウの[設定] ページの[拡張設定]テキストボックスに、 「SendColumnNames=ON」 と入力します。 223 統合データベースの準備 リモート データベースには、パブリケーション、ユーザ、サブス クリプションを少なくとも 1 つずつ定義しておく必要がありま す。複数のパブリケーションまたはユーザがある場合は、-n また は -u あるいはその両方のスイッチを使用して、作業するサブスク リプションを指定する必要があります。 統合データベースに既存のスクリプトがある場合、MobiLink は何 も実行しません。既存のスクリプトがない場合、MobiLink はパブ リケーションで指定されているすべてのテーブルについてスクリ プトを生成します。スクリプトは、クライアントと統合データベー スとの間で行われるデータのアップロードおよびダウンロードを 制御します。 リモート データベースと統合データベースでカラム名が異なる場 合は、生成されたスクリプトを変更して統合データベース上の名 前に合わせる必要があります。 コマンド プロンプトから同期スクリプトを生成することもできます。 -za スイッチを指定してサーバを起動し、dbmlsync を実行し、 SendColumnNames 拡張オプションを on に設定します。たとえば、次 のようになります。 dbmlsrv8 -c "dsn=masterdb" -za dbmlsync -c "dsn=remotedb" -e SendColumnNames=ON 生成されたスクリプト 表 13-3 は、カラム emp_id、emp_name、および dept_id を持つ emp とい う名前のテーブル用に生成されたスクリプトを示します。主キーは emp_id です。 表 13-3: 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 データをダウンロードするために生成されたスクリプトは、 「スナップ ショット」同期を実行します。テーブルの完全なイメージがリモート データベースにダウンロードされます。通常、これらのスクリプトを 編集して、転送されるデータを制限する必要があります。詳細につい ては、234 ページの「データのダウンロードの制限」を参照してくだ さい。 224 PowerBuilder 第 13 章 MobiLink 同期の使い方 いずれかのスクリプトを変更する前に、同期プロセスをテストして、 生成されたスクリプトが予想どおりに動作することを確認します。1 つ変更するたびにテストを実行すると、エラーの絞り込みに役立ちま す。 Sybase Central でのスクリプトおよびユーザに対する作業 Sybase Central では、Mobile Link 同期 9 プラグインで、既存のスクリプ トを表示して変更したり、新しいスクリプトを書き込んだりすること ができます。以下の手順では、プラグインとの接続とスクリプトの記 述方法、およびユーザを統合データベースに追加する方法について説 明します。 ❖ Sybase Central で統合データベースに接続するには 1 Sybase Central を起動し、メニューバーの[ツール|接続]を選択 し、新しい接続 ダイアログボックスの[Mobile Link 同期 9]を選 択し、 [OK]をクリックします。 2 [接続]ダイアログボックスの[ID]ページで、[ODBC データ・ ソース名]を選択し、統合データベースの DSN を参照して選択し、 [OK]をクリックします。 Mobile Link 同期 9 プラグインで統合データベースのノードを展開する と、 [テーブル(所有者)]、 [接続スクリプト]、 [同期テーブル]、 [ユー ザ]、 [バージョン]の 5 つのフォルダが表示されます。この節のすべ ての手順では、まず、これらのフォルダのいずれかを開きます。 スクリプト バージョ ン スクリプトは、スクリプト バージョンと呼ばれるグループに分けられ ます。特定のバージョンを指定すると、MobiLink クライアントは、アッ プロード ストリームの処理とダウンロード ストリームの準備に使用 する同期スクリプトのセットを選択できます。異なるバージョンのス クリプトを定義したい場合は、統合データベースに、まずスクリプト バージョンを追加し、その後スクリプトを追加する必要があります。 2 つの異なるバージョンを作成する場合は、必要なすべてのイベント のスクリプトを両方のバージョンで用意していることを確認します。 ❖ スクリプト バージョンを追加するには 1 [バージョン]フォルダを選択し、 [バージョンを追加]をダブル クリックします。 アプリケーション テクニック 225 統合データベースの準備 2 新しいスクリプト・バージョンを追加 ダイアログボックスに、バー ジョンの名前を入力し、オプションで説明を入力し、 [完了]をク リックします。 Sybase Central によって、新しいバージョンが作成され、固有の整 数識別子が付けられます。 スクリプトの追加 接続イベント用に追加されたスクリプトは、同期のたびに実行されま す。テーブル イベントに追加されたスクリプトは、特定のテーブルが 変更されたときに実行されます。テーブルに対するスクリプトを追加 する前に、そのテーブルを同期するように指定する必要があります。 ❖ 同期テーブルを統合データベースに追加するには 1 [テーブル(所有者)]フォルダを選択し、 [DBA]をダブルクリッ クします。 2 ❖ 同期されたテーブルのリストに追加するテーブルを右クリック し、ポップアップ メニューの[同期テーブルに追加]を選択します。 同期テーブルにスクリプトを追加するには 1 [同期テーブル]フォルダを選択し、スクリプトを追加するテーブ ルを選択し、 [テーブル・スクリプトを追加]をダブルクリックし ます。 2 1 つ目のドロップダウン リストで、スクリプトを追加するバージョ ンを選択します。 3 2 つ目のドロップダウン リストで、スクリプトを追加するイベン トを選択します。 すでにスクリプトを持っているイベントはドロップダウン リスト には表示されません。 4 3 つ目のドロップダウン リストで、スクリプトを記述する言語を 選択します。 5 [新しいイベントのスクリプトをすぐに編集]チェックボックスが オンになっていることを確認し、[完了]をクリックします。 6 226 表示されるエディタにスクリプトを入力し、ファイルを保存して 閉じます。 PowerBuilder 第 13 章 MobiLink 同期の使い方 たとえば、リモート データベースの 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 イベントの使い方についての詳細は、 『Mobile Link 同期ユーザーズ・ガイド』マニュアルの削除の処理に ついての節を参照してください。 ❖ 接続レベルのスクリプトを追加するには 1 [接続スクリプト]フォルダを選択し、 [接続スクリプトを追加]を ダブルクリックします。 2 前の手順の 2 ~ 6 に従います。 スクリプトの変更 既存のスクリプトを変更するには、前の手順で説明したように Sybase Central でスクリプトに移動し、バージョン名の左の編集アイコンをダ ブルクリックします。 ユーザの追加 統合データベースの ml_user テーブルに直接ユーザを追加し、そのユー ザ名とオプションのパスワードをユーザに提供できます。ユーザを追 加するには、[ユーザ]フォルダを選択し、[ユーザの追加]をダブル クリックし、新しいユーザの追加 ウィザードを完了します。 231 ページの「Mobile Link ユーザの作成」で説明するように、各リモー ト データベースに少なくとも 1 つのユーザ名を追加する必要がありま す。 アプリケーション テクニック 227 リモート データベースの作成 リモート データベースの作成 MobiLink インストールでリモート データベースとして使用するため に、任意の ASA データベースを変換できます。また、統合された ASA データベースの全部または一部を使用する新規 ASA リモート データ ベースを作成できます。 Sybase Central Adaptive Server Anywhere プラグイン、データベース ペ インタの Create ASA Database ユーティリティ、またはその他のツール を使用してデスクトップにデータベースを作成します。データベース で英語文字セットを使用している場合は、1252 Latin1 照合順序を使用 します。 データベースを MobiLink 同期のリモート データベースとして使用す るには、少なくとも 1 つのパブリケーションと MobiLink ユーザを作成 し、そのユーザのパブリケーションにサブスクリプションを追加する 必要があります。229 ページの「パブリケーションの作成と変更」、231 ページの「Mobile Link ユーザの作成」、および 233 ページの「サブス クリプションの追加」を参照してください。 リモート データベー ス スキーマ リモート データベース内のテーブルは、統合データベース内のテーブ ルと同じでなくてもかまいませんが、一般に、統合データベースのテー ブル構造のサブセットであるテーブル構造をリモート データベース で使用することによってデザインを単純化できます。この方法では、 リモート データベース内のすべてのテーブルが必ず統合データベー ス上に存在することになります。対応するテーブルは、統合データベー スのテーブルと同じ構造および外部キー関係を持っています。 統合データベース上のテーブルには、同期されていない別のカラムが 含まれていることがよくあります。これらのカラムを使って、同期を 促進することもできます。たとえば、タイムスタンプ カラムで、統合 データベース上の新しい行または更新された行を識別できます。また、 統合データベース上の別のカラムまたはテーブルに、リモート サイト では必要ない情報を保持することもあります。 統合データベースとリモート データベースの関係についての詳細は、 『Mobile Link 同期ユーザーズ・ガイド』 マニュアルを参照してください。 228 PowerBuilder 第 13 章 MobiLink 同期の使い方 パブリケーションの作成と変更 パブリケーションは、Sybase Central または SQL CREATE PUBLICATION ステートメントを使用して作成します。Sybase Central では、すべての パブリケーションとアーティクルが[パブリケーション]フォルダに 表示されます。この節では、Sybase Central でパブリケーションを作成 する方法について説明します。SQL を使用したパブリケーションの作 成と変更については、 『Mobile Link 同期ユーザーズ・ガイド』マニュ アルを参照してください。 Mobile Link 同 期 9 プ ラ グ イ ン で は な く、Sybase Central で Adaptive Server Anywhere プラグインを使用して、MobiLink クライアントおよび リモート データベースについて作業します。PowerBuilder 設計時環境 から Sybase Central を開始する方法については、『ユーザーズ ガイド』 マニュアルを参照してください。 Sybase Central への 接続 パブリケーション、MobiLink ユーザ、サブスクリプションを作成また は変更するには、DBA 権限が必要です。 ❖ Sybase Central に接続して MobiLink 同期クライアントについて作業するには 1 Sybase Central を起動し、Sybase Central のメニューバーの[ツール |接続]を選択し、新しい接続 ダイアログボックスの[Adaptive Server Anywhere 9]を選択し、[OK]をクリックします。 2 接続 ダイアログボックスの[ID]ページに、ユーザ名として「DBA」 、 パスワードとして「SQL」と入力します。次に[ODBC データ・ ソース名]ラジオ ボタンを選択し、リモート データベースを参照 して選択し、[OK]をクリックします。 3 Adaptive Server Anywhere プラグインで、リモート データベースの ノードを展開します。 作成できる最も簡単なパブリケーションは、1 つまたは複数のテーブ ルのすべての行とカラムで構成される単一のアーティクルです。テー ブルはすでに存在していなければなりません。 テーブル内のすべての 行およびカラムの発行 ❖ Sybase Central で 1 つまたは複数のテーブル全体を発行するには 1 229 ページの「Sybase Central への接続」に従って、Sybase Central に接続します。 2 [パブリケーション]フォルダを開き、 [新しいパブリケーション] ボタンをクリックします。 3 アプリケーション テクニック 新しいパブリケーションの名前を入力し、 [次へ]をクリックしま す。 229 リモート データベースの作成 4 [テーブル]ページの[使用可能なテーブル]のリストからテーブ ルを選択し、[追加]をクリックします。 テーブルは、右側の[選択したテーブル]リストに表示されます。 5 さらにテーブルを追加することもできます。テーブルの順序は重 要ではありません。 6 [完了]をクリックします。 テーブル内の一部のカ ラムだけの発行 テーブルのすべての行と一部だけのカラムを含むパブリケーションを 作成できます。 ❖ Sybase Central でテーブル内の一部のカラムだけを発行するには 1 229 ページの「テーブル内のすべての行およびカラムの発行」の最 初の 4 つの手順に従います。 2 [カラム]ページで、テーブルのアイコンをダブルクリックして利 用可能なカラムのリストを展開します。発行するカラムをそれぞ れ選択し、[追加]をクリックします。 選択したカラムが右側に表示されます。 3 [完了]をクリックします。 テーブルの一部または全部のカラムと、一部だけの行を含むパブリ ケーションを作成できます。それには、発行する行だけに一致する検 索条件を記述します。 テーブル内の一部の行 だけの発行 MobiLink では、すべてのサブスクリプションからパブリケーションに WHERE 句を使用して、同じ行セットを除外します。パブリケーション のすべてのサブスクライバは、検索条件を満たす行に対するすべての 変更をアップロードします。 ❖ Sybase Central で WHERE 句を使ってパブリケーションを作成するには 1 229 ページの「テーブル内のすべての行およびカラムの発行」の最 初の 4 つの手順に従います。 2 [Where 句]ページで、テーブルを選択し、下のボックスに検索条 件を入力します。 3 [完了]をクリックします。 既存のパブリケーションにアーティクルを追加できます。 アーティクルの追加 ❖ Sybase Central でアーティクルを追加するには 1 230 229 ページの「Sybase Central への接続」に従って、Sybase Central に接続します。 PowerBuilder 第 13 章 MobiLink 同期の使い方 2 [パブリケーション]フォルダを開き、アーティクルを追加するパ ブリケーションの名前をダブルクリックします。 3 [新しいアーティクル]ボタンをクリックします。 4 新しいアーティクルの作成 ウィザードで、テーブルを選択し、 [次 へ]をクリックします。 5 一部のカラムだけが同期されるようにしたい場合は、 [選択したカ ラム]ラジオボタンを選択し、カラムを選択します。 6 WHERE 句を追加する場合は、 [次へ]をクリックし、句を入力し ます。 7 [完了]をクリックします。 パブリケーションの場所に移動し、ポップアップ メニューから[プロ パティ]または[削除]を選択すると、Sybase Central で既存のパブリ ケーションを変更または削除できます。同じ方法で、アーティクルを 変更および削除することができます。 パブリケーションと アーティクルの変更と 削除 パブリケーションを変更できるのは、DBA または パブリケーションの オーナだけです。パブリケーションを削除するには、DBA 権限が必要 です。パブリケーションを削除した場合、そのパブリケーションのす べてのサブスクリプションも同様に自動的に削除されます。 実行中の MobiLink セットアップではパブリケーションの変更を避ける 実行中の MobiLink セットアップでパブリケーションを変更すると、複 製エラーが発生して、データの損失につながるおそれがあるので、実 行する場合は十分に注意してください。 Mobile Link ユーザの作成 Mobile Link ユーザは、データベース ユーザと同じではありません。そ れぞれのタイプのユーザは、別の名前空間に置かれています。Mobile Link ユーザ ID がデータベース ユーザの名前と一致することはありま すが、これは必須ではありません。 ❖ Sybase Central で Mobile Link ユーザをリモート データベースに追加するには 1 229 ページの「Sybase Central への接続」に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、[新しい Mobile Link ユー ザ]ボタンをクリックします。 アプリケーション テクニック 231 リモート データベースの作成 3 Mobile Link ユーザの名前を入力します。 名前は、同期中に Mobile Link 同期サーバに入力されます。本稼動 データベースでは、通常、各ユーザ名が統合データベースに追加 され、個別のユーザに提供されます。 4 [完了]をクリックします。 ❖ Sybase Central でユーザ プロパティを設定するには 1 229 ページの「Sybase Central への接続」に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、Mobile Link ユーザを右ク リックし、ポップアップ メニューから[プロパティ]を選択します。 3 ❖ 必要に応じてプロパティを変更します。 Sybase Central で Mobile Link ユーザを削除するには 1 229 ページの「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+ スイッチを指定してサーバを起動できます。 232 PowerBuilder 第 13 章 MobiLink 同期の使い方 リモート データベースで定義された任意のユーザは、authenticate_user 接続イベントのスクリプトが未定義の間は、統合データベースの ml_user テーブルに追加されます。通常、-zu+ スイッチは、本稼働環境 では使用されません。名前は、通常、統合データベースの ml_user テー ブルに追加され、その後各リモート データベースに追加されます。各 ユーザには、固有の名前とオプションのパスワードが与えられます。 サブスクリプションの追加 同期サブスクリプションは、特定の Mobile Link ユーザとパブリケー ションをリンクします。同期に必要なほかの情報も含めることができ ます。たとえば、Mobile Link サーバのアドレス、およびその他の接続 オプションを指定できます。特定のサブスクリプションの値は、個別 の Mobile Link ユーザの設定を上書きします。 ウィザードでのオプションの上書き ASA MobiLink 同期ウィザードで、サブスクリプションとユーザに設定 されている Mobile Link サーバ名およびポート設定を上書きできます。 同期サブスクリプションは、Mobile Link ASA リモート データベース で必要です。サーバ ロジックは、統合データベースの Mobile Link シ ステム テーブルに格納されている同期スクリプトを通じて実装され ます。 単一の ASA データベースが、複数の Mobile Link 同期サーバと同期を 取ることができます。複数のサーバとの同期を可能にするには、各ユー ザに対して異なるサブスクリプションを作成します。 ❖ Sybase Central で Mobile Link ユーザのサブスクリプションを追加するには 1 229 ページの「Sybase Central への接続」に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダを開き、サブスクリプションを追加 するユーザを選択します。 3 [同期サブスクリプション]ページで[新しい同期サブスクリプ ション]ボタンをクリックします。 4 アプリケーション テクニック サブスクリプションを追加する[パブリケーション]を選択し、 [完了]をクリックします。 233 同期のテクニック ❖ Sybase Central でサブスクリプションを変更するには 1 229 ページの「Sybase Central への接続」に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダから Mobile Link ユーザを開き、同 期サブスクリプションを右クリックし、ポップアップ メニューか ら[プロパティ]を選択します。 3 ❖ 必要に応じてプロパティを変更します。 Sybase Central で同期サブスクリプションを削除するには 1 229 ページの「Sybase Central への接続」に従って、Sybase Central に接続します。 2 [Mobile Link ユーザ]フォルダから Mobile Link ユーザを開き、同 期サブスクリプションを右クリックし、ポップアップ メニューか ら[削除]を選択します。 同期のテクニック この節では、Mobile Link 同期を使用するアプリケーションの設計で考 慮が必要な問題を取り上げます。これらのすべての問題についての詳 細は、『Mobile Link 同期ユーザーズ・ガイド』マニュアルの同期のテ クニックについての章を参照してください。 データのダウンロード の制限 同期の主要な目的の 1 つは、移動されるデータの量を制限することに よって、データ移動の高速化と効率化を図ることです。download_cursor スクリプトによって転送されるデータを制限するために、タイムスタ ンプ、Mobile Link ユーザ名、またはその両方に基づいてデータを分割 できます。 タイムスタンプによる分割 ダウンロードを、前回のダウンロード以降 に変更されたデータに限定するには、統合データベースの各テーブル に last_modified カラムを追加する方法があります。テーブル自体を変更 できない場合は、主キーを保持し、download_cursor スクリプトでオリ ジナルのテーブルに結合されるシャドウ テーブルに追加します。 last_modified カラムは、統合データベースにだけ追加する必要がありま す。 ASA では、このカラム用に組み込みの DEFAULT TIMESTAMP データ型 を使用できます。他の DBMS では、更新トリガを提供して、last_modified カラムのタイムスタンプを設定する必要があります。 234 PowerBuilder 第 13 章 MobiLink 同期の使い方 タイムスタンプは、統合データベースで生成され、同期中には変更さ れずにリモート データベースにダウンロードされます。リモート デー タベースのタイム ゾーンはこれに影響しません。 ユーザベースの分割 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 は、衝 突の検出と解決のためのメカニズムを提供しています。 リモート データベー スだけからの行の削除 デフォルトでは、ユーザが同期を開始すると、前回の同期以降にデー タベースに対して行われたすべての変更の最終結果が統合データベー スにアップロードされます。しかし、データが古くなったり、顧客が 別の販売担当に移されたりしたことで、リモート ユーザがリモート データベースの特定の行を削除して空き容量を再取得している場合が あります。通常は、検出されたこれらの行を統合データベースから削 除しないでください。 削除行を処理する方法として、PowerBuilder アプリケーションのスク リプトで STOP SYNCHRONIZATION DELETE コマンドを使用して、それに 続く SQL DELETE ステートメントをトランザクション ログから隠す方 法 が あ り ま す。そ の 接 続 で の そ れ 以 降 の DELETE 操 作 は、START SYNCHRONIZATION DELETE ステートメントが実行されるまで同期され ません。 アプリケーション テクニック 235 同期のテクニック たとえば、Delete Local というメニュー項目を提供し、削除を扱うコー ドを次の例のようにラップできます。 STOP SYNCHRONIZATION DELETE; // 削除操作を実行するコードを呼び出します。 START SYNCHRONIZATION DELETE; COMMIT; 削除については、ほかの方法でも対処できます。詳細については、 『Mobile Link 同期ユーザーズ・ガイド』マニュアルの同期のテクニッ クについての章を参照してください。 236 PowerBuilder 第 1 4 章 PowerBuilder XML サービスの使 い方 この章について この章では、PowerBuilder の XML サービスの概要について説明し ます。PowerBuilder ドキュメント オブジェクト モデル(PBDOM: PowerBuilder Document Object Model)と、それを PowerBuilder ア プリケーションで使う方法について説明します。 内容 項目 XML と PowerBuilder について PBDOM について PBDOM オブジェクト階層 PBDOM ノード オブジェクト ライブラリ探索パスへの pbdom100.pbd の追加 PBDOM の使い方 PBDOM 例外の処理 XML 名前空間 ページ 237 238 239 240 256 257 264 265 XML と PowerBuilder について PowerBuilder には、Extensible Markup Language(XML)を扱うた めの機能がいくつかあります。以下のことを行うことができます。 アプリケーション テクニック • データウィンドウ オブジェクト内のデータを XML にエクス ポートし、XML ドキュメント内のデータ、または文字列を データウィンドウ オブジェクトにインポートする • PowerScript 関数の XMLParseFile と XMLParseString を使用して、 XML ドキュメントや文字列が well-formed(整形式)であるか、 あるいはスキーマや DTD に準拠しているかを判断する • XML ドキュメントの作成および処理を行うアプリケーション とコンポーネントを作成する 237 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 ドキュメントの 読み込みと修正が行えます。 238 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 オブジェクト階層 アプリケーション テクニック 239 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 クラス を拡張します。このクラスの詳細については、264 ページの「PBDOM 例外の処理」を参照してください。 PBDOM ノード オブジェクト この節では、PBDOM_OBJECT クラスと、そのクラスを継承するすべ てのクラスについて説明します。 240 • 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 のテキスト データを取得する アプリケーション テクニック 241 PBDOM ノード オブジェクト • HasChildren では、PBDOM_OBJECT に子があるかどうかを判断す る • 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 から派生したクラスの任意のオブジェクトに対して 有効に動作します。 スタンドアロン オブ ジェクト 242 PBDOM_OBJECT は、すべてのドキュメントや親の PBDOM_OBJECT から独立した自己完結型のオブジェクトを作成できます。このような PBDOM_OBJECT をスタンドアロン オブジェクトと呼びます。たとえ ば、次のようになります。 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 PBDOM_ELEMENT pbdom_elem_1 pbdom_elem_1 = Create PBDOM_ELEMENT 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 メソッドでは、 ルート要素、処理命令などのドキュメントレベル情報にアクセスでき ます。 アプリケーション テクニック 243 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 メソッドを使用して、要素属性、子、 およびテキストにアクセスできます。 メソッド 244 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 の関係 ルート と 子 を結ぶ実線は、親子関係を表します。点線は、属性とその オーナ要素との間の「~のプロパティ」という関係を表します。 アプリケーション テクニック 245 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)からデタッチ されます。 属性と名前空間の詳細については、265 ページの「XML 名前空間」を 参照してください。 246 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") アプリケーション テクニック 247 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 248 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())) アプリケーション テクニック 249 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 を拡張し、文字データの操作専用のメソッドを持ちます。 メソッド 250 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 テキスト ノードを表します。 アプリケーション テクニック 251 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 オブジェクトがあります。 252 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」を表します。 アプリケーション テクニック 253 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 クラスから派生します。 メソッド 254 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 になる 255 ライブラリ探索パスへの pbdom100.pbd の追加 ライブラリ探索パスへの pbdom100.pbd の追加 PBDOM ク ラ ス は DLL フ ァ イ ル pbdom100.pbx に 実 装 さ れ ま す。 PBDOM クラスを PowerBuilder アプリケーションで使用するには、 pbdom100.pbx をアプリケーションのパスに置き、pbdom100.pbd ファイ ルをアプリケーションのライブラリ探索パスに追加する必要がありま す。PBD は、DLL のラッパーとして動作し、これにより PowerBuilder アプリケーションは、PowerBuilder クラスのユーザ オブジェクトを使 用するのと同じように、DLL 内で PBDOM クラスを使用できます。 pbdom100.pbx ファイルと pbdom100.pbd ファイルは、PowerBuilder のイ ンストール時に Shared\PowerBuilder ディレクトリに配置されます。 PBDOM アプリケーションの作成時に pbdom100.pbx を別の場所にコ ピーする必要はありませんが、アプリケーションの探索パス中のディ レクトリに、このファイルをアプリケーションとともに配布する必要 があります。 pbdom100.pbd ファイルは、アプリケーションのライブラリ リスト内に ある必要があります。テンプレート アプリケーション ウィザードを使 用して、ウィザード内でアプリケーション ターゲットの作成および PBD ファイルの追加を行えます。アプリケーション ウィザードを使用 するか、既存のターゲットがある場合、ターゲットのプロパティ ダイ アログボックスで、ライブラリ リストに PBD ファイルを追加できま す。 ❖ pbdom100.pbd を新規ターゲットの探索パスに追加するには 1 新規作成 ダイアログボックスで、[テンプレート アプリケーショ ン ウィザード]アイコンを選択し、ウィザードの指示に従って[ア プリケーション ライブラリ検索パスの追加]ページまで進みます。 2 参照([...] )ボタンをクリックし、Shared\PowerBuilder ディレクト リに移動します。 3 [ファイルの種類]ドロップダウン リストから「PB ダイナミック ライブラリ」を選び、「pbdom100.pbd」を選択して、[開く]をク リックします。 4 ❖ ウィザードを完了します。 pbdom100.pbd を既存ターゲットの探索パスに追加するには 1 システムツリー内でクライアント ターゲットを右クリックし、 ポップアップ メニューから[プロパティ]を選択します。 2 [ライブラリ リスト]ページで[参照]を選択し、 Shared\PowerBuilder ディレクトリに移動します。 256 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 3 [ファイルの種類]ドロップダウン リストから「PB ダイナミック ライブラリ」を選び、「pbdom100.pbd」を選択して、ダイアログ ボックスを閉じます。 pbdom100.pbd を追加した後、PBDOM オブジェクトがシステム ツリー に表示されます。 PBDOM の使い方 この節では、PBDOM のクラスおよびメソッドを使用して基本的なタ スクを遂行する方法について説明します。ダウンロードしてテストで きる完全なコード サンプルを見るには、Windows の[スタート|プロ グラム| Sybase | PowerBuilder 10.0 | PB 10 コード サンプル]を選択 します。 アプリケーション テクニック 257 PBDOM の使い方 XML の検証 ファイルか文字列からドキュメントを作成する前に、XMLParseFile PowerScript 関数または XMLParseString PowerScript 関数を使用して、そ の XML が well formed(整形式)であるかどうか、あるいはオプショ ンで、DTD かスキーマに準拠しているかどうかをテストできます。た とえば、次のコードは、ファイル内の XML が well formed(整形式)で あるかどうかをテストします。 long ll_ret ll_ret = XMLParseFile("c:\temp\mydoc.xml", ValNever!) デフォルトでは、これらの関数により、エラーが発生した場合にメッ セージ ボックスが表示されます。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>" 258 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 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") BuildFromDataStore の使い方 次に示す 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 アプリケーション テクニック 259 PBDOM の使い方 解析エラー 解析エラーが検出され、GetParseErrors が true を返した場合、調べるこ とができる完全な 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) 260 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 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() 要素オブジェクト 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/> アプリケーション テクニック 261 PBDOM の使い方 </Element_1> <Element_2/> <Element_3/> </Root> 次のコードは、GetContent メソッドから返された要素を格納する配列 を宣言します。このメソッドは、pbdom_doc という名前の PBDOM_DOCUMENT オブジェクトを読み込みます。 PBDOM_OBJECT pbdom_obj_array[] ... 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> 262 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 配列とオブジェクト参照 PBDOM_DOCUMENT クラスの GetContent メソッドなどのメソッドを 使 用 し て PBDOM_OBJECT 参 照 の 配 列 を 返 す 場 合、そ の 参 照 は PBDOM オブジェクトに対するものです。配列項目を通してこれらの オブジェクトのいずれかを修正した場合、変更内容は永続し、同じオ ブジェクト参照を持つほかのすべての配列に反映されます。 ノード ツリー階層の操作 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(オブジェクトが別のオブジェクトの先 祖かどうかを示す)などです。 アプリケーション テクニック 263 PBDOM 例外の処理 PBDOM 例外の処理 PBDOM は、標準の PowerBuilder Exception クラスから派生する例外ク ラス PBDOM_EXCEPTION を定義します。Exception クラスの標準 Text プロパティを使用して、送出される例外の性質に関する詳細を知るこ とができます。このクラスは PowerBuilder Exception クラスを拡張し、 1 つのメソッド GetExceptionCode を持ちます。このメソッドは、送出さ れる例外を識別する固有のコードを返します。 例外コードのリストについては、『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 264 PowerBuilder 第 14 章 PowerBuilder XML サービスの使い方 CATCH ( PBDOM_Exception pbde ) MessageBox( "PBDOM 例外 ", pbde.getMessage() ) CATCH ( PBXRuntimeError re ) MessageBox( "PBNI 例外 ", re.getMessage() ) END TRY 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="" アプリケーション テクニック 265 XML 名前空間 含んでいる要素とその子要素を名前空間内に配置しないよう宣言しま す。NONAMESPACE の名前空間内の要素には、空の文字列に設定され た名前空間の接頭辞および URI セットが付けられています。 初期状態 PBDOM_ELEMENT か PBDOM_ATTRIBUTE を初めて作成したとき、 そ れ に は 名 前 が あ り ま せ ん。名 前 空 間 の 情 報 は、デ フ ォ ル ト で NONAMESPACE に設定されています。(つまり、その名前空間の接頭 辞と URI はどちらも空の文字列です。)SetName メソッドを使用して ローカル名を設定し、SetNamespace メソッドを使用して名前空間の接 頭辞と URI を設定します。 名前は必須 名前は 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" /> 266 PowerBuilder 第 14 章 <bad n1:a="1" </x> PowerBuilder XML サービスの使い方 n2:a="2" /> <!-- 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> 最初の例では、<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[]) メソッドを呼び出す場合 : 267 XML 名前空間 配列内で、いずれか 2 つの PBDOM_ATTRIBUTE オブジェクトが 同じ名前および同じ名前空間 URI を持つ場合、 EXCEPTION_INVALID_NAME 例外が送出されます。名前の衝突 または名前空間の衝突が配列内にない場合、PBDOM_ELEMENT のすべての既存の属性が、配列内で PBDOM_ATTRIBUTE オブ ジェクトに置き換えられます。 注意 上のシナリオはすべて、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> 268 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 アプリケーション テクニック 269 XML 名前空間 SaveDocument からの XML 出力は、次のようになります。 <root xmlns:pre1="http://www.pre.com" xmlns:pre2="http://www.pre.com"> <child1 pre2:a="456"/> </root> 270 PowerBuilder 第 1 5 章 グラフの操作 この章について この章では、実行時に、アプリケーションのグラフにアクセスし て変更するためのコードの記述方法について説明します。 内容 項目 グラフの使い方 グラフへのデータ表示 グラフのプロパティの修正 データのプロパティへのアクセス ポイント アンド クリックの使い方 ページ 271 273 275 277 279 グラフの使い方 PowerBuilder でグラフを表示するには、2 つの方法があります。 • データウィンドウで、データウィンドウ データ ソースから取 り出したデータを使用する方法 • ユーザ オブジェクトまたはウィンドウ内のグラフ コントロー ルで、アプリケーション コードから提供されたデータを使用 する方法 この章では、グラフ コントロールについて検討し、アプリケーショ ン コードを使用してグラフにデータを提供し、その外観を操作す る方法について説明します。 データウィンドウのグラフについての詳細は、 『データウィンドウ プログラマーズ ガイド』マニュアルと『データウィンドウ リファ レンス』マニュアルを参照してください。 ペインタにおけるグラフのデザインとグラフ プロパティの設定に ついては、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照し てください。 アプリケーション テクニック 271 グラフの使い方 コードにおけるグラフ コントロールの操作 ウィンドウ内のグラフ コントロールは、使用可能 / 使用不可、表示 / 非表示を切り替えることができ、ドラッグ アンド ドロップを使用でき ます。また、グラフ コントロールのイベントおよび補助的なグラフ関 数を使用するコードも記述できます。 グラフ コントロール のプロパティ グラフにアクセスする(そしてオプションで修正する)には、実行時 にスクリプトでグラフのプロパティを操作します。グラフのプロパ ティには次の 2 種類があります。 • グラフ定義自体のプロパティ これは、グラフを作成するときにデー タウィンドウ ペインタで最初に設定するプロパティです。グラフ の種類、タイトル、軸ラベルを設定し、軸に目盛りを付けるかど うかを指定します。 • データのプロパティ これらのプロパティは、実行時にデータがグ ラフにロードされたときにだけ関係します。これらのプロパティ では、グラフ内の系列数(系列は実行時に作成される)、系列の横 棒または縦棒の色、系列がオーバーレイかどうか、項目の文字(項 目は実行時に作成される)などを設定します。 グラフ コントロール のイベント グラフ コントロールには、表 15-1 にリストされているイベントがあり ます。 表 15-1: グラフ コントロールのイベント Clicked DragLeave Constructor DragWithin Destructor GetFocus DoubleClicked LoseFocus DragDrop Other DragEnter RButtonDown たとえば、 (グラフが使用できる状態で)エンド ユーザがグラフをク リックしたとき、またはオブジェクトをグラフ上にドラッグしたとき に起動されるようなスクリプトを記述できます。 グラフ コントロール 用の関数 272 表 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 ) アプリケーション テクニック 273 グラフへのデータ表示 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") 274 PowerBuilder 第 15 章 グラフの操作 次に実行結果のグラフを示します。 実行時には、グラフ関数を介して、ウィンドウ内のグラフのデータを 追加、修正、または削除できます。 詳細情報 各グラフ関数についての詳細は、『PowerScript リファレンス』マニュ アルを参照してください。 グラフのプロパティの修正 ウィンドウまたはユーザ オブジェクト ペインタでグラフを定義する ときは、その動作と表示方法を指定します。たとえば、何らかのタイ トルをもつ縦棒グラフとしてグラフを定義し、数値軸を 4 つの目盛り に分割します。各入力項目は、グラフのプロパティに対応します。ど のグラフにも、グラフの種類を指定するカタログ型の属性 GraphType があります。 グラフの種類の動的な変更 グラフの種類を変更する場合、新しいグラフを正しく定義するには、 必要に応じてほかのプロパティも変更しなければなりません。 実行時にこれらのグラフ プロパティを変更するには、スクリプトでグ ラフ プロパティに値を割り当てます。たとえば、グラフ gr_emp の種 類を縦棒グラフに変更するには、次のコードを使用します。 gr_emp.GraphType = ColGraph! 実行時にグラフのタイトルを変更するには、次のコードを使用します。 gr_emp.Title = " 新しいタイトル " アプリケーション テクニック 275 グラフのプロパティの修正 グラフ要素の表示 グラフは、タイトル、凡例、および軸で構成されます。これらの要素 には、それぞれ表示プロパティがあります。これらの表示プロパティ は、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 プロパティに格納されています。 276 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() アプリケーション テクニック 277 データのプロパティへのアクセス データウィンドウにおけるグラフのさまざまな構文 次に示すように、グラフがデータウィンドウ内にある場合には、同じ 関数の構文がもっと複雑になります。 DataWindowName.FunctionName ( "graphName", otherArguments... ) 詳細については、『データウィンドウ プログラマーズ ガイド』マニュ アルを参照してください。 データの情報の取得 表 15-3 の PowerScript 関数を使用すれば、実行時にグラフ内のデータ に関する情報を取得できます。 表 15-3: 実行時に情報を取得するための PowerScript 関数 関数 CategoryCount CategoryName DataCount FindCategory FindSeries GetData GetDataPieExplode GetDataStyle GetDataValue GetSeriesStyle ObjectAtPointer SeriesCount SeriesName 278 受け取る情報 グラフ内の項目数 指定された項目番号に対応する項目名 系列内のデータ ポイント数 指定された項目名に対応する項目番号 指定された系列名に対応する系列番号 指定された系列と位置に対応するデータ ポイント値 (GetDataValue の方が柔軟性が高い) 円グラフのスライスを突出させる割合 指定されたデータ ポイントの色や模様など表示関係 のプロパティ 指定された系列と位置に対応するデータ ポイント値 指定された系列の色や模様などの表示関係のプロパ ティ マウスがクリックされたときにポイントされている グラフの要素 グラフ内の系列数 指定された系列番号に対応する系列名 PowerBuilder 第 15 章 グラフの操作 グラフのデータの保存 表 15-4 の PowerScript 関数を使って、グラフからのデータを保存でき ます。 表 15-4: グラフのデータの保存に使用する PowerScript 関数 関数 Clipboard SaveAs 動作内容 指定されたグラフのビットマップ イメージをクリッ プボードにコピー 基になるグラフ内のデータをクリップボードまたは さまざまな書式のファイルに保存 色や模様、そのほかのデータの修正 表 15-5 の PowerScript 関数を使って、グラフ内のデータの表示方法を 修正できます。 表 15-5: データの表示を修正するための PowerScript 関数 関数 ResetDataColors SetDataPieExplode SetDataStyle SetSeriesStyle 動作内容 指定されたデータ ポイントの色をリセット 円グラフ内のスライスを突出させる 指定されたデータ ポイントの色や模様などの表示関 係のプロパティを設定 系列の色や模様などの表示関係のプロパティを設定 ポイント アンド クリックの使い方 エンド ユーザは、実行時にグラフをクリックできます。PowerScript に は、何がクリックされたかという情報を格納する ObjectAtPointer 関数が あります。この関数は、Clicked イベントにおいてさまざまな方法で使 用できます。たとえば、グラフ内のデータ値をポイント アンド クリッ クして、メッセージ ボックス内にその値に関する情報を表示する機能 を付けることができます。この節では、その方法について説明します。 Clicked イベントとグ ラフ エンド ユーザがグラフをクリックしたときにアクションが起動する ように、グラフのコントロールに Clicked スクリプトを記述します。コ ントロールが有効でなければ、Clicked イベントは発生しません。 アプリケーション テクニック 279 ポイント アンド クリックの使い方 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 280 PowerBuilder 第 15 章 グラフの操作 // 次の関数は、クリックされた系列の番号を // 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 アプリケーション テクニック 281 ポイント アンド クリックの使い方 282 PowerBuilder 第 1 6 章 リッチテキストの作成方法 この章について この章では、リッチテキスト データウィンドウ オブジェクトと リッチテキスト エディット コントロールにおける、リッチテキス トの使い方について説明します。 内容 はじめに 項目 アプリケーションにおけるリッチテキストの使い方 リッチテキスト データウィンドウ オブジェクトの使い方 リッチテキスト エディット コントロールの使い方 リッチテキストとエンド ユーザ ページ 283 284 287 305 この章は、 『PowerBuilder ユーザーズ ガイド』マニュアルで解説さ れている、リッチテキスト データウィンドウ オブジェクトとリッ チテキスト エディット コントロールの作成方法を知っているこ とを前提としています。 アプリケーションにおけるリッチテキストの使い方 リッチテキスト形式(RTF)は、1 つの ASCII 文書中に書式や文書 内容を指定するテキストファイルの標準形式です。リッチテキス ト フォーマットをサポートするエディタは、フォーマット命令を 解釈しフォーマットしたテキストを表示します。 アプリケーションでは、たとえば以下のような処理が可能です。 • リッチテキスト文書の作成用のウィンドウを表示する 本格的なワープロ機能ではありませんが、リッチテキスト エ ディット コントロールを使用することによってエンド ユーザ は、段落、単語、および文字に書式を設定することができます。 • 差し込み印刷をする 開発者またはエンド ユーザは、データベース カラムに関連付 けられた入力フィールドを使用して、文書を作成できます。 • アプリケーション テクニック 書式付きテキストのレポートを表示する 283 リッチテキスト データウィンドウ オブジェクトの使い方 リッチテキスト データウィンドウ オブジェクトは、基本的に、 データ入力よりもデータ表示のために使用されるオブジェクトで す。ほかの提示様式と異なり、データウィンドウ提示様式では編 集様式は使用できません。 • リッチテキストを String 型のデータとしてデータベースに格納し、 リッチテキスト エディット コントロールで表示させる リッチテキストの作成 ワード プロセッサ リッチテキスト形式のファイルを保存またはエクスポートできるワー ド プロセッサを使用して、リッチテキストを作成できます。 PowerBuilder だけの 入力フィールド 多くのワードプロセッサではなんらかの種類のフィールドをサポート していますが、通常それらのフィールドはほかのリッチテキストと互 換 性 が あ り ま せ ん。PowerBuilder ア プ リ ケ ー シ ョ ン に お い て 入 力 フィールドを指定するには、PowerBuilder のリッチテキスト エディッ ト コントロールを使用してフィールドを挿入しなければなりません。 データベースにおける リッチテキスト リッチテキストは ASCII 文字によって表現されているため、データ ベースの String 型カラムや文字列変数に格納することもできます。 デ ー タ ベ ー ス の String 型 カ ラ ム か ら リ ッ チ テ キ ス ト を 取 得 し、 PasteRTF 関数を使用してリッチテキスト エディット コントロールに 書式付きテキストを表示できます。 リッチテキスト データウィンドウ オブジェクトの使い方 この節では、以下の項目について説明します。 ページ スクロール 284 • ほかの提示様式とのページ スクロールの違い • 新しい行におけるデフォルト値と入力条件則 • エンド ユーザが変更を行ったときの動作 リッチテキスト データウィンドウ オブジェクトでは、複数ページの リッチテキスト(文書テンプレート)を作成でき、1 行のデータが複 数ページにまたがることもあります。これに対して、ほかの提示様式 では、1 ページに複数行のデータが表示されることもあります。 PowerBuilder 第 16 章 リッチテキストの作成方法 リッチテキスト データウィンドウ オブジェクトでは、1 ページの構成 がほかの提示様式と異なるため、スクロール関数はほかの提示様式と は異なる動作をします。 • ScrollNextRow 関数と ScrollPriorRow 関数は、データベース テーブル の行から行へと移動するので、リッチテキスト(文書テンプレー ト)内において、前の行または次の行のデータを表示します。 • ScrollNextPage 関数と ScrollPriorPage 関数は、行ではなく、文書の ページをスクロールします。 改ページ スクロールすると、行から行へと移動します。文書の最終 ページで次ページへスクロールすると、次の行の最初のページへ移動 します。ユーザは、文書内の多くのインスタンスでスクロールの効果 を利用することができます。 新しい行 : デフォルト のデータと入力条件則 入力フィールドに値がない場合、入力フィールドは非表示になります。 入力フィールドが見えるように、データが検索される前は、入力フィー ルドには疑問符(??)が表示されます。新しい行に対しては、カラム のデータ型を基に入力フィールドに初期値が設定されます。 カラムにすでに初期値が設定されている場合は、その値が使用されま す。初期値が設定されていない場合、PowerBuilder は、String 型のカラ ムに対しては空白文字(スペース)を、numeric 型のカラムに対しては ゼロを初期値として設定します。 PowerBuilder で提供されるデフォルトの初期値が入 力条件則を満たさない場合、新しい行が挿入された直後にエンド ユー ザに入力条件則エラーが表示されます。これを回避するためには、入 力条件則に合う初期値を指定する必要があります。 入力条件則エラー エンド ユーザによる 変更 編集禁止の指定 リッチテキストオブジェクト プロパティ シートの [全 般]タブ ページで[編集禁止]チェックボックスをオンにすると、エ ンド ユーザはデータおよびテキストを一切変更できなくなります。 [ポップアップ メニュー]チェックボックスをオンにした場合は、エ ンド ユーザはプロパティ シートを開くことができるので、 [編集禁止] チェックボックスをオフにして、データウィンドウ オブジェクトを編 集可能にすることができます。 入力フィールド 編集可能なリッチテキスト データウィンドウでは、エ ンド ユーザはカラムの入力フィールドを選択して点滅させ、スペース キーを押しアクティブにして、値を入力することができます。入力 フィールドのプロパティ シートを表示し、[データ値]テキストボッ クスを編集することもできます。計算フィールドに対応する入力 フィールドの場合、[データ値]テキストボックスは変更できません。 アプリケーション テクニック 285 リッチテキスト データウィンドウ オブジェクトの使い方 データのかわりに入力フィールド名を表示させることができます。 データのかわりに入力フィールド名を表示して、エンド ユーザが独自 にリッチテキスト データウィンドウを作成できる編集環境を提供す ることもできます。しかし、エンド ユーザに編集環境を提供したい場 合は、リッチテキスト データウィンドウよりも、スクリプトで制御で きるリッチテキスト エディット コントロールを使用する方が適して います。 リッチテキスト エンド ユーザがテキストまたは書式を変更した場合 は、文書テンプレートが変更されたことになります。変更はすべての 行に現れます。 文書テンプレートに対する変更を保存するスクリプトを記述しておか ないと、エンド ユーザが行った変更は現行のセッションだけに適用さ れ、次回まで保持されません。 変更を保存するには、CopyRTF 関数を使用します。この関数は、入力 フィールドを含むすべてのテキストを取得しますが、行データは取得 しません。その後、取得した文字列をファイルまたはデータベースに 保存します。これによって、エンド ユーザがリッチテキスト データ ウィンドウを操作するときに、前回の変更点を復元して表示させたり、 オリジナルの文書テンプレートに戻して表示させることができます。 リッチテキスト デー タウィンドウにおける 関数 データウィンドウ コントロールには、数多くの関数があります。 同様に動作する関数 Update 関数や Retrieve 関数のようなデータ操作関 数は、すべての提示様式のデータウィンドウ オブジェクトに対して同 様に動作します。 コントロール内のオブジェクトがリッチテキスト データウィンドウ オブジェクトである場合には、一部の関数は適用されないか、異なる 動作を行います。 適用されない関数 関数の中には、リッチテキスト データウィンドウ オ ブジェクトでは使用できないものもあります。以下の関数は、エラー を返すか、または何も処理を行いません。 • グラフとクロスタブ データウィンドウ オブジェクトのための関数 • グループ化のための関数 : GroupCalc、FindGroupChange • コード表のための関数 : GetValue、SetValue • 行選択のための関数 : SelectRow、SetRowFocusIndicator、 GetSelectedRow • カラムと詳細区域の表示形態を指定するための関数 : SetBorderStyle、 SetDetailHeight 286 PowerBuilder 第 16 章 • ObjectAtPointer • OLEActivate リッチテキストの作成方法 リッチテキスト データウィンドウの場合に異な る動作をする関数もあります。 異なる動作をする関数 • クリップボードのための関数 : Copy、Clear など • 編集可能なテキストのための関数(ほかの提示様式のエディット コントロールに適用されます): LineCount、Position、SelectText など • Find と FindNext 関数(一般的なデータウィンドウの Find 関数か、 リッチテキストの Find 関数かは、Find 関数に指定する引数によっ て決まります) • ページ スクロール リッチテキスト エディット コントロールの使い方 ウィンドウまたはユーザ オブジェクト上に配置したリッチテキスト エディット コントロールを使用して、エンド ユーザに、書式設定され たテキストを参照させたり、編集させることができます。PowerScript 関数を使用して、テキストの挿入、選択されたテキストの取得、入力 フィールドの管理、内容のプロパティ設定などを行って、コントロー ルの内容を操作できます。 ウィンドウ ペインタまたはユーザ オブジェクト ペインタで、リッチ テキスト エディット コントロールを定義します。 エンド ユーザに制御権を与える ウィンドウまたはユーザ オブジェクト ペインタでは、リッチテキスト エディット コントロールのプロパティ シートの[ドキュメント]ペー ジで、表 16-1 の機能を使用可能または使用不可に設定できます。 アプリケーション テクニック 287 リッチテキスト エディット コントロールの使い方 表 16-1: リッチテキスト エディット コントロールの機能 機能 編集用ツールバー ポップアップ メ ニュー 印刷されない文字の 表示 フィールドの表示 詳細 書式設定、ルーラ、およびタブ プロパティシートや、ファイルの挿入、クリップボー ド コマンドが使用可能 キャリッジ リターン、タブ文字、および半角スペー ス フィールドの表示 / 非表示、フィールド名で表示す るかどうか、およびフィールドの背景色 自動ワードラップ 新たに入力されたテキストだけに影響する 余白 既存の段落に新しいテキストを入力すると、テキス トは、コントロールの右端に達したときにワード ラップされる。コントロールがサイズ可変の場合 は、コントロールのサイズを少し縮小することに よって、既存のテキストをワードラップさせること ができる デフォルトのページ サイズに対応 また、印刷キューに表示される文書の名前を設定することもできます。 文書名は、コントロールに挿入するテキスト ファイルとは関係ありま せん。 エンド ユーザによる プロパティの変更 エンド ユーザは、プロパティ シートを使用して、リッチテキスト文書 のプロパティを設定できますが、開発者が望まない操作を行う可能性 もあります。たとえば以下のような操作を行ってしまうかもしれませ ん。 • 上書き禁止に設定してある文書の[編集禁止]オプションをオフ にして、文書を編集する • ツール バー、ルーラ、タブ バーを非表示にする • データではなく入力フィールド名を表示する • ポップアップ メニューを使用不可にしたため、非表示にしたツー ルを元に戻すことができなくなる このような操作ミスを防ぐために、スクリプトでプロパティ値を変更 することができます。たとえば、以下のスクリプトをコマンドボタン の Clicked イベントに記述して、ポップアップ メニューを表示させる ことができます。 rte_1.PopMenu = TRUE 288 PowerBuilder 第 16 章 変更の取り消し リッチテキストの作成方法 UndoDepth プロパティを設定することによって、アプリケーションに 操作の取り消し機能を持たせることができます。この場合、〔Ctrl〕+ 〔Z〕を押すと、変更は取り消されます。また、コマンドボタンやメ ニュー項目のスクリプトから Undo 関数を呼びだすこともできます。 Undo 関数が繰り返し呼ばれた場合は、UndoDepth プロパティで設定し た上限まで、変更は取り消されます。スクリプトで CanUndo 関数を呼 び出すと、元に戻せる変更があるかどうか(つまり UndoDepth プロパ ティの上限に達しているかどうか)をチェックすることができます。 IF rte_1.CanUndo() THEN rte_1.Undo() ELSE MessageBox(" 停止 ", " 元に戻せる操作がありません ") END IF リッチテキスト エディット コントロールのためのテキスト ウィンドウ ペインタでは、リッチテキスト エディット コントロール にテキストを入力することはできません。そのかわり、アプリケーショ ンにおいて、スクリプトからテキストを挿入したり、エンド ユーザに テキスト入力をさせることができます。 テキストの挿入 ファイルから挿入 InsertFile 関数を使用して、アプリケーションにテキ スト ファイルを挿入することができます。挿入できるファイルは、 リッチテキスト形式または ASCII 形式です。 li_rtn = rte_1.InsertDocument & ("c:\mydir\contacts.rtf", FALSE, FileTypeRichText!) Boolean 型の clearflag 引数によって、ファイルを挿入するのか、既存 のテキストと置き換えるのかを指定できます。 データベースから挿入 データベースに文字列としてリッチテキストを 保存した場合、データストア オブジェクトを使用してテキストを取得 することができます。 以下のスクリプトは、データベースからテキストを取得して、リッチ テキスト エディット コントロールに貼り付けます。 ls_desc = dw_1.Object.prod_desc.Primary[1] rte_1.PasteRTF(ls_desc) アプリケーション テクニック 289 リッチテキスト エディット コントロールの使い方 リッチテキストとクリップボード 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 イベントは、エンド ユーザがテキス トの編集を終えて、コマンドボタンまたはデータウィンドウを選択し たときに起動されます。 290 PowerBuilder 第 16 章 リッチテキストの作成方法 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 関数は、入力フィールドのデータは保存しません。文書 テンプレートを保存します。 アプリケーション テクニック 291 リッチテキスト エディット コントロールの使い方 同名のファイルが存在する場合 フ ァ イ ル が 既 に 存 在 す る 場 合 は、 SaveDocument 関 数 を 呼 ぶ と FileExists イ ベ ン ト が 起 動 さ れ ま す。 FileExists イベントのスクリプトで、エンド ユーザにファイルを上書き するかどうかを問い合わせることができます。 保存処理をキャンセルするには、FileExists イベントのスクリプトでリ ターン コードの 1 を指定します。 保存する必要のある変更があるか Modified プロパティは、リッチテキス ト エディット コントロールの文書が変更されたかどうかを示します。 また、文書が保存されていない状態であることも示します。最初の変 更で Modified イベントが起動されて、Modified プロパティに TRUE が 設定されます。SaveDocument 関数を呼ぶと、文書が保存され、Modified プロパティに FALSE が設定されます。 ファイルをリッチテキスト エディット コントロールに挿入すると、 リッチテキスト エディット コントロールの文書が変更されるので、 Modified イベントが起動されて Modified プロパティに TRUE が設定さ れます。しかし通常の場合、本当に知りたいのはファイルの内容がコ ントロールの内容に対応しているかどうかです。この点を確認するた めには、ファイルを開くスクリプトで、Modefied プロパティを FALSE に設定します。エンド ユーザが文章を編集すると Modified イベントが 起動され、Modified プロパティに TRUE が設定されるので、コントロー ルの文書の内容とファイルの内容が一致していないことがわかりま す。 292 PowerBuilder 第 16 章 リッチテキストの作成方法 ファイルを開く、ファイルを保存する : 例 ファイルを開いたり保存したりするスクリプトの例を示します。エン ド ユーザは、既存のファイルを開いて、リッチテキスト エディット コ ントロールで文書を変更して保存することができます。また、文書を ファイルに保存することもできます。エンド ユーザが開いたファイル に文書を保存する場合は、ファイルの上書きは確認されずにそのまま 保存されます。既存のファイルと同名のファイル名で保存しようとす ると、ファイルの上書きを確認するメッセージボックスが表示されま す。 この例では、インスタンス変数の宣言、スクリプト、関数、イベント について解説します。 インスタンス変数の宣 言 ib_saveas FileExists イベントのためのフラグ。FALSE の場合は、エン ド ユーザが開いたファイルに保存しようとしているため、ファイルは 上書きされます。 boolean ib_saveas=FALSE is_filename 現行ファイル名。初期状態では「タイトル未設定」と設 定されます。 string is_filename アプリケーション テクニック 293 リッチテキスト エディット コントロールの使い方 ファイルを開くための スクリプト 以下のスクリプトは、エンド ユーザが選択したファイルを開きます。 ファイルを開くときに Modified イベントが起動されて Modified プロ パティが TRUE に設定されるので、スクリプトで Modified プロパティ を FALSE にリセットしています。 [変更]チェックボックスの Checked プロパティも、FALSE に設定されています。 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 // ファイル名が無効な場合は、ファイル名を取得します。 294 PowerBuilder 第 16 章 リッチテキストの作成方法 IF is_filename = " タイトル未設定 " THEN cb_saveas.EVENT Clicked() ELSE li_result = Parent.of_save(is_filename) END IF 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 関数は、ファイル名を引数として受け取り、その ファイルに文書を保存します。また、保存したファイル名をインスタ ンス変数 is_filename に設定し、SaveDocument 関数を正常に呼び出せた 後は、自動的に FALSE に設定される Modified プロパティに対応するよ うに、 [変更]チェックボックスの値を設定します。 of_save 関数 integer li_result MessageBox(" ファイル名 ", as_name) // 拡張子が正しい種類の保存を起動するので、 // ファイルの種類は必要ありません。 li_result = rte_1.SaveDocument(as_name) IF li_result = -1 THEN MessageBox(" 警告 ", " ファイルは保存されませんでした ") RETURN -1 ELSE アプリケーション テクニック 295 リッチテキスト エディット コントロールの使い方 // ファイルが正常に保存された場合。 is_filename = as_name st_filename.Text = is_filename cbx_modified.Checked = rte_1.Modified RETURN 1 END IF 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 296 PowerBuilder 第 16 章 リッチテキストの作成方法 Modified イベント [変更] チェックボックスに値を設定し、エンド ユー ザに、文書の変更が保存されていないことを表示します。Modified プ ロパティは、Modified イベントが起動されたときに自動的に設定され ます。リッチテキスト エディット コントロールの文書が変更されたと きに、Modified イベントが起動されます。 cbx_modified.Checked = TRUE 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 リッチテキストの書式設定 リッチテキスト コントロールには、ユーザがアドレス指定可能なオブ ジェクトがいくつか存在します。 • 文書(リッチテキスト データウィンドウ)全体 • 選択されたテキストと段落 • 入力フィールド • ピクチャ エンド ユーザは上記のオブジェクトを選択したり、ツールバーを使用 したり、プロパティ シートを表示することができます。 アプリケーション テクニック 297 リッチテキスト エディット コントロールの使い方 開発者またはエンドユーザが入力フィールドにデータを入力したり、 DataSource を呼び出してコントロールをデータウィンドウ オブジェク トまたはデータストアに関連付けることによって、入力フィールドは 値を取得します。 入力フィールド 入力フィールドは、名前付きの値です。入力フィールドは、名前を付 けて、値を設定して使用します。値は、入力フィールド名に関連付け られます。入力フィールドがコピーされていて、同じ名前の入力フィー ルドが複数ある場合、すべての入力フィールドに同じ値が表示されま す。また、エンド ユーザが入力フィールドの値を変更すると、その変 更は、同じ名前のすべての入力フィールドに反映されます。 以下のサンプル テキストでは、入力フィールド customer をコピーして 3 箇所で使用しています。 {customer} 様 {customer} 様からご注文いただいた品が入荷されております。ま た、30 日からセールが始まりますので、{customer} 様のお知り合 いにもお声をおかけください。 スクリプトで、入力フィールド customer にデータ値を設定することが できます。 rte_1.InputFieldChangeData("customer", " 本田 ") テキストは、以下のように表示されます。 本田様 本田様からご注文いただいた品が入荷されております。また、30 日からセールが始まりますので、本田様のお知り合いにもお声を おかけください。 さらに、エンド ユーザも、データ値を設定することができます。以下 のいずれかの方法を使用します。 • 入力フィールドを選択して(クリックして点滅させます)、新しい データ値を入力します。 • 入力フィールド オブジェクト プロパティ シートを表示して、[全 般]タブ ページの[データ値]テキストボックスを編集します。 スクリプトで入力フィールドを挿入 InputFieldInsert 関数は、挿入ポイント に入力フィールドを挿入します。 rtn = rte_1.InputFieldInsert("datafield") 298 PowerBuilder 第 16 章 リッチテキストの作成方法 たとえば、リッチテキスト編集アプリケーションで、エンド ユーザに 入力フィールドを挿入させるとします。この場合、エンド ユーザに入 力フィールド名を指定させる方法が必要です。 たとえば、エンド ユーザに、リストボックスから入力フィールド名を 選択させるとします。以下のスクリプトは、選択された入力フィール ド名を使用して、挿入ポイントに入力フィールドを挿入します。 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 日付とページ番号のた めの入力フィールド ❖ 日付やページ番号を入れて文書を印刷するには、入力フィールドを定 義して、その入力フィールドに日付やページ番号を設定します。 文書に日付を入れるには 1 テキスト中に入力フィールドを作成し、入力フィールド名を指定 します。 2 ウィンドウの Open イベントなどで、入力フィールドのデータ値に 今日の日付を設定します。 たとえば、本文に入力フィールド today が含まれている場合、入力 フィールドにデータ値を設定するスクリプトは、以下のように記述し ます。 integer li_rtn li_rtn = rte_1.InputFieldChangeData( "today", & String(Today()) ) 印刷時にページ番号を設定する方法については、302 ページの「プレ ビューと印刷」を参照してください。 アプリケーション テクニック 299 リッチテキスト エディット コントロールの使い方 データベースのデータの使い方 リッチテキスト エディット コントロールを、データウィンドウ コン トロールまたはデータストア オブジェクトと関連付けることができ ます。入力フィールド名が、データウィンドウ オブジェクトのカラム 名または計算フィールド名と一致する場合、入力フィールドはその同 じカラム名のデータを表示します。 リッチテキスト エディット コントロールにデータ ソースがあるかな いかにかかわらず、リッチテキストの内容は常に 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} から福島県に転 勤を希望する場合は、会社がすべての経費をカバーします。 行とページの操作 リッチテキスト エディット コントロールでは、エンド ユーザはペー ジ単位で文書をスクロールすることができます。ページ単位ではなく 行単位でスクロールさせるには、そのためのコマンドボタンを追加し、 スクリプトを記述しなければなりません。 [前の行へ移動]ボタンと[次の行へ移動]ボタンを追加する必要があ ります。スクリプトは簡単です。 [次の行へ移動]ボタンでは、以下の ように記述します。 rte_1.ScrollNextRow() [前の行へ移動]ボタンでは、以下のように記述します。 rte_1.ScrollPriorRow() 300 PowerBuilder 第 16 章 リッチテキストの作成方法 ページ ボタンを用意することもできます。エンド ユーザが最終ページ で次ページへスクロールすると、先頭ページの次の行に対応するデー タ値を表示します。 rte_1.ScrollNextPage() リッチテキスト エディット コントロールにおけるカーソル位置 関数を使用して、リッチテキスト エディット コントロールで選択され ている項目を取得したり、テキストを選択したりすることができます。 挿入ポイントの位置と 選択されている内容の 判定 テキストには常に挿入ポイントがあり、挿入ポイントが、選択された テキストを含むこともあります。テキストが選択されている場合、挿 入ポイントの位置は選択範囲の先頭または最後になります。テキスト を前から後ろへドラッグして選択した場合、挿入ポイントは選択範囲 の最後にあります。テキストを後ろから前へドラッグして選択した場 合、挿入ポイントは選択範囲の先頭にあります。 Position 関数は、テキストの選択範囲と挿入ポイントに関する情報を提 供します。 Position 関数についての詳細は『PowerScript リファレンス』マニュア ルを参照してください。 プログラムによるテキ ストの選択 以下の関数を使用して、挿入ポイントの位置から相対的にテキストを 選択することができます。 • SelectTextWord 関数 • SelectTextLine 関数 • SelectTextAll 関数 最も一般的なテキスト選択の関数は、SelectText 関数です。テキストの 選択範囲を、最初と最後の行番号と文字番号で指定します。 SelectText 関数へ値を渡す Position 関数で得られる値は、テキストの選 択範囲だけではないので、その値を直接 SelectText 関数に渡すことはで きません。特に、ゼロは選択範囲を示すには意味がありますが、テキ スト選択には有効な値ではありません。 Position 関数についての詳細は『PowerScript リファレンス』マニュア ルを参照してください。 スペルチェックのために、1 つずつ単語を選択したい場合は、 『PowerScript リファレンス』マニュアルの SelectTextWord 関数を参照してください。 アプリケーション テクニック 301 リッチテキスト エディット コントロールの使い方 タブ順序、フォーカ ス、選択 ウィンドウまたはユーザ オブジェクトで、リッチテキスト エディット コントロールをコントロールのタブ順序に含めます。ただ し、リッチテキスト エディット コントロールにタブ移動した場合、 〔Tab〕を押すたびにテキストの中にタブを挿入してしまいます。リッ チテキスト コントロールから別のコントロールへは、タブ移動できま せん。その点に注意してください。 タブ順序 フォーカスとテキストの選択 リッチテキスト エディット コントロール を〔Tab〕を押して選択すると、コントロールがフォーカスされ、現行 の挿入ポイントまたはテキスト選択は保持されます。リッチテキスト エディット コントロールを選択してフォーカスを設定した場合は、挿 入ポイントはエンド ユーザがクリックした位置に移動します。 したがって、エンド ユーザが別のコントロールへフォーカスを変更す ると、テキストの選択が更新されます。テキストの選択を変更せずに コントロールへフォーカスを戻すことはできません。 LoseFocus イベント エンド ユーザがリッチテキスト エディット コン トロールのツールバーを選択すると LoseFocus イベントが発生します が、リッチテキスト エディット コントロールのフォーカスは残りま す。コントロールがフォーカスを失ったかどうかを GetFocus 関数で確 認することができます。 プレビューと印刷 エンド ユーザは、リッチテキスト エディット コントロールのレイア ウトをプレビューしたり、内容を印刷することができます。 レイアウトのプレ ビュー 302 エンド ユーザは、プレビュー モードで文書のレイアウトを確認するこ とができます。プレビュー モードでは、コントロールの大きさに合わ せて文書の内容が縮小されます。コントロールが小さい場合は、プレ ビューされる内容がとても小さくなります。 PowerBuilder 第 16 章 リッチテキストの作成方法 エンド ユーザは、プレビュー モードで以下の操作が可能です。 • 文書の余白を設定する • 矢印ボタンを使用して、ページをスクロールする リッチテキスト エディット コントロールがデータウィンドウ オ ブジェクトとデータを共有している場合は、プレビューはテキス トとマージされた最初のデータ行だけを表示します。 プレビューするには、以下のいずれかの操作を行います。 • エンド ユーザは、〔Ctrl〕+〔F2〕を押すことによって、編集モー ドとプレビュー モードを切り換えることができます。 • スクリプトで Preview 関数を呼び出します。 rte_1.Preview(TRUE) 印刷 リッチテキスト エディット コントロールがデータウィンドウ オブ ジェクトのデータを使用している場合、データウィンドウ コントロー ルの Print.Page.Range プロパティを設定して、印刷される行の数を制限 することができます。Print.Page.Range プロパティの値は、印刷する ページ番号をリストした文字列です。ダッシュ(-)を使用して範囲を 指定できます。 たとえば、リッチテキスト エディット コントロール が、データウィンドウ コントロール dw_source のデータを共有してい るとします。リッチテキスト文書は 3 ページで、2 行目と 5 行目のデー タを印刷するとします。印刷する前に、ページ範囲のプロパティを設 定することができます。 ページ範囲の例 dw_source.Object.DataWindow.Print.Page.Range = & "4-6,13-15" さらに、行が印刷されないように、行をフィルタまたは破棄すること ができます。 詳細については、『PowerScript リファレンス』マニュアルの SetFilter、 Filter、RowsMove、RowsDiscard 関数および『データウィンドウ リファ レンス』マニュアルの Print データウィンドウ オブジェクト プロパ ティを参照してください。 ページ番号を印刷するには、ヘッダまたはフッタに入力フィールドを 配置します。 ページ番号の設定 ❖ ヘッダまたはフッタにページ番号を挿入するには 1 アプリケーション テクニック ヘッダまたはフッタに入力フィールドを作成し、入力フィールド 名を指定します。 303 リッチテキスト エディット コントロールの使い方 2 PrintHeader または PrintFooter イベントのスクリプトで、現行の ページ番号を入力フィールドの値として設定します。 ページ番号の付け方は、開発者が決定します。イベントには、ページ 番号を計算するために使用できる引数が 3 つあります。currentpage 引 数の値を変更せずにそのまま使用したり、または、データの行ごとに ページ番号をリセットすることもできます。 連続番号の使用 たとえば文書のフッタに、テキストとともに page と total という 2 つの入力フィールドがあるとします。 Page {page} of {total} PrintFooter イベントで、以下のようなスクリプトを記述して値を設定 します。 rte_1.InputFieldChangeData( "page", & String(currentpage)) rte_1.InputFieldChangeData( "total", & String(totalpages)) 行ごとのページ番号のリセット 行ごとにページ番号をリセットする場 合には、フッタはたとえば次のように設定します。 Row {row}, Page {page} 「連続番号の使用」と同様に、PrintFooter イベントのスクリプトで、値 を設定します。各行が同じページ数であると仮定すると、ページの値 はスクリプトに渡された引数から算出されます。 rte_1.InputFieldChangeData( "page", & String(Mod(currentpage, totalpages/currentrow))) rte_1.InputFieldChangeData( "row", & String(currentrow)) スクリプトによるフッ タ テキストの挿入 以下のサンプル コードでは、フッタに挿入ポイントを設定して、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!) 304 PowerBuilder 第 16 章 リッチテキストの作成方法 リッチテキストとエンド ユーザ 『PowerBuilder ユーザーズ ガイド』マニュアルのリッチテキストの使い 方に関する章、およびこの章で解説した編集ツールは、エンド ユーザ も使用することができます。 エンド ユーザが行え る操作 エンド ユーザが可能 な操作のスクリプトで の記述 エンド ユーザは、以下の操作を行うことができます。 • ツールバーを使用したテキストの書式設定 • ポップアップ メニューの使用(ほかのリッチテキストや ASCII ファイルを開いたり、クリップボードを使用できます) • 入力フィールドの内容の編集 • 編集ツールのオン / オフの切り換え エンド ユーザが以下の操作をできるように、アプリケーションを設定 することができます。 • 入力フィールドの挿入と削除 • ピクチャの挿入 • ヘッダとフッタ編集への切り換え • 印刷する文書のプレビュー リッチテキスト エディット コントロールが、データウィンドウ オブ ジェクトまたはデータストア オブジェクトとデータを共有する場合、 以下のようにスクリプトを記述することができます。 • 行から行へスクロールさせる(ページからページへスクロールさ せるスクリプトも記述できますが、その必要はありません) • 入力フィールドで変更されたデータ値をデータベースへ更新する リッチテキストを使用するアプリケーションを作成する際には、開発 者自身がエンド ユーザとなってアプリケーションを使用し、テキスト を編集してみることをお勧めします。実行時にも、編集用のすべての ツールを使用することができます。 エンド ユーザへの表 示 デフォルトの表示は本文テキストです。ヘッダとフッタのテキストお よび印刷プレビューも表示できます。 リッチテキスト データウィンドウ オブジェクトまた はリッチテキスト エディット コントロールにおいて、メニューまたは コマンドボタンのスクリプトで ShowHeadFoot 関数を呼ぶことができ ます。この関数を呼ぶと、ヘッダとフッタの編集パネルが表示されま す。 ヘッダとフッタ アプリケーション テクニック 305 リッチテキストとエンド ユーザ dw_1.ShowHeadFoot(TRUE) 通常の表示に戻すには、再度 ShowHeadFoot 関数を呼び出します。 dw_1.ShowHeadFoot(FALSE) 印刷プレビュー エンド ユーザは、 〔Ctrl〕+〔F2〕を押すことによって、 プレビュー モードのオンとオフを切り換えることができます。また、 スクリプトからプレビュー モードを制御することもできます。 リッチテキスト エディット コントロールでは、Preview 関数を呼び出 します。 rte_1.Preview(TRUE) リッチテキスト データウィンドウ オブジェクトでは、Preview プロパ ティを設定します。 dw_1.Object.DataWindow.Print.Preview = TRUE エンド ユーザは、以下の項目に対して書式設定をすることができま す。 テキストの構成要素と 書式設定 ❖ • 選択されたテキスト • 段落 • ピクチャ • リッチテキスト文書全体 オブジェクトのプロパティ シートを表示するには 1 2 ❖ • ドラッグするか、または編集キーを使用してテキストを選択し ます。 • ピクチャをクリックします。 • リッチテキスト文書に挿入ポイントを設定します(テキストを 選択しないように注意してください)。 ワークスペースで右クリックして、ポップアップ メニューから[プ ロパティ]を選択します。 選択された段落に書式を設定するには • 306 以下の操作を行って、オブジェクトを選択します。たとえば、次 のようになります。 ルーラをダブルクリックします。 または 〔Ctrl〕+〔Shift〕+〔S〕を押します。 PowerBuilder 第 16 章 リッチテキストの作成方法 リッチテキスト オブジェクトを編集禁止に設定していない限り、エン ド ユーザは入力フィールドの値を変更できます。 入力フィールドの値の 変更 ❖ 入力フィールドの値を変更するには 1 入力フィールドをクリックして選択します。 入力フィールドが点滅します。 2 スペースキーを押して値を入力するか、ワークスペースで右ク リックして、ポップアップ メニューから[プロパティ]を選択し ます。 入力フィールド オブジェクト プロパティ シートが表示されます。 3 [全般]ページの[データ値]テキストボックスを編集します。 入力フィールドに書式を設 定することができます。入力フィールドを選択している場合は、入力 フィールド オブジェクト プロパティ シートの[フォント]ページと ツールバーによって書式を設定することができます。テキストととも に入力フィールドを選択している場合は、書式設定は、入力フィール ドを含むすべてのテキストに反映されます。 入力フィールドにおけるデータ値の書式設定 エンド ユーザは、入力フィールドの個々の文字または単語に書式を設 定することはできません。入力フィールドを選択すると、入力フィー ルド全体が選択されます。 スクリプトを記述して、エンド ユーザに 入力フィールドを挿入させたり削除させることができます。また、エ ンド ユーザは、既存の入力フィールドをコピーして貼り付けることも できます。コピーされた入力フィールドは、すべて同じデータ値を表 示します。 入力フィールドの挿入と削除 書式設定のためのキー とツールバー ツールバーが表示されている場合、エンド ユーザはツールバーのボタ ンを使用して、プレビュー モードでテキストの書式を設定したり、 ショートカット キーを使用してワークスペース内のテキストの書式 を設定できます。 リッチテキストにおける書式設定のためのショートカット キーにつ いては、 『PowerBuilder ユーザーズ ガイド』マニュアルのリッチテキス トに関する章を参照してください。 アプリケーション テクニック 307 リッチテキストとエンド ユーザ 308 PowerBuilder 第 1 7 章 データ ソース間のデータ転送 この章について この章では、アプリケーションでパイプライン オブジェクトを使 用して、1 つまたは複数の転送元テーブルから新規または既存の転 送先テーブルへデータ パイプライン処理を行う方法について説明 します。 内容 サンプル アプリケーショ ン 項目 データ パイプラインについて 必要なオブジェクトの作成 パイプライン処理の前準備 パイプライン処理の開始 エラー行の処理 パイプラインの後処理 ページ 310 311 319 322 329 333 この章では、簡単な商品受注管理システムを使ってデータ パイプ ラインの使い方を説明します。データ パイプライン処理の参考例 として、Code Examples サンプル アプリケーションのデータ パイ プライン項目にあるサンプルを参照してください。 サンプル アプリケーションの使い方についての詳細は、第 1 章「サ ンプル アプリケーションの使い方」を参照してください。 アプリケーション テクニック 309 データ パイプラインについて データ パイプラインについて データ パイプラインとは、データベース テーブル間でデータを転送で きる機能です。データ パイプライン機能によって、1 つまたは複数の 転送元テーブルから、新規または既存の転送先テーブルに行をコピー できます。また、この機能によって、同一のデータベース内、複数の データベース間、または異なる DBMS 間においてもデータを移行でき ます。 データ パイプライン 処理の用途 データ パイプライン処理は、以下の 2 種類の用途で使用されます。 • 開発時のユーティリティとして PowerBuilder 開発環境での作業中に、データを移行したいことがあ ります(運用時に使用する大きなテーブルからテスト用に小さな テーブルを作成するときなど)。この場合、データ パイプライン ペインタで対話的に作業を行って、すぐにデータを移行できます。 データ パイプライン ペインタの開発環境での使い方についての 詳細は、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照して ください。 • アプリケーションにおけるデータ移行ツールとして実装するには 複数のテーブル間でデータの移行を必要とするようなアプリケー ションを構築している場合は、データ パイプライン ペインタで適 切なデータ パイプラインを設計し、パイプラインオブジェクトを 保存しておきます。これにより、アプリケーション実行時に、エ ンド ユーザにそのデータ パイプライン処理を行わせることがで きます。 データ パイプラインは、アプリケーションのさまざまな局面で利 用できます。たとえば、アプリケーションで、データベース サー バからテーブルのローカル コピーをリモート ユーザにダウン ロードさせる場合や、分散しているトランザクション テーブルの データをマスタ トランザクション テーブルにまとめる場合など です。 基本操作の概要 アプリケーションにデータ パイプラインを使用する必要がある場合 は、そのための手順を決定しなければなりません。通常は、以下の 5 段階の基本操作を行います。 ❖ 310 アプリケーションでデータ パイプライン処理を行うには 1 パイプライン、ユーザ オブジェクト、ウィンドウなど、必要なオ ブジェクトを作成します。 2 パイプライン処理の準備を行います。 PowerBuilder 第 17 章 3 パイプライン処理を開始します。 4 エラーとなった行を処理します。 5 パイプラインの後処理をします。 データ ソース間のデータ転送 本章の後半は、以上の各操作の詳細について説明します。 必要なオブジェクトの作成 アプリケーションでデータのパイプライン処理を実装するには、以下 の種類のオブジェクトを作成する必要があります。 • パイプライン オブジェクト • ユーザ オブジェクト • ウィンドウ パイプライン オブジェクトの作成 パイプライン オブジェクトを作成して、アプリケーションで実行した いパイプラインのデータ定義やアクセス情報を指定します。パイプラ イン オブジェクトは、PowerBuilder のデータ パイプライン ペインタで 作成し、パイプライン処理に必要な特性を定義しておきます。 パイプラインの定義 データ パイプライン ペインタでは、以下の特性を指定してパイプライ ン オブジェクトを定義します。 • アクセスする転送元テーブルとテーブルから取得(検索)するデー タ(データソースにストアド プロシージャもアクセスできる) • データを転送する転送先テーブル • パイプライン操作(作成、置き換え、リフレッシュ、追加、更新) の実行 • パイプライン操作中に COMMIT を発行する頻度(n 行ごとの発行、 すべての行を転送した後で発行、またはコミットしない。この場 合、開発者がスクリプトで COMMIT 文を実行する必要がある) • パイプライン操作が終了するまでに許容されるエラーの件数 • (転送元データベースの PowerBuilder リポジトリから)転送先デー タベースに拡張属性を転送するかどうか アプリケーション テクニック 311 必要なオブジェクトの作成 データ パイプライン ペインタを使用してパイプライン オブジェクト を作成する方法についての詳細は、『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 カラムを減算しています。 312 PowerBuilder 第 17 章 データの転送方法 データ ソース間のデータ転送 pipe_sales_extract1 が転送元データを転送する方法を 以下に示します。 このパイプライン オブジェクトが、販売成績(Quarterly-extract)とい う転送先テーブルを新規に作成するように定義していることに注意し てください。アプリケーションで、この新規テーブルを格納する転送 先データベースを指定する方法については、 (転送元テーブルのデータ ベースを指定する方法についても)後で示します。 このほか、pipe_sales_extract1 について以下の項目に注意してください。 • コミットが発行されるのは、対象となる行がすべて転送された後 のみ(つまり、パイプラインの実行が中断されると、Quarterly_extract テーブルに対する変更内容はすべてロールバックされ破棄され る) • アプリケーションで発生するエラー件数の制限はない。したがっ て、どの行でエラーが起きても、パイプラインの実行は中断され ない • 拡張属性は、転送先データベースには転送されない • Quarterly-extract テーブルの主キーは、srep-id カラムと ssum-quarter カラムから構成される複合キーである • アプリケーション テクニック アプリケーションが Quarterly-extract テーブルに作成する計算カラ ムの名前は、computed_net である 313 必要なオブジェクトの作成 ユーザ オブジェクトの作成 ここまで、パイプライン オブジェクトにパイプラインに対するデータ やアクセスを定義する方法について説明してきましたが、パイプライ ン オブジェクトには、アプリケーションで実際にパイプラインを実行 したり管理する際に必要となるさまざまな定義(プロパティ、イベン ト、関数など)は含まれていません。 アプリケーションでパイプライン処理を行う際に、そのアプリケー シ ョ ン で 必 要 と な る 個 別 の 定 義 を 実 装 す る に は、PowerBuilder の Pipeline システム オブジェクトを継承させたユーザ オブジェクトの作 成が必要です。表 17-1 に、実行時にアプリケーションによるオブジェ クトの管理を可能にする、Pipeline システム オブジェクトのさまざま なプロパティ、イベント、関数を示します。 Pipeline システム オ ブジェクトについて 表 17-1: Pipeline システム オブジェクトのプロパティ、イベント、関数 プロパティ DataObject、 イベント PipeStart、 RowsRead、 PipeMeter、 PipeEnd RowsWritten、 関数 Start、 Repair、 Cancel RowsInError、 Syntax アプリケーションにおけるこれらのプロパティ、イベント、関数の使 い方は、この章の後半で説明します。 ❖ パイプライン処理をサポートするユーザ オブジェクトを作成するには 1 新規作成 ダイアログボックスの[PB オブジェクト]タブから[標 準クラス]を選択します。 標準クラス データ型の選択 ダイアログボックスが表示され、新規 のユーザ オブジェクトに継承したい PowerBuilder のシステム オブ ジェクト名が指定できます。 314 PowerBuilder 第 17 章 データ ソース間のデータ転送 2 「pipeline」を選択して、[OK]ボタンを選択します。 3 必要に応じて、ユーザ オブジェクトに変更を加えます。アプリケー ションで使用するイベント、関数、変数などを記述します。 特に有効なユーザ オブジェクトの機能については、324 ページの 「パイプライン処理のモニタ」を参照してください。 再利用を考えた設計 ユーザ オブジェクトを作成する場合、そのユーザ オブジェクトが 将来再利用され、ほかのパイプライン処理の実行にも使用される ことがあることを考慮してください。ユーザ オブジェクトは、デー タ パイプライン ペインタで作成した特定のパイプライン オブ ジェクトと自動的に関連付けられるわけではなく、ほかのパイプ ライン オブジェクトに対しても使用することができます。 この柔軟性を有効に活用するためにも、ユーザ オブジェクトで記 述するイベント、関数、変数は、あらゆるパイプライン オブジェ クトに適応できるような汎用性を持たせておく必要があります。 4 ユーザ オブジェクトを保存します。 ユーザ オブジェクト ペインタでの操作手順については、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 ウィンドウの作成 ウィンドウは、アプリケーションでデータ パイプライン処理をすると きに必要となるもう 1 つのオブジェクトです。ウィンドウを作成して、 パイプライン処理に対するユーザ インタフェースを提供し、エンド ユーザによるさまざまなパイプライン操作を可能にします。通常のア プリケーションでは、以下のようなエンド ユーザ操作が考えられま す。 • パイプライン処理を開始する • エラー内容の表示や修正を行う • 必要に応じ、パイプライン処理の実行を中断する アプリケーション テクニック 315 必要なオブジェクトの作成 ウィンドウに必要とな る機能 ウィンドウを作成する際に、そのパイプライン処理でエラーとなった 行(何らかの理由で転送先テーブルに転送できない行)を表示するデー タウィンドウ コントロールが必要となります。このデータウィンドウ コントロールにデータウィンドウ オブジェクトを関連付ける必要は ありません。実行時にパイプラインによって独自のデータウィンドウ オブジェクトが提供されます。 このデータウィンドウ コントロールの使い方については、322 ページ の「パイプライン処理の開始」および 329 ページの「エラー行の処理」 を参照してください。 ウィンドウに対するオ プション機能 必要なデータウィンドウ コントロールさえ含めれば、ウィンドウは開 発者が自由に設計できます。通常は、以下のようなコントロールを配 置してユーザ インタフェースを実現します。 • エンド ユーザが(パイプラインの開始、修正、停止などの)操作 を行えるようにするコマンドボタン コントロールやピクチャボタ ン コントロール • パイプラインのステータス情報を表示するスタティック テキスト コントロール • 転送元テーブルや転送先テーブルの内容を表示するデータウィン ドウ コントロール ウィンドウの作成についての詳細は、『PowerBuilder ユーザーズ ガイ ド』マニュアルを参照してください。 316 PowerBuilder 第 17 章 例 データ ソース間のデータ転送 次のウィンドウは、商品受注管理システムにおけるデータ パイプライ ン処理のユーザ インタフェースを扱います。ウィンドウ名は、 w_sales_extract です。 このウィンドウ上の各コントロールは、パイプライン処理に関連した さまざまな機能を実現するために使用されています。使用されている コントロールの詳細を、表 17-2 にまとめています。 表 17-2: パイプラインの機能を実現するためのウィンドウ コントロール コントロールの 種類 ラジオボタン コントロール名 rb_create rb_insert アプリケーション テクニック 目的 実行するパイプライン オブジェクト に、pipe_sales_extract1 を選択する 実行するパイプライン オブジェクト に、pipe_sales_extract2 を選択する 317 必要なオブジェクトの作成 コントロールの 種類 コマンドボタン データウィンド ウ スタティック テキスト 318 コントロール名 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 章 データ ソース間のデータ転送 パイプライン処理の前準備 アプリケーションで必要となるオブジェクトの準備ができたら、アプ リケーションでパイプライン処理を行うスクリプトを記述します。ま ず、アプリケーションがパイプライン処理を実行できるように、いく つかの設定を行わなければなりません。 ❖ アプリケーションでパイプラインを実行するための準備をするには 1 パイプラインに用いる転送元および転送先データベースに接続し ます。 これは、適切なイベントにおいて、接続のための一般的なスクリ プトを記述して行います。ただし、転送元データベースに接続す る際に使用するトランザクション オブジェクトと、転送先データ ベースとの接続に使用するトランザクション オブジェクトは、 (同 一のデータベースの場合でも)異なることに注意してください。 データベースへの接続についての詳細は、第 12 章「トランザク ション オブジェクトの使い方」を参照してください。 2 ユーザ オブジェクトのインスタンスを作成します(インスタンス を作成することにより、アプリケーションでユーザ オブジェクト のプロパティ、イベント、関数が使用できるようになります)。 最初に、定義したユーザ オブジェクトをデータ型とする変数を宣 言します。次に、スクリプトで CREATE 文を使って、ユーザ オブ ジェクトのインスタンスを作成し、それを変数に代入します。 3 使用したいパイプライン オブジェクトを指定します。 これは、スクリプトで代入文を記述して行います。使用するパイプ ライン オブジェクト名を示す文字列を、ユーザ オブジェクトのイ ンスタンスの DataObject プロパティに代入します。 CREATE 文および代入文についての詳細は、 『PowerScript リファレンス』 マニュアルを参照してください。 例 次のサンプル コードは、商品受注管理システムにおけるこれらのパイ プラインの設定を行います。 転送元および転送先データベースとの接続 この場合は、会社の販売デー タベース(ABNCSALE.DB)を、転送元および転送先の両方のデータベー ス と し て 使 用 し て い ま す。こ の 販 売 デ ー タ ベ ー ス と の 接 続 は、 uevent_pipe_setup というユーザ イベントにスクリプトを記述して行っ ています(uevent_pipe_setup イベントは、w_sales_extract ウィンドウの Open イベントからポストされます)。 アプリケーション テクニック 319 パイプライン処理の前準備 以下のスクリプトは、転送元データベースとの接続を確立します。 // トランザクション オブジェクトのインスタンスを新規に作成し、 // 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 が設定されていなければ、拡張属性は転送されません。 320 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 このコードは、選択されたパイプラインを開始するスクリプトより前 に、通常スクリプトの先頭で記述します。 アプリケーション テクニック 321 パイプライン処理の開始 パイプライン オブジェクトを配布する際の注意 通常、アプリケーションは、実行時にパイプライン オブジェクトを (String 型の変数によって)動的に参照します。そのため、アプリケー ションを配布する場合は、これらのオブジェクトを 1 つまたは複数の PBD か DLL ファイルにパッケージ化する必要があります。なお、実行 (EXE)ファイルにパイプライン オブジェクトを含めることはできま せん。 配布についての詳細は、第 9 部「配布のテクニック」を参照してくだ さい。 パイプライン処理の開始 パイプラインの準備が整ったら、実行を開始します。 ❖ パイプライン処理を開始するには 1 適切なスクリプトに Start 関数を記述します。この関数では、以下 の内容が指定できます。 • 転送元データベースに対するトランザクション オブジェクト • 転送先データベースに対するトランザクション オブジェクト • Start 関数がエラー行を表示するデータウィンドウ コントロール Start 関数は、PowerBuilder のパイプライン エラー データウィ ンドウ オブジェクトと、使用するデータウィンドウ コント ロールを自動的に関連付けます(必要な場合のみ)。 • パイプライン オブジェクトで定義した検索引数に対する値 これらの値を省略すると、Start 関数は、アプリケーション実行 時にそれらの入力を自動的に要求します。 2 Start 関数の結果を調べます。 Start 関数の記述についての詳細は、 『PowerScript リファレンス』マニュ アルを参照してください。 322 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 アプリケーション テクニック 323 パイプライン処理の開始 CASE -4 Beep (1) MessageBox(" 転送エラー ", & "Quarterly_Extract テーブルは存在しません ... RETURN ... END CHOOSE パイプライン処理のモニタ パイプラインの実行状態をモニタするには、Start 関数の戻り値を調べ る方法があります。そのほかの方法として、ユーザ オブジェクトがパ イプライン処理された行数を保持している集計値を取得する方法もあ ります。これにより、パイプラインによって処理された以下の数値が 求められます。 • 転送元テーブルから読み込まれた行数 • 転送先テーブルおよびエラーのデータウィンドウ コントロールに 書き込まれた行数 • (転送先テーブルではなく)エラー用のデータウィンドウ コント ロールに書き込まれたエラー行の数 これらの集計値をユーザ オブジェクトから取得し、ウィンドウ上で動 的に表示して、エンド ユーザにパイプライン処理を確認させることが できます。 ❖ パイプラインによって処理された行の集計を表示するには 1 ユーザ オブジェクト ペインタで、ユーザ オブジェクトを開きま す。 ユーザ オブジェクト ペインタのワークスペースが表示され、ユー ザ オブジェクトの編集が可能になります。 2 StaticText 型の インスタンス変数を 3 種類宣言します。 statictext ist_status_read, ist_status_written, & ist_status_error これらのインスタンス変数は、今後、ウィンドウ上の 3 つのスタ ティック テキスト コントロールの内容を保持するために使用し ます。これにより、ユーザ オブジェクトでスタティック テキスト コントロールの内容を直接操作し、パイプラインによる各種の行 の集計を動的に表示できます。 324 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 イベントからポストされます) 。 アプリケーション テクニック 325 パイプライン処理の開始 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 個のスタティック テキスト コントロールに表 示されます。 パイプライン処理のキャンセル パイプラインの実行を途中で停止する機能をエンド ユーザ(またはア プリケーション)に提供したい場合が多くあります。たとえば、間違っ てパイプラインを開始したり、 (大量の行数を扱っているときに)処理 を途中で中断したい場合などです。 326 PowerBuilder 第 17 章 ❖ データ ソース間のデータ転送 パイプラインの実行をキャンセルするには 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 コマンドボタンを選択する ことによって、現在実行中のパイプラインを停止できるようにします。 アプリケーション テクニック 327 パイプライン処理の開始 更新処理のコミット パイプライン オブジェクトを実行すると、データ パイプライン ペイ ンタでの指定に従って転送先テーブルへの更新がコミットされます。 開発者は、アプリケーションのスクリプトで、このコミット処理のた めに 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 ユーザーズ ガイド』マニュアルを参 照してください。 328 PowerBuilder 第 17 章 データ ソース間のデータ転送 エラー行の処理 パイプラインの実行時に、行が転送先テーブルに書き込めない場合が あります。たとえば、転送先テーブルに転送元テーブルと同じ主キー を持つ行がある場合などです。 パイプライン エラー データウィンドウの使 い方 パイプラインは、ウィンドウ上に配置され Start 関数で指定したデータ ウィンドウ コントロールにエラーとなった行を表示します。これは、 特定のデータウィンドウ オブジェクト(PowerBuilder のパイプライン エラー データウィンドウ)とデータウィンドウ コントロールが自動的 に関連付けられて行われます。 これを商品受注管理システムで考えてみましょう。w_sales_extract ウィ ンドウでパイプラインを実行する場合、Start 関数は、すべてのエラー 行を dw_pipe_errors データウィンドウ コントロールに表示します。 dw_pipe_errors には、各行のエラーを表示するエラー メッセージ カラ ムが配置されています。 エラー メッセージを短くする パイプラインの転送先のトランザクション オブジェクトが ODBC データ ソースを指定している場合は、DBParm の MsgTerse パラメータ を設定して、データウィンドウに表示するエラー メッセージを短くす ることができます。具体的には、以下のように指定します。 MsgTerse = 'Yes' アプリケーション テクニック 329 エラー行の処理 このように指定することによって、SQLSTATE エラー番号は表示され ません。 MsgTerse DBParm についての詳細は、オンライン ヘルプを参照してく ださい。 エラー行の処理 エラー行がある場合は、それらを処理する必要があります。以下のい ずれかの操作を行います。 • エラー行の一部またはすべての修復 • エラー行の一部またはすべての破棄 エラー行の修復 ほとんどの場合は、エラーとなった行を修正して、転送先テーブルに 適用できるようにすることをお勧めします。通常、1 つまたは複数の カラム値を転送先テーブルで受け入れられるように変更して修復しま す。エラー行の修正は、エラーを表示しているデータウィンドウ コン トロール上の行を以下のいずれかの方法で編集して行います。 • エンド ユーザに編集させる(開発者がスクリプトを記述する必要 なし) • アプリケーションのスクリプトによって編集する いずれの場合も、次の操作手順で、修正した行をこのデータウィンド ウ コントロールから転送先テーブルに適用します。 ❖ 転送先テーブルに行の修正内容を適用するには 1 適切なスクリプトに Repair 関数を記述します。Repair 関数には、転 送先データベースに対する トランザクション オブジェクトを指 定します。 2 Repair 関数の結果を調べます。 Repair 関数の記述についての詳細は、 『PowerScript リファレンス』マ ニュアルを参照してください。 例 330 次の例では、エンド ユーザがデータウィンドウ コントロール 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 データウィンドウか ら修正した行を持つ転送先テーブルを更新できるようになります。 行の修正の停止 パイプラインの実行時にエンド ユーザ(またはアプリケーション)が 転送先テーブルへの行の書き込みを中断する方法については、この章 ですでに説明しました。状況によっては、行の修正中にも同様に書き 込みを停止させることができます。 詳細については、326 ページの「パイプライン処理のキャンセル」を 参照してください。 行の修正内容のコミッ ト Repair 関数は、Start 関数と同じ方法でデータベースの更新をコミット (またはロール バック)します。 詳細については、328 ページの「更新処理のコミット」を参照してく ださい。 修正されていない行の 処理 Repair 関数の実行後、エラー行が、エラー データウィンドウ コント ロールにまだ残っていることがあります。これには、以下のような原 因が考えられます。 • エンド ユーザやアプリケーションによって修正されたにもかかわ らず、エラーがまだ直っていない場合 • エンド ユーザやアプリケーションによってエラーが修正されてい ない場合 • Cancel 関数が呼び出されたため、転送先テーブルに書き込まれな かった場合(または、停止時に、転送先テーブルからロールバッ クされた場合) アプリケーション テクニック 331 エラー行の処理 この時点でも、これらの行は、エンド ユーザやアプリケーションに よって再度修正し、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 データウィンドウからす べてのエラー行が破棄されるようになります。 332 PowerBuilder 第 17 章 データ ソース間のデータ転送 パイプラインの後処理 アプリケーションでのパイプライン処理が終わったら、いくつかの後 処理を行わなければなりません。これらの処理には、パイプライン処 理のために取得したリソースの解放などが含まれます。 ガベージ コレクション 破棄するオブジェクトがほかで使われていないことを確認できない場 合には、リソースの後処理に DESTROY 文を使わないでください。 PowerBuilder のガベージ コレクション機能によって、参照されていな いオブジェクトは自動的に削除されます。詳細については、49 ページ の「ガベージ コレクションとメモリ管理」を参照してください。 ❖ パイプラインの後処理を行うには 1 パイプライン処理に使用したユーザ オブジェクトのインスタンス を破棄します。 適切なスクリプトに DESTROY 文を記述し、そのユーザ オブジェ クトのインスタンス変数名を指定します。 2 パイプラインの転送元データベースおよび転送先データベースと の接続を解除します。 これは、適切なスクリプトに DISCONNECT 文を 2 行記述して行い ます。一方の DISCONNECT 文では、転送元トランザクション オ ブジェクトのインスタンス変数名を、もう一方の DISCONNECT 文 では転送先トランザクション オブジェクトのインスタンス変数名 を、それぞれ指定します。 各 DISCONNECT 文の結果を調べます。 3 転送元トランザクション オブジェクトのインスタンスと転送先ト ランザクション オブジェクトのインスタンスを破棄します。 これは、適切なスクリプトに DESTROY 文を 2 行記述して行いま す。一方の DESTROY 文では、転送元トランザクション オブジェ クトのインスタンス変数名を、もう一方の DESTROY 文では転送 先トランザクション オブジェクトのインスタンス変数名を、それ ぞれ指定します。 DESTROY 文と DISCONNECT 文についての詳細は、 『PowerScript リファ レンス』マニュアルを参照してください。 例 次のコードは、w_sales_extract ウィンドウの Close イベントに対してス クリプトを記述し、パイプラインの後処理を行います。 アプリケーション テクニック 333 パイプラインの後処理 ユーザ オブジェクト インスタンスの破棄 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 334 PowerBuilder 第 5 部 プログラム アクセス テクニック 第 5 部では、PowerBuilder によるアプリケーション開発 において、プログラム アクセス機能を実現するためのテ クニックについて説明します。アプリケーションにおけ る DDE の使い方および OLE の使い方、メール対応アプ リケーションの構築、そのほかの拡張処理機能の追加な どについて説明します。 第 1 8 章 DDE の使い方 この章について この章では、PowerBuilder がサポートする DDE 機能について説明 します。 内容 項目 DDE について DDE 関数とイベント ページ 337 338 DDE について ダイナミック データ エクスチェンジ(DDE: Dynamic Data Exchange) を使用すると、2 つの Windows アプリケーション間でコマンドや データをやり取りさせて、相互に通信することができます。つま り、2 つのアプリケーションでデータを共有したり、コマンドの遠 隔実行や、エラー状態のチェックを行うことができます。 PowerBuilder は DDE をサポートするために、特別な PowerScript 関 数やイベントを提供しています。これらの関数やイベントを用い ることにより、PowerBuilder アプリケーションから DDE をサポー トするほかのアプリケーションにメッセージを送信したり、ほか の DDE アプリケーションからの DDE リクエストに対して応答で きます。 クライアントとサーバ DDE をサポートしているアプリケーションは、クライアントまた はサーバのどちらかの役割を果たすことができます。 用語について DDE で用いるクライアントとサーバという用語は、PC やワーク ステーションのクライアント マシンがデータベース サーバにア クセスするクライアント / サーバ アーキテクチャとは関係ありま せん。 アプリケーション テクニック 337 DDE 関数とイベント クライアント アプリケーションは、DDE をサポートしているほかのア プリケーション(サーバと呼ばれる)に対してリクエストを出します。 このリクエストは、コマンド(open、close、save など)であったりデー タに対するリクエストであったりします。 サーバ アプリケーションは、クライアント アプリケーションとは逆の 機能を実行します。サーバ アプリケーションは、DDE をサポートして いるほかのアプリケーション(クライアントと呼ばれる)からのリク エストに応答します。クライアント アプリケーションの場合と同様 に、このリクエストはコマンドや特定のデータに対するリクエストで す。 PowerBuilder のアプリケーションは、DDE クライアントとしても、DDE サーバとしても機能します。 PowerBuilder では DDE クライアントおよび DDE サーバに対して特別 な組み込み関数とイベントを用意しています。コマンドやデータがク ライアントからサーバに(またはサーバからクライアントに)送られ ると、DDE 関連のイベントが起動されます。 DDE 関数とイベント 以下の表に、DDE 関連の関数とイベントを示します。関数とイベント は DDE クライアントと DDE サーバごとにそれぞれまとめられていま す。DDE サポートの詳細については、『PowerScript リファレンス』マ ニュアルを参照してください。 戻り値 DDE 関数はすべて整数値を返します。 338 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 サーバ アプリケーションが新しい(変更され た)データを送信したとき 339 DDE 関数とイベント DDE サーバ 表 18-3: DDE サーバ関数 関数 GetCommandDDE GetCommandDDEOrigin GetDataDDE GetDataDDEOrigin RespondRemote SetDataDDE StartServerDDE StopServerDDE 動作内容 DDE クライアント アプリケーションが送信した コマンドを取得する どの DDE クライアント アプリケーションがコマ ンドを送信したかを判別する DDE クライアント アプリケーションが送信した データを取得して、指定した文字列型変数に保持 する どの DDE クライアント アプリケーションがホッ トリンクでデータを送信したかを判別する DDE アプリケーションから受信したコマンドま たはデータが DDE サーバに受け入れられたかど うかを、送信元の DDE クライアント アプリケー ションに通知する 指定されたデータを DDE クライアント アプリ ケーションに送信する PowerBuilder アプリケーションを DDE サーバと して起動する PowerBuilder が DDE サーバとして動作すること を終了させる 表 18-4: DDE サーバ イベント イベント RemoteExec RemoteHotLinkStart RemoteHotLinkStop RemoteRequest RemoteSend 340 発生する状況 DDE クライアント アプリケーションがコマンド を送信したとき DDE クライアント アプリケーションがホットリ ンクの開始を要求するとき DDE クライアント アプリケーションがホットリ ンクの終了を要求するとき DDE クライアント アプリケーションがデータを 要求したとき DDE クライアント アプリケーションがデータを 送信したとき PowerBuilder 第 1 9 章 アプリケーションにおける OLE の 使い方 この章について この章では、PowerBuilder のアプリケーションで OLE を実装する 方法について説明します。 内容 項目 PowerBuilder における OLE のサポート ウィンドウにおける OLE コントロール OLE コントロールと挿入可能なオブジェクト OLE カスタム コントロール プログラム可能な OLE オブジェクト スクリプトにおける OLE オブジェクト オブジェクト ブラウザでの OLE 情報 OLE オブジェクトの高度な操作 ページ 341 343 346 360 364 374 394 396 PowerBuilder における OLE のサポート OLE(Object Linking and Embedding)を利用すると、Windows プロ グラムでのデータとプログラム機能の共有が簡単にできます。 PowerBuilder の OLE コントロールは、OLE サーバ アプリケーショ ンを呼び出して、OLE オブジェクトを表示したり、操作を行うこ とができる、OLE コンテナです。 OLE コントロール アプリケーション テクニック ウィンドウ ペインタの OLE コントロールを使用すれば、複数のア プリケーションのコンポーネントをウィンドウにリンクしたり、 埋め込んだりすることができます。さらに、OLE サーバによって 定義された関数とプロパティを使用して、OLE サーバを制御する ことができます。 341 PowerBuilder における 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 ユーザーズ ガイド』マニュアルを参照してく ださい。 COM または OLE サーバとしての PowerBuilder についての詳細は、第 27 章「COM/COM+ コンポーネントの構築」および第 20 章「PowerBuilder のランタイム オートメーション サーバ」を参照してください。 342 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 ウィンドウにおける OLE コントロール OLE オブジェクトと ActiveX コントロールは、ウィンドウまたはユー ザ オブジェクトに追加できます。そのためには、OLE コンテナとして 機能する、PowerBuilder OLE コントロールの 1 つを使用します。この 節では、コントロールが OLE オブジェクト(挿入可能なオブジェクト とも呼ばれます)または ActiveX コントロールのどちらを保持するか を選ぶことによって、必要なコントロールを選択する方法について説 明します。 • 挿入可能な 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 から継承したインタフェースを使用できま す。 拡張コントロール 343 ウィンドウにおける OLE コントロール • PowerBuilder は、ウィンドウ レベ ルで IOleContainer クラスを実装しているので、ウィンドウ上のす べてのコントロールは兄弟関係にあり、お互いに各コントロール の情報を共有できます。コントロールの開発者がこの情報にアク セスするには、OLE EnumObjects メソッドが使用できます。コント ロールが一連のコントロールの一部となっている場合、兄弟関係 に関する情報はとても便利です。ほかのコントロールと異なり、 ウィンドウ上の OLE コントロールは単一の階層構造に格納されま す。 OLE コンテナとしてのウィンドウ OLE オブジェクトと OLE コントロールに限られます このオブジェクト列挙子に見えるのは OLE オブジェクトと OLE コントロールに限られます。ウィンドウ上のほかのコントロール を処理するのにはこのテクニックは使用できません。 • メッセージの反映 コントロール コンテナがメッセージの反映をサ ポートしていない場合、リフレクタ ウィンドウは、OLE コント ロールが親コントロールにメッセージを送ったときに作成されま す。リフレクタ ウィンドウはコントロールに戻るメッセージを反 映するので、コントロール自身でメッセージを処理できます。コ ンテナがメッセージの反映をサポートしている場合は、リフレク タ ウィンドウは必要なく、それに関連する実行時オーバーヘッド もなくなります。PowerBuilder の OLE コントロール コンテナは、 特定のメッセージ セットに対してメッセージの反映を行います。 コントロールの定義 OLE コントロールを作成して、その内容を選択する手順は以下のとお りです。 ❖ ウィンドウ オブジェクトやユーザ オブジェクトで OLE コントロールを配置 するには 1 OLE コントロールを含むウィンドウまたはユーザ オブジェクトを 開きます。 2 メニュー バーから[挿入|コントロール| OLE]を選択します。 オブジェクトの挿入 ダイアログボックスが表示されます。オブ ジェクトは、3 つのタブから選択できます。 3 344 サーバ アプリケーションまたは特定の OLE オブジェクトを選択 して、OLE コントロールに OLE オブジェクトを埋め込むか、リン クできます。また、OLE カスタム コントロール(OCX)を選択し て、OLE カスタム コントロールに挿入できます。または、OLE コ ントロールにオブジェクトを挿入しないでおくこともできます。 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 • 新しいオブジェクトを作成して埋め込む場合は、[新規作成] タブをクリックします。OLE サーバ アプリケーションを選択 して、[OK]ボタンをクリックします。 • OLE コントロールに既存のオブジェクトを選択する場合は、 [ファイルから作成]タブをクリックします。ファイル名を指 定して、 [OK]ボタンをクリックします。 • カスタム コントロール(ActiveX コントロール)を挿入する場 合は、 [コントロールの挿入]タブをクリックします。ActiveX コントロールを選択してから、 [OK]ボタンをクリックします。 • OLE コントロールにオブジェクトを挿入しない場合は、 [キャ ンセル]ボタンをクリックします。 [キャンセル]ボタンをクリックした場合には、コントロール は OLE カスタム コントロールではなく、OLE コントロールに なります。OLE コントロールへの OLE オブジェクトの埋め込 みまたはリンクは、いつでもできます。しかし、後から ActiveX コントロールを挿入することはできません。 4 コントロールを表示したい場所で、ウィンドウをクリックします。 OLE オブジェクトを挿入した場合、PowerBuilder は、OLE オブジェ クトを表示して編集できるように、OLE サーバ アプリケーション を起動します。ActiveX コントロールは開くことができません。 一覧表示されていない OLE サーバ アプリケーションに属するオブ ジェクトを挿入するときは、OLE サーバ アプリケーションをインス トールする必要があります。インストール方法については、OLE サー バ アプリケーションのマニュアルを参照してください。 オブジェクトの挿入 ダイアログボックスの使い方についての詳細は、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 アプリケーション テクニック 345 OLE コントロールと挿入可能なオブジェクト OLE コントロールと挿入可能なオブジェクト OLE コントロール内には、挿入可能な OLE オブジェクトがあります。 ペインタやスクリプトで OLE コントロール内の OLE オブジェクトを 変更できます。また、PowerBuilder のプロパティを設定して、OLE オ ブジェクトを指定できます。 OLE コントロールの設定 OLE コントロールを作成して、OLE オブジェクトを挿入すると、OLE サーバ アプリケーションがアクティブになり、OLE オブジェクトが修 正できます。PowerBuilderOLE オブジェクトを非アクティブにした後 (レイアウト ビューで OLE オブジェクトの枠線の外側をクリックしま す)、OLE コントロールのプロパティ シートを使用して、OLE コント ロールを設定できます。 ❖ OLE コントロールの表示と動作の形態を指定するには 1 OLE コントロールをダブルクリックするか、コントロールのポッ プアップ メニューから[プロパティ]を選択します。 2 プロパティ ビューで、使用アプリケーションに関係する名前をコ ントロールに与えます。 スクリプトではこの名前を使用します。デフォルト名は「ole_」の 接頭辞に数字を組み合わせたものです。 3 OLE サーバが使用する表示の名前の値を指定します。OLE サーバ は、ウィンドウのタイトル バーにこの名前を使用できます。 4 コントロールの外観と動作を指定するには、プロパティ ビューで 適切な設定を選択します。 ほかのコントロールにある標準的な[表示可能]、 [使用可能]、 [フォーカス時の枠表示]、および[枠のスタイル]プロパティの ほかに、OLE オブジェクトと OLE サーバとの関係を管理するオプ ションがあります。 346 PowerBuilder 第 19 章 オプション 起動方法 アプリケーションにおける OLE の使い方 意味 コントロールをアクティブにする方法 オプションは以下のとおり • ダブルクリック(activatedoubleclick!)– コントロール がダブルクリックされたときに、OLE サーバ アプリ ケーションをアクティブにする • フォーカス(activategetfocus!) – コントロールがク リックされるか、タブによって選択されたときに、 OLE サーバ アプリケーションをアクティブにする。 また、GetFocus イベントに対するスクリプトでは、 MessageBox 関数などのフォーカス移動させるような 関数を呼び出さないようにする • スクリプト(activatemanually!)– Activate 関数をスク リプトで使用しなければ、コントロールをアクティ ブにできない 表示の種類 コントロールは、 [起動方法]オプションの設定に関係 なく、いつでもスクリプトでアクティブにできる コントロールに何を表示するかの指定 オプションは以下のとおり • 内容(displayascontent!)– コントロールのサイズに合 わせて、オブジェクトを縮小して表示する • アイコン(displayasicon!)– データに関連付けられて いるアイコンを表示する。通常このアイコンは、OLE サーバ アプリケーションから提供される 内容の更新 可能 • ActiveX ドキュメント(displayasactivexdocument!)– ActiveX ドキュメントとして表示する。ActiveX ド キュメントは、コンテナのスペースを満たし、サー バ アプリケーションのすべての機能を使用できる コントロール上のオブジェクトをリンクするか埋め込 むかの指定 オプションは以下のとおり • 埋め込み / リンク(containsany!)– オブジェクトをリ ンクまたは埋め込みで挿入できる • 埋め込み(containsembeddedonly!)– オブジェクトを 埋め込みで挿入できる • リンク(containslinkedonly!)– オブジェクトをリンク で挿入できる [内容の更新可能]オプションを設定すると、 ContentsAllowed プロパティの値が変更される アプリケーション テクニック 347 OLE コントロールと挿入可能なオブジェクト オプション 意味 リンクの更新 オプション コントロール上のオブジェクトがリンクされていると きの、リンク情報の更新方法 オプションは以下のとおり • 自動(linkupdateautomatic!)– リンクが中断されて、 PowerBuilder がリンクされたファイルを検索できな い場合に、エンド ユーザがファイルを指定できるダ イアログボックスを表示する • スクリプト(linkupdatemanual!)– リンクが中断され ると、オブジェクトはアクティブにできない。スク リプトで LinkTo 関数または UpdateLinksDialog 関数を 使用して、再リンクを行う [リンクの更新オプション]を設定すると、 LinkUpdateOptions プロパティの値が変更される サイズ モード コンテナにおけるオブジェクトの表示方法 オプションは以下のとおり • クリップ(clip!)– オブジェクトの画像がフルサイズ で表示される。画像が OLE コントロールより大きい 場合は、コントロールの枠線からはみ出す部分が切 り捨てられる • ストレッチ(stretch!)– オブジェクトの画像は、OLE コンテナ コントロールのサイズに合うようにサイズ 変更される(デフォルト) ペインタにおけるオブジェクトのアクティブ化 OLE コントロール内のオブジェクトをサーバ アプリケーションを使 用して操作するには、そのオブジェクトをアクティブにしなければな りません。デフォルトでは、ユーザがオブジェクトをアクティブにす るときには、そのオブジェクトをダブルクリックします。このデフォ ルトの方法を変更するには、コントロールの[起動方法]プロパティ を設定します(前の表を参照)。開発時は、ウィンドウ ペインタでオ ブジェクトをアクティブにします。 ❖ ウィンドウ ペインタで OLE オブジェクトをアクティブにするには 1 OLE コントロールのポップアップ メニューから[開く]を選択し ます。 コントロールにオブジェクトが挿入されていない場合は、 [開く] は選択できません。ポップアップ メニューから[オブジェクトの 挿入]を選択して、コントロールにオブジェクトを挿入してくだ さい。 348 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 サーバ アプリケーションが起動され、オブジェクトがオフサイト でアクティブ化されます。 2 サーバ アプリケーション上で、オブジェクトを修正します。 3 更新が終わったら、ハッチング表示の枠線の外をクリックして、オ ブジェクトを非アクティブにします。 サーバ アプリケーションの[ファイル]メニューから[閉じる] または[閉じて戻る]を選択することもできます。 OLE コントロール内のオブジェクトの変更 ウィンドウ ペインタで、OLE コントロール内のオブジェクトの変更や 削除ができます。 ❖ OLE コントロールからオブジェクトを削除するには • OLE コントロールのポップアップ メニューから[オブジェクトの 削除]を選択します。 これで OLE コントロール内のオブジェクトは削除されたので、ア クティブ化できません。 [削除]は選択しないでください。ウィン ドウから OLE コントロールが削除されます。 ❖ OLE コントロールにオブジェクトを挿入するには 1 コントロールのポップアップ メニューから[オブジェクトの挿入] を選択します。 オブジェクトの挿入 ダイアログボックスが表示されます。 2 [新規作成]タブを選択してサーバ アプリケーションを選択する か、コントロールを定義したときと同様に、[ファイルから作成] タブを選択してファイルを指定します。 3 [OK]をクリックします。 実行時のオブジェクト の変更 InsertObject、InsertFile、InsertClass、または LinkTo 関数を呼び出して、OLE コントロールに OLE オブジェクトを挿入できます。Cut 関数または Clear 関数を呼び出して、OLE コントロールから OLE オブジェクトを 削除できます。 ユーザの OLE コントロールの使い方 OLE コントロールが配置されたウィンドウが開くと、PBL(アプリケー ションが作成されている場合は、PBD または EXE ファイル)内の OLE コントロールに格納された情報を使用して、データが表示されます。 アプリケーション テクニック 349 OLE コントロールと挿入可能なオブジェクト エンド ユーザがダブルクリックするか、コントロールをタブで選択す るか、スクリプトで Activate 関数を呼び出して、オブジェクトがアク ティブ化されると、サーバ アプリケーションが起動され、OLE コント ロール内でオブジェクトが編集できます。OLE コントロール内でオブ ジェクトが編集できない場合は、オフサイトで編集できます。 エンド ユーザがオブジェクトを変更すると、OLE コントロールのデー タは最新の状態に更新されます。オブジェクトが OLE コントロール内 で編集されているときは、データが更新されていることは明らかです が、オフサイトで編集している場合も同じように更新されます。ほと んどのサーバ アプリケーションは、連続的にではなく定期的にオブ ジェクトを更新します。そのため、ユーザが認識するのは、コントロー ルの内容に対する定期的な変更だけかもしれません。また、オフサイ トの編集を終了するときは、自動的に最後に行った変更が更新されま す。したがって、OLE コントロールの内容もそのときのタイミングで 変更が反映されます。しかし、安全のためには、オフサイトの編集を 終了する前に、サーバ アプリケーションで Update コマンドを選択して おく必要があります。 リンクと埋め込み アプリケーションでは、OLE オブジェクトはリンクすることも埋め込 むこともできます。どちらの方法を選択するかは、どのようにデータ を管理したいかによって決まります。 データの埋め込み オブジェクトを埋め込んだ場合、そのデータはアプリケーションに保 持されます。開発時には、そのデータはアプリケーションの PBL ファ イルに保存されます。また、アプリケーションが完成すると、EXE ファ イルや PBD ファイルに保存されます。このデータはユーザのためのテ ンプレートまたは開始点です。埋め込みオブジェクトは構築したアプ リケーションの一部として保存されているため、実行中にそのデータ を編集することはできますが、変更内容は保存されません。 オブジェクトの埋め込みは、たとえばレター フォームの本文のよう な、変更を行わないデータに適した方法です。また、変更してどこか ほかのところに保持するデータの開始点として使用するのに適してい ます。 実行時にデータを保存するには、SaveAs 関数と Open 関数を使用して、 ファイルまたは OLE ストレージにデータを保存することができます。 350 PowerBuilder 第 19 章 データのリンク アプリケーションにおける OLE の使い方 オブジェクトのリンクでは、データそのものではなく、データへの参 照をアプリケーションに含めます。アプリケーションは、表示を目的 としたデータの画像も格納します。サーバ アプリケーションが、実際 のデータ(通常、ファイルに保存されるデータ)を取り扱います。そ のため、ほかのアプリケーションからも同じデータにリンクできます。 アプリケーションがデータに加えた変更は、リンクしているすべての 文書に現れます。 リンクには優れた点が 2 つあります。 • 複数のアプリケーションから同一のデータにアクセスできる • サーバ アプリケーションがデータの保存を管理する。そのデータ にアクセスする PowerBuilder アプリケーションが 1 つしかなくて も、データは変更できる リンク情報の管理 リンク情報の管理は、PowerBuilder ではなくサーバが 行います。起動するサーバ、および使用するファイル内のデータ ファ イルや項目といった情報は、OLE オブジェクトによって PowerBuilder に通知されます。サーバは、データを提供し、そのデータを更新して 元のデータ ファイルに保存し、さらに、その項目に関する情報(たと えば、リンクした列の範囲内に列を挿入した場合の覚え書きといった 情報)を更新します。 中断されたリンクの修復 サーバがリンクを管理しているので、開発者 は、OLE オブジェクトが埋め込まれているのかリンクされているのか を気にせずに、そのオブジェクトをアプリケーション内で移動したり 操作したりすることができます。 ファイルの移動、名前の変更、または削除などが原因でリンクが中断 された場合は、コントロールの[リンクの更新オプション]の設定内 容によって、それにどう対処するかが決まります。 [リンクの更新オプ ション]が「自動」に設定されている場合は、PowerBuilder がダイア ロ グ ボ ッ ク ス を 表 示 し て、フ ァ イ ル の 検 索 を 指 示 し ま す。 UpdateLinksDialog 関数を使用して、スクリプトで同じダイアログボック スを表示することができます。また、リンクは、LinkTo 関数を使用し てスクリプトで行うことができます。 コントロールには、リンクされているオブジェクトが、そのオブジェ クトを開いたときと同じ画像で表示されます。 アプリケーション テクニック 351 OLE コントロールと挿入可能なオブジェクト オフサイト アクティブ化とインプレース アクティブ化 アプリケーション実行時に、エンド ユーザが OLE コントロール上の オブジェクトをアクティブにすると、PowerBuilder は、埋め込まれて いるオブジェクトをインプレース アクティブ化しようとします。つま り、エンド ユーザによるそのオブジェクトの操作は、PowerBuilder の ウィンドウ内部で行われます。サーバ アプリケーションが提供するメ ニューは、PowerBuilder アプリケーションのメニューとマージされま す。メニューのマージは、メニュー ペインタで管理できます(353 ペー ジの「インプレース アクティブ化に対するメニュー」参照)。 コントロールがインプレース アクティブ化されると、幅広のハッチン グ表示の枠線が現れます。 オフサイト アクティブ化とは、サーバ アプリケーションが開き、サー バのウィンドウ上でオブジェクトの内容(文書など)が開かれること です。この場合は、サーバのメニューすべてが使用できます。コント ロール自体は斜線ストライプの影が付けられて表示され、オブジェク トがサーバ アプリケーションで開いていることが示されます。 インプレース アクティブ化の制限 PowerBuilder が OLE オブジェクトをインプレース アクティブ化でき るかどうかは、サーバの機能によって決まります。OLE 1.0 オブジェ クトは、インプレース アクティブ化できません。また、OLE 2.0 標準 は、リンクされたオブジェクトがインプレースではなくオフサイトで アクティブ化するように指定しています。 ウィンドウ ペインタ上では、オブジェクトは常にオフサイト アクティ ブ化されます。 352 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 デフォルトの動作形態は、スクリプトで Activate 関数を呼び出し、オブ ジェクトをインプレースまたはオフサイトのどちらでアクティブ化す るかを指定して変更することができます。コントロールの[起動方法] が「スクリプト(activatemanually!)」に設定されている場合は、Activate 関数の呼び出しを DoubleClicked イベント(またはほかのイベント)に 対するスクリプトに記述します。 デフォルトの動作形態 の変更 ole_1.Activate(Offsite!) コントロールがアクティブ化されない場合 空のコントロール、つまり OLE オブジェクトと関連付けられていない OLE コントロールは、アクティブ化できません。エンド ユーザに OLE オブジェクトを選択させたい場合は、InsertObject 関数を呼び出すスク リプトを記述します。 また、コントロール上のオブジェクトをリンクするときにリンクする ファイルが見つからない場合も、そのコントロールをアクティブ化で きません。ただし、 [リンクの更新オプション]が「自動」に設定され ている場合は、PowerBuilder がダイアログボックスを表示して、エン ド ユーザにファイルを検索させることができます。 [リンクの更新オプション]が「スクリプト(activatemanually!)」に設 定されている場合は、UpdateLinksDialog 関数を使用して、スクリプトで ダイアログボックスを表示したり、LinkTo 関数を使用して、スクリプ トで別ファイルにリンクすることができます。 インプレース アクティブ化に対するメニュー オブジェクトがインプレース アクティブ化すると、サーバ アプリケー ションのメニューは、PowerBuilder アプリケーションのメニューと マージされます。メニュー ペインタの[マージ オプション]の設定内 容によって、2 つのアプリケーションのメニューのマージ方法が決定 されます。選択肢としては、「merge!」と「exclude!」のほかに、標準 メニュー名があります。 ❖ OLE オブジェクトがアクティブ化されたときに、アプリケーションのメニュー を制御するには 1 メニュー ペインタでメニューを開きます。 2 メニュー バーに表示するメニュー項目を選択します。[マージ オ プション]の設定は、ドロップダウン メニューのメニュー項目で はなく、メニュー バーのメニュー項目だけに適用されます。 アプリケーション テクニック 353 OLE コントロールと挿入可能なオブジェクト 3 プロパティ ページで、適切な[マージ オプション]の設定を選択 します。表 19-1 は設定のリストです。 表 19-1: [マージ オプション]の設定 オプション filemenu! 意味 コンテナ アプリケーション (PowerBuilder アプリケーション) のメニュー バーの一番左に表示 されるメニュー。サーバの[ファ イル]メニューは表示されない editmenu! コンテナ アプリケーションの[編 集]メニューは表示されない。サー バの[編集]メニューが表示される windowmenu! 開いているシートのリストを持つ コンテナ アプリケーションのメ ニュー。サーバの[ウィンドウ] メニューは表示されない filemenu! コンテナ アプリケーションの[ヘ ルプ]メニューは表示されない。 サーバの[ヘルプ]メニューが表 示される merge! サーバ アプリケーションの最初 のメニューの後に、そのメニュー が表示される exclude! オブジェクトがアクティブな間 は、メニューは表示されない 4 標準メニューの標準的 な割り当て アクティブ化されたオ ブジェクトのメニュー バー 354 メニュー バーに 表示される メニューの入手先 コンテナ サーバ コンテナ サーバ コンテナ メニュー バーにある各メニュー項目に対して、操作手順 2 と 3 を 繰り返します。 通常、 [マージ オプション]の「filemenu!」 「editmenu!」、 、 「windowmenu!」 、 および 「helpmenu!」は、それぞれ[ファイル]、[編集]、 [ウィンド ウ]、[ヘルプ]の各メニューに割り当てます。実際のメニュー名が国 際的なアプリケーションにおいては異なるかもしれないので、 [マージ オプション]を使用して正しい関係を設定します。 [マージ オプション]を設定すると、メニュー バーに、コンテナの [ファイル]と[ウィンドウ]メニュー、およびサーバの[編集]と [ヘルプ]メニューを表示できます。 「merge!」が設定されたすべての メニューは、メニュー バーの適切な位置に挿入されます。また、メ ニュー バーには、サーバが適切であると判断したほかのメニューも表 示されます。 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 OLE コントロール上でのオブジェクトの修正 OLE オブジェクトが OLE コントロールに表示されているときは、その オブジェクトとそれを作成したアプリケーション(OLE サーバ)の操 作が可能です。また、そこで行われる可能性のある操作をスクリプト に記述することもできます。この節では、以下の方法について説明し ます。 • OLE オブジェクトをアクティブにして、一般的なコマンドをサー バに送る方法 • コントロール内のオブジェクトの変更と保存方法 • データまたはプロパティがイベントによって変更されたときに、 それを検出する方法 コントロールのオートメーションについては、374 ページの「スクリ プトにおける 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 サー バは、バーブしかサポートしておらず、オートメーションはサポート していません。 アプリケーション テクニック 355 OLE コントロールと挿入可能なオブジェクト OLE コントロール上のオブジェクトの変更 PowerBuilder は、OLE コントロール上のオブジェクトを変更するため の関数をいくつか提供しています。これらの関数は、表 19-2 に示すよ うに、オブジェクトをエンド ユーザに選択させるか、オブジェクトを リンクするか埋め込むかによって使い分けます。 表 19-2: OLE コントロール上のオブジェクトを変更するための関数 選択条件 オブジェクトをエンド ユーザに選択させる。 コントロールの Contents プロパティが Any の 場合は、オブジェクトをリンクしても埋め込 んでもかまわない 指定したサーバで新たなオブジェクトを作成 し、コントロールに埋め込む 既存のオブジェクトのコピーをコントロール に埋め込む 既存のオブジェクトをコントロールにリンク する 既存のオブジェクトをファイルかストレージ から開く。ファイルの情報が、オブジェクト をリンクするか埋め込むかを決める 関数 InsertObject InsertClass InsertFile LinkTo Open 図 19-1 は、リンクか埋め込みかの選択ができない 3 つの関数の動きを 示しています。 図 19-1: リンクか埋め込みかの選択ができない関数 356 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 Blob 型変数に保持されている OLE オブジェクトのデータは、OLE コ ントロールの ObjectData プロパティに代入できます。 blob myblob ...// Blob 型変数に保持した OLE データを代入するコード ole_1.ObjectData = myblob コントロールの Contents プロパティによって、埋め込みやリンクの対 象となるオブジェクトを受け入れるかどうかが指定されます。これに よって、エンド ユーザにオブジェクトの挿入 ダイアログボックスで埋 め込みかリンクかを選択させるかどうかが決まります。また、Contents プロパティによって、使用可能な関数が決められます。このプロパティ が許可しない方法を選択する関数を呼び出すと、その関数の実行は失 敗します。 オブジェクト ブラウ ザでの OLE 情報 使用しているシステムにインストールされている OLE サーバ アプリ ケーションの登録名を検索する場合は、オブジェクト ブラウザを使用 し ま す。こ こ に 表 示 さ れ る 名 前 は、InsertClass、ConnectToObject、 ConnectToNewObject の各関数の引数として使用できます(364 ページの 「プログラム可能な OLE オブジェクト」を参照)。 OLE とオブジェクト ブラウザについての詳細は、394 ページの「オブ ジェクト ブラウザでの OLE 情報」を参照してください。 クリップボードの使い 方 メニュー項目のスクリプトに Cut、Copy、Paste の各関数を記述すると、 クリップボード機能がエンド ユーザに提供されます。Cut 関数や Copy 関数を OLE コントロールに対して呼び出すと、そのコントロール上の OLE オブジェクトがクリップボードにコピーされます。同様に、エン ド ユーザがサーバ アプリケーションでこれらのメニュー項目を選択 すると、データがクリップボード上にコピーされます。これらの関数 は、メニュー項目に限らず、任意のスクリプトで記述できます。 OLE コントロールには、オブジェクトを挿入するための Paste 関数が いくつか用意されています。これらの関数には、貼り付けるオブジェ クトをリンクするか、埋め込むかの違いがあるだけです。 表 19-3: Paste 関数 選択条件 クリップボード上のオブジェクトをコント ロールに埋め込む 関数 クリップボード上のオブジェクトをコント ロールに貼り付けてリンクする 貼り付けるオブジェクトを埋め込むか、リン クするかをエンド ユーザに選択させる PasteLink アプリケーション テクニック Paste PasteSpecial 357 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) 358 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 型変数に保持できます(399 ページの「ス トレージを開く、保存する」を参照)。 リンクしたオブジェクトをサーバに保存しても、リンク情報に影響は ありません。したがって、その開いているオブジェクト自体は、保存 する必要はありません。しかし、エンド ユーザがそのオブジェクト名 を変更したり、リンクした項目の範囲に影響を及ぼした場合は、Save 関数を呼び出して、リンク情報を保存しなければなりません。 OLE コントロールにおけるイベント サーバ アプリケーションで OLE オブジェクトに影響するアクション が起きたことを PowerBuilder に通知するイベントがいくつか用意され ています。 データのイベント データに関するイベントは、次のとおりです。 • DataChange イベント データが変更されたとき • Rename イベント オブジェクトの名前が変更されたとき • Save、SaveObject イベント データが保存されたとき • ViewChange イベント エンド ユーザがデータの表示を変更したとき これらのイベントが起こると、その変更内容は OLE コントロールに自 動的に反映されます。オブジェクトに対する名前の変更、保存、また はオブジェクトの変更が行われたときに、何らかの処理を必要とする 場合は、適切なスクリプトを記述して対処します。 アプリケーション テクニック 359 OLE カスタム コントロール OLE アーキテクチャが起因して、上記イベント内で OLE オブジェクト を処理できない場合があります。実行すると、ランタイム エラーを引 き起こしかねません。通常は、PostEvent 関数を使用して非同期イベン ト ハンドラにイベントをポストします。SaveObject イベントをポスト する必要はないので、サーバ アプリケーションがオブジェクトを保存 する際に、常にオブジェクト内のデータをファイルに保存したい場合 には、このイベントが便利です。 プロパティのイベント サーバがプロパティ通知をサポートしている場合は、サーバのプロパティ 値が変更されたときに、PropertyRequestEdit イベントと PropertyChanged イベントが起動されます。変更をキャンセルしたり、古い値を保存し たり、または新しい値を読み込むスクリプトを記述することができま す。 プロパティ通知の詳細については、387 ページの「ホット リンクの作 成」を参照してください。 OLE カスタム コントロール [コントロール]ドロップダウン ツールバーの[OLE]ボタンをクリッ クして、OLE コンテナに OLE オブジェクトまたは OLE カスタム コン トロールのどちらを挿入するかを選択できます。OLE カスタム コント ロール(ActiveX コントロール)を選択すると、コンテナの種類と内容 が確定されます。後から、挿入するオブジェクトを選択したり、別の ActiveX コントロールを選択することはできません。 ActiveX コントロールには、ActiveX コントロール自身のプロパティ、 イベント、関数があります。スクリプトで ActiveX コントロールのプ ロパティとメソッドを呼び出す際に、ActiveX コントロールが変更され ないようにすることは、エラーの回避にもなります。 OLE カスタム コントロールの設定 PowerBuilder のカスタム コントロール コンテナには、どんな ActiveX コントロールにも適用するプロパティがあります。ActiveX コントロー ルは、ActiveX コントロール自身のプロパティを持っています。この節 では、それぞれの種類のプロパティの用途と設定方法について説明し ます。 PowerBuilder のプロ パティ 360 OLE カスタム コントロールのプロパティには、2 つの用途があります。 PowerBuilder 第 19 章 • アプリケーションにおける OLE の使い方 ほかのコントロールと同様に、コンテナの表示と動作の形態を設 定する [全般]プロパティ ページの標準設定([表示可能]、[使用可能] など)と同様に、表示位置、ポインタ、およびドラッグアンドド ロップの設定ができます。 • ActiveX コントロールが使用できるデフォルトの情報を提供する OLE コンテナのフォント情報や表示名をアンビエント プロパティ と呼びます。PowerBuilder が直接アンビエント プロパティを使用 して ActiveX コントロールにテキストを表示することはありませ ん。ActiveX コントロールがアンビエント プロパティを認識でき る場合は、ActiveX コントロールは、PowerBuilder のプロパティを 使用できます。ActiveX コントロールは、テキストを表示したり、 タイトル バーに OLE コンテナの名前を表示できます。 ❖ OLE カスタム コントロールの PowerBuilder プロパティを変更するには 1 OLE コントロールをダブルクリックするか、コントロールのポッ プアップ メニューから[プロパティ]を選択します。 OLE カスタム コントロール プロパティ シートが表示されます。 2 コントロールに名前を付けます。スクリプトではこの名前を使用 します。デフォルト名は「ole_」の接頭辞に数字を組み合わせたも のです。 3 [全般]プロパティ ページやほかのページにあるプロパティの値も 適切な値に設定します。 4 プロパティの設定が終わったら、 [OK]ボタンをクリックします。 コントロールの説明 ウィンドウまたはコントロールの[タグ]プロパティに、使用してい る ActiveX コントロールに関する説明を入力します。別の環境でこの ウィンドウを使用する際に ActiveX コントロールがインストールされ ていない場合、ウィンドウがどの ActiveX コントロールを使用してい たかを簡単に調べることができます。 ActiveX コントロール のプロパティ ActiveX コントロールは、通常、ActiveX コントロール自身のプロパ ティと、プロパティの値を設定するためのプロパティ シートを持って います。ActiveX コントロールのプロパティは、PowerBuilder の OLE コンテナではなく、ActiveX コントロールの表示と動作の形態を管理し ます。 アプリケーション テクニック 361 OLE カスタム コントロール ❖ 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 362 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 次の構文は、ActiveX コントロールの関数を呼び出します。適切なデー タ型の変数で、戻り値を取得できます。 { value } = olecontrol.Object.ocxfunction ( { argumentlist } ) プロパティのアクセス 時のエラー PowerBuilder のコンパイラは、ActiveX コントロールのプロパティと関 数にアクセスするための正しい構文を認識しないため、Object プロパ ティの後の構文をチェックしません。これは、ActiveX コントロールの プログラミングに必要な柔軟性につながります。しかし、プロパティ や関数の名前が間違っていたり、不足していたりすると、アプリケー ションが実行時にエラーを起こす可能性があります。 PowerBuilder は、OLE のエラー処理をするため、ExternalException と Error という 2 つのイベントを用意しています。ActiveX コントロール が組み込みエラー イベントを定義した場合、PowerBuilder OLE コント ロール コンテナには、追加イベントである ocx_event があります。こ れらのイベントを使用すると、割り込みの形でエラー処理ができ、 SystemError イベントが起動してアプリケーションが終了することは ありません。また、例外ハンドラ TRY-CATCH も使用できます。 詳細については、384 ページの「エラー処理」を参照してください。 ActiveX コントロール のイベントの使い方 ActiveX コントロールには、ActiveX コントロール自身が持つイベント があります。PowerBuilder は、ActiveX コントロールのイベントと OLE カスタム コントロール コンテナのイベントをマージします。ActiveX コントロールのイベントは、PowerBuilder のイベントとともに、イベ ント リストビューに表示されます。PowerBuilder のイベントに対する スクリプトと同じように、PowerScript で ActiveX コントロールのイベ ントに対するスクリプトも記述できます。ActiveX コントロールのプロ パティとメソッドを参照するには、OLE カスタム コントロールの Object プロパティを使用します。 ActiveX コントロールのイベントと PowerBuilder のイベントの唯一の 違いは、イベントが起動されるタイミングです。ActiveX コントロール のイベントの詳細については、ActiveX コントロールのマニュアルを参 照してください。ActiveX コントロールの開発元が、ActiveX コント ロールのイベント、プロパティ、関数に関するマニュアルを提供して います。 ActiveX コントロールのプロパティとメソッドの一覧は、PowerBuilder オブジェクト ブラウザで参照できます。詳細については、394 ページ の「オブジェクト ブラウザでの OLE 情報」を参照してください。 アプリケーション テクニック 363 プログラム可能な OLE オブジェクト ActiveX コントロールの新規バージョン ActiveX コントロールの新規バージョンをインストールして、その ActiveX コントロールに新規のイベントがあった場合でも、ウィンドウ ペインタの[イベント]ドロップダウン リストボックスには新規のイ ベントが追加されません。新規のイベントを使用するには、既存のイ ベントのスクリプトとともに、OLE カスタム コントロールを削除して 再作成しなければなりません。新規のイベントを使用しない場合は、 コントロールをそのままにしておき、更新された既存の ActiveX コン トロール イベントを使用することができます。 プログラム可能な OLE オブジェクト OLE オブジェクトをスクリプトで操作するときは、必ずしも、ウィンド ウ上に OLE コントロールを配置しなくてもかまいません。PowerBuilder アプリケーションで表示する必要のない OLE オブジェクトは、コント ロールと無関係に作成し、サーバ アプリケーションとの関連付けを行 い、関数呼び出しやプロパティを設定することができます。サーバ ア プリケーションが、関数を実行して、OLE オブジェクトのプロパティ を変更します。つまり、OLE オブジェクトを変更します。 アプリケーションの中には、表示、非表示の指定が可能なものがあり ます。表示を指定すれば、エンド ユーザは、そのアプリケーションを アクティブ化し、サーバ アプリケーションのコマンドやツールを使用 して、OLE オブジェクトを操作できます。 OLEObject オブジェクト型 PowerBuilder の OLEObject オブジェクト データ型は、オートメーショ ン機能で用いるために設計されています。OLEObject 変数は動的オブ ジェクトの一種です。つまり、コンパイラは、このオブジェクトに対 するどのようなプロパティ名、関数名、パラメータ リストも受け入れ ます。PowerBuilder は、それらのプロパティと関数が有効かどうかを 知る必要がありません。このオブジェクトのメソッドの呼び出しやプ ロパティの設定は、そのオブジェクトを作成したサーバ アプリケー ションによって把握されています。これらの関数やプロパティが、ア プリケーション実行時に存在しない場合は、実行時エラーが起こりま す。 364 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 関連付けを行ったら、オートメーションのために用意されている一連 のサーバ コマンドを使用して、オブジェクトの操作ができます(374 ページの「スクリプトにおける OLE オブジェクト」を参照) 。 アプリケーション テクニック 365 プログラム可能な 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") 366 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 ページの「ガベージ コレクションとメモリ管理」 を参照してください。 アプリケーション テクニック 367 プログラム可能な OLE オブジェクト OLEControl、OLECustomControl、OLEObject データ型の代入 OLEObject 変数に OLE コントロール(OLEControl オブジェクト デー タ型)や ActiveX コントロール(OLECustomControl オブジェクト デー タ型)を直接代入することはできません。 コントロールのベンダがプログラム識別子(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") 368 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 oleChild = CREATE oleobjectchild oleChild.SetAutomationPointer( ole1 ) これで、オートメーションで olechild を使用できます。 オートメーション オートメーションに関する各手順は、単一のスクリプトの中に含まれ ていたり、ウィンドウ上のいくつかのコントロールのアクションに分 離されていたりします。エンド ユーザをオートメーションによる処理 に関与させたい場合は、以下のようにします。 • OLE オブジェクトをウィンドウのインスタンス変数として宣言する • その変数のインスタンスを作成し、ウィンドウの Open イベントで サーバとの関連付けを行う • エンド ユーザによるリストボックスからの選択やエディット ボッ クスへの入力に応答して、サーバにコマンドを送る • ウィンドウの Close イベントで、サーバとの関連付けを解除し、そ のインスタンスを破棄する エンド ユーザをオートメーションに関与させたくない場合は、すべて の処理を単一のスクリプトで行います。 例 : OLE を使用したレター フォームの生成 この例では、Microsoft Word で VBA スクリプティング を使用して、 データウィンドウ オブジェクトから名前と住所を、マルチラインエ ディットから手紙の本文を取り込み、手紙の作成と印刷を行います。 ❖ レター フォームの例をセットアップするには 1 4 つのブックマークがある CONTACT.DOC という名前の Word 文 書を作成し、PowerBuilder ディレクトリに保存します。 ブックマークは次のとおりです。 アプリケーション テクニック • name1 – 受取人の名前 • name2 – あいさつ文に入れる名前 • address1 – 受取人の住所(番地、市、県、郵便番号) • body – 手紙の本文 369 プログラム可能な OLE オブジェクト 手紙の本文は次のとおりです。 Multimedia Promotions, Inc. 1234 Technology Drive Westboro, Massachusetts January 12, 2001 [bookmark name1] [bookmark address1] Dear [bookmark name2]: [bookmark body] Sincerely, Harry Mogul President 会社名や自筆サインのロゴなどを付けて、手紙の形式を充実させ ることもできます。重要な項目は、ブックマークの名前と位置で す。 2 PowerBuilder では、d_maillist というデータウィンドウ オブジェクト を定義します。このデータウィンドウ オブジェクトには、以下の カラムがあります。 id first_name last_name street city state zip データウィンドウ オブジェクトに検索引数の指定 ダイアログ ボックスを表示して、エンド ユーザが手紙を受け取る顧客を選択 できるようにします。 370 PowerBuilder 第 19 章 3 アプリケーションにおける OLE の使い方 dw_mail という データウィンドウ コントロール、mle_body という マルチライン エディット、およびコマンドボタンやピクチャボタ ンなどを含むウィンドウを定義します。 4 データウィンドウ オブジェクト d_maillist をデータウィンドウ コ ントロール dw_mail に割り当てます。 5 データベースと接続し、データをデータウィンドウ オブジェクト に読み取るスクリプトをウィンドウの Open イベントに記述しま す。以下のコードは、Adaptive Server 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) アプリケーション テクニック 371 プログラム可能な 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 /*************************************************** 372 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 OLEObject 変数にメモリを割り当てます。 ***************************************************/ 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:\pb10\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") アプリケーション テクニック 373 スクリプトにおける OLE オブジェクト contact_ltr.Selection.goto("address1") 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 つの使用方法について説明しました。学習した内容は以下のとお りです。 374 • 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 サーバ アプリ ケーションのマニュアルを参照してください。 アプリケーション テクニック 375 スクリプトにおける OLE オブジェクト OLE カスタム コントロールとプログラム可能な OLE オブジェクトに ついては、PowerBuilder オブジェクト ブラウザでプロパティとメソッ ドのリストを参照できます。オブジェクト ブラウザにおける OLE 情 報についての詳細は、394 ページの「オブジェクト ブラウザでの 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 サーバ修飾子は、オブジェクトとの関連付けを行う方法に応じて指定 する必要があります。詳細については、380 ページの「サーバ コマン ドの修飾子」を参照してください。 関数の呼び出し 以下の構文は、OLE コントロールの Object プロパティを使用して、 サーバの関数を呼び出すことができます。 376 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) アプリケーション テクニック 377 スクリプトにおける 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.& 378 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) アプリケーション テクニック 379 スクリプトにおける 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 のようになっています。 380 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 アプリケーション テクニック 381 スクリプトにおける OLE オブジェクト ole_1.Object.application.ActiveDocument. & Bookmarks.[i].Name コントロール上のオブジェクトではなく、PowerBuilder の OLEObject オブジェクト データ型のデータを操作しているときは、コマンドのア プリケーション修飾子を省略します。オブジェクトを関連付けるとき に、すでに指定しているからです。OLEObject オブジェクト データ型 についての詳細は、364 ページの「プログラム可能な 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" 382 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 アプリケーション テクニック 383 スクリプトにおける OLE オブジェクト ls_curr_bookmark = ole_wb.bookmarkname(i) ... // リストにブックマークの名前を保存するためのコード END FOR エラー処理 PowerBuilder は、OLE サーバが実行できるオートメーションの構文を 知らないので、スクリプトをコンパイルしても、OLE サーバのプロパ ティを参照するステートメントはチェックされません。コンパイラは エラーをチェックすることができないので、OLE サーバが認識できな いプロパティや関数の名前および引数を指定すると、アプリケーショ ンを実行したときに実行時エラーが起きます。 OLE エラー時のイベ ントの連鎖 OLE コントロールまたは OLE サーバによりエラーが発生した場合、以 下の順で PowerBuilder のイベントが連続して起動されます。 1 組み込みエラー イベントを設定している ActiveX コントロール に よりエラーが発生した場合、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 イベントが起動された後も処理を継続することはよくあ りません。 384 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! イベントにスクリプトが記述されていない場合と同 じ。エラーが発生すると、エラー イベントの起動順位 にしたがって、次のエラー イベントが起動される アプリケーション テクニック 385 スクリプトにおける 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 386 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 イベント が起動されます。このイベントに対するスクリプトで、以下のような ことが可能です。 アプリケーション テクニック 387 スクリプトにおける 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 大規模な変更が発生し た場合 388 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 アプリケーションの場合)は、自国の言語 と英語のオートメーション インタフェースが提供されます。エンド ユーザが開発者と異なる言語を使用している場合は、開発者の自国語 でオートメーション コマンドを記述することは適当ではありません。 アプリケーション テクニック 389 スクリプトにおける 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 プロパティは、データウィンドウ オブジェクト内のオブジェク トへのインタフェースとなります。 390 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 に関連付けら れたサーバ アプリケーションのための長い 名前 391 スクリプトにおける OLE オブジェクト プロパティ ClassShortName データ型 LinkItem String ObjectData String Blob 説明 (読み出し専用)OLE DWObject に関連付けら れたサーバ アプリケーションのための短い 名前 (読み出し専用)オブジェクトのリンク先項 目の完全なリンク名 たとえば、オブジェクトが C:\FILENAME.XLS!A1:B2 にリンクされてい る場合は、LinkItem は C:\FILENAME.XLS!A1:B2 となる オブジェクトが埋め込まれている場合は、オ ブジェクト自身が 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 カラムを使用するには、ウィンドウに データウィンドウ コント ロールを配置し、データウィンドウ オブジェクトとの関連付けを行い ます。 392 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 ユーザーズ ガイド』マニュアルを参照してくださ い。 アプリケーション テクニック 393 オブジェクト ブラウザでの OLE 情報 オブジェクト ブラウザでの OLE 情報 OLE サーバ アプリケーションと OLE カスタム コントロール(OCX) をインストールすると、そのオブジェクトの情報がレジストリに登録 されます。 PowerBuilder は、レジストリを読み込んで、登録されたすべての OLE サーバと OCX のレジストリ情報を表示します。 ❖ 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 は、いくつかのキーとその説明です。 394 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 オブ ジェクト ブラウザ ❖ OLE の情報をスクリプトに貼り付けるには 1 ブラウザを開きます。 2 [OLE]タブをクリックします。 アプリケーション テクニック 395 OLE オブジェクトの高度な操作 3 オブジェクトを検索するためにリストを展開します。たとえば、ある ActiveX コントロール プロパティを検索するために、その ActiveX コントロール のリストをさらに展開します。 4 プロパティをハイライト表示して、ポップアップ メニューから[コ ピー]を選択します。 5 スクリプト ビューで挿入ポイントを決めて、ポップアップ メニュー から[貼り付け]を選択します。 オブジェクト ブラウザは、以下のようにスクリプトに構文を挿入 します。 OLECustomControl.Object.NeedlePosition OLECustomControl を実際のコントロール名に変更した後は、スク リプトで NeedlePosition プロパティを正しく設定してください。 オブジェクト ブラウザがスクリプトに貼り付ける内容は、選択した内 容によって異なります。オブジェクト(階層構造におけるプロパティ の 1 つ上のレベル)を選択した場合は、PowerBuilder はオブジェクト の ProgID を貼り付けます。ConnectToNewObject 関数で ProgID を使用で きます。 オートメーションとレジストリについての詳細は、第 20 章「PowerBuilder のランタイム オートメーション サーバ」を参照してください。 OLE オブジェクトの高度な操作 PowerBuilder は、コントロール上の OLE オブジェクトとオートメー ションに対するオブジェクトのほかにも、基本的な OLE データ スト レージに対するインタフェースを提供しています。 OLE データは、ストリームと呼ばれるオブジェクトに保持されていま す。また、ストリームは、ストレージと呼ばれるオブジェクトの中に 存在します。ストリームとストレージは、ファイル システムにおける ファイルとディレクトリの関係に似ています。ストリームやストレー ジを開き、読み取り、書き込み、保存、削除することにより、OLE オ ブジェクトの作成、結合、削除を行うことができます。PowerBuilder では、OLEStorage オブジェクトと OLEStream オブジェクトの 2 つの データ型を用いて、ストレージやストリームへのアクセスを行います。 396 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 OLE コントロールと OLEObject 変数を定義すれば、サーバ アプリケー ションやオートメーションのすべての機能にアクセスでき、これだけ でも、OLE の機能を活用することができます。したがって、保持され ているデータの構造が複雑でなければ、PowerBuilder のストレージ オ ブジェクトやストリーム オブジェクトは必要ありません。 ほかのアプリケーションのストレージ ファイル この節では、PowerBuilder アプリケーションが作成した OLE ストレー ジ ファイルについて説明します。ほかの PowerBuilder アプリケーショ ンも、PowerBuilder で作成したストレージ ファイル内のオブジェクト を開くことができます。Excel、Word、およびそのほかのサーバ アプ リケーションは、それらのネイティブ データを OLE ストレージに保 持しますが、各ファイルに独自の形式があるため、それらをストレー ジ ファイルとして直接開くことはお勧めしません。Word や Excel など のファイルは、 (InsertFile 関数を用いて)コントロール上に挿入するか、 (ConnectToObject 関数を用いて)コントロールとオートメーションで関 連付けた方がよいでしょう。 OLE ストレージの構造 OLE ストレージは、OLE データのリポジトリです。ストレージは、ディ スクのディレクトリ構造に似ています。ストレージは、1 つの OLE オ ブジェクトである場合や、ほかのストレージやサブストレージに格納 されている複数の OLE オブジェクトを格納している場合もあります。 図 19-3 に示すように、サブストレージは、ディレクトリ内のファイル のように、独立した要素の個別の OLE オブジェクトにもでき、画像を 含む文書などの大規模な OLE オブジェクトも形成できます。 図 19-3: OLE ストレージの構造 アプリケーション テクニック 397 OLE オブジェクトの高度な操作 OLE オブジェクトを含むストレージやサブストレージでは、それが特 定のサーバ アプリケーションに属していることを示すタグを付けて 情報を識別しています。これにより、その下位レベルの各コンポーネ ントは、そのサーバ アプリケーションでしか操作されなくなります。 なお、サーバのオブジェクトを格納しているストレージを開いて、そ の中からオブジェクトを取り出すことができますが、そのストレージ は変更すべきではありません。 OLE オブジェクトを格納しているストレージは、オブジェクトの表示 情報を持っています。表示情報がストレージに属しているので、OLE は、オブジェクトを表示するためにサーバ アプリケーションを起動す る必要がありません。 OLE オブジェクトを含まず、単にほかのストレージを格納しているだ けのストレージもあります。この場合は、挿入するオブジェクトがな いので、そのストレージをコントロール上で開くことはできません。 ストレージとストリームに対するオブジェクト データ型 PowerBuilder は、OLE ファイルのストレージとストリームに対するオ ブジェクト データ型を 2 種類用意しています。 • OLEStorage • OLEStream これらのオブジェクトは、トランザクション オブジェクトやメッセー ジ オブジェクトと同じようなクラス ユーザ オブジェクトです。これ らのオブジェクト データ型の変数を宣言し、そのインスタンスを作成 してから、ストレージを開きます。ストレージを使った作業を終了し たら、ストレージを閉じ、変数を破棄して、OLE サーバと変数に割り 当てられていたメモリを解放します。 ストレージを開くと、OLEStorage 変数とディスク上のファイルが関連 付けられます。このファイルは、現行セッションのための一時的なファ イルであったり、OLE オブジェクトを含む既存のファイルであったり します。ファイルが存在しない場合は、PowerBuilder が作成します。 OLE オブジェクトをストレージに格納するには、SaveAs 関数を使用し ます。また、ウィンドウ上の OLE コントロールとストレージとの関連 付けは、OLE コントロールに対する Open 関数を呼び出して行います。 398 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") アプリケーション テクニック 399 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 ストレージ 400 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) アプリケーション テクニック 401 OLE オブジェクトの高度な操作 char(1) が必要なのは、Microsoft の DocFile Viewer などのユーティリ ティでストレージを見たときに、IOle10Native の "I" は I ではないから です。 ストリームを開く場合も同じように記述する必要があります。たとえ ば、次のようになります。 ole_stream.open(ole_storage, char(1) + 'Ole10Native', & StgReadWrite!, StgExclusive!) 例 : ストレージの作成 たとえば、描画ツールで描かれた製品イメージ図を、データウィンド ウ オブジェクトの製品レコードに対応させて表示するものとします。 データベース レコードにはその画像の識別子が格納されています。ア プリケーションでは、この識別子をファイル名として用いて InsertFile 関数を呼び出します。しかし、サーバ アプリケーションを呼び出して 画像を表示するには比較的時間がかかります。 以下の図のように、ストレージ ファイルを作成し、すべての図を保持 しておくことにします。アプリケーションで画像を表示したいときは、 適切なサブ ストレージが開かれるようにします。 図 19-5: OLE ストレージ ファイル サーバ アプリケーションからファイルをコントロールに挿入せずに、 このようにストレージ ファイルを使用すると、処理速度が速くなるう え、すべての画像を単一のファイルにまとめることができて扱いやす くなります。どの画像を表示するにもストレージ ファイルを 1 つだけ 開けばよく、サーバ アプリケーションの起動も必要としないので、画 像が速く表示できるようになります。 402 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 アプリケーション テクニック 403 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 404 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 オブジェクトの生データが入っているので、サー バ アプリケーションで作成したストリームを変更することはまずあ りません。しかし、ストリームをストレージ ファイルに追加してスト レージに関する情報を格納することができます。たとえば、各ストレー ジに対するラベルを付けたり、ストレージのメンバーのリストを表示 するようなストリームを記述できます。 アプリケーション テクニック 405 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 は、ストリームの開閉や、ストリームに対する情報の入 出力に用いるストリーム関数をいくつか用意しています。 406 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 表 19-11: ストリーム関数 関数 Open Length Seek Read Write Close 例 : ストリームの読み 書き 機能 指定した OLEStream 変数にストリームを開く。このストリー ムを格納しているストレージは、あらかじめ開いておかなけ ればならない ストリームのサイズをバイト単位で取得する シーク ポインタをストリーム内に配置する。次の読み書き操 作は、このポインタから行われる ストリームからのデータの読み取りをシーク ポインタの位置 から開始する ストリームへのデータの書き込みをシーク ポインタの位置か ら開始する ポインタがストリームの終わりを指していない場合は、Write 関数は既存データを上書きする。書き込むデータがストリーム の現行サイズより大きくなる場合は、そのサイズが拡張される ストリームを閉じ、OLEStream 変数との関連を解除する 以下の例は、製品の在庫データをデータウィンドウ オブジェクトの dw_product に表示するときに、その製品の画像を OLE コントロール ole_product に表示します。 ここでは、前述のユーティリティ アプリケー ションで構築したファイルを使用します(402 ページの「例 : ストレー ジの作成」を参照)。画像は、OLE ストレージ ファイルに格納されて います。また、各画像のストレージの名前はデータベース テーブルの 製品コードと同一です。この例では、各画像にラベル情報を追加し、 製品コードに接尾辞 _lbl を付けた名前のストリームに格納します。 図 19-6 はファイルの構造を示しています。 アプリケーション テクニック 407 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 result = stg_prod_pic.Open( is_ole_file) 408 PowerBuilder 第 19 章 アプリケーションにおける OLE の使い方 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 に表示します。 st_label.Text = labelid END IF アプリケーション テクニック 409 OLE オブジェクトの高度な操作 /**************************************************** ストリームを閉じ、ストリーム変数のメモリを解放します。 ***************************************************/ 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 データを保持する別の手段として、ス トレージを使用できます。 ストレージの構造の遷移を記録しておくこともできます。ストレージ ファイル内のメンバー名(ストレージやストリーム)のリストを表示 するストリームをルート レベルで記述したり、ストリームにストレー ジのラベルやデータベースのキー情報を記述してストレージの説明文 書として利用することができます。 410 PowerBuilder 第 2 0 章 PowerBuilder のランタイム オート メーション サーバ この章について この章では、オートメーションを使用して PowerBuilder のクラス ユーザ オブジェクトにアクセスする方法について説明します。 PowerBuilder オブジェクトは、OLE サーバとして使用できます。 PowerBuilder や OLE に対応した開発ツールは、PowerBuilder オブ ジェクトのメソッドやプロパティにアクセスできます。 内容 アプリケーション テクニック 項目 ランタイム オートメーション サーバの使い方 ユーザ オブジェクトをオートメーション サーバとして使用 する方法 PowerBuilder をオートメーション サーバとして使用する方法 名前付きサーバの作成と使用 ユーザ オブジェクトとレジストリについての詳細 オートメーション サーバを使用するアプリケーションの配布 オートメーション サーバ リファレンス PowerBuilder.Application サーバ オブジェクト CreateObject 関数 GenerateGUID 関数 GenerateRegFile 関数 GenerateTypeLib 関数 例外コード レジストリ更新ファイルのサンプル ページ 412 417 422 427 429 437 439 439 442 444 447 450 454 455 411 ランタイム オートメーション サーバの使い方 ランタイム オートメーション サーバの使い方 PowerBuilder COM サーバの使い方 この章では、PowerBuilder ランタイム オートメーション サーバの使い 方に重点を置いて説明します。COM 準拠のサーバを構築する際には、 PowerBuilder の COM/COM+ サーバ生成がよく用いられます。 PowerBuilder のオートメーション サーバ テクノロジは、将来のリリー スでは廃止される可能性があります。 カスタム クラス ユーザ オブジェクトから PowerBuilder COM オブジェ クトを生成する方法の詳細については、第 27 章「COM/COM+ コンポー ネントの構築」を参照してください。 第 19 章「アプリケーションにおける OLE の使い方」では、OLE オブ ジェクトとカスタム コントロールのコンテナの提供方法と、OLE オブ ジェクトのメソッドとプロパティにアクセスするためのオートメー ションの使用方法について説明しました。 OLE オブジェクトの機能は、 サーバ アプリケーションによって提供されます。データを操作するた めのコマンドをサーバ アプリケーションに送ります。 オートメーション サーバについて PowerBuilder オートメーション サーバは、挿入可能でビジュアルなオ ブジェクトではなく、プログラミング可能なオブジェクトに対応した OLE サーバです。PowerBuilder オートメーション サーバは、PowerBuilder ライブラリ内のクラス ユーザ オブジェクト(非ビジュアル ユーザ オ ブジェクト)へのアクセスを提供します。ユーザ オブジェクトにアク セスするには、オートメーション サーバとのセッションを確立して ユーザ オブジェクトのインスタンスを作成します。次に、オートメー ションの構文を使用してコマンドをユーザ オブジェクトに送ります。 クラス ユーザ オブジェクトは、ほかのオブジェクトのインスタンスを 作成できます。サーバは、これらのオブジェクトの参照をクライアン トに渡すことができます。 412 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ 図 20-1: サーバはクラス ユーザ オブジェクトの参照をクライアントに渡す クライアント アプリ ケーション オートメーション サーバとプログラミング可能なオブジェクトをサ ポートするクライアント アプリケーションは、PowerBuilder オート メーション サーバにアクセスできます。クライアント アプリケーショ ンは、PowerBuilder、Visual C++、Visual Basic などの COM 準拠のツー ルで作成できます。 実行時のオーバーヘッ ド オートメーション サーバとの関連付けが行われると、PowerBuilder の 実行環境のインスタンスが起動します。ただし、サーバのランタイム セッションとクライアントのランタイム セッションはシステム クラ スの定義を共有するため、オーバーヘッドにはなりません。 ユーザ クラスの定義は、共有されません。したがって、複数のランタ イム セッションごとに、同じ大きさのオブジェクトを作成した場合、 オブジェクトのメモリ使用量はランタイム セッションの数の倍にな ります。アプリケーションを再編成して 1 つのサーバ セッションにオ ブジェクトを作成するようにすれば、アプリケーションはメモリを効 率的に使用できます。 ランタイム オートメーションの用途 機能をカプセル化してアクセス情報を提供するクラス ユーザ オブ ジェクトは、オートメーション サーバとして使用できます。クライア ント アプリケーションからアクセスする情報は、パブリックのインス タンス変数に保持するか、関数の戻り値や引数(参照渡し)で使用で きるようにする必要があります。 オートメーション サーバの例として、以下のユーザ オブジェクトがあ ります。 アプリケーション テクニック 413 ランタイム オートメーション サーバの使い方 • データストア オブジェクトを作成して、検索したデータの統計を レポートするユーザ オブジェクト • データの妥当性チェックを行うなど、ビジネス ルールが定義され たユーザ オブジェクト 3 つのアクセス方法 PowerBuilder ユーザ オブジェクトにアクセスするには、3 つの方法が あります。以下にその方法を示します。 オートメーション サーバとしてのユーザ オブジェクト • 定義および登録した PowerBuilder クラス ユーザ オブジェクトにア クセスする • 指定したライブラリにある定義済みのオブジェクトを作成した 後、PowerBuilder 自身をサーバとしてアクセスする • PowerBuilder サーバへのアクセスを提供すると同時に、ビジネスに 適した名前を使用できる名前付きサーバにアクセスする クラス ユーザ オブジェクトを定義し、レジストリに登録できます。ク ライアント アプリケーションで提供されている外部オブジェクトに アクセスするための関数を使用すれば、ユーザ オブジェクトのプロパ ティと関数にアクセスできます。オートメーションでは、ユーザ オブ ジェクトのインスタンス変数をプロパティとしてアクセスします。 ユーザ オブジェクトをオートメーション サーバとしてレジストリに 登録する利点は、以下のとおりです。 414 • レジストリに登録されたユーザ オブジェクトの情報を取得できる ので、ほかの開発者はそのユーザ オブジェクトを使用したプログ ラムを簡単に作成できる • ユーザ オブジェクトにアクセスするためのクライアント アプリ ケーションのコードが簡単になる • クライアント アプリケーションは、レジストリに登録されたクラ スだけにアクセスできる。したがって、ユーザ オブジェクトの関 数の戻り値やインスタンス変数にアクセスできる PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ 図 20-2: サーバとしてのクラス ユーザ オブジェクトとクライアントの対話 個々のユーザ オブジェクトにアクセスするには、アクセスするすべて のユーザ オブジェクトをレジストリに登録する必要があります。 OLEObject オブジェクト データ型の変数にユーザ オブジェクトを関 連付け、オートメーションを使用してユーザ オブジェクトのメソッド やプロパティ(インスタンス変数)にアクセスします。ユーザ オブ ジェクトを関連付けると、PowerBuilder のランタイム セッションが起 動します。 ランタイム セッション内でユーザ オブジェクトにアクセスする場合 は、そのユーザ オブジェクトのインスタンスを作成します。ユーザ オ ブジェクトの 1 つのインスタンスを作成するたびに、PowerBuilder の ランタイム セッションが起動します。登録オブジェクトごとに、追加 のランタイム セッションのオーバーヘッドがかかります。 ユーザ オブジェクトをレジストリに登録して使用するための操作手 順については、417 ページの「ユーザ オブジェクトをオートメーショ ン サーバとして使用する方法」を参照してください。 オートメーション サーバとしての PowerBuilder PowerBuilder をインストールすると、PowerBuilder をオートメーション サーバとして使用できるように、レジストリに PowerBuilder.Application キーが登録されます。複数のクラス ユーザ オブジェクトのインスタン スを作成し、それぞれのプロパティやメソッドにアクセスできます。 オートメーションでは、ユーザ オブジェクトのインスタンス変数をプ ロパティとしてアクセスします。 PowerBuilder.Application サーバ オブジェクトを使用する利点は、以下 のとおりです。 • アプリケーション テクニック PowerBuilder の実行環境を複数起動することがないので、その分の オーバーヘッドがかからない。1 つのサーバ セッションで複数の ユーザ オブジェクトにアクセスできる 415 ランタイム オートメーション サーバの使い方 • 指定したライブラリ リスト内のすべてのシステム クラスと、プラ イベート クラスに直接アクセスできる。これらのクラスは PowerBuilder.Application サーバ オブジェクトの CreateObject 関数を 使用してインスタンスを作成できる PowerBuilder.Application サーバ オブジェクトに関連付けを行った後 で、アクセスするランタイム ライブラリを指定します。ライブラリ内 のユーザ オブジェクトやシステム クラスは、同じサーバ セッション に複数のインスタンスを作成できます。 クライアント アプリケーションで作成した各オブジェクトのインス タンスは、クライアントの OLEObject オブジェクトとして扱います。 OLEObject オブジェクトに対してオートメーションを使用すると、そ れぞれのオブジェクトにアクセスできます。クライアント アプリケー ションが、同じランタイム セッションでサーバ オブジェクトの参照を 別のサーバ オブジェクトに渡す場合、その渡されたオブジェクトの参 照は、PowerBuilder では PowerBuilder オブジェクト データ型として認 識されます。これによって、クライアントからのオートメーション コ マンドに制限されずに、同じサーバ セッションで 2 つのオブジェクト を相互に操作できるようになります。 図 20-3: 1 つのサーバ セッション内で対話するオブジェクト PowerBuilder.Application を設定して使用するための操作手順について は、422 ページの「PowerBuilder をオートメーション サーバとして使 用する方法」を参照してください。 416 PowerBuilder 第 20 章 名前付きオートメー ション サーバ PowerBuilder のランタイム オートメーション サーバ ビジネス上の理由で、エンド ユーザに PowerBuilder.Application サーバ オブジェクトを参照できないようにするが、このサーバ オブジェクト が提供する機能(たとえば、1 つのサーバ セッションで複数のユーザ オブジェクトのインスタンスを作成するような場合)は利用するとし ます。 レジストリに PowerBuilder.Application サーバ オブジェクトを参照する もう 1 つのエントリを登録すると、そのビジネスに適切な OLE オート メーション サーバの名前を付けることができます。 名前付きオートメーション サーバを設定するための操作手順につい ては、427 ページの「名前付きサーバの作成と使用」を参照してくだ さい。 ユーザ オブジェクトをオートメーション サーバとして 使用する方法 レジストリに登録されたユーザ オブジェクトをオートメーション サーバとしてアクセスするには、以下の操作手順に従います。 1 クラス ユーザ オブジェクトを作成します。 2 クラス ユーザ オブジェクトのランタイム ライブラリを構築します。 3 クラス ユーザ オブジェクトをレジストリに登録します。 4 クライアント アプリケーションで、クラス ユーザ オブジェクトを 関連付けるオートメーション コマンドを記述します。 サーバとなるクラス ユーザ オブジェクトの作成 ユーザ オブジェクトをオートメーション サーバとして使用するため にどのような定義を行うかは、アプリケーションの設計に依存します。 ユーザ オブジェクトは、カスタム クラス ユーザ オブジェクトでなけ ればなりません。ユーザ オブジェクトのインスタンス変数と関数を定 義します。ユーザ オブジェクトは、PowerBuilder のほかのオブジェク トを宣言してそのオブジェクトのインスタンスを作成できます。 アプリケーション テクニック 417 ユーザ オブジェクトをオートメーション サーバとして使用する方法 ビジュアル オブジェクトは参照しない オートメーション サーバとして使用するクラス ユーザ オブジェクト は、メッセージ ボックスやウィンドウなどのビジュアル オブジェクト への参照を含むことができません。 クライアント アプリ ケーションにおけるオ ブジェクト クライアント アプリケーションの任意のオブジェクトは、クラス ユー ザ オブジェクトを参照できます。ユーザ オブジェクトを参照するに は、OLEObject オブジェクト データ型を使用します。クライアント ア プリケーションのオブジェクトは、オートメーションを使用してその ユーザ オブジェクトのプロパティやメソッドにアクセスできます。 オートメーションでは、ユーザ オブジェクトのインスタンス変数をプ ロパティとしてアクセスします。 ユーザ オブジェクト のテスト ユーザ オブジェクトをオートメーション サーバとしてアクセスする 前に、簡単なテスト環境で、そのユーザ オブジェクトが問題なく機能 するかどうかをテストしてください。ローカルでユーザ オブジェクト をテストするためのアプリケーションを構築できます。 ユーザ オブジェクトのランタイム ライブラリの構築 ユーザ オブジェクトを定義した後は、ライブラリ ペインタを使用して 動的ライブラリ(PBD)かコンパイルされたライブラリ(DLL)を構 築します。Pcode かマシン コードのどちらかを選択する理由は、どの PowerBuilder アプリケーションを構築するときでも同じです。 詳細については、820 ページの「コンパイラの基本事項」を参照して ください。 ユーザ オブジェクトとユーザ オブジェクト内でインスタンスを作成 するオブジェクトだけを 1 つのライブラリに格納するように、ライブ ラリ ペインタを使用してライブラリを再編成します。使用されないオ ブジェクトを残したままにしておくと、ランタイム ライブラリが必要 以上に大きくなります。 ライブラリ ペインタで動的ライブラリを構築するには、以下の操作を 行います。 1 ライブラリ ペインタで、ライブラリ名を選択します。 2 [エントリ|ライブラリ|動的ライブラリの構築]を選択します。 3 418 PBD ファイルと DLL ファイルのいずれを作成するかに応じて、 [マシン コード]チェックボックスをオンまたはオフにします。 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ 動的ライブラリの構築 ダイアログボックスのほかのオプションは、 このプロセスでは不要です。ほかのオプションの詳細については、 [ヘルプ]ボタンを選択して、説明を参照するか、『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 4 [OK]ボタンをクリックしてランタイム ライブラリを構築します。 レジストリに登録するディレクトリに、ランタイム ライブラリを 移動します。 5 ユーザ オブジェクトの登録 ユーザ オブジェクトをオートメーション サーバとして使用するには、 レジストリに登録する必要があります。また、ユーザ オブジェクトの プロパティと関数についての情報を提供するタイプ ライブラリを作 成して、ブラウザ アプリケーションを登録することもできます。 詳細については、429 ページの「ユーザ オブジェクトとレジストリに ついての詳細」を参照してください。 オートメーション サーバ プロジェクト ウィザードを使用すれば、タ イプ ライブラリの登録と作成が簡単にできます。 ❖ レジストリ情報を作成してユーザ オブジェクトを登録するには 1 新規作成 ダイアログボックスの[プロジェクト]タブから[オー トメーション サーバ ウィザード]を選択します。 2 ウィザード内のすべてのページを完成します。 表 20-1 を参考にしてください。 表 20-1: オートメーション サーバ ウィザードのページ ページ [コンポーネン トの選択] [プログラム識 別子の指定] アプリケーション テクニック 指定する内容 オートメーション サーバとして使用するオブジェク トを選択する。オブジェクトは 1 つだけ選択できる。 PowerBuilder.Application を指定するタイミングについ ては、427 ページの「名前付きサーバの作成と使用」 を参照 Mycompany.Myapp など、オブジェクトの識別子を指定 する。バージョン番号は指定しない。PowerBuilder は、 別の画面で指定されたバージョン番号を使用して、 バージョンに依存するエントリを構築する。識別子に 使用できる文字数の上限は 39 文字である。ベンダと アプリケーション間のピリオド以外に句読文字は使 用できない。先頭に数字は使用できない 419 ユーザ オブジェクトをオートメーション サーバとして使用する方法 ページ [レジストリ ファイルとオブ ジェクト GUID の指定] 指定する内容 [オブジェクト クラスの GUID]テキストボックスが 空である場合には、[新規]をクリックして新規のグ ローバル一意識別子(GUID)を生成する。新規の GUID は、オブジェクトのクラス識別子(CLSID)に なる。既存のプログラム識別子を指定した場合は、そ の GUID がテキストボックスに表示される。既存の GUID を再利用しない場合は、新規の GUID を作成。 GUID の再利用の詳細については、438 ページの「複 数のバージョンとアップデート」を参照 レジストリ更新ファイルは、レジストリの更新情報を 格納するテキスト ファイルである。一般に、このファ イルはライブラリと同じ名前を持ち、拡張子は REG である [タイプ ライブ タイプ ライブラリを作成する必要があるのは、オブ ラリの作成] ジェクトのプロパティとメソッドに関する情報を OLE ブラウザで表示する場合のみ [構築オプショ PBD ファイルのかわりに DLL を構築した場合には、 ンの指定] [マシン コード DLL の使用]チェックボックスをオン にする 3 メニューバーから[ファイル|開く]を選択してウィザードによっ て作成されたプロジェクトを選択するか、ToDo リストの「... プロ ジェクトを構築する」をダブルクリックします。 4 プロジェクト ペインタでメニューバーから[デザイン|プロジェ クトの配布]を選択し、レジストリ ファイルとタイプ ライブラリ ファイルを生成します。 5 レジストリ ファイルを実行して、レジストリに情報を追加します。 レジストリおよび独自の登録ツールの記述方法の詳細については、433 ページの「レジストリ情報の作成」を参照してください。 ユーザ オブジェクトにアクセスするクライアント アプリケーションの コードの記述 レジストリに登録されたユーザ オブジェクトにアクセスするクライ アント アプリケーションのコードは、PowerBuilder.Application サーバ にアクセスするコードよりも簡単に記述できます。ライブラリ リスト とマシン コードのプロパティは、すでにレジストリに登録されていま す。 ユーザ オブジェクトのプロパティやメソッドにアクセスするには、 ユーザ オブジェクトを関連付けてオートメーションを使用します。 420 PowerBuilder 第 20 章 クライアント アプリ ケーションとしての PowerBuilder PowerBuilder のランタイム オートメーション サーバ ユーザ オブジェクトにアクセスするためにオートメーション サーバ のセッションを確立するには、以下のようにします。 1 ユーザ オブジェクトに関連付けるために、OLEObject オブジェク ト データ型の変数を宣言します。 OLEObject ole_analyze 2 ユーザ オブジェクトのプログラム識別子(ProgID)を使用してユー ザ オブジェクトと関連付けを行い、サーバ セッションが確立され たことをチェックします。ステータス 0 は、セッションの確立が 成功したことを示します。 ole_analyze = CREATE OLEObject li_status = ole_analyze.ConnectToNewObject & ("MyCompany.Analyze") IF li_status < 0 THEN MessageBox(" サーバが存在しません ", & "MyCompany.Analyze に関連付けできません。") RETURN END IF 3 オートメーション構文を使用してユーザ オブジェクトの関数やプ ロパティにアクセスします。 ld_avg = ole_analyze.uof_average() ole_analyze.Projection = TRUE li_status = ole_analyze.uof_RTFreport(REF ls_rpt) OLEObject の ExternalException イベントと Error イベントでエラーを処 理したい場合には、OLEObject 変数を宣言するかわりに、OLEObject か ら継承したユーザ オブジェクトを使用します。 1 ユーザ オブジェクト ペインタを開き、OLEObject オブジェクトを 継承した標準クラス ユーザ オブジェクトを作成します。 2 Error イベントと ExternalException イベントのスクリプトを記述し ます。 3 OLEObject オブジェクトのかわりに、新しいクラス名を宣言文で使 用します。 uo_oleobject ole_analyze クライアントとしての Visual Basic Visual Basic でも、同様のコードを使用して、レジストリに登録された ユーザ オブジェクトにアクセスできます。 1 ユーザ オブジェクトと関連付けるために、オブジェクト型の変数 を宣言します。 Dim ole_analyze As Object アプリケーション テクニック 421 PowerBuilder をオートメーション サーバとして使用する方法 2 ユーザ オブジェクトのプログラム識別子(ProgID)を使用してユー ザ オブジェクトと関連付けを行い、サーバ セッションが確立され たことをチェックします。 Set ole_analyze = CreateObject("MyCompany.Analyze") If ole_analyze Is Nothing Then REM エラー処理 End If 3 オートメーション構文を使用してユーザ オブジェクトの関数やプ ロパティにアクセスします。 ld_avg = ole_analyze.uof_average() ole_analyze.Projection = TRUE li_status = ole_analyze.uof_RTFreport(REF ls_rpt) PowerBuilder をオートメーション サーバとして使用する 方法 オートメーション サーバとして PowerBuilder.Application サーバ オブ ジェクトを使用するには、以下の手順が必要です。 1 アクセスするクラス ユーザ オブジェクトを定義します。 2 作成したオブジェクトのためのランタイム ライブラリを構築しま す。 3 クライアント アプリケーションで、PowerBuilder と関連付けを行 い、ユーザ オブジェクトのインスタンスを作成し、ユーザ オブ ジェクトのメソッドやプロパティにアクセスするコードを記述し ます。 アクセスするユーザ オブジェクトの作成 ユーザ オブジェクトをオートメーション サーバとして使用するため にどのような定義を行うかは、アプリケーションの設計に依存します。 ユーザ オブジェクトは、カスタム クラス ユーザ オブジェクトでなけ ればなりません。ユーザ オブジェクトのインスタンス変数と関数を定 義します。ユーザ オブジェクトは、PowerBuilder のほかのオブジェク トを宣言してそのオブジェクトのインスタンスを作成できます。 422 PowerBuilder 第 20 章 オートメーションを使 用して作成されたオブ ジェクト PowerBuilder のランタイム オートメーション サーバ クライアント アプリケーションが、同じサーバ ランタイム セッショ ンに複数のオブジェクトのインスタンスを作成した場合、オブジェク トの参照を別のオブジェクトに渡してこれらのオブジェクトを一緒に 処理できます。 オブジェクトの参照を渡すと、クライアント アプリケーションで作成 した PowerBuilder オブジェクトのインスタンスが、ほかのオブジェク トを認識できます。オブジェクトのインスタンスが同じサーバ セッ ションにある場合、PowerBuilder はその OLE オブジェクトの参照と PowerBuilder オブジェクト データ型を認識します。どの PowerBuilder アプリケーションでも、オブジェクトの参照は、オブジェクトのプロ パティとメソッドへのアクセスを提供します。 ユーザ オブジェクトの関数は、クライアント アプリケーションから渡 されたオブジェクトの参照を受け入れたり、正しいオブジェクト デー タ型の変数にオブジェクトの参照を代入したりすることができます。 また、PowerBuilder オブジェクトのインスタンスの参照を扱うことも できます。 ランタイム ライブラリの構築 ユーザ オブジェクトを定義した後は、ライブラリ ペインタを使用し て、PowerBuilder 動的ライブラリ(PBD)またはコンパイルされたラ イブラリ(DLL)を構築します。同じ PowerBuilder.Application サーバ セッションでアクセスされるランタイム ライブラリは、すべて同じ種 類(PBD か DLL のどちらか)でなければなりません。Pcode かマシン コードのどちらかを選択する理由は、どの PowerBuilder アプリケー ションを構築するときでも同じです。 ライブラリ ペインタでランタイム ライブラリを構築するには、以下の 操作を行います。 1 ライブラリ ペインタで、ライブラリ名を選択します。 2 [エントリ|ライブラリ|動的ライブラリの構築]を選択します。 3 PBD ファイルと DLL ファイルのいずれを作成するかに応じて、 [マシン コード]チェックボックスをオンまたはオフにします。 動的ライブラリの構築 ダイアログボックスのほかのオプションは、 このプロセスでは不要です。ほかのオプションの詳細については、 [ヘルプ]ボタンを選択して、説明を参照するか、『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 4 [OK]ボタンをクリックしてランタイム ライブラリを構築します。 アプリケーション テクニック 423 PowerBuilder をオートメーション サーバとして使用する方法 5 PowerBuilder.Application サーバ オブジェクトの LibraryList プロパ ティに指定した各ライブラリに対して、操作 1 ~ 4 を繰り返しま す。 6 構築された PBD ファイルまたは DLL ファイルを適切なディレク トリへ移動します。クライアント アプリケーションでは、オート メーション サーバがランタイム ファイルの場所を確認できるよ うに、ランタイム ファイルのパスを指定します。 プロジェクト ペインタでのプロジェクトの構築の詳細については、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 PowerBuilder とユーザ オブジェクトにアクセスするクライアント アプ リケーションのコードの記述 クライアント アプリケーションで、PowerBuilder.Application サーバ セッションを確立するには、以下の記述を行います。 • オートメーション サーバへの関連付け • オートメーション サーバのプロパティの設定 • ユーザ オブジェクトのインスタンスの作成 • ユーザ オブジェクトへのアクセス サーバ セッションの確立は失敗することもあるので、プロセスのすべ ての手順でエラー チェックを行う必要があります。 以下の例は、その方法を表しています。最初に、PowerBuilder のクラ イアント アプリケーションのコードを示します。次に、Visual Basic の 例を示します。 クライアント アプリ ケーションとしての PowerBuilder PowerBuilder.Application サーバ セッションを確立してオブジェクトに アクセスするには、以下のようにします。 1 PowerBuilder.Application サーバ オブジェクトと関連付けを行うた めに、OLEObject オブジェクト データ型の変数を 1 つ宣言します。 次に、ユーザ オブジェクトのインスタンスを作成するために、 OLEObject オブジェクト データ型の変数を追加宣言します。 OLEObject ole_pba, ole_analyze OLEObject オブジェクトの ExternalException イベントと Error イベ ントでエラーを扱う場合は、OLEObject オブジェクトを継承した標 準クラス ユーザ オブジェクトを使用します。 424 PowerBuilder 第 20 章 2 PowerBuilder のランタイム オートメーション サーバ オートメーション サーバに関連付けを行い、サーバ セッションが 確立されたことをチェックします。ステータス 0 は、サーバ セッ ションが成功したことを示します。 ole_pba = CREATE OLEObject li_status = ole_pba.ConnectToNewObject & ("PowerBuilder.Application") IF li_status < 0 THEN MessageBox(" サーバが存在しません ", & "PowerBuilder.Application に関連付けできません。 ") RETURN END IF 3 アクセスするランタイム ライブラリを設定するために、 PowerBuilder.Application サーバ オブジェクトのプロパティを設定 します。ユーザ オブジェクトのインスタンスを作成した後では、 これらのプロパティの値を変更することはできません。 ole_pba.LibraryList = & "c:\pb10\myobj\serv1.dll;c:\pb10\myobj\serv2.dll" ole_pba.MachineCode = TRUE 4 ユーザ オブジェクトのインスタンスを作成し、インスタンスの作 成が成功したかどうかをチェックします。このとき、ランタイム ライブラリ内にあるユーザ オブジェクトの名前を指定します。 ole_analyze = ole_pba.CreateObject("uo_analyze") IF IsNull(ole_analyze) THEN MessageBox(" オブジェクトが存在しません ", & " オブジェクト uo_analyze を作成できません。") RETURN END IF 5 オートメーションの構文を使用してオブジェクトの関数やプロパティ にアクセスします。以下にプロパティとメソッドの例を示します。 ld_avg = ole_analyze.uof_average() ole_analyze.Projection = TRUE li_status = ole_analyze.uof_RTFReport(REF ls_rpt) 6 アクセスが終了したら、PowerBuilder.Application サーバ オブジェ クトとの関連付けを解除し、ユーザ オブジェクトのインスタンス を破棄します。また、この処理は、アプリケーションを終了して 実行することもできます。 DESTROY ole_analyze ole_pba.DisconnectObject() DESTROY ole_pba アプリケーション テクニック 425 PowerBuilder をオートメーション サーバとして使用する方法 クライアント アプリ ケーションとしての Visual Basic 以下に、PowerBuilder.Application サーバ オブジェクトを使用する Visual Basic クライアントのコードを示します。コードの内容は、PowerBuilder と同じです。 1 PowerBuilder.Application サーバ オブジェクトと関連付けるために、 オブジェクト型の変数を宣言します。また、インスタンスを作成 するオブジェクトのために、オブジェクト型の変数を追加宣言し ます。 Dim ole_pba As Object Dim ole_analyze As Object 2 オートメーション サーバに関連付けを行い、サーバ セッションが 確立されたことをチェックします。ステータス 0 は、サーバ セッ ションが成功したことを示します。 Set ole_pba = CreateObject_ ("PowerBuilder.Application") If ole_pba Is Nothing Then REM エラー処理 End If 3 アクセスするランタイム ライブラリを設定するために、 PowerBuilder.Application サーバ オブジェクトのプロパティを設定 します。ユーザ オブジェクトのインスタンスを作成した後では、 これらのプロパティの値を変更することはできません。 ole_pba.LibraryList = _ "c:\pb\myobj\serv1.dll;c:\pb\myobj\serv2.dll" ole_pba.MachineCode = TRUE 4 ユーザ オブジェクトのインスタンスを作成し、インスタンスの作 成が成功したかどうかをチェックします。このとき、ランタイム ライブラリ内にあるユーザ オブジェクトの名前を指定します。 Set ole_analyze = ole_pba.CreateObject _ ("uo_analyze") If ole_analyze Is Nothing Then REM エラー処理 End If 5 オートメーションの構文を使用してオブジェクトの関数やプロパ ティにアクセスします。以下にプロパティとメソッドの例を示し ます。 ld_avg = ole_analyze.uof_average() ole_analyze.Projection = TRUE li_status = ole_analyze.uof_RTFreport(REF ls_rpt) 426 PowerBuilder 第 20 章 6 PowerBuilder のランタイム オートメーション サーバ オブジェクトのインスタンスを破棄します。アプリケーションを 終了しても同じ結果が得られます。 Set ole_analyze = Nothing Set ole_pba = Nothing PowerBuilder.Application サーバ オブジェクトの関数とプロパティの詳 細については、439 ページの「オートメーション サーバ リファレンス」 を参照してください。 名前付きサーバの作成と使用 名前付きサーバを使用するには、以下のようにします。 アクセスするユーザ オブジェクトの作成 1 アクセスするクラス ユーザ オブジェクトを定義します。 2 作成したオブジェクトのためのランタイム ライブラリを構築しま す。 3 レジストリにサーバを登録します。 4 サーバとの関連付け、オブジェクトの作成、およびオブジェクト のメソッドとプロパティへのアクセスを行うクライアント アプリ ケーションのコードを記述します。 名前付きサーバにおけるユーザ オブジェクトの定義は、 PowerBuilder.Application サーバ オブジェクトと同じです。 詳細については、422 ページの「アクセスするユーザ オブジェクトの 作成」を参照してください。 ランタイム ライブラ リの構築 名前付きサーバにおけるランタイム ライブラリの構築は、 PowerBuilder.Application サーバ オブジェクトと同じです。 詳細については、423 ページの「ランタイム ライブラリの構築」を参 照してください。 サーバの登録 419 ページの「ユーザ オブジェクトの登録」で説明したように、サー バを登録するには、オートメーション サーバ プロジェクト ウィザー ドを使用します。 1 つのユーザ オブジェクトではなく、サーバを登録するには、コンポー ネントとして PowerBuilder.Application を選択します。419 ページの 「ユーザ オブジェクトの登録」で説明したように操作を行い、レジス トリにレジストリ更新ファイルを取り込みます。名前付きサーバのタ イプ ライブラリ ファイルを作成する必要はありません。 アプリケーション テクニック 427 名前付きサーバの作成と使用 サーバとユーザ オブ ジェクトをアクセスす るクライアント アプ リケーションのコード の記述 クライアント アプリケーションで、名前付きサーバのセッションを確 立するには、以下の記述を行います。 • 名前付きサーバへの関連付け • ユーザ オブジェクトのインスタンスの作成 • ユーザ オブジェクトへのアクセス 以下の例は、その方法を表しています。例は、PowerBuilder のクライ アント アプリケーションのコードです。サーバ セッションの確立は失 敗することもあるので、プロセスのすべての手順でエラー チェックを 行う必要があります。 1 名前付きサーバと関連付けを行うために、OLEObject オブジェクト データ型の変数を 1 つ宣言します。次に、ユーザ インスタンスを 作成するために、OLEObject オブジェクト データ型の変数を追加 宣言します。 OLEObject ole_server, ole_analyze OLEObject オブジェクトの ExternalException イベントと Error イベ ントでエラーを扱う場合は、OLEObject オブジェクトを継承した標 準クラス ユーザ オブジェクトを使用します。 2 名前付きサーバに関連付けを行い、サーバ セッションが確立され たことをチェックします。ステータス 0 は、セッションの確立が 成功したことを示します。 ole_server = CREATE OLEObject li_status = ole_server.ConnectToNewObject & ("MyCompany.MyServer") IF li_status < 0 THEN MessageBox(" サーバが存在しません ", & " サーバに関連付けできません。") RETURN END IF 3 ユーザ オブジェクトのインスタンスを作成し、インスタンスの作 成が成功したかどうかをチェックします。このとき、ランタイム ライブラリ内にあるユーザ オブジェクトの名前を指定します。 ole_analyze = & ole_server.CreateObject("uo_analyze") IF IsNull(ole_analyze) THEN MessageBox(" オブジェクトが存在しません ", & " オブジェクト uo_analyze を作成できません。") RETURN END IF 428 PowerBuilder 第 20 章 4 PowerBuilder のランタイム オートメーション サーバ オートメーションの構文を使用してオブジェクトの関数やプロパ ティにアクセスします。以下にプロパティとメソッドの例を示し ます。 ld_avg = ole_analyze.uof_average() ole_analyze.Projection = TRUE li_status = ole_analyze.uof_RTFReport(REF ls_rpt) 5 アクセスが終了したら、サーバとの関連付けを解除し、ユーザ オ ブジェクトのインスタンスを破棄します。また、この処理は、ア プリケーションを終了して実行することもできます。 DESTROY ole_analyze ole_server.DisconnectObject() DESTROY ole_server ユーザ オブジェクトとレジストリについての詳細 レジストリは、登録されたオブジェクトをアクセスするために、プロ グラムが必要とするレジストリ情報を格納しています。この情報は登 録データベースに格納されています。レジストリを更新するには、レ ジストリ エディタでレジストリ更新ファイル(REG)を読み取り、レ ジストリ情報を更新します。 識別子について GUID と CLSID グローバル一意識別子(GUID)は、128 ビットの整数で一意であるこ と が 保 証 さ れ て い ま す。PowerBuilder.Application オ ブ ジ ェ ク ト の GenerateGUID 関数を使用すると、独自に GUID を生成することもでき ます。GUID は、時刻、日付、使用しているネットワーク カードの固 有の番号に基づいて生成されます。ネットワーク カードを使用してい ない場合は、Microsoft に 256 セットの GUID を問い合わせることがで きます。 GUID は、オブジェクトとタイプ ライブラリを一意に識別するための クラス識別子(CLSID)として使用されます。CLSID は、プログラム が使用するオブジェクトを確実に識別することができます。 アプリケーション テクニック 429 ユーザ オブジェクトとレジストリについての詳細 ProgID プログラム識別子(ProgID)は、ローカルの環境で一意です。ProgID に使用でいる文字数の上限は 39 文字で、ピリオド以外の区切り記号を 使用したり、先頭文字に数字を使用したりすることはできません。 ProgID には、2 つの種類があります。 • バージョン非依存 (Vergion-independent) ProgID ProgID にバージョ ン番号を含まない applicationname.objectname たとえば、MyApp.Application、MyApp.AnalysisUserObject などです。 • バージョン依存 (Vergion-dependent) ProgID ProgID に バ ー ジ ョ ン 番号を含む applicationname.objectname.versionnumber たとえば、MyApp.Application.1、MyApp.AnalysisUserObject.1 などです。 ほかの開発者がオブジェクト間の関係を理解できるように、アプリ ケーションとオブジェクトの命名規約は、一貫性があるようにする必 要があります。 レジストリに登録したオブジェクトへアクセスするために、ProgID を 使用します。バージョン非依存 ProgID を指定した場合、レジストリは 現行のバージョンのオブジェクトを呼び出します。 PowerBuilder.Application オブジェクトの GenerateRegFile 関数を使用す るときに、バージョン非依存 ProgID を引数に指定すると、関数の引数 に指定したバージョン番号を使用してバージョン番号のある ProgID が作成されます。 オブジェクトに関する情報の登録場所 オブジェクトに関する情報は、レジストリの以下のサブキーに登録さ れます。以下のセクションがあります。 • CLSID • Version-dependent ProgID • Version-independent ProgID • TypeLib(オプション) オブジェクトがどのように起動されても、このサブキーの参照によっ て、オブジェクトに関する情報が必ず見つかるようになっています。 430 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ キーとサブキー PowerBuilder.Application オブジェクトの関数は、HKEY_CLASSES_ROOT キーを更新します。レジストリのほかのキーに対してもこの情報が反 映されます。 サブキー オブジェクトの情報は、キーの下位レベルにあるサブキーに登録され ます。サブキーには、ファイル名などの値が含まれているものや、 NotInsertable などのように存在するだけで意味のあるものもあります。 各エントリとそのサブキーについては、以下で説明します。 ProgID 登録された ProgID の一覧は、レジストリの以下のキーの下にあります。 マイ コンピュータ \HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES バージョン依存 ProgID とバージョン非依存 ProgID が表示されます。 ProgID は、オブジェクトの CLSID への相互参照です。 表 20-2: ProgID サブキー サブキー \CLASSES\ProgID \CLASSES\ProgID\CLSID 値 オブジェクトのコメント オブジェクトの CLSID バージョン依存 ProgID \CLASSES\ProgID\CurVer(バー ジョン 非依存 ProgID のみ) \CLASSES\ProgID\NotInsertable 空の文字列 CLSID CLASSES キーの下には、レジストリに登録されたすべての CLSID の 一覧を表示するサブキー CLSID があります。各 CLSID は、登録され たオブジェクトに関するすべての情報を記録しています。 マイ コンピュータ \HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID アプリケーション テクニック 431 ユーザ オブジェクトとレジストリについての詳細 表 20-3: CLSID サブキーの内容 サブキー \CLASSES\CLSID\{guid} \CLASSES\CLSID\{guid}\InProcServer32 \CLASSES\CLSID\{guid}\NotInsertable \CLASSES\CLSID\{guid}\PowerBuilder \CLASSES\CLSID\{guid}\Programmable \CLASSES\CLSID\{guid}\ProgID \CLASSES\CLSID\{guid}\TypeLib \CLASSES\CLSID\{guid}\ VersionIndependentProgID 値 オブジェクトの GUID PowerBuilder のランタイム DLL ファイル名とパス名 "" 何も設定されない。サブキーは、 オブジェクトの環境に関する情 報を格納する(次表を参照)。 "" 現行のバージョン番号が指定さ れたバージョン依存 ProgID タイプ ライブラリの CLSID バージョン非依存 ProgID 表 20-4: PowerBuilder サブキーの内容 \CLASSES\CLSID の下の PowerBuilder サブキー {guid}\PowerBuilder\BinaryType {guid}\PowerBuilder\LibraryList {guid}\PowerBuilder\ClassName TypeLib 値 ランタイム ライブラリの種類。 コンパイルされたマシン コード (MCODE)か Pcode オブジェクトを格納しているラ ンタイム ライブラリの名前 ランタイム ライブラリ内のオブ ジェクトの名前 CLASSES キーの下には、タイプ ライブラリのためのサブキーがあり ます。 マイ コンピュータ \HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES TypeLib 432 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ 表 20-5: TypeLib サブキーの内容 サブキー \CLASSES\TypeLib\{guid} \CLASSES\TypeLib\{guid}\ VersionNum \CLASSES\TypeLib\{guid}\FLAGS \CLASSES\TypeLib\{guid}\HELPDIR 値 タイプ ライブラリの GUID タイプ ライブラリのバージョン番号 いくつかの言語に対応したタイプ ラ イ ブ ラ リ を 登 録 で き る よ う に、 バージョン番号から下にサブキー のツリーがある VersionNum\LanguageID\Win32 は、 32 ビットの Windows オペレーティ ング システム用タイプ ライブラリ ファイルのパスと名前を指定する 0 ヘルプ ファイルがあるディレクトリ レジストリ情報の作成 クライアント アプリケーションは、ユーザ オブジェクトにアクセスす るために必要な情報を取得するために、レジストリを使用します。レ ジストリは、PowerBuilder の実行環境とランタイム ライブラリがある ディレクトリのパス名を格納しています。また、オブジェクトのプロ パティとメソッドの情報を提供するタイプ ライブラリ ファイルの GUID と、そのディレクトリのパス名をレジストリに登録できます。タ イプ ライブラリが登録されていれば、エンド ユーザに OLE ブラウザ の機能を持つアプリケーションで、ユーザ オブジェクトを調べること ができます。ユーザ オブジェクトのインスタンス変数は、OLE ブラウ ザではプロパティとして表示されます。 PowerBuilder.Application サーバ オブジェクトには、レジストリ情報を 生成する機能があります。レジストリにオブジェクトを登録するには、 レジストリ更新ファイルが必要です。このファイルには、システムの 登録データベースに追加される情報が格納されます。タイプ ライブラ リの作成は任意です。ほかの開発者が、OLE ブラウザでオブジェクト のプロパティやメソッドを調べる場合に必要です。 以下の関数を使用するには、PowerBuilder.Application サーバ オブジェ クトにアクセスするクライアント アプリケーションを実行する必要 があります。開発環境で、クライアント アプリケーションを実行する ことができます。 アプリケーション テクニック 433 ユーザ オブジェクトとレジストリについての詳細 以下の関数は、レジストリ情報を生成します。 • GenerateGUID 関数 グローバル一意識別子(GUID)を生成します。 GUID は、オブジェクトやそのオブジェクトのタイプ ライブラリ の CLSID として使用します。 レジストリ エディタ(REGEDT32.EXE)で 取り込めるレジストリ更新ファイルを生成します。レジストリ更 新ファイルには、PowerBuilder.Application サーバ オブジェクトの プロパティ、ユーザ オブジェクトの GUID、クラス名などが記述 されています。 • GenerateRegFile 関数 • GenerateTypeLib 関数 タイプ ライブラリ ファイルを生成します。 タイプ ライブラリは、ユーザ オブジェクトのメソッドやプロパ ティ情報などが記述されています。 開発者は、以下の例で示されるように、これらの関数を使用できます。 また、InstallShield のようなインストール アプリケーションを使用して レジストリ情報を作成することもできます。 配布とレジストリ ローカル マシンで作成したレジストリ ファイルは、ローカル マシン にオブジェクトを登録するために使用できます。ファイル(オブジェ クトが格納されているライブラリとタイプ ライブラリ)のパス名はマ シン固有で、ほかのマシンには適用できません。オブジェクトを配布 する場合は、エンド ユーザがインストールするときに指定するディレ クトリに応じて、レジストリ更新ファイルを修正するか、レジストリ 自身を更新する関数を呼び出す必要があります。 437 ページの「オートメーション サーバを使用するアプリケーション の配布」を参照してください。 レジストリ情報を生成 するためのスクリプト のサンプル このスクリプトは、いくつかのシングルライン エディット コントロー ルとチェックボックスから情報を取得し、レジストリ更新ファイルと タイプ ライブラリを生成します。スクリプトではバージョン情報を直 接指定していますが、エディット ボックスなどを使用してエンド ユー ザに入力させることもできます。 例で使用されているシングルライン エディット コントロールとチェッ クボックスは、表 20-6 のとおりです。 434 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ 表 20-6: シングルライン エディット コントロールとチェックボックスの例 データ入力用の コントロール sle_object sle_progid sle_desc sle_regfile sle_typelibfile sle_library cbx_machinecode 入力されるデータ PowerBuilder ライブラリ内のユーザ オブジェクトの名前 プログラム識別子 レジストリに表示されるオブジェクトのコメント 生成するレジストリ更新ファイルの名前 生成するタイプ ライブラリ ファイルの名前 オブジェクトを格納している PowerBuilder ランタイム ラ イブラリの名前 ランタイム ライブラリが、マシン コードと Pcode のどち らで作成されているか 以下のプログラムは、レジストリ更新ファイルとタイプ ライブラリを 生成します。 oleObject ole_pb string ls_reg_guid, ls_tlb_guid long ll_result, ll_res2 // PowerBuilder.Application サーバ オブジェクトとの関連付け ole_pb = CREATE oleObject ll_result = ole_pb.ConnectToNewObject & ("PowerBuilder.Application") IF ll_result < 0 THEN MessageBox( " 関連付けできません ", & "PowerBuilder.Application への接続エラー ") RETURN END IF // 値となる PowerBuilder.Application サーバ オブジェクトの // プロパティの設定 ole_pb.LibraryList = sle_library.Text ole_pb.MachineCode = cbx_machinecode.Checked // オブジェクトとタイプ ライブラリの GUID の取得 ll_result = ole_pb.GenerateGUID( REF ls_reg_guid) ll_res2 = ole_pb.GenerateGUID( REF ls_tlb_guid) IF ll_result < 0 THEN MessageBox( "GUID を取得できません ", & " レジストリ ファイルの GUID の生成に失敗しました。") RETURN アプリケーション テクニック 435 ユーザ オブジェクトとレジストリについての詳細 ELSEIF ll_res2 < 0 THEN MessageBox( "GUID を取得できません ", & " タイプ ライブラリ ファイルの GUID の生成に失敗しました。 ") RETURN END IF // レジストリ更新ファイルを生成するために、エンド ユーザが // 入力した情報を使用 // GenerateRegFile 関数の引数 : // 有効な GUID // PB ライブラリのユーザ オブジェクトの名前 // レジストリにおける ProgID // メジャー バージョン、マイナー バージョン // コメント // レジストリ ファイルの名前 ll_result = ole_pb.GenerateRegFile( & ls_reg_guid, & sle_object.Text, & sle_progid.Text, & 1, 0, & sle_desc.Text, & sle_RegFile.Text ) IF ll_result < 0 THEN MessageBox(" レジストリ ファイルを生成できません ", & " 結果コードは " + String(ll_result) ) RETURN END IF // タイプ ライブラリを生成するために、レジストリ更新ファイルと // 一致する情報を使用 // GenerateTypeLib 関数の引数 : // // レジストリ ファイル内の GUID // PB ライブラリのユーザ オブジェクトの名前 // レジストリ ファイルにおける ProgID // ロケール、メジャー バージョン、マイナー バージョン // コメント // ヘルプ コンテキスト、ヘルプ ファイル // タイプ ライブラリの GUID // タイプ ライブラリ ファイルの名前 // レジストリ ファイルの名前 ll_result = ole_pb.GenerateTypeLib( & ls_reg_guid, & 436 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ sle_object.Text, & sle_progid.Text, & 0, 1, 0, & sle_desc.Text, & 0, "", & ls_tlb_guid, & sle_typelibfile.text, & sle_regfile.text) IF ll_result < 0 THEN MessageBox(" タイプ ライブラリ ファイルを生成できません ", & " 結果コードは " + String(ll_result) ) RETURN END IF オートメーション サーバを使用するアプリケーションの 配布 オブジェクトを配布する場合、すべてのファイルのインストール先の ディレクトリのパス名をレジストリに登録する必要があります。 PowerBuilder ランタ イム ファイル PowerBuilder.Application サーバ オブジェクトとオートメーション サー バとして登録されたユーザ オブジェクトを実行するには、エンド ユー ザのマシンに PowerBuilder の実行環境を配布する必要があります。 PowerBuilder の配布および必要なファイルの詳細については、第 9 部 「配布のテクニック」を参照してください。 レジストリは、実行環境を起動するために PowerBuilder の仮想マシン DLL(PBVM100.DLL)を PowerBuilder の実行ファイルのかわりに検索 します。配布時に、このファイルのディレクトリのパス名がレジスト リに登録されます。レジストリの情報が無効になるので、別のレジス トリにこのファイルを移動しないでください。 オブジェクトが格納さ れたライブラリとタイ プ ライブラリ レジストリは、オブジェクトが格納されているライブラリとタイプ ラ イブラリのディレクトリのパス名を登録します。 ローカル マシンでレジストリ更新ファイルを生成すると、パス情報は そのマシンの現行のファイルのパスを反映します。配布するときに、 以下のことができます。 アプリケーション テクニック 437 オートメーション サーバを使用するアプリケーションの配布 • レジストリ更新ファイルをカスタマイズする(レジストリ更新 ファイルは、編集可能なテキスト ファイル) • レジストリ更新ファイルを更新した後で、レジストリを変更する レジストリの変更には、PowerBuilder または Windows SDK の関数 をプログラムで使用する方法と、レジストリ エディタを使用して 手動で取り込む方法がある 複数のバージョンとアップデート 新しいバージョンのオブジェクトを再配布する場合、以前のバージョ ンの CLSID を再利用できます。また、新しい GUID を CLSID として レジストリに登録することもできます。どちらを選択するかは、バー ジョン間の互換性に依存します。 表 20-7: CLSID オプション CLSID のオプション GUID の再利用 新しい GUID の割り当て 条件 オブジェクトのインタフェースが同じで、既存の アプリケーションが古いバージョンと同じプロ パティと関数にアクセスできる場合 オブジェクトのインタフェースが変更され、既存 のアプリケーションが新しいバージョンをアク セスすると、アプリケーションがエラーを発生す る場合 既存のアプリケーションが古いオブジェクトをそのまま使用できるよ うに、新しい GUID を割り当てた場合は、新しい ProgID も必要になり ます。既存のアプリケーションがバージョン非依存 ProgID を参照して いて、新しいバージョンのオブジェクトも同じ ProgID である場合、既 存のアプリケーションは新しいオブジェクトにアクセスします。 サーバ オブジェクトを設計する場合は、そのオブジェクトの将来の発 展を考慮して現行のアプリケーションを設計する必要があります。 438 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ オートメーション サーバ リファレンス この節では、PowerBuilder.Application サーバ オブジェクトのプロパ ティと関数について説明します。 • PowerBuilder.Application サーバ オブジェクト • CreateObject 関数 • GenerateGUID 関数 • GenerateRegFile 関数 • GenerateTypeLib 関数 • 例外コード • レジストリ更新ファイルのサンプル PowerBuilder.Application サーバ オブジェクト 説明 PowerBuilder.Application サーバ オブジェクトは、オートメーション サーバです。オートメーション サーバを起動する OLE クライアント アプリケーションは、オートメーションとオートメーション オブジェ クト型をサポートする PowerBuilder やほかのクライアントになりま す。 サーバを使用したオブジェクトへのアクセス . 以下のようにして、オート メーションを使用して PowerBuilder オブジェクトにアクセスできま す。 1 PowerBuilder をサーバ アプリケーションとして起動するように、 OLEObject オブジェクト データ型(クライアント アプリケーショ ンに用意されている同等のオブジェクト データ型)の変数を PowerBuilder.Application サーバ オブジェクトに関連付けます。 2 アクセスする PowerBuilder ランタイム ライブラリを指定するため に、PowerBuilder.Application サーバ オブジェクトのプロパティを 設定します。 3 ライブラリでクラス ユーザ オブジェクト(非ビジュアル)のイン スタンスを作成する関数を呼び出し、別の OLEObject オブジェク ト データ型の変数に、作成したインスタンスを代入します。 4 オートメーション構文を使用してユーザ オブジェクトのプロパティ と関数にアクセスします。 アプリケーション テクニック 439 PowerBuilder.Application サーバ オブジェクト レジストリにおけるオートメーション オブジェクト . PowerBuilder.Application サーバ オブジェクトは、PowerBuilder システ ム オブジェクトの階層構造にあるクラスではありません。Windows の レジストリに登録されたオートメーション オブジェクトです。オブ ジェクト ブラウザで参照するには、 [OLE]タブを選択し、 [OLE オー トメーション オブジェクト]カテゴリを展開します。 プロパティ 表 20-8: PowerBuilder.Application のプロパティ プロパティ LibraryList MachineCode データ型 説明 String ランタイム ファイル(DLL か PBD)をセ ミコロン(;)で区切ったファイル名の一 覧。PowerBuilder.Application サーバ セッ ションでアクセスするオブジェクトが格 納されている Boolean すべてのランタイム ライブラリは、同じ 実行形式(マシン コードか Pcode)でなけ ればならない LibraryList プロパティの設 定は、オブジェクトのインスタンスを作成 する前だけに有効である。オブジェクトの インスタンスを作成した後で変更しても、 設定は無視される ランタイム ライブラリがマシン コードと Pcode のどちらで生成するかを指定する 値は以下のとおり • TRUE –(デフォルト)ライブラリはマ シン コードで生成される。デフォルト のファイル名の拡張子は DLL • FALSE – ライブラリは Pcode で生成さ れる。デフォルトのファイル名の拡張 子は PBD MachineCode プロパティの設定は、オブ ジェクトのインスタンスを作成する前だ けに有効である。オブジェクトのインスタ ンスを作成した後で変更しても、設定は無 視される 440 PowerBuilder 第 20 章 関数 PowerBuilder のランタイム オートメーション サーバ 表 20-9: PowerBuilder.Application の関数 関数 戻り値の データ型 CreateObject OLEObject GenerateGUID Long GenerateRegFile Long GenerateTypeLib Long アプリケーション テクニック 説明 OLE サーバ セッションに、クラス ユーザ オブジェクトのインスタンスを作成する。 クライアント セッションにオブジェクト の参照が戻る。クライアント アプリケー ションは、オートメーションの構文を使用 してオブジェクトのプロパティと関数に アクセスできる グローバル一意識別子(GUID)を生成し て文字列として返す。文字列は参照によっ て渡される文字列変数で識別される この関数を使用するには、ネットワーク カードが必要 レジストリ更新ファイルを生成する。レジ ストリ ファイルの内容は、オートメー ション サーバとして配布する PowerBuilder のオブジェクトに関する情報である タイプ ライブラリ ファイルを生成する。 タイプ ライブラリは、オートメーション サーバとして配布する PowerBuilder のオ ブジェクトに関する情報をほかの開発者 に提供する 441 CreateObject 関数 CreateObject 関数 機能 PowerBuilder.Application OLE サーバ セッションで、PowerBuilder クラ スのインスタンスを作成します。 対象 PowerBuilder.Application(オートメーション サーバ) 構文 { automationobject.}CreateObject ( classname ) 引数 automationobject classname 説明 PowerBuilder が OLE クライアント アプリケーションの 場合は、PowerBuilder.Application サーバ オブジェクトと 関連付けられた OLEObject オブジェクト データ型のイ ンスタンス変数。PowerBuilder 以外の OLE クライアン ト アプリケーションの場合は、そのアプリケーション が提供する同じ機能を持つ関数を呼び出すために、適切 な構文を使用する 作成するクラスの名前を指定した文字列。 PowerBuilder.Application サーバ オブジェクトの LibraryList プロパティで指定したライブラリ内に定義 されたクラスでなければならない 戻り値 OLEObject 型。オートメーションで有効なオブジェクトのインスタン スを返します。オブジェクトのインスタンスが作成できなかった場合、 CreateObject 関数は NULL 値を返します。 解説 OLE クライアント アプリケーションが Visual Basic の場合は、キーワー ド nothing を使用して CreateObject 関数が成功したかどうかを確認でき ます。 ランタイム ライブラリに格納されたオブジェクトの実行形式が指定 した MachineCode プロパティに対応しない場合、CreateObject 関数は NULL 値を返します。1 つの PowerBuilder.Application サーバ セッショ ンで作成されたすべてのオブジェクトのインスタンスは、同じ実行形 式(Pcode ま た は マ シ ン コ ー ド)で な け れ ば な り ま せ ん。1 つ の PowerBuilder.Application サーバ セッションで、複数のオブジェクトの インスタンスを作成する場合、作成したオブジェクトの参照を、ほか のオブジェクトの関数の引数に渡すことができます。 CreateObject 関数を呼び出す前に、CREATE 文を使用して OLEObject 型 のインスタンスを作成する必要はありません。 442 PowerBuilder 第 20 章 例 PowerBuilder のランタイム オートメーション サーバ 以下の例は、PowerBuilder.Application サーバ オブジェクトを起動し、 MYLIBRARY.DLL に格納されているオブジェクトを作成する PowerBuilder のスクリプトです。オブジェクトの作成が成功した場合は、 関数 uf_calc を呼び出します。この関数は、計算結果を変数 ld_result に 代入して、ステータス コードとして Long 型の戻り値を返します。 OLEObject PBObject, PBNVObject long ll_status double ld_result PBObject = CREATE OLEObject ll_status = PBObject.ConnectToNewObject & ("PowerBuilder.Application") IF ll_status = 0 THEN // エラー処理 ELSE PBObject.LibraryList = "c:\myappl\mylibrary.dll" PBObject.MachineCode = TRUE PBNVObject = CREATE OLEObject PBNVObject = & PBObject.CreateObject("nvo_myobject") IF IsNull(PBNVObject) THEN // エラー処理 ELSE ll_status = PBNVObject.uf_calc & (12, 14, REF result) END IF DESTROY PBNVObject PBObject.DisconnectObject( ) END IF DESTROY PBObject 以下の例は、上記の PowerBuilder スクリプトと同じことを行う Visual Basic スクリプトです。 Dim Dim Dim Dim PBObject as object PBNVObject as object status as long result as double Set PBObject = _ CreateObject("PowerBuilder.Application") If PBObject is nothing then REM エラーの取り扱い アプリケーション テクニック 443 GenerateGUID 関数 Else PBObject.LibraryList = "c:\myappl\mylibrary.dll" Set PBNVObject = _ PBObject.CreateObject("nvo_myobject") If PBNVObject is nothing then REM エラーの取り扱い Else status = PBNVObject.uf_calc(12, 14, REF result) Set PBNVObject = nothing End if Set PBObject = nothing End if 関連項目 ConnectToNewObject GenerateGUID 関数 機能 グローバル一意識別子(GUID)を生成します。GUID は、オブジェク トとそのタイプ ライブラリを Windows のレジストリに登録するとき に、クラス識別子(CLSID)として使用します。オブジェクトとその タイプ ライブラリに対して、それぞれ GUID があります。 対象 PowerBuilder.Application(オートメーション サーバ) 構文 { automationobject.}GenerateGUID ( REF guidvariable ) 引数 automationobject REF guidvariable 説明 PowerBuilder が OLE クライアント アプリケーションの 場合は、PowerBuilder.Application サーバ オブジェクトと 関連付けられた OLEObject オブジェクト データ型のイ ンスタンス変数。PowerBuilder 以外の OLE クライアン ト アプリケーションの場合は、そのアプリケーション が提供する同じ機能を持つ関数を呼び出すために、適切 な構文を使用する 参照渡し(reference)の String 型変数。生成された GUID を文字列として返す GenerateGUID 関数は、構文がコンパイラによって チェックされていないオートメーションの関数として 呼び出されているので、guidvariable を参照渡しで渡す ために REF を指定する必要がある 444 PowerBuilder 第 20 章 戻り値 解説 PowerBuilder のランタイム オートメーション サーバ Long 型。エラーが発生したかどうかを表すステータス コードを返しま す。値は以下のとおりです。 0 GUID は正常に生成されました。 -1 GenerateGUID 関数を呼び出すために必要な DLL をロードするこ とができませんでした。 -2 ネットワーク カードが見つからなかったので、GUID を生成する ことができませんでした。 -3 GUID の生成が失敗しました。 -9 予期せぬエラーが発生しました。 GenerateGUID 関数を使用する場合、以下のものが必要です。 • RPCRT4.DLL ファイル。この DLL ファイルの UuidCreate 関数を呼 び出します。DLL ファイルは、現行のパスに存在する必要があり ます。 • ネットワーク カード。関数は固有の値を生成するため、ネットワー ク カードの識別情報を使用します。 これらの条件が満たされないときは、Microsoft から GUID を入手して ください。 GUID は、書式(8-4-4-4-12 桁の数字)の文字列として表現できる Long 型の 16 進数の数値です。 {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} GUID は、アプリケーションが使用するオブジェクトを識別するため に、Windows レジストリで使用されます。レジストリに登録されたオ ブジェクトとそのタイプ ライブラリには、それぞれに対応する GUID があります。 オブジェクトがレジストリに登録されるまでは、PowerBuilder のオブ ジェクトに対してオートメーションを実行することはできません。 GenerateGUID 関数は、必要なレジストリ情報の作成を補助する関数です。 生成された GUID は、レジストリ更新ファイルを作成する GenerateRegFile 関数と GenerateTypeLib 関数に渡します。各ユーザのマシンの更新ファ イルを使用して、レジストリにオブジェクトを登録します。 オブジェクトに対して、新しい GUID を生成してレジストリを更新す ると、新しいレジストリ エントリが作成されます。レジストリ更新 ファイルに前と同じ GUID を使用した場合は、現行のレジストリのオ ブジェクトの情報は、新しい情報に置き換えられます。 アプリケーション テクニック 445 GenerateGUID 関数 オブジェクトを更新して配布する場合に、同じ GUID を使用して新し いオブジェクトに対するレジストリ更新ファイルを生成することがで きます。新しく更新されたオブジェクトのインタフェース(そのオブ ジェクトのプロパティと関数のシグネチャ)が更新前のオブジェクト と互換性がある場合、現行のアプリケーションは新しいオブジェクト に正常にアクセスできます。ただし、オブジェクトのインタフェース を変更した場合は、更新したオブジェクトに対する新しい GUID を使 用する必要があります。新しい GUID を使用すると、既存のアプリケー ションは、引き続き更新前のオブジェクトにアクセスできます。また、 新しいアプリケーションは新しいオブジェクトにアクセスできるの で、変更または新しい機能を使用できます。 PowerBuilder ツールを使用してユーザ オブジェクトを登録する方法に ついては、419 ページの「ユーザ オブジェクトの登録」を参照してく ださい。 例 以下の例では、PowerBuilder.Application サーバ オブジェクトと関連付 けを行い、GUID を生成します。 oleObject PBObject string ls_GUID long ll_result PBObject = CREATE oleObject result = PBObject.ConnectToNewObject & ("PowerBuilder.Application") IF result < 0 THEN // エラー処理 ELSE ll_result = PBObject.GenerateGUID(REF ls_GUID) END IF 関連項目 446 GenerateRegFile GenerateTypeLib PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ GenerateRegFile 関数 機能 オートメーション サーバとして配布するための PowerBuilder オブジェ クトに対するレジストリ更新ファイルを生成します。 対象 PowerBuilder.Application(オートメーション サーバ) 構文 { automationobject.}GenerateRegFile ( guid, classname, progid, majorversion, minorversion, description, outputfilename ) 引数 automationobject guid 説明 PowerBuilder が OLE クライアント アプリケーションの場 合は、PowerBuilder.Application サーバ オブジェクトと関 連付けられた OLEObject オブジェクト データ型のインス タンス変数。PowerBuilder 以外の OLE クライアント アプ リケーションの場合は、そのアプリケーションが提供す る同じ機能を持つ関数を呼び出すために、適切な構文を 使用する String 型。オブジェクトのグローバル一意識別子(GUID) 以下のように、生成された GUID を指定できる • GenerateGUID 関数の呼び出しによって生成 • 以前に生成された GUID を再利用(このオブジェクト は以前のバージョンを置き換える) classname progid majorversion minorversion description outputfilename アプリケーション テクニック • マイクロソフト社から取得 String 型。オートメーション サーバとなるクラス ユーザ オブジェクトの名前。オブジェクトは LibraryList プロパ ティで指定したランタイム ライブラリ内になければなら ない String 型。サーバ オブジェクトにアクセスするために使 用するプログラム識別子 Integer 型。サーバ オブジェクトのメジャー バージョン番号 Integer 型。サーバ オブジェクトのマイナー バージョン番号 String 型。サーバ オブジェクトのコメント。コメントは、 レジストリ エディタや OLE ブラウザ機能のあるアプリ ケーションで表示される String 型。OLE GenerateRegFile 関数が生成するレジスト リ更新ファイルの名前。レジストリが認識できるデフォ ルトのファイル名の拡張子は REG 447 GenerateRegFile 関数 戻り値 解説 Long 型。エラーが発生したかどうかを表すステータス コードを返しま す。値は以下のとおりです。 0 レジストリ更新ファイルが正常に生成されました。 -1 メモリ割り当てのエラーが発生しました。 -2 出力ファイル名が指示されていません。 -3 出力ファイルが開けません。 -9 予期せぬエラーが発生しました。 GenerateRegFile 関数を呼び出す前に、PowerBuilder.Application サーバ オブジェクトと関連付け、その LibraryList プロパティと MachineCode プロパティに値を設定する必要があります。また、オブジェクトのク ラス識別子(CLSID)に使用する GUID も必要です。GUID の書式の詳 細については、444 ページの「GenerateGUID 関数」を参照してください。 レジストリ更新ファイルを生成した後は、オブジェクトのメソッドと プロパティの情報を提供するタイプ ライブラリ ファイルも生成する ことができます。450 ページの「GenerateTypeLib 関数」を参照してく ださい。 レジストリ更新ファイルのデフォルトの拡張子は、REG です。レジス トリ更新ファイルをダブルクリックすると、レジストリにオブジェク トを登録できます。オブジェクトが格納されているランタイム ライブ ラリとタイプ ライブラリ ファイルのディレクトリのパス名など、オブ ジェクトに関する情報がレジストリに登録されます。PowerBuilder ツールを使用してユーザ オブジェクトを登録する方法については、 419 ページの「ユーザ オブジェクトの登録」を参照してください。 例 以下の例では、GenerateRegFile 関数を呼び出しています。ご使用のア プリケーションでは、この GUID を使用しないでください。 long ll_result ll_result = GenerateRegFile( & "{12345678-1234-1234-1234-123456789012}", & "uo_salary_formulas", "MyCompany.SalaryFormulas", & 1, 0, & "PowerBuilder functions for calculating salaries", & "c:\pbds\bizrules.reg") 以下の例では、PowerBuilder.Application サーバ オブジェクトと関連付 けを行い、レジストリ更新ファイルを生成するために必要なすべての プロパティ値を設定しています。 oleObject PBObject string ls_GUID long ll_result 448 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ PBObj = CREATE oleObject result = & PBObj.ConnectToNewObject("PowerBuilder.Application") IF result < 0 THEN // エラー処理 ELSE PBObject.LibraryList = "c:\myappl\mylibrary.pbd" PBObject.MachineCode = FALSE ll_result = PBObject.GenerateGUID(REF ls_GUID) IF ll_result < 0 THEN // エラー処理 ELSE ll_result = PBObject.GenerateRegFile( ls_GUID, & "uo_myserverobject", "MyCompany.Object", & 1, 0, "My object's description", & "c:\myappl\object.reg") IF ll_result < 0 THEN // エラー処理 ELSE // タイプ ライブラリの生成 END IF END IF END IF 関連項目 GenerateGUID GenerateTypeLib アプリケーション テクニック 449 GenerateTypeLib 関数 GenerateTypeLib 関数 機能 オートメーション サーバとして配布する PowerBuilder オブジェクトの タイプ ライブラリ ファイルを生成します。 アクセス レベル PowerBuilder.Application(オートメーション サーバ) 構文 { automationobject.}GenerateTypeLib ( classguid, classname, progid, localeid, majorversion, minorversion, description, helpcontext, helpfile, typelibguid, typelibfilename, registryfilename ) 引数 automationobject classguid classname progid localeid 説明 PowerBuilder が OLE クライアント アプリケーションの 場合は、PowerBuilder.Application サーバ オブジェクトと 関連付けられた OLEObject オブジェクト データ型のイ ンスタンス変数。PowerBuilder 以外の OLE クライアン ト アプリケーションの場合は、そのアプリケーション が提供する同じ機能を持つ関数を呼び出すために、適切 な構文を使用する String 型。オブジェクトのレジストリ ファイルを生成す るときに指定したグローバル一意識別子(GUID) String 型。PowerBuilder ランタイム ライブラリに格納さ れているオブジェクトの名前。指定したオブジェクトの タイプ ライブラリが生成される classname は、レジストリ ファイルを生成したときに指 定した名前と同じ名前でなければならない String 型。サーバ オブジェクトにアクセスするために使 用するプログラム識別子 progid は、レジストリ ファイルを生成したときに指定 した値と同じ値にする必要がある Long 型。オブジェクトの国別言語のためのロケール識 別子(LCID)。言語 ID(LANGID)は、マイクロソフト 株式会社が提供するマニュアルに定義されている PowerBuilder のカタログ データ型 LanguageID の値を指 定することも可能 majorversion Integer 型。サーバ オブジェクトのメジャー バージョン 番号 minorversion Integer 型。サーバ オブジェクトのマイナー バージョン 番号 description helpcontext String 型。サーバ オブジェクトのコメント Long 型。helpfile のヘルプ トピックのためのコンテキス ト ID。ヘルプ ファイルの目次ページを表示するには、 0 を指定する 450 PowerBuilder 第 20 章 引数 helpfile typelibguid typelibfilename registryfilename PowerBuilder のランタイム オートメーション サーバ 説明 String 型。サーバ オブジェクトのヘルプ トピックを格 納しているヘルプ ファイルの名前 String 型。レジストリに登録するタイプ ライブラリに対 するグローバル一意識別子(GUID) String 型。GenerateTypeLib 関数が生成するタイプ ライ ブラリ ファイルの名前。レジストリが認識できるデ フォルトのファイル名の拡張子は TLB String 型。 GenerateRegFile 関数によって生成されたレジ ストリ更新ファイルの名前 タイプ ライブラリ ファイルだけを生成する場合は、 registryfilename に空の文字列を指定する 戻り値 Long 型。エラーが発生したかどうかを表すステータス コードを返しま す。値は以下のとおりです。 0 レジストリ更新ファイルが正常に生成されました。 2 出力ファイル名が指示されていません。 3 タイプ ライブラリの生成に失敗しました。 4 無効な名前か名前の設定中にエラーが発生しました。 5 無効なロケール識別子かロケール識別子の設定中にエラーが発生 しました。 6 タイプ ライブラリの GUID を CLSID に変換中にエラーが発生しま した。 7 無効な GUID か GUID を設定中にエラーが発生しました。 8 コメントの設定中にエラーが発生しました。 9 バージョンの設定中にエラーが発生しました。 10 ヘルプ コンテキストの設定中にエラーが発生しました。 11 ヘルプ ファイル名の設定中にエラーが発生しました。 14 LibraryList プロパティに指定したランタイム ライブラリには、ク ラスを見つけることができませんでした。 18 オブジェクトの GUID を CLSID に変換中にエラーが発生しまし た。 30 標準タイプ ライブラリのロード中にエラーが発生しました(OLE が正しくインストールされていません)。 31 IUnknown インタフェースにアクセス中にエラーが発生しました (OLE が正しくインストールされていません)。 アプリケーション テクニック 451 GenerateTypeLib 関数 32 IDispatch インタフェースにアクセス中にエラーが発生しました (OLE が正しくインストールされていません)。 36 このタイプ ライブラリに関連付けられているレジストリ更新ファ イルを開いているときにエラーが発生しました。 解説 タイプ ライブラリの登録は任意です。オブジェクトのプロパティとメ ソッドに関する情報を、OLE ブラウザ機能のあるアプリケーションで 表示する場合は、タイプ ライブラリが必要です。 タイプ ライブラリを登録する場合は、タイプ ライブラリ ファイルを 作成する前に、オブジェクトを登録するレジストリ更新ファイルが存 在する必要があります。タイプ ライブラリを生成する過程で、レジス トリ更新ファイルに情報を追加します。 レジストリ更新ファイルの生成については、447 ページの 「GenerateRegFile 関数」を参照してください。 GenerateTypeLib 関数の引数に指定する値は、すでに生成されたレジス トリ更新ファイルの値と同じでなければなりません。レジストリ更新 ファイルと同じ値を使用しない場合、どのオブジェクトにも関連付け られていない TypeLib サブキーがレジストリに作成されます。 GenerateTypeLib 関数を呼び出す前に、PowerBuilder.Application サーバ オ ブジェクトと関連付けを行い、 その LibraryList プロパティと MachineCode プロパティの値を設定する必要があります。さらに、オブジェクトの CLSID として使用される GUID(レジストリ更新ファイルを生成したと きに指定した GUID)とタイプ ライブラリの GUID が必要です。GUID の書式の詳細については、444 ページの「GenerateGUID 関数」を参照 してください。 レジストリ更新ファイルとタイプ ライブラリ ファイルを生成した後 は、オブジェクトをレジストリに登録できます。 オブジェクトをレジストリに登録すると、ライブラリ ファイルとタイ プ ライブラリ ファイルのディレクトリのパス名が格納されます。 LibraryList プロパティの値は、オブジェクトが格納されているランタ イム ファイルがあるディレクトリのパス名です。オブジェクトを登録 するときは、タイプ ライブラリ ファイルが、指定したディレクトリに ある必要があります。 例 以下の例は、GenerateTypeLib 関数を呼び出しています。ご使用のアプ リケーションでは、この GUID を使用しないでください。 long ll_result ll_result = GenerateTypeLib( & "{12345678-1234-1234-1234-123456789012}", & "uo_salary_formulas", "MyCompany.SalaryFormulas", & 452 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ 0, 1, 0, & "PowerBuilder functions for calculating salaries", & 0, "c:\pbds\bizrules.hlp", & "{12345679-1234-1234-1234-123456789012}", & "c:\pbds\bizrules.tlb", "c:\pbds\bizrules.reg") 以下の例は、PowerBuilder.Application サーバ オブジェクトと関連付け を行い、レジストリ更新ファイルを生成するために必要なすべての値 を設定しています。 oleObject PBObject string ls_GUID, ls_typelibGUID long ll_result PBObject = CREATE oleObject result = PBObject.ConnectToNewObject & ("PowerBuilder.Application") IF result < 0 THEN // エラー処理 RETURN -1 END IF PBObject.LibraryList = "c:\myappl\mylibrary.pbd" PBObject.MachineCode = FALSE // オブジェクトの CLSID のための GUID ll_result = PBObject.GenerateGUID(REF ls_GUID) IF ll_result < 0 THEN // エラー処理 RETURN -1 END IF // オブジェクトのタイプ ライブラリのための GUID ll_result = PBObject.GenerateGUID(REF ls_typelibGUID) IF ll_result < 0 THEN // エラー処理 RETURN -1 END IF // レジストリ更新ファイルの生成 ll_result = PBObject.GenerateRegFile( ls_GUID, & "uo_myserverobject", "MyCompany.Object", & 1, 0, "My object's description", & "c:\myappl\object.reg") IF ll_result < 0 THEN // エラー処理 アプリケーション テクニック 453 例外コード RETURN -1 END IF // タイプ ライブラリの生成 ll_result = PBObject.GenerateTypeLib( ls_GUID, & uo_myserverobject", "MyCompany.Object", 0, 1, 0, & "My object's description", 0, & "c:\myappl\myhelp.hlp", ls_typelibGUID, & "c:\myappl\object.tlb", "c:\myappl\object.reg") IF ll_result < 0 THEN // エラー処理 RETURN -1 END IF 関連項目 GenerateGUID GenerateRegFile 例外コード PowerBuilder オートメーション サーバにアクセスするオートメーション クライアントでは、ある状況で、OLE の例外が発生する場合がありま す。エンド ユーザのアクションが例外を発生させた場合、PowerBuilder は例外の種類を識別する例外コードを、呼び出し元から渡された EXCEPINFO 構造体に値を設定します。PowerBuilder のクライアント ア プリケーションに対しては、ExternalException イベントの引数に例外 コードが渡されます。 クライアント アプリケーションは、PowerBuilder オートメーション サーバから、以下の例外コードを受け取ります。 表 20-10: PowerBuilder オートメーション サーバの例外コード コード 1001 1002 1003 1004 1005 1006 1007 1008 454 意味 メモリの割り当てに失敗しました。 要求されたオブジェクトが、ライブラリ リストにありませんでした。 オブジェクトの作成に失敗しました。 バイナリ書式がバージョンと一致しないか、期限が過ぎています。 配列としてアクセスされたプロパティは、配列ではありませんでした。 スクリプトの実行中に予期せぬエラーが発生しました。 要求された名前と引数のデータ型に一致するメソッドが、1 つも 見つかりませんでした。 Variant 型の引数を変換することができませんでした。 PowerBuilder 第 20 章 PowerBuilder のランタイム オートメーション サーバ レジストリ更新ファイルのサンプル 以下のレジストリ ファイルのサンプルには、uo_salarydata という名前 のクラス ユーザ オブジェクトの登録情報があります。 REGEDIT4 ;;;;;;;;;;;;;;;; ; ; MyCompany.SalaryData のためのレジストリ エントリ ; ; CLSID = {E022EF01-6789-11CF-92BF-00805F9236E9} ; ; PowerBuilder が生成したレジストリ ファイル ;;;;;;;;;;;;;;;; ; バージョン番号のないエントリ: [HKEY_CLASSES_ROOT\MyCompany.SalaryData] @="DataStore with functions returning salary statistics" [HKEY_CLASSES_ROOT\MyCompany.SalaryData\CLSID] @="{E022EF01-6789-11CF-92BF-00805F9236E9}" [HKEY_CLASSES_ROOT\MyCompany.SalaryData\CurVer] @="MyCompany.SalaryData.1" [HKEY_CLASSES_ROOT\MyCompany.SalaryData\NotInsertable" @="" ; バージョン番号に特定のエントリ: [HKEY_CLASSES_ROOT\AppID\{E022EF01-6789-11CF-92BF-00805F9236E9}] @="DataStore with functions returning salary statistics" [HKEY_CLASSES_ROOT\MyCompany.SalaryData.1] @="DataStore with functions returning salary statistics" [HKEY_CLASSES_ROOT\MyCompany.SalaryData.1\CLSID] @="{E022EF01-6789-11CF-92BF-00805F9236E9}" [HKEY_CLASSES_ROOT\MyCompany.SalaryData.1\NotInsertable] @="" ; CLSID エントリ: [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF00805F9236E9}] @="DataStore with functions returning salary statistics" "AppID"="{E022EF01-6789-11CF-92BF-00805F9236E9}" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF-0805F9236E9}\ProgID] @="MyCompany.SalaryData.1" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF00805F9236E9}\VersionIndependentProgID] @="MyCompany.SalaryData" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF00805F9236E9}\InProcServer32] @="pbVM100.dll" アプリケーション テクニック 455 レジストリ更新ファイルのサンプル "ThreadingModel"="Apartment" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF 00805F9236E9}\NotInsertable] @="" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF-00805F9236E9}\Programmable] @="" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF00805F9236E9}\PowerBuilder\ClassName] @="uo_salarydata" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF00805F9236E9}\PowerBuilder\LibraryList] @="D:\\pbserver.pbd" [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF00805F9236E9}\PowerBuilder\BinaryType] @="PCODE" ; タイプ ライブラリ登録エントリ: [HKEY_CLASSES_ROOT\CLSID\{E022EF01-6789-11CF-92BF-00805F9236E9}\TypeLib] @="{E022EF02-6789-11CF-92BF-00805F9236E9}" [HKEY_CLASSES_ROOT\TypeLib\{E022EF02-6789-11CF-92BF-00805F9236E9}\1.0] @="Type Library for DataStore with functions returning salary statistics" [HKEY_CLASSES_ROOT\TypeLib\{E022EF02-6789-11CF-92BF00805F9236E9}\1.0\9\Win32] @="D:\\pbserver.tlb" 456 PowerBuilder 第 2 1 章 MAPI の使い方 この章について この章では、PowerBuilder アプリケーションで MAPI(Messaging Application Program Interface)を使用して電子メールを送受信する 方法について説明します。 内容 項目 MAPI について MAPI の使い方 ページ 457 458 MAPI について PowerBuilder は MAPI(Messaging Application Program Interface)を サポートします。これにより、アプリケーションは MAPI 準拠の 任意の電子メール システムを使用してメッセージを送受信できま す。 たとえば、PowerBuilder アプリケーションは以下を実行できます。 MAPI サポートの実装方法 アプリケーション テクニック • アプリケーションが実行した解析の結果をメールで送信する • ユーザが特定の操作を実行したときにメールを送信する • 情報を要求するメールを送信する • アプリケーションのユーザが必要とする情報を含むメールを 受け取る MAPI をサポートするために、PowerBuilder は 表 21-1 に示す項目 を提供します。 457 MAPI の使い方 表 21-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 458 PowerBuilder 第 21 章 MAPI の使い方 オブジェクト ブラウザを使用して、MailSession システム オブジェク トのプロパティと関数、メール関連の構造体のプロパティ、およびメー ル関連のカタログデータ型として有効な値についての詳細を取得でき ます。 オブジェクト ブラウザの使い方の詳細については、 『PowerBuilder ユー ザーズ ガイド』マニュアルを参照してください。MailSession 関数の詳 細については、 『PowerScript リファレンス』マニュアルを参照してく ださい。MAPI についての詳細は、各 MAPI に準拠したメール アプリ ケーションのマニュアルを参照してください。 アプリケーション テクニック 459 MAPI の使い方 460 PowerBuilder 第 2 2 章 外部関数とそのほかの拡張処理機能 の使い方 この章について この章では、PowerBuilder における外部関数の使い方とそのほか の拡張処理機能について説明します。 内容 項目 外部関数の使い方 ユーティリティ関数の使い方 Windows メッセージの送信 メッセージ オブジェクト コンテキスト情報 ページ 461 468 470 472 474 外部関数の使い方 外部関数は、PowerScript 以外の言語で記述され、ダイナミック ラ イブラリに保存されている関数です。Windows 上では、外部関数 はダイナミック リンク ライブラリ( DLL: Dynamic LinkLibrary)に 保存されます。 32 ビット プラットフォーム用の標準呼び出しシーケンスをサ ポートする、任意の言語で書かれた外部関数を使用できます。 自分で書いたライブラリ内の関数を呼び出す場合は、その関数を エクスポートしなければならないので注意してください。このエ クスポートは、使用コンピュータによって関数プロトタイプまた はリンカ定義(DEF)ファイルで行います。 アプリケーション テクニック 461 外部関数の使い方 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 種類の外部関数 462 2 種類の外部関数が宣言できます。 • グローバル外部関数この関数は、アプリケーション内のどこから でも使用できます。 • ローカル外部関数この関数は、特定のウィンドウ、メニュー、ま たはユーザ オブジェクトに対して定義されます。 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 ローカル外部関数はオブジェクトの定義の一部となるので、その オブジェクト自身のスクリプトの中で使用できます。さらに、こ の関数をほかのスクリプトで使用することも可能です。 外部関数の引数のデー タ型 外部関数を宣言するときは、引数のデータ型がその関数のソース定義 の中で宣言されたデータ型と一致しなければなりません。 外部関数のデータ型と PowerBuilder 内のデータ型の比較については、 『PowerScript リファレンス』マニュアルの外部関数の宣言と呼び出し に関する章を参照してください。 ❖ 外部関数を宣言するには 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" アプリケーション テクニック 463 外部関数の使い方 デフォルトでは、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 Web の サイト 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" 464 & PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 外部関数 IsZoomed を使用するスクリプトは、468 ページの「ユーティ リティ関数の使い方」に例として記載してあります。 これらの関数についての詳細は、MSDN Library のサイト http://msdn.microsoft.com/library/default.asp にある 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 型の引数 を必要とします。 アプリケーション テクニック 465 外部関数の使い方 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 型を返します。 466 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 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 リファレンス』マニュアル を参照してください。 C の関数への文字の受け渡し C の外部関数に渡された Char 型の変数 は、渡される前に C の Char 型に変換されます。Char 型変数の配列は、 C の同等の Char 型変数の配列に変換されます。 構造体に埋め込まれた Char 型変数の配列は、C の構造体に埋め込まれ た配列に変換されます。これは、埋め込みの String 型(C の構造体の String への埋め込みポインタとなります)とは異なります。 注意 可能なときは必ず、関数からの戻り値として String 型の変数を PowerBuilder に返してください。 アプリケーション テクニック 467 ユーティリティ関数の使い方 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 でコンポーネントが外部関数を呼び出す場合には、コンポーネ ントは、その関数が置かれている共有ライブラリを検出できなければ なりません。そのためには、ライブラリ パス環境変数を更新して、そ の共有ライブラリが置かれているディレクトリを追加する必要があり ます。 ユーティリティ関数の使い方 ユーティリティ関数は、Windows の情報を入手して外部関数に渡す手 段を提供するので、PowerScript の Send 関数の引数として使用できま す。表 22-1 に、PowerScript のユーティリティ関数を示します。 468 PowerBuilder 第 22 章 5 つのユーティリティ 関数 外部関数とそのほかの拡張処理機能の使い方 表 22-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 uint hWnd // PowerBuilder のウィンドウのハンドルを入手します。 hWnd = handle(This) // タイトル バーを使用不可にします。 FlashWindow (hWnd, TRUE) アプリケーション テクニック 469 Windows メッセージの送信 // しばらくそのままにします。 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 イベン トの発生方法 470 PowerBuilder イベントを発生させるには、表 22-2 に示した方法を使用 できます。 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 表 22-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() アプリケーション テクニック 471 メッセージ オブジェクト メッセージ オブジェクト メ ッ セ ー ジ(Message)オ ブ ジ ェ ク ト は、あ ら か じ め 定 義 さ れ た PowerBuilder のグローバル オブジェクトです(デフォルトのトランザ クション オブジェクトの SQLCA やエラー オブジェクトの同類です)。 メッセージ オブジェクトは、PowerBuilder で定義されたイベントにな い Microsoft Windows イベントを処理するスクリプ トの中で使用され ます。 PowerBuilder で定義されたイベントにない Windows イベントが発生す ると、PowerBuilder はそのイベントに関する情報をメッセージ オブ ジェクトに保持します。 メッセージ オブジェ クトのそのほかの用途 メッセージ オブジェクトは、以下のような場合にも用いられます。 • ウィンドウの開閉時に、ウィンドウ間でパラメータの受け渡しを するため 詳細については、『PowerScript リファレンス』マニュアルの OpenWithParm、OpenSheetWithParm、および CloseWithReturn の各関 数の説明を参照してください。 • TriggerEvent 関数や PostEvent 関数で、オプションのパラメータが使 用された場合でも、イベントに情報を渡すため 詳細については、 『PowerScript リファレンス』マニュアルを参照し てください。 メッセージ オブジェ クトのカスタマイズ アプリケーションで使用しているグローバル メッセージ オブジェク トは、組み込みの Message オブジェクトを継承した標準クラス ユーザ オブジェクトを定義することによってカスタマイズできます。その ユーザ オブジェクトでは、新たなプロパティ(インスタンス変数)や 関数の追加が可能です。アプリケーションの必要に応じて、ユーザ定 義プロパティの設定や関数の呼び出しが行えます。 標準クラス ユーザ オブジェクトの定義の詳細については、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 メッセージ オブジェクトのプロパティ メッセージ オブジェクトの最初の 4 つのプロパティは、Microsoft Windows のメッセージ構造体の最初の 4 つのプロパティに対応しま す。 472 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 表 22-3: メッセージ オブジェクトのプロパティ プロパティ Handle データ型 用途 Integer Number Integer WordParm UnsignedInt LongParm Long DoubleParm StringParm PowerObjectParm Double Processed Boolean ウィンドウやコントロールのハンドル イ ベ ン ト を 識 別 す る 番 号。こ の 番 号 は Windows から送られる イベントの Word パラメータ。このパラ メータは Windows から送られる。パラメー タの値と意味はイベントによって異なる イベントの Long 型パラメータ。このパラ メータは Windows から送られる。パラメー タの値と意味はイベントによって異なる 数値または数値変数 文字列または String 型変数 構造体を含む PowerBuilder オブジェクト データ型 ユーザ定義イベントに対応するスクリプ トで設定された Boolean 型の値 String PowerObject • 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 アプリケーション テクニック 473 コンテキスト情報 Microsoft Windows のメッセージ番号とパラメータの詳細については、 Microsoft Windows ソフトウェア開発キット(SDK)のマニュアルを参 照してください。 コンテキスト情報 PowerBuilder のコンテキスト機能を使用して、アプリケーションで一 定のホスト(PowerBuilder 以外)のサービスにアクセスできます。こ れは、COM QueryInterface に類似した PowerBuilder の実装機能です。 PowerBuilder では、以下のホスト サービスにアクセスできます。 • コンテキスト情報サービス • コンテキスト キーワード サービス • CORBACurrent サービス • エラー ロギング サービス • インターネット サービス • Secure Sockets Layer サービス • トランザクション サーバ サービス PowerBuilder は、現行の実行コンテキスト(ネイティブな PowerBuilder、 PowerBuilder のプラグイン、PowerBuilder ウィンドウの ActiveX、トラ ンザクション サーバ)に合わせて適切なサービス オブジェクトを作成 します。この機能により、アプリケーションで実行環境を最大限利用 できるようになります。たとえば、PowerBuilder ウィンドウのプラグ インでは、EMBED 構成要素に指定されたパラメータにアクセスでき ます。また、Internet Explorer で PowerBuilder ウィンドウの ActiveX を 実行しているときは、アプリケーションから ActiveX オートメーショ ン サーバにアクセスできるので、プログラムからブラウザにアクセス したり、その制御を行うことができます。 コンテキスト機能では、ContextInformation、ContextKeyword、 CORBACurrent、ErrorLogging、Inet、SSLServiceProvider、 TransactionServer という 7 つの PowerBuilder サービス オブジェクトと InternetResult オブジェクトを使用します。コンテキスト機能はコンテ キスト オブジェクトと呼ばれることがありますが、PowerBuilder のシ ステム オブジェクトではありません。 474 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 これらのオブジェクトの詳細については、 『オブジェクトとコントロー ル』マニュアルまたは PowerBuilder オブジェクト ブラウザを参照して ください。 サービスを使用可能に する方法 サービスを使用する前に、GetContextService 関数を呼び出して、その サ ー ビ ス の イ ン ス タ ン ス を 作 成 し ま す。こ の 関 数 を 呼 び 出 す と、 PowerBuilder はそのインスタンス化されたサービスへの参照を返しま す。サービスの関数を呼び出すときは、この参照をドット(.)表記で 使用してください。 ❖ サービスを使用可能にするには 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) 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 の実行環境)のオブジェクトが作成されます。 アプリケーション テクニック 475 コンテキスト情報 コンテキスト情報サービス コンテキスト情報サービスは、アプリケーションの実行コンテキスト に関する情報を入手するときに使用します。このサービスでは、アプ リケーションが PowerBuilder 実行環境で PowerBuilder ウィンドウのプ ラグインまたは PowerBuilder ウィンドウの ActiveX として実行してい るかどうかがわかるだけでなく、現行バージョンに関する情報も入手 できます。この情報を使えば、ディスプレイの特性やアプリケーショ ンの動作形態を修正できます。たとえば、プラグインや ActiveX とし て実行しているときに、コマンドボタン[閉じる]を非表示にできます。 さらに、Internet Explorer の PowerBuilder ウィンドウの ActiveX で実行 している場合、コンテキスト情報サービスは ActiveX のオートメー ション サーバ オブジェクトへの参照を返します。アプリケーションで この参照を使えば、Web ブラウザを制御する関数を呼び出せます。 コンテキスト情報への アクセス コンテキスト情報サービスを使用して、表 22-4 の情報にアクセスでき ます。 表 22-4: コンテキスト情報 項目 使用する関数 コンテキスト名 GetName 説明 戻り値はコンテキストによって異な る • デフォルト :PowerBuilder Runtime • ウィンドウのプラグイン : PowerBuilder Window Plug-in • ウィンドウの ActiveX:PowerBuilder Window ActiveX コンテキスト名 の略称 GetShortName 戻り値はコンテキストによって異なる • デフォルト :PBRUN • ウィンドウのプラグイン : PBWinPlugin • ウィンドウの ActiveX:PBRTX 476 会社名 GetCompanyName バージョン GetVersionName メジャー バー ジョン マイナー バー ジョン フィックス バージョン GetMajorVersion GetMinorVersion GetFixesVersion 会社名を返す(Sybase, Inc など) 完全なバージョン番号を返す(10.0.1 など) メジャー バージョン番号を返す(10 など) マイナー バージョン番号を返す(0 など) フィックス バージョン番号を返す(1 など) PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 ClassName 関数を使用して、オブジェクトのコンテキストを決定する こともできます。ClassName 関数の戻り値は、コンテキストによって 異なります。たとえば、ウィンドウのプラグインの戻り値は plugincontextinformation で、ウィンドウの ActiveX では rtxcontextinformation です。 ClassName 関数の使 い方 この情報は以下のようなさまざまな用途に使用できます。 • • 実行コンテキストに基づいてアプリケーションの表示形態を修正する場合 たとえば、PowerBuilder ウィンドウ プラグインや PowerBuilder ウィ ンドウ ActiveX として実行しているときには[閉じる]ボタンを 非表示にできます。プラグインや ActiveX では、ウィンドウを閉 じると HTML ページに空のスペースが生成されます。 コンテキストで現行バージョンをサポートしているかどうかを検証する 場合 たとえば、アプリケーションで管理バージョン 10.0.1 の機能 や修正部分が必要な場合は、コンテキスト情報サービスを使用し て、現行の実行コンテキストのバージョンを確認できます。 ❖ コンテキスト情報にアクセスするには 1 ContextInformation 型のインスタンスまたはグローバル変数を宣言 します。 ContextInformation 2 icxinfo_base GetContextService 関数を呼び出して、コンテキスト情報サービスを 作成します。 this.GetContextService("ContextInformation", icxinfo_base) 3 & 必要な場合は、コンテキスト情報サービス関数を呼び出します。 この例では、GetShortName 関数を呼び出して現行コンテキストを 確認し、さらに GetVersionName 関数を呼び出して現行バージョン を確認します。 String ls_name String ls_version Constant String ls_currver = "7.0.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 アプリケーション テクニック 477 コンテキスト情報 Internet Explorer の バ ー ジ ョ ン 3.0 ま た は こ れ 以 降 の バ ー ジ ョ ン で PowerBuilder ウィンドウの ActiveX を実行している場合は、アプリケー ションでコンテキスト情報サービスの GetHostObject 関数を使用して、 ActiveX オートメーション サーバ オブジェクト(ホスト オブジェクト) への参照を入手できます。特に、インスタンス化されていない OLEObject 変数を GetHostObject に渡すと、IWebBrowserApp オートメーション サーバへの参照が返されます。 ActiveX オートメー ション サーバのアク セス アプリケーションでは、IWebBrowserApp のメソッドとプロパティを呼 び出し、アクセスできるので、以下のようなブラウザの動作にアクセ スし、その制御を行うことが可能です。 • [戻る] • [進む] • [ホーム] • [更新] • [お気に入り] • [終了] IWebBrowserApp インタフェース、メソッド、およびプロパティの詳細 については、Internet Explorer のマニュアルまたは Microsoft の Web サ イトを参照してください。 ❖ ActiveX オートメーション サーバにアクセスするには 1 ContextInformation 型および OLEObject 型のインスタンスまたはグ ローバル変数を宣言します。 ContextInformation icxinfo_base OLEObject iole_browser 2 GetContextService 関数を呼び出して、コンテキスト情報サービスを 作成します。 GetContextService("ContextInformation", icxinfo_base) 3 & GetHostObject 関数を呼び出して、 ActiveX オートメーション サーバ への参照を設定します。 Integer li_rtrn li_rtrn = icxinfo_base.GetHostObject(iole_browser) IF li_rtrn = 1 THEN sle_host.Text = "GetHostObject 成功 " ELSE sle_host.Text = "GetHostObject 失敗 " 478 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 END IF 4 必要な IWebBrowserApp の関数を呼び出します。この例では、Navigate 関数を呼び出して、Sybase のホーム ページを表示するデフォルト の Web ブラウザを開きます。 IF IsValid(iole_browser) THEN iole_browser.Navigate & ("http://www.sybase.com", 0, 0, 0) END IF コンテキスト キーワード サービス 現行コンテキストの環境情報にアクセスするには、コンテキスト キー ワード サービスを使用します。デフォルト環境の場合、このサービス はホストのワークステーションの環境変数を返します。PowerBuilder ウィンドウ プラグインでは、このサービスを使用すると、プラグイン の Embed 構成要素に指定されているパラメータにアクセスできます。 EAServer 内で実行するときには、キーワード サービスを使用して、コ ンポーネントのプロパティ値を取得できます。 EAServer でコンテキスト キーワード サービスを使用する方法の詳細 については、539 ページの「コンポーネント プロパティへのアクセス」 を参照してください。 PowerBuilder の実行環境(デフォルトのコンテキスト)で実行してい る場合、このサービスを使用して環境変数を戻します。 環境変数のアクセス ❖ 環境変数にアクセスするには 1 ContextKeyword 型のインスタンスまたはグローバル変数を宣言し ます。戻り値を保持する String 型の可変長配列も宣言します。 ContextKeyword icxk_base String is_values[ ] 2 GetContextService 関数を呼び出して、コンテキスト情報サービスを 作成します。 this.GetContextService("ContextKeyword", icxk_base) 3 GetContextKeyword 関数を呼び出して、必要な環境変数にアクセス します。この例では、GetContextKeyword 関数を呼び出して現行ア プリケーションの Path を確認します。 icxk_base.GetContextKeywords("Path", is_values) アプリケーション テクニック 479 コンテキスト情報 4 戻り値の配列から値を抽出します。環境変数にアクセスする場合、 配列の構成要素は常に 1 つだけにしなければなりません。 MessageBox("Path", "Path is:" + is_values[1]) Embed 構成要素には追加のユーザ指定パラメータを入れることが可能 です。また、Embed 構成要素では、各パラメータに 2 つ以上の値を持 たせることが可能です。 Embed 構成要素パラ メータのアクセス PowerBuilder ウィンドウ プラグインのコンテキストで実行している場 合、キーワード サービスは、Embed 構成要素に指定されたパラメータ へアクセスするときに使用します。指定されたパラメータが見つから ない場合、このサービスは指定されたパラメータと環境変数の照合を 試みます。 ❖ Embed 構成要素のパラメータにアクセスするには 1 ContextKeyword 型のインスタンスまたはグローバル変数を宣言し ます。戻り値を保持する String 型の可変長配列も宣言します。 ContextKeyword icxk_base String is_values[ ] 2 GetContextService 関数を呼び出して、コンテキスト情報サービスを 作成します。 GetContextService("ContextKeyword", icxk_base) 3 GetContextKeyword 関数を呼び出します。この例では、 GetContextKeyword 関数を呼び出してユーザ指定パラメータ VALID の値にアクセスします。 icxk_base.GetContextKeywords("VALID", is_values) 4 戻り値の配列から値を抽出します。この例では、パラメータをリ ストボックスに表示します。 Integer li_count FOR li_count = 1 to UpperBound(is_values) lb_parms.AddItem(is_values[li_count]) NEXT 480 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 CORBACurrent サービス クライアント アプリケーションおよび[OTS スタイル]としてマーク された EAServer コンポーネントは、CORBACurrent コンテキスト サー ビス オブジェクトの関数を使用して、EAServer トランザクションに関 する情報の作成、制御、および取得ができます。CORBACurrent オブ ジェクトは、CORBACurrent インタフェース用に定義された数多くの メソッドを備えています。 詳細については、580 ページの「クライアントとコンポーネントを区 別するトランザクション」を参照してください。 エラー ロギング サービス トランザクション サーバ内で動作している PowerBuilder オブジェクト によって生成されたエラーをログ ファイルに記録するには、ErrorLogging サービス オブジェクトのインスタンスを作成し、そのログ メソッドを 呼び出します。たとえば、次のようになります。 ErrorLogging erlinfo_base this.GetContextService("ErrorLogging", & erlinfo_base) erlinfo_base.log(" この文字列をログに書き込む ") コンポーネントが EAServer で動作している場合、エラーは EAServer ログに記録されます。コンポーネントが COM+ で動作している場合 は、エラーは Windows のシステム アプリケーション ログに記録され ます。 インターネット サービス インターネット サービスは、以下の用途に使用します。 • • デフォルトのブラウザで Web ページを表示する。HyperLinkToURL 関数は指定された URL を使ってデフォルトのブラウザを起動す る 指定されたページの HTML にアクセスする。GetURL 関数は HTTP Get を実行する • アプリケーション テクニック CGI、ISAPI、または NSAPI プログラムにデータを送信する。 PostURL 関数は HTTP Post を実行する 481 コンテキスト情報 インターネット サービスの HyperLinkToURL 関数を呼び出して、指定さ れた URL を使ってデフォルトのブラウザを起動します。 URL へのハイパーリ ンク接続 ❖ URL にハイパーリンクで接続するには 1 Inet 型のインスタンスまたはグローバル変数を宣言します。 Inet 2 iinet_base GetContextService 関数を呼び出して、インターネット サービスを作 成します。 THIS.GetContextService("Inet", iinet_base) 3 HyperLinkToURL 関数を呼び出して、 ブラウザの起動時に表示される ページの URL を渡します。 iinet_base.HyperlinkToURL & ("http://www.sybase.com") インターネット サービスの GetURL 関数を呼び出して HTTP Get を実 行し、指定された URL の生の HTML を入手します。この関数は、 InternetResult オブジェクトを介して生の HTML を返します。 URL の入手 ❖ HTTP Get を実行するには 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 GetURL 関数を呼び出し、返されるページの URL と、子孫オブジェ クト InternetResult のインスタンスへの参照を渡します。 iinet_base.GetURL & ("http://www.sybase.com", iir_msgbox) GetURL 関数は実行を終了すると、子孫オブジェクト InternetResult で定義されている InternetData 関数を呼び出し、指定された URL の HTML を渡します。 482 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 インターネット サービスの PostURL 関数を呼び出して HTTP Post を実 行し、データを CGI、ISAPI、または NSAPI プログラムに送信します。 この関数は、InternetResult オブジェクトを介して生の HTML を返しま す。 URL へのポスト ❖ 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" 5 PostURL 関数を呼び出し、実行するルーチンの URL、引数、ヘッ ダ、および子孫オブジェクト InternetResult のインスタンスへの参 照を渡します。 iinet_base.PostURL & (ls_url, lblb_args, ls_headers, 8080, iir_msgbox) PostURL 関数は実行を終了すると、子孫オブジェクト InternetResult で定義された InternetData 関数を呼び出し、指定されたルーチンか ら返された HTML を渡します。 アプリケーション テクニック 483 コンテキスト情報 GetURL 関数と PostURL 関数は、いずれも InternetResult オブジェクトの データを受け取ります。このオブジェクトは、インターネット経由で 返される非同期データを受け取り、キャッシュするバッファとして動 作します。データを全部受け取ると、この InternetResult オブジェクト はその InternetData 関数を呼び出すので、必要であれば、ここでデータ を上書きして処理できます。 InternetResult オブ ジェクトの使い方 InternetResult の子孫オブジェクトへの実装 この機能は、InternetResult 型の標準クラス ユーザ オブジェクトを作成 して実装します。この子孫ユーザ オブジェクトのそれぞれに、渡され た HTML を必要に応じて処理する InternetData 関数を定義してくださ い。 ❖ 子孫オブジェクト InternetResult を実装するには 1 InternetResult 型の標準クラス ユーザ オブジェクトを作成します。 2 以下のような新規ユーザ オブジェクト関数を宣言します。 3 • 名前 • アクセス レベル • 戻り値 Integer • 引数名 値渡しのデータ • 引数のデータ型 Blob InternetData パブリック 返された HTML を処理する InternetData 関数のコードを追加しま す。この例では、HTML を MessageBox に表示するだけです。 MessageBox(" 返された HTML", & String(data, EncodingANSI!)) Return 1 484 PowerBuilder 第 22 章 外部関数とそのほかの拡張処理機能の使い方 Secure Sockets Layer サービス PowerBuilder を使用すれば、EAServer への Secure Sockets Layer(SSL) 接続を設定できます。SSL プロトコルでは、デジタル認証に基づく公 開鍵の暗号化と認証のアルゴリズムを使用して、安全に接続すること ができます。SSL は「ラッパー」プロトコルであり、ほかのプロトコ ル用のパケットは、SSL パケットの内部に埋め込むことによって保護 されます。たとえば、HTTPS は、各 HTTP パケットを SSL パケット内 に埋め込むことによって保護される HTTP です。同様に、IIOPS は、 SSL 内に埋め込まれた IIOP です。 SSLServiceProvider オブジェクトのインスタンスを使用して、クライア ントからサーバへの接続を確立します。詳細については、 『PowerScript リファレンス』マニュアルおよび第 26 章「PowerBuilder クライアント での SSL の使い方」を参照してください。 トランザクション サーバ サービス EAServer、COM+ などのトランザクション サーバ内で動作するオブ ジェクトのコンテキストに関する情報にアクセスするには、トランザ クション サーバ サービスを使用します。TransactionServer オブジェク トを使用すれば、トランザクションの動作をプログラムで制御したり、 トランザクション サーバ上の別のコンポーネントのメソッドにアク セスしたりすることができます。 詳細については、第 24 章「EAServer コンポーネントの構築」および 第 27 章「COM/COM+ コンポーネントの構築」を参照してください。 アプリケーション テクニック 485 コンテキスト情報 486 PowerBuilder 第 6 部 分散アプリケーションの開発 第 6 部では、PowerBuilder で分散アプリケーションを構 築するためのツールとテクニックについて説明します。 PowerBuilder Enterprise 版のみ PowerBuilder で使用可能な多層アプリケーションを構築するた めのツールは、Enterprise 版でのみサポートします。 第 2 3 章 PowerBuilder を使った分散アプリ ケーション開発 この章について この章では PowerBuilder を使った分散アプリケーション開発の概 要を示します。 PowerBuilder Enterprise 版のみ 分散アプリケーション開発は、Enterprise 版でのみサポートされて います。 内容 項目 分散アプリケーションのアーキテクチャ サーバのサポート ページ 489 490 分散アプリケーションのアーキテクチャ 分散アプリケーション開発は、多階層アプリケーション開発とも 呼ばれ、自然な方法でアプリケーションで必要なビジネス ロジッ クからアプリケーションのユーザ インタフェース コンポーネン トを分離できます。ビジネス ロジックを中間層のサーバに集中す ることで、クライアントの作業負荷を軽減し、機密情報へのアク セス制御を行えます。 分散アプリケーションでは、クライアントとサーバは、連携して ビジネス ユーザのためのタスクを実行します。クライアントは、 ユーザとの対話をすべて処理し、中間層のサーバはクライアント に対してバックグラウンドのサービスを提供します。通常、中間 層のサーバがほとんどの処理とデータベース アクセスを行いま す。サーバのサービスを呼び出すには、クライアントは、サーバ に置かれたコンポーネント(またはオブジェクト)に関連付けら れているメソッド(または関数)を呼び出します。 アプリケーション テクニック 489 サーバのサポート 分割されたアプリケー ション エンタープライズ アプリケーションのクライアントサイドのロジッ クは、ネットワークの帯域幅を節約できるようにできるだけ小さく効 率的にする必要があります。このためには、アプリケーションをプレ ゼンテーション、ビジネス ロジック、データベース アクセスの 3 つに 分割します。データベースは、エンタープライズ システムの最下層に あり、組織の資産を保持し、またセキュリティ保護します。ビジネス ロジックは、中間層またはサーバに置かれます。プレゼンテーション は、ユーザのデスクトップ、つまり最上位層に配置されるか、ユーザ のデスクトップに動的にダウンロードされます。 サーバは、企業のビジネス ロジックの大多数の実行とセキュリティ保 護を担当します。このため、サーバは、ネットワーク中心のアーキテ クチャの重要なコンポーネントとなります。クライアントは、ビジネ ス ロジックを実行する中間層コンポーネントを呼び出して、サーバと 通信を行います。 Web アプリケーショ ン アーキテクチャ Web アプリケーションは分散型アーキテクチャの一種で、クライアン トが Web ブラウザで動作しています。PowerBuilder には、シン クライ アント ソリューションを提供する Web ターゲットおよび Web データ ウィンドウなど、Web アプリケーションの構築のためのテクノロジが 複数用意されています。アプリケーションのアーキテクチャは、使用 するテクノロジによって異なります。 詳細については、第 30 章「PowerBuilder での Web アプリケーション開 発」を参照してください。 サーバのサポート PowerBuilder の開発者は、Sybase EAServer および COM+ サーバのサー ビスを呼び出すクライアントを作成し、さらに各サーバの内部でビジ ネス ロジックを実行するコンポーネント(またはオブジェクト)を作 成できます。 また、PowerBuilder は、 J2EE 準拠のサーバで動作する Enterprise JavaBeans コンポーネント(EJB)のクライアントの作成もサポートしています。 EAServer 490 PowerBuilder と EAServer は完全に統合されました。PowerBuilder アプ リケーションは、EAServer コンポーネントのクライアントの役割を果 たします。さらに、EAServer は、中間層コンポーネントとして動作す る PowerBuilder カスタム クラス ユーザ(非ビジュアル)オブジェクト を持つことができます。 PowerBuilder 第 23 章 PowerBuilder を使った分散アプリケーション開発 EAServer は、PowerBuilder 仮想マシンのネイティブのホストとして機 能します。つまり、EAServer と PowerBuilder 非ビジュアル ユーザ オ ブジェクトは互いに直接通信できます。PowerBuilder で開発された EAServer コンポーネントは、PowerScript の使いやすさと柔軟性、およ び PowerBuilder のシステム オブジェクトのパワーをフルに活用できま す。 PowerBuilder で開発されたコンポーネントは、トランザクション、相 互運用性、およびインスタンス プールなどの機能を活用できます。 図 23-1 に示すように、どのタイプのクライアントでも、コンポーネン トの開発に使用された言語に関係なく、EAServer で動作するすべての タイプのコンポーネントにアクセスできます。 図 23-1: クライアントと EAServer 上のコンポーネント 詳細については、第 24 章「EAServer コンポーネントの構築」および 第 25 章「EAServer クライアントの構築」を参照してください。 COM+ PowerBuilder アプリケーションは、COM サーバへのクライアントとし て機能できます。このサーバは、PowerBuilder またはそのほかの COM 準拠型アプリケーション開発ツールを使用して作成できます。また、 図 23-2 に示すように、インプロセス サーバとしてリモート コンピュー タ上で、または COM+ で、ローカルに実行できます。 アプリケーション テクニック 491 サーバのサポート 図 23-2: COM コンポーネントの PowerBuilder クライアント ビジネス ロジックを含むカスタム クラス ユーザ オブジェクトを PowerBuilder で開発してから、そのオブジェクトを COM オブジェクト としてパッケージすることができます。PowerBuilder COM サーバに は、1 つまたは複数の PowerBuilder カスタム クラス ユーザ オブジェク トを組み込むことができます。ユーザ オブジェクトをユーザ オブジェ クト ペインタで作成してから、プロジェクト ペインタでサーバを構築 します。COM サーバをローカルの COM+ サーバに直接配布したり、プ ロジェクト ペインタで COM+ パッケージを作成したりすることもで きます。 詳細については、第 27 章「COM/COM+ コンポーネントの構築」およ び第 28 章「COM/COM+ クライアントの構築」を参照してください。 492 PowerBuilder 第 23 章 J2EE サーバ PowerBuilder を使った分散アプリケーション開発 J2EE(Java 2 Platform, Enterprise Edition)は、エンタープライズ アプリ ケーション開発用の公認 Java フレームワークです。J2EE アプリケー ションは、多層システムのさまざまなコンピュータにインストールさ れた別々のコンポーネントで構成されます。図 23-3 に、このシステム の 3 つの階層、クライアント層、中間層、エンタープライズ情報シス テム(EIS)層を示します。中間層は、Web 層とビジネス層の 2 つの層 で構成されるとみなされることもあります。 図 23-3: J2EE クライアント層、中間層、EIS 層 アプリケーション クライアントやアプレットなどのクライアント コ ンポーネントは、クライアント層のコンピュータ上で動作します。Java サーブレットおよび JavaServer Pages(JSP)コンポーネントなどの Web コンポーネントは、Web 層の J2EE サーバで動作します。Enterprise JavaBeans(EJB)コンポーネントはビジネス コンポーネントであり、 ビジネス層の J2EE サーバで動作します。EIS 層は、リレーショナル データベース管理システム、エンタープライズ リソース プランニング アプリケーション、メインフレーム トランザクション処理、そのほか のレガシ情報システムを実行するサーバで構成されます。 PowerBuilder では、任意の J2EE 準拠サーバで動作する EJB コンポーネ ントのサービスを使用するクライアント アプリケーションを作成で きます。詳細については、第 29 章「EJB クライアントの構築」を参照 してください。 アプリケーション テクニック 493 サーバのサポート 494 PowerBuilder 第 2 4 章 EAServer コンポーネントの構築 この章について この章では、PowerBuilder を使用して EAServer コンポーネントを 構築する方法について説明します。 内容 項目 EAServer コンポーネントの構築について 共有コンポーネントおよびサービス コンポーネントの操作 インスタンス プーリングのサポート トランザクションのサポート EAServer コンポーネントからデータベースへのアクセス コンポーネント インタフェースの定義 既存インタフェースの実装 別のサーバ コンポーネントのメソッドの呼び出し コンポーネント プロパティへのアクセス Web サービスとしての NVO のエクスポーズ コンポーネントのテストとデバッグ データの印刷 EAServer へのコンポーネントの配布 ページ 495 499 505 510 516 530 534 536 539 543 545 550 556 EAServer コンポーネントの構築について PowerBuilder には、カスタム クラス(非ビジュアル)ユーザ オブ ジェクトを開発して、それらを EAServer コンポーネントとして配 布する ための ツール がありま す。こう したコ ンポーネ ントを Windows、Sun Solaris、Hewlett-Packard HP-UX、IBM AIX オペレー ティングシステムで実行している EAServer ホストに配布できま す。556 ページの「EAServer へのコンポーネントの配布」を参照 してください。 アプリケーション テクニック 495 EAServer コンポーネントの構築について UNIX の制限 コンポーネントを UNIX サーバに配布することを予定している場合、 UNIX プラットフォーム上では PowerBuilder ランタイム ライブラリが グラフィック処理や、Windows アプリケーション プログラミング イン タフェースの呼び出しをサポートしていないことに注意してください。 ウィザードの使い方について PowerBuilder には、EAServer コンポーネントの開発と配布を容易にす るウィザードがいくつか用意されています。 • ターゲット ウィザード 新規のアプリケーション、新規のカスタム クラス ユーザ オブジェクト、および新規のプロジェクトを作成し ます。 • オブジェクト ウィザード 既存のアプリケーションと新規のプロ ジェクトの中に、カスタム クラス ユーザ オブジェクトを新規作成 します。 • プロジェクト ウィザード 既存のカスタム クラス ユーザ オブジェ クトから EAServer コンポーネントを生成するためのプロジェクト を作成します。 開発プロセスについて EAServer コンポーネ ントの作成手順 496 カスタム クラス ユーザ オブジェクトから EAServer コンポーネントを 作成して配布するには、次の手順で操作を進めます。 1 EAServer コンポーネント ターゲット ウィザードを使用して、新規 アプリケーションでユーザ オブジェクトを新規作成します。既存 のアプリケーションで作業している場合は、この操作を行うかわ りに、EAServer コンポーネント オブジェクト ウィザードを使用し てオブジェクトを作成できます。これらのウィザードでは、新規 ユーザ オブジェクトを Web サービスとしてエクスポーズするた めの情報を入力することもできます。 2 ユーザ オブジェクト ペインタで、生成されたユーザ オブジェクト に関数、イベント、およびインスタンス変数を追加します。 3 オブジェクトのテストとデバッグを行います。 4 オブジェクトを EAServer に配布します。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 PowerBuilder で開発した EAServer コンポーネントのテストまたは配布 を行うには、プロジェクト オブジェクトとプロジェクトを作成しま す。プロジェクト オブジェクトは、ターゲット ウィザード、オブジェ クト ウィザード、またはプロジェクト ウィザードで作成できます。 コンポーネントを配布するには、プロジェクト ペインタでプロジェク トを開き、必要な場合はプロジェクトの設定を修正して、プロジェク トを作成します。その後、EAServer コンポーネント ジェネレータに よって、コンポーネント インタフェースと PowerBuilder に実装された そのインタフェースがターゲット サーバに配布されます。 テストのために、ライブ編集を利用してユーザ オブジェクト ペインタ から自動的にプロジェクトを作成できます。この操作では、プロジェ クト ペインタからプロジェクトを作成する必要はありません。ユーザ オブジェクト ペインタでライブ編集を有効にすると、ユーザ オブジェ クトを保存するたびに EAServer コンポーネントのプロジェクトが作 成されます。ライブ編集についての詳細は、545 ページの「コンポー ネントのテストとデバッグ」を参照してください。 To-Do リスト EAServer のターゲット ウィザードかオブジェクト ウィザードを使用 して新規のユーザ オブジェクトを作成すると、オプションで To-Do リ ストを作成できます。ウィザードの最終ページにある[To-Do リスト の作成]チェックボックスをオンにすると、ウィザードは To-Do リス トにタスクを追加して、開発の全フェーズが遂行されるように開発者 の注意を促します。 EAServer プロファイルの作成 EAServer プロファイルは、システム レジストリに保存されている名 前付きパラメータ セットで、特定の EAServer ホストへの接続を定義 します。ウィザードを使用してコンポーネントを作成する前に、コン ポーネントが配布されるサーバのプロファイルを作成する必要があり ます。 アプリケーション テクニック 497 EAServer コンポーネントの構築について EAServer プロファイル ダイアログボックスには、定義済みの EAServer プロファイルが一覧表示されます。このダイアログボックスから、 EAServer プロファイルの作成、編集、削除、およびテストを実行でき ます。 ❖ EAServer プロファイルを作成するには 1 パワーバーの[EAServer プロファイル]ボタンをクリックします。 EAServer プロファイル ダイアログボックスが表示され、定義済み の EAServer プロファイルが一覧表示されます。 2 [追加]を選択します。 EAServer プロファイルの編集 ダイアログボックスが表示されま す。 3 プロファイル名、サーバ名、ポート番号、ログイン名、およびパ スワード(必要な場合)を入力します。 4 (オプション)[テスト]を選択して、接続の検証を行います。 5 [OK]をクリックして変更内容を保存し、ダイアログボックスを 閉じます。 EAServer プロファイル ダイアログボックスに、新規プロファイル 名のリストが表示されます。EAServer プロファイルの値は、 HKEY_CURRENT_USER\Software\Sybase\PowerBuilder\10.0\Jagu arServerProfiles のレジストリに保存されます。 498 PowerBuilder 第 24 章 EAServer コンポーネントの構築 共有コンポーネントおよびサービス コンポーネントの操作 PowerBuilder で EAServer コンポーネントを作成するときには、標準コ ンポーネント、共有コンポーネント、またはサービス コンポーネント のどれを作成するかをウィザードで選択できます。 共有コンポーネントについて EAServer によるプロ グラム変数領域の管理 EAServer アーキテクチャはコンポーネント指向です。各コンポーネン トは、それぞれの状態を保持しています。1 つのクライアントがサー バ上でいくつかの PowerBuilder オブジェクトをインスタンス化する と、EAServer は、オブジェクトのプログラム変数領域を別々に管理し ます。EAServer で動作する各 PowerBuilder ユーザ オブジェクトは、グ ローバル変数と共有変数について独自のコピーを保持しています。 PowerBuilder オブジェクトはそれぞれ共通の状態にはありません。し たがって、PowerBuilder オブジェクトどうしは、メソッド、EAServer の共有コンポーネント、サーバ ファイル、およびデータベースを介し てのみ通信できます。 クライアントが状態情報を共有できるように、EAServer は共有コン ポーネントをサポートします。共有コンポーネントを使用すれば、複 数のクライアントが同じコンポーネント インスタンスを共有できま す。 PowerBuilder ウィザードで共有コンポーネントとしてマークすると、 EAServer Manager のコンポーネント プロパティ ダイアログボックス の[インスタンス]ページでコンポーネントを共有としてマークした 場合と同じ結果になります。EAServer では、コンポーネントの 1 つの インスタンスだけをインスタンス化できます。 クライアント(とそのほかのサーバ コンポーネント)は、共有コン ポーネントに対して、それがあたかも別の種類のコンポーネントであ るかのようにアクセスします。 EAServer 共有コン ポーネントを使用する 利点 共有コンポーネントを使うと、以下のことが可能になります。 • クライアント接続ごとに別々に取り出す必要がある共通データに 容易にアクセスできるようにする • データベース アクセスの数を減らすことによって、データベース サーバをほかの処理に使用できるようにする アプリケーション テクニック 499 共有コンポーネントおよびサービス コンポーネントの操作 EAServer 共有コン ポーネントと PowerBuilder 共有オ ブジェクト EAServer 共有コンポーネントとして提供する利点の多くは、 PowerBuilder 共有オブジェクトの場合と同じです。EAServer に配布する PowerBuilder コンポーネントは、PowerBuilder 共有オブジェクトに加えて、EAServer 共有コンポーネントに対してもクライアントの役目を果たせます。 EAServer 共有コンポーネントに対しては、PowerBuilder で実装されて いないクライアントとコンポーネントからアクセスできます。 しかし、EAServer は、PowerBuilder 共有オブジェクトを EAServer 共有 コンポーネントのようには扱いません。したがって、PowerBuilder 共 有 オ ブ ジ ェ ク ト の 操 作 に 使 用 す る 関 数(SharedObjectRegister や SharedObjectGet など)は、EAServer 共有コンポーネントでは動作しま せん。EAServer で動作している PowerBuilder コンポーネント内でこれ らの関数を呼び出そうとしても、そのリクエストは失敗します。 サービス コンポーネントについて サービス コンポーネントは、EAServer クライアントとそのほかの EAServer コンポーネントのバックグラウンド処理を行います。EAServer は、サーバの起動時にサービス コンポーネントをロードします。 いずれかの PowerBuilder ウィザードで、コンポーネントをサービス コ ンポーネントとしてマークした場合には、そのコンポーネントは配布 時にサービスとして EAServer にインストールされます。これは、サー バの com.sybase.EAServer.server.services プロパティを修正して、サーバ のサービス リストにコンポーネントを追加するのと同じです。 共有か非共有か サービス コンポーネントを作成する場合は、ウィザードでサービス コ ンポーネントにマークを付けます。サービス コンポーネントの複数の インスタンスを使用したい場合は、プロジェクト ペインタで設定を変 更できます。プロジェクト ペインタの EAServer コンポーネント ジェ ネレータのプロパティ シートにある[コンポーネント]ページで、 [作 成]スピン コントロールから使用したいインスタンスの数を選択しま す。インスタンスの数を複数に変更すると[同時実行]と[自動的な デマケーション / 不活性化]がオンになるので、注意してください。こ れは、EAServer でコンポーネントがスレッド実行の問題に遭わないよ うにするためです。詳細については、次の「スレッド実行の問題とコ ンポーネントの種類」を参照してください。 サービス コンポーネ ントの関数 PowerBuilder ウィザードは、サービス コンポーネント用に 3 つの補助 関数を組み込みます。これらの関数は CTSServices::GenericServices イ ンタフェースに定義されており、サービスに関連付けられているバッ クグラウンド処理の動作を制御できます。 500 PowerBuilder 第 24 章 EAServer コンポーネントの構築 サービス コンポーネントがロードされた後、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 スレッド実行の問題とコンポーネントの種類 PowerBuilder コンポーネントの各インスタンスは独自のセッションを 実行しているため、各セッションではスレッドを 1 つしか実行できま せん。したがって、PowerBuilder コンポーネントのインスタンスの 1 つが、クライアントのリクエストを同時に複数実行することは不可能 です。ただし、同じコンポーネントの複数のインスタンスは、それぞ れ別のクライアントのリクエストを実行できます。コンポーネントを 作成すると、EAServer でのスレッドの処理方法に影響するいくつかの プロパティにデフォルト値が設定されます。 Thread Manager の使い方 EAServer Thread Manager では、より堅固なサービスの開発も可能です。 504 ページの「EAServer Thread Manager の使い方」を参照してください。 Concurrency プロパ ティ コンポーネントの複数のインスタンスを作成して複数のクライアント のリクエストを処理できるかどうかは、Concurrency プロパティによっ て 決 ま り ま す。com.sybase.jaguar.component.thread.safe プ ロ パ テ ィ を TRUE に設定するには、ウィザードかプロジェクト ペインタで[同時 実行]チェックボックスをオンにします。 アプリケーション テクニック 501 共有コンポーネントおよびサービス コンポーネントの操作 標準コンポーネント 標準コンポーネントでは、コンポーネントの複数 のインスタンスでクライアントのリクエストを処理することによっ て、パフォーマンスを向上できます。デフォルト設定では、標準コン ポーネントの Concurrency プロパティがチェックされますが、そのコ ンポーネントのインスタンスを 1 つしか使用しない場合は、設定を変 更することも可能です。 共有コンポーネント 共有コンポーネントの場合、コンポーネントのイ ンスタンスは常に 1 つしかアクティブになりません。したがって、ス レッドは 1 つしか実行できません。共有コンポーネントの[同時実行] チェックボックスは選択不可能で、オンにはなりません。 サービス コンポーネント 通常は、サービス コンポーネントは共有コン ポーネントとして処理されますが、サービス コンポーネントのインス タンスを複数作成して、パフォーマンスとスケーラビリティを向上さ せることも可能です。サービス コンポーネントの[コンポーネント] ページには、[同時実行]、[自動的なデマケーション / 不活性化]、お よび[作成]の 3 つのオプションがあり、 [作成]オプションはサービ ス コンポーネントでのみ変更できます。 [作成]オプションを 2 以上に変更すると、[同時実行]チェックボッ クスと[自動的なデマケーション / 不活性化]チェックボックスがオ ンになります。必要であれば、サービス コンポーネントの複数のイン スタンスを作成し、各メソッドの呼び出し後、それらのインスタンス を非アクティブにできます。開発者がコンポーネントのインスタンス を明示的に非アクティブにするために[自動的なデマケーション / 不 活性化]チェックボックスをオフにすると、 [作成]スピン コントロー ルは 1 にリセットされ、 [同時実行]チェックボックスがオフになりま す。 bind.thread、sharing、 および tx_vote プロパ ティ EAServer のスレッドの処理に影響するコンポーネント プロパティには、 ほかに sharing、tx_vote、および bind.thread の 3 つがあります。 Bind Object プロパティ(未使用) 付加的なプロパティである bind.object を使うと、クライアント スレッ ドを 1 つのインスタンス内で実行できるだけでなく、複数インスタン スの作成もサポートされます。このプロパティは、PowerBuilder コン ポーネント用には使用できないため、常に FALSE に設定されます。 502 PowerBuilder 第 24 章 EAServer コンポーネントの構築 bind.thread プロパティが TRUE に設定されているときは、コンポーネン ト インスタンスのメソッドは、そのインスタンスを作成したスレッド と同じスレッドで実行されなければなりません。ライブ編集を使用し てコンポーネントを作成している場合は、このプロパティを TRUE に 設定しなければなりません。UNIX サーバに配布されるコンポーネン トでは、スケーラビリティを向上させるために、このプロパティを FALSE に設定する必要があります。 sharing プロパティでは、コンポーネントを共有するかどうかを識別し ます。このプロパティは、ウィザードで[標準]を選択したときは FALSE、 [共有]または[サービス]を選択したときには TRUE に設定 されます。PowerBuilder でこのプロパティを変更するには、プロジェ クト ペインタで、サービス コンポーネントの[コンポーネント]タブ ページにある[インスタンス]設定を変更する以外、方法はありませ ん。sharing プロパティか thread.safe プロパティの一方が TRUE に設定 されている場合は、もう一方のプロパティを FALSE に設定しなければ なりません。 連続するメソッド呼び出しの間、アクティブなまま保たれるコンポー ネントのことを、ステートフル(状態を持つ)コンポーネントと呼び ます。インスタンス プーリングをサポートしていてメソッド呼び出し 後に非アクティブになるコンポーネントのことを、ステートレス(状 態を持たない)コンポーネントと呼びます。一般に、ステートレス コ ンポーネントで作成されたアプリケーションの方が、高いスケーラビ リティを実現できます。コンポーネントがメソッド呼び出し後に非ア クティブになるかどうかは、tx_vote プロパティによって決まります。 このプロパティが FALSE(ステートレス)に設定されるのは、ウィザー ドの[自動的なデマケーション / 不活性化]チェックボックスをオン にした場合またはプロジェクト ペインタの[コンポーネント]ページ で複数のインスタンスを選択した場合です。それ以外の場合、このプ ロパティは TRUE(ステートフル)に設定されます。ステートフル サー ビス オブジェクトのインスタンスは、1 つしか所有できません。 表 24-1 に、コンポーネントの種類によるデフォルト設定と変更できる 設定を示します。 アプリケーション テクニック 503 共有コンポーネントおよびサービス コンポーネントの操作 表 24-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 プロパ ティが自動的に無効化されます。 EAServer Thread Manager の使い方 Thread Manager は組み込みの EAServer コンポーネントで、EAServer コ ンポーネントのインスタンスを、クライアントのメソッド呼び出しが 独立して行われるスレッド内で実行できます。Thread Manager によっ て生成されたスレッドを使用して、ユーザとの対話と非同期に発生す る処理を実行できます。 たとえば、ファイルのインデックス作成という長い操作を開始するコ ンポーネント メソッドがあるとします。この場合、メソッドを使えば、 Thread Manager を呼び出して新しいスレッドで処理を開始し、即座に 復帰できます。 504 PowerBuilder 第 24 章 EAServer コンポーネントの構築 PowerBuilder コンポーネントの各インスタンスは独自のセッションを 実行し、それぞれのセッションは実行のスレッドを 1 つしかサポート しないため、Thread Manager を使用せずに停止や更新ができるサービ スを開発するのは不可能です。サービスの start メソッドと run メソッ ドは、サービスの処理を行うスレッドを生成します。サービスの stop メソッドは、Thread Manager の stop メソッドを呼び出して、スレッド を停止します。 Thread Manager についての詳細は、『EAServer プログラマーズ・ガイ ド』マニュアルを参照してください。 インスタンス プーリングのサポート インスタンス プーリ ングの利点 EAServer コンポーネントは、オプションでインスタンス プーリングを サポートできます。インスタンス プーリングを利用すると、EAServer クライアントはコンポーネント インスタンスを再利用できます。イン スタンス プーリングは、コンポーネント インスタンスを繰り返し割り 当てることにより生じるリソースの枯渇を解消し、EAServer の全体的 なパフォーマンスを改善します。 ウィザードでのプーリ ング オプションの指 定 いずれかの PowerBuilder ウィザードを使用して EAServer コンポーネ ントを作成した場合には、コンポーネントに対して表 24-2 に示すいず れかのインスタンス プーリング オプションを指定できます。 アプリケーション テクニック 505 インスタンス プーリングのサポート 表 24-2: EAServer コンポーネント プーリング オプション プーリング オプ ション 説明 [サポートする] クライアント使用のたびに必ずコンポーネントのプーリ ングを実行します。このオプションが選択された場合に は、コンポーネントに対して CanBePooled イベントは発 生しません。 このオプションをオンにすると、コンポーネントのプー リング プロパティが TRUE に設定されます。コンポーネ ントの[自動的なデマケーション / 不活性化]設定が有効 である場合には、メソッド呼び出しのたびにインスタン スがプールされます。[自動的なデマケーション / 不活性 化]設 定 が 無 効 で あ る 場 合 に は、コ ン ポ ー ネ ン ト が TransactionServer コンテキスト オブジェクトの SetComplete メソッドか SetAbort メソッドを呼び出したときに、イン スタンスがプールされます。 [サポートなし] デフォルトでは、クライアント使用後にコンポーネント プーリングは実行されません。ただし、CanBePooled イベ ントのスクリプトを作成してデフォルト動作を無効にす ることも可能です。CanBePooled イベントでは、特定のコ ンポーネント インスタンスをプールするかどうかをプロ グラムで指定できます。CanBePooled イベントのスクリプ トを作成した場合には、このイベントはクライアント使 用のたびに発生します。 このオプションをオンにすると、コンポーネントのプー リング プロパティが FALSE に設定されます。 プールされたインスタ ンスの状態の制御 インスタンス プーリングをサポートする EAServer コンポーネントを 作成した場合には、各クライアントがプールされたインスタンスの使 用を終了した後で、そのコンポーネントの状態をリセットしなければ ならないことがあります。 コンポーネントの状態を制御できるように、コンポーネントの有効期 間中に、EAServer は 表 24-3 に示すイベントを 1 つまたは複数発生さ せます。 表 24-3: コンポーネントの状態イベント イベント Activate CanBePooled Deactivate 506 PBM コード PBM_COMPONENT_ACTIVATE PBM_COMPONENT_CANBEPOOLED PBM_COMPONENT_DEACTIVATE PowerBuilder 第 24 章 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 イベントにロジックを 追加します。 プール サイズの最大 値と最小値 インスタンス プーリングによってクライアント応答時間を短縮でき ますが、サーバのメモリ使用量が増加することもあります。EAServer Manager の[リソース]タブ ページのオプションを設定して、プール サイズの最大値と最小値を設定し、インスタンス プールを維持するた めのメモリ量を制限できます。たとえば、頻繁に使用するコンポーネ ントのプール サイズの最大値と最小値は、あまり使用されないコン ポーネントより大きくする必要があります。 アプリケーション テクニック 507 インスタンス プーリングのサポート EAServer は、プールにあらかじめインスタンスを割り当てません。プー ル サイズは、クライアント リクエストを満たすための追加インスタン スが必要になるにつれて、指定された最大サイズ(最大値が指定され ている場合)まで増加します。最小プール サイズに到達すると、最小 サイズ以下には縮小されません。プールから休止中のインスタンスを 解放するため、EAServer には定期的に実行されるガベージ コレクタ ス レッドがあります。このスレッドが実行されるたびに、ガベージ コレ クタは、休止中のインスタンスを 1 つプールから削除します。ただし、 プールが最小サイズに到達したときは削除されません。 プールサイズの最小値を設定する場合は、最大値はそれより少し大き めに設定します。最大値と最小値の差分があると、実際のプール サイ ズが最小値に近づいた場合に、減衰率のためにインスタンスの割り当 てと解除を繰返し行わずに済みます。 PowerBuilder と EAServer におけるメモリの管理方法は、環境変数で設 定できます。詳細については、51 ページの「メモリ管理の設定」およ び テ ク ニ カ ル ド キ ュ メ ン ト EAServer/PowerBuilder Memory Tuning and Troubleshooting のサイト http://www.sybase.com/detail?id=1027319 を参照し てください。 コンポーネントの有効 期間 508 インスタンス プーリングの仕組みを理解するには、コンポーネント イ ンスタンスの有効期間(ライフサイクル)を理解する必要があります。 コンポーネントの有効期間中の動作を以下に示します。 1 一般に、コンポーネントは最初のメソッド呼び出しでインスタン ス化されます。PowerBuilder で開発されたコンポーネントがこのイ ンスタンス化の対象となった場合、コンポーネントが動作するた めの新しい PowerBuilder セッションが EAServer により作成されま す。 2 PowerBuilder セッションでは、EAServer コンポーネントを表す、 PowerBuilder 非ビジュアル オブジェクトのインスタンスを作成し ます。オブジェクトを作成すると、Constructor イベントが発生し ます。 3 オブジェクトがインスタンス化された後、EAServer は非ビジュア ル オブジェクト上で Activate イベントを発生させ、オブジェクト が新しいクライアントによって使用されることをオブジェクトに 通知します。この時点で、コンポーネントは、自分自身が実行可 能な状態であることを確認しなければなりません。 4 次に、EAServer はコンポーネント上のクライアントによって呼び 出されたメソッドを実行します。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 5 コ ン ポ ー ネ ン ト が そ の 作 業 の 完 了 を 知 ら せ る と、EAServer は Deactivate イベントを発生させて、コンポーネントがその後処理を 行えるようにします。コンポーネントの[自動的なデマケーショ ン / 不活性化]設定が有効である場合には、各メソッド呼び出しの 後で、Deactivate イベントが自動的に発生します。設定が無効であ る場合には、コンポーネントが TransactionServer コンテキスト オ ブジェクトの SetComplete メソッドか SetAbort メソッドを呼び出し たときに、Deactivate イベントを発生させます。 6 プーリング オプションで[サポートしない]を選択するか、コン ポーネントのインスタンス プーリング プロパティを FALSE に設 定し、CanBePooled イベントのスクリプトも作成した場合には、 EAServer は、このイベントを発生させることによって、この時点 でプーリングできるかどうかをコンポーネントにたずねます。 CanBePooled イベントを発生させると、コンポーネント インスタン スは、プーリングを選択的に実行するか拒否できます。CanBePooled イベントの戻り値は、コンポーネント インスタンスがプールされ るかどうかを決定します。 戻り値が 1 である場合には、プーリングが有効です。戻り値が 0 である場合には、プーリングが無効です。CanBePooled イベントの スクリプトが作成されていない場合、デフォルトでは、インスタ ンスはプールされません。 プーリング プロパティが有効である場合の動作 プーリング オプションで[サポートする]を選択した場合、また はコンポーネントのプーリング プロパティを TRUE に設定した場 合 は、コ ン ポ ー ネ ン ト イ ン ス タ ン ス は 常 に プ ー ル さ れ、 CanBePooled イベントは発生しません。 7 アプリケーション テクニック 非アクティブ化の後でインスタンスがプールされない場合には、 EAServer は Destructor イベントを発生させます。次に、PowerBuilder オブジェクトを破棄し、実行時セッションを終了させます。 509 トランザクションのサポート トランザクションのサポート EAServer のトランザ クション サポートの 利点 PowerBuilder で開発する EAServer コンポーネントは、EAServer トラン ザクションに関与できます。EAServer トランザクションは、その境界 と結果が EAServer によって決定されるトランザクションです。コン ポーネントにマークを付けることによって、トランザクション サポー トを提供するコンポーネントを判別できます。コンポーネントがトラ ンザクション サポートを提供する場合には、EAServer は、コンポーネ ントのデータベース操作がトランザクションの一部として実行される ことを保証します。 1 つの EAServer トランザクションに複数の EAServer コンポーネント が関与できます。EAServer では、関与するコンポーネントによるデー タベース変更内容すべてのコミットまたはロールバックが確実に完了 します。EAServer トランザクションを使用するコンポーネントを定義 すれば、トランザクションに関与するコンポーネントによって実行さ れるすべての作業は意図したとおりに行われることを保証できます。 コンポーネントによる トランザクション サ ポートの指示 各 EAServer コンポーネントには、コンポーネントが EAServer トラン ザクションにどう関与するかを指示するトランザクション属性があり ます。PowerBuilder で EAServer コンポーネントを開発する場合には、 ウィザードでトランザクション属性を指定できます。表 24-4 に、オプ ションを示します。 表 24-4: トランザクション属性オプション トランザクションの 種類 [サポートなし] [トランザクション をサポート] 510 説明 コンポーネントはトランザクションの一部として実 行されない。コンポーネントが、トランザクション 内部で実行中の別のコンポーネントによってアク ティブにされた場合には、その新しいインスタンス の作業は既存のトランザクションの外部で行われる コンポーネントは EAServer トランザクションのコ ンテキスト内で実行できるが、コンポーネントのメ ソッドを実行するためにトランザクションは必要と しない。コンポーネントがクライアントによって直 接インスタンス化された場合、EAServer はトランザ クションを開始しない。コンポーネント A がコン ポーネント B によってインスタンス化されていて、 コンポーネント B はトランザクション内部で実行さ れている場合には、コンポーネント A は同じトラン ザクション内で実行される PowerBuilder 第 24 章 トランザクションの 種類 [トランザクション が必要] [新規のトランザク ションが必要] [Mandatory] [OTS スタイル] [Never] トランザクション サービス コンテキス ト オブジェクトの使 い方 EAServer コンポーネントの構築 説明 コンポーネントは常にトランザクションで実行され る。コンポーネントがクライアントによって直接イ ンスタンス化された場合には、新しいトランザク ションが始まる。コンポーネント A がコンポーネン ト B によってアクティブ化され、B はトランザク ション内で実行されている場合には、A は同じトラ ンザクション内で実行される。B がトランザクショ ン内で実行されていない場合には、A は新しいトラ ンザクション内で実行される コンポーネントがインスタンス化されるたびに、新 しいトランザクションが始まる。コンポーネント A がコンポーネント B によってアクティブにされ、B がトランザクション内部で実行されている場合に は、A は B のトランザクションの結果に影響されな い新しいトランザクションを開始する。B がトラン ザクション内で実行されていない場合には、A は新 しいトランザクション内で実行される メソッドは、実行中のトランザクションがあるクラ イアントによってのみ呼び出される。実行中のトラ ンザクションがないときにこのコンポーネントを呼 び出すと、実行時エラーになる コンポーネントはトランザクションを管理でき、ま たクライアントのトランザクションを継承できる。 トランザクションなしで呼び出された場合、コン ポーネントは、CORBACurrent コンテキスト サービ ス オブジェクトのインスタンスを使用して、トラン ザクションの開始、コミット、およびロールバック を行う 未処理のトランザクションがある場合、メソッドの 呼び出しは不可能。実行中のトランザクションがあ るときにこのコンポーネントを呼び出すと、実行時 エラーになる コンポーネント メソッドを使うと、EAServer のトランザクション状態 プリミティブを呼び出して、EAServer が現行のトランザクションをコ ミットするか中断するかを制御できます。EAServer のトランザクショ ン状態プリミティブにアクセスできるようにするため、PowerBuilder は TransactionServer というトランザクション サービス コンテキスト オブジェクトを提供します。 アプリケーション テクニック 511 トランザクションのサポート TransactionServer コンテキスト オブジェクトを使用するには、 UseContextObject DBParm パラメータを Yes に設定する必要がありま す。これによって、COMMIT と ROLLBACK のかわりに TransactionServer オブジェクトのメソッドを使用して、コンポーネントが現行のトラン ザクションの作業を完了したかどうかを示すことを PowerBuilder に指 示します。 トランザクション コンテキスト サービスを使用するには、 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() END IF TransactionServer インタフェースが提供する 表 24-5 のメソッドを使用 すれば、EAServer のトランザクション プリミティブにアクセスできま す。 512 PowerBuilder 第 24 章 EAServer コンポーネントの構築 表 24-5: TransactionServer メソッド メソッド DisableCommit EnableCommit IsInTransaction IsTransactionAborted SetAbort SetComplete 自動的なデマケーショ ン / 不活性化 説明 コンポーネントの作業が完了していないため、現行の トランザクションをコミットできないことを示す。イ ンスタンスは、現行のメソッドが復帰した後もアク ティブなままである 現行のメソッドを呼び出した後で、コンポーネントを 非アクティブにしないことを示す。コンポーネント インスタンスが非アクティブにされた場合には、現行 のトランザクションをコミットできる 現行のメソッドがトランザクション内で実行されて いるかどうかを判定する 現行のトランザクションが中断されたかどうかを判定 する コンポーネントは現行のトランザクションに対する 作業を完了できず、トランザクションをロールバック することを示す。メソッドが復帰したとき、コンポー ネント インスタンスは非アクティブにされる コンポーネントが現行のトランザクションで作業を 完了し、そのコンポーネントに関する限り、トランザ クションをコミットでき、コンポーネント インスタ ンスを非アクティブにできることを示す 各メソッド呼び出しの後でコンポーネントを自動的に非アクティブに したい場合には、コンポーネントの[自動的なデマケーション / 不活 性化]を有効にしてください。これによって、コンポーネントの tx_vote プロパティに FALSE が設定されます。 [自動的なデマケーション / 不活 性化]が有効にされた場合には、デフォルトで SetComplete が想定され るため、SetComplete を明示的に呼び出して非アクティブにする必要は ありません。トランザクションをロールバックするには、SetAbort を呼 び出します。 各メソッド呼び出しの後でコンポーネントを自動的に非アクティブに したくない場合には、コンポーネントの[自動的なデマケーション / 不 活性化]設定を無効にします。これによって、コンポーネントの tx_vote プロパティに TRUE が設定されます。[自動的なデマケーション / 不活 性化]を無効にすると、EAServer は、通知を待ってからトランザク ションを完了します。したがって、プログラムで SetComplete か SetAbort を明示的に呼び出すことによって、必ず非アクティブにしてください。 アプリケーション テクニック 513 トランザクションのサポート 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 を呼び出し、コンポー ネントを非アクティブにする必要があります。それ以外の場合は、コ ンポーネントは非アクティブにされません。 トランザクション処理 と実行時エラー 514 PBVM で内部例外が発生したとき、または PowerBuilder コンポーネン トが実行時例外を生成したときの EAServer の動作を制御できます。そ のためには、コンポーネントが実行されているサーバ上で、環境変数 PBOnFatalError または PBRollbackOnRTError をバッチ ファイル内で設 定するか、システム環境変数として設定します。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 表 24-6: 例外処理用の環境変数 変数 PBOnFatalError 説明 PBVM で内部例外が発生したときに、EAServer を継続動作させるか、シャッ トダウンするか、または再起動するかを指定する。デフォルトはシャットダ ウン。EAServer で実行されている PowerBuilder コンポーネントによって未 処理の内部例外が生成されると、PBVM が不安定になり、予期しない動作を 起こす可能性がある 値は以下のとおり • continue - 動作を継続させて CORBA_TRANSACTION_ROLLEDBACK 例 外を送出する • restart - 自動的に再起動する PBRollbackOnRTError • shutdown - 自動的にシャットダウンする(デフォルト) EAServer で実行されている PowerBuilder コンポーネントによって実行時例 外が生成されたときに、トランザクションをどのように処理するかを指定す る。デフォルトでは、トランザクションをロールバックしてクライアントに 例外を送出する 値は以下のとおり • n、no、または false - トランザクションをコミットしてからクライアント に例外を送出する • y、yes、または true - トランザクションをロールバックしてからクライア ントに例外を送出する(デフォルト) トランザクションとコ ンポーネント有効期間 EAServer のトランザクション モデルとコンポーネント有効期間は密 に統合されています。トランザクションに関与するコンポーネント イ ンスタンスは、トランザクションが終了するか、トランザクションに 対するコンポーネントの関与が終了したことが示される(その作業が 終了してコミットの用意ができるか、その作業をロールバックする必 要がある)までは、非アクティブになりません。インスタンスがアク ティブになるタイミングは、トランザクションへのインスタンスの関 与開始と終了に正確に一致します。 詳細については、EAServer のマニュアルを参照してください。 アプリケーション テクニック 515 EAServer コンポーネントからデータベースへのアクセス EAServer コンポーネントからデータベースへのアクセス データベースの接続性 EAServer コ ン ポ ー ネ ン ト か ら デ ー タ ベ ー ス に ア ク セ ス で き ま す。 EAServer による接続プーリングとトランザクション管理のサポートを 活用したい場合には、EAServer によってサポートされているデータ ベース インタフェースのいずれかを使用して、データベースに接続す る必要があります。データベース インタフェースについての詳細は、 『データベースとの接続』マニュアルを参照してください。 データストアの使い方 PowerBuilder で開発された EAServer コンポーネントは、データストア を使用してデータベースと対話できます。データストアは、非ビジュ アルなデータウィンドウのコントロールです。データストアは、デー タウィンドウのコントロールと同じように機能しますが、ビジュアル 属性を持っていません。 データストアは、分散アプリケーションで使用すると便利です。デー タストアを使用すると、各クライアント マシンのかわりに、リモート サーバ上でデータベース処理を実行できます。 リッチテキスト提示様式はサポートされていません サーバ コンポーネントは、リッチテキスト提示様式を使用するデータ ウィンドウ オブジェクトを備えたデータストアを格納できません。 リッチテキスト処理は、分散アプリケーションではサポートされてい ません。 サーバとクライアント 間でのデータ共有 サーバ上で検索されるデータに視覚的なインタフェースを提供したい 場合、データウィンドウ コントロールを持つウィンドウをクライアン トに追加します。サーバ上でデータが検索されるたびに、データウィ ンドウ コントロールを更新してサーバ上のデータストアの結果集合 を表示します。同様に、ユーザがクライアント上でデータを変更する たびに、サーバ上のデータストアの内容を更新して、クライアント上 のデータウィンドウ コントロールの最新のステータスを反映させま す。 クライアントとサーバ間でデータを共有するには、サーバのデータス トアとクライアントのデータウィンドウ コントロールをプログラム によって同期させます。アプリケーションにデータベース更新の処理 を行わせたい場合は、加えてデータウィンドウのデータ バッファとス テータス フラグを、クライアントとサーバの間で互いにやりとりする 必要もあります。 サーバのデータストアとクライアントのデータウィンドウとの同期に ついての詳細は、522 ページの「更新の実行」を参照してください。 516 PowerBuilder 第 24 章 EAServer コンポーネントの構築 分散アプリケーションは ShareData 関数をサポートしません クライアント上のデータウィンドウ コントロールとサーバ上のデー タストアとの間では、ShareData 関数を使用してのデータ共有はできま せん。 接続キャッシュの使い方 接続キャッシュの利点 データベース処理を最適化するため、EAServer は接続キャッシュをサ ポートします。接続キャッシュを使用すれば、EAServer コンポーネン トは、リモート データベース サーバに対してあらかじめ割り当てられ た接続のプールを共有できるため、コンポーネントの各インスタンス が別々の接続を確立することによるオーバーヘッドを避けることが可 能です。接続キャッシュを設定することによって、サーバは同じデー タ ソースに対する接続を再利用できます。 動作 通常、PowerBuilder アプリケーションがデータベースに接続されると、 PowerBuilder は、DISCONNECT 文が実行された各データベース接続を 物理的に終了させます。一方、PowerBuilder コンポーネントが EAServer 接続キャッシュを使用した場合には、EAServer はデータベース接続を 論理的に終了させますが、接続を物理的に解除するわけではありませ ん。接続キャッシュ内ではデータベース接続が開いたままであり、ほ かのデータベース操作で再利用できます。 destructor イベントで接続を解除しない EAServer は、トランザクションが完了する時やコンポーネントが非ア クティブになる時に、キャッシュへのすべての接続ハンドルを解放し ます。destructor イベント(deactivate イベントの 後に発生する)に DISCONNECT 文を配置すると、接続はすでに論理的に終了しているの で、DISCONNECT で 物 理 的 に 終 了 さ れ ま す。DISCONNECT 文 は、 deactivate イベントに配置できます。 キャッシュ内のすべての接続は、共通のユーザ名、パスワード、サー バ名、および接続ライブラリを共有しなければなりません。 アプリケーション テクニック 517 EAServer コンポーネントからデータベースへのアクセス ユーザによるキャッ シュへのアクセス 指定された一連のユーザ名、パスワード、サーバ、および接続ライブ ラ リ の 値 を 使 用 す る キ ャ ッ シ ュ か ら 接 続 を 検 索 し た い 場 合 に は、 キャッシュを使えるようにデータベース アクセス コードを修正する 必要はありません。EAServer Manager で、コンポーネントが必要とす るデータベース接続プロパティ(ユーザ名、パスワード、サーバ名、 および接続ライブラリ)を備えた新しいキャッシュを作成します。実 行時に、コンポーネントがデータベースへの接続を試みると、EAServer は、コンポーネントが要求する接続値に一致する接続をキャッシュか ら自動的に返します。 名前によるキャッシュ へのアクセス キャッシュ名を指定することによって、キャッシュから接続を検索し たい場合には、CacheName DBParm を設定して、使用したいキャッシュ を識別します。名前によってキャッシュにアクセスすれば、コンポー ネントの対応するソース コードを変更せずに、EAServer Manager で ユーザ名、パスワード、またはサーバを変更できます。 キャッシュ名によるアクセスを有効にする 名前によってキャッシュにアクセスするには、EAServer Manager で キャッシュの[Enable Cashe-By-Name Access]オプションを選択しま す。デフォルトでは、このオプションは選択されません。 このオプションを有効にするには、jagadmin 権限が必要です。 次の 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 での名前と完全に一致す ることを確認してください。 プロキシによる接続 518 キャッシュにユーザによってアクセスするか名前によってアクセスす るかに関係なく、プロキシで接続できます。プロキシで接続した場合 は、代替ログイン名を入力することで、別のユーザの識別情報と権限 を使用できます。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 この機能は、SQL コマンド set session authorization を認識する任意の データベースで使用できます。ユーザ A が ProxyUserName DBParm を 使用して別のユーザ B の識別情報を使用するには、ユーザ A はこのス テートメントを実行する権限を所有していなければなりません。たと えば、ASA の場合、ユーザ A は DBA 権限を所有している必要があり、 また ASE の場合、ユーザ A はシステムのセキュリティ担当者から set session authorization を実行する権限を与えられている必要があります。 プロキシ接続をサポートする PowerBuilder データベース インタフェー スについての詳細は、 『データベースとの接続』マニュアルを参照して ください。 プロキシ接続を使用するには、代替ログイン名を識別するための ProxyUserName DBParm を設定します。次の例に、プロキシによる接 続方法を示します。 SQLCA.DBMS = "ODBC" SQLCA.DBParm = "CacheName='MyEAServerCache', UseContextObject='Yes',ProxyUserName='pikachu'" プロキシ接続を利用する前に コンポーネントがプロキシ接続を利用するには、事前にキャッシュ プ ロパティ ファイルでプロキシ設定の Set-proxy サポートを有効にして おく必要があります。EAServer Manager では、キャッシュ作成時には 個々のキャッシュのプロパティは自動作成されません。したがって、 こ の フ ァ イ ル は 手 動 で 作 成 す る 必 要 が あ り ま す。フ ァ イ ル に cachename.props という名前を付けて、EAServer\Repository\ConnCache ディレクトリに格納します。キャッシュのプロパティ ファイルを作成 したら、次の行を追加します。 com.sybase.jaguar.conncache.ssa=true この設定を有効にするには、EAServer を更新しなければなりません。 接続キャッシュの管理についての詳細は、 『EAServer システム管理者 ガイド』マニュアルを参照してください。 また、データベース サーバが ProxyUserName DBParm で定義した代替 ログイン名を認識して権限を与えるように設定しなければなりませ ん。 アプリケーション テクニック 519 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 接続をサポートします。 • OCI_9U – Oracle9i Unicode キャッシュ • ODBCU – ODBC Unicode キャッシュ これらの接続キャッシュ タイプは、Unicode 接続パラメータを受け 取ってから、データベース ドライバにリクエストを送信してデータ ベースへの Unicode 接続を開きます。Unicode 接続では、PowerBuilder コンポーネントは Unicode を使用してデータベースと通信できます。 EAServer 内の PowerBuilder コンポーネントで、Oracle9i データベース にアクセスするために Oracle9i ネイティブ インタフェース(O90)を 使用している場合は、接続キャッシュ用にデータベース ドライバ タイ プ OCI_9U を使用します。 520 PowerBuilder 第 24 章 EAServer コンポーネントの構築 ODBC 接続キャッシュに関しては、データベース ドライバ タイプ ODBCU を使用して、ASA Unicode データベースの複数言語データや ASA 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 型です。 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" アプリケーション テクニック 521 EAServer コンポーネントからデータベースへのアクセス 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 つの関数を提供しています。 • GetFullState • SetFullState • GetChanges • SetChanges これらの関数は分散アプリケーション上では非常に役立ちますが、複 数のデータウィンドウ(データストア)を同期させなければならない、 分散モデル以外のアプリケーションでも使用できます。 データウィンドウの バッファとステータス フラグの移動 522 クライアント上のデータウィンドウ コントロールとサーバ上のデー タストアを同期させるには、データウィンドウのデータ バッファとス テータス フラグを、データの変化が起こるたびにクライアントとサー バの間でやりとりします。これを行うための手順は、変更の原因がク ライアントにあってもサーバにあっても、本質的に同じです。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 完全な状態情報を 1 つのデータウィンドウ(またはデータストア)か ら別のデータウィンドウ(またはデータストア)に適用するには、次 の手順を実行する必要があります。 1 GetFullState 関数を呼び出して、ソース データウィンドウの現行状 態を取り込みます。 2 SetFullState 関数を呼び出して、ソース データウィンドウの状態を ターゲットに適用します。 変更を 1 つのデータウィンドウ(またはデータストア)から別のデー タウィンドウ(またはデータストア)に適用するには、次の手順を実 行する必要があります。 1 GetChanges 関数を呼び出して、ソース データウィンドウから変更 を取り込みます。 2 SetChanges 関数を呼び出して、ソース データウィンドウの変更を ターゲットに適用します。 SetChanges は空のデータウィンドウに適用できます SetChanges を呼び出して、変更を空のデータウィンドウ(またはデー タストア)に適用できます。ターゲット データウィンドウは、前の取 り出し操作の結果集合を格納する必要はありません。しかし、データ ウィンドウはデータウィンドウ定義にアクセスできなければなりませ ん。つまり、SetChanges を呼び出す前に、データウィンドウ オブジェ クトをターゲット データウィンドウに割り当てる必要があります。 データウィンドウの状 態は Blob に格納され ます GetFullState 関数または GetChanges 関数を呼び出したとき、PowerBuilder はデータウィンドウのステータス情報を Blob 型の値で返します。 GetFullState 関数から返される Blob 値は、データ バッファ、ステータス フラグ、データウィンドウの詳細な仕様など、データウィンドウの再 構築に必要なすべての情報を提供します。GetChanges 関数から返され る Blob 値は、変更あるいは削除が行われた行についてのみ、データ バッファやステータス フラグの情報を提供します。 更新後の同期 デフォルトでは、Update 関数は、更新に成功した後で更新フラグをリ セットします。したがって、サーバ上で Update 関数を呼び出した場合 には、サーバ データストアのステータス フラグは自動的にリセットさ れます。しかし、対応するクライアント データウィンドウ コントロー ルの更新フラグはリセットされません。したがって、サーバ データス トアの Update 関数が成功した場合には、クライアント データウィンド ウの ResetUpdate を呼び出して、フラグをリセットします。 アプリケーション テクニック 523 EAServer コンポーネントからデータベースへのアクセス 1 つのソース、1 つの ターゲット 1 つのソース データウィンドウ(データストア)と 1 つのターゲット データウィンドウ(データストア)との同期化が可能です。1 つのソー スを複数のターゲットに同期させたり、逆に複数のソースを 1 つの ターゲットに同期させたりしないでください。 一般的な使用シナリオ サーバに、DS_1 というデータストアを使用するコンポーネントがある とします。このデータストアは、クライアント上の DW_1 というター ゲット データウィンドウのデータのソースです。Activate イベントで は、コンポーネントはデータベースに接続し、データストアを作成し、 データストアにデータウィンドウ オブジェクトを割り当てます。 そのメソッドの 1 つで、サーバ コンポーネントは DS_1 に対する Retrieve 関数を発行し、DS_1 の GetFullState 関数を呼び出して、取得した Blob をクライアントに渡します。コンポーネントの[自動的なデマケーショ ン / 不活性化]設定が無効にされているため、メソッドが復帰する前 に SetComplete 関数も呼び出して、コンポーネント インスタンスを非 アクティブにします。 [自動的なデマケーション / 不活性化]が有効である場合 コンポーネントに対する[自動的なデマケーション / 不活性化]設定 が有効の場合には、メソッドが実行を終了した時点で、コンポーネン ト インスタンスは自動的に非アクティブにされます。したがって、取 り出しの後に SetComplete 関数を呼び出す必要はありません。 クライアントがデータウィンドウ Blob を取得すると、SetFullState 関数 を呼び出して、Blob の状態情報を DW_1 に適用します。この時点で、 ユーザは DW_1 に新しい行を挿入したり、既存の行を変更または削除 したりできます。ユーザが更新リクエストを行うと、クライアントは GetChanges 関数を呼び出し、別のコンポーネント メソッドを呼び出し て取得した Blob をサーバに戻します。次に、コンポーネント メソッド は SetChanges 関数を呼び出して、DW_1 の変更を DS_1 に適用します。 サーバ コンポーネントは、DS_1 を DW_1 に同期させてから、データ ベースを更新し、SetComplete 関数または SetAbort 関数を呼び出して、 更新に成功したかどうかを示します。 更新が成功した場合には、クライアントは ResetUpdate 関数を呼び出し て、クライアント データウィンドウのステータス フラグをリセットし ます。 524 PowerBuilder 第 24 章 EAServer コンポーネントの構築 図 24-1: 更新処理の例 最初の更新操作が完了した後、クライアントとサーバは、完全な状態 情報ではなく Blob の変更結果を互いにやりとりして、それ以降の更新 を処理できます。それ以降の更新プロセスは、手順 7 から手順 14 まで の繰り返しとなります。 例 次の例に、PowerBuilder クライアントと EAServer コンポーネントの間 で、データウィンドウの同期をとる方法を示します。この例ではステー トレス コンポーネントを使用します。 アプリケーション テクニック 525 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 クライアント ウィンドウの[更新]ボタンには、次のスクリプトがあ ります。 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 526 PowerBuilder 第 24 章 Activate EAServer コンポーネントの構築 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 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 アプリケーション テクニック 527 EAServer コンポーネントからデータベースへのアクセス Deactivate uo_employee オブジェクトの Deactivate イベントは、データストアを破 棄し、データベースから接続を解除します。 DESTROY ids_datastore DISCONNECT USING SQLCA; 結果集合の受け渡し PowerBuilder は、2 つのシステム オブジェクトを提供することによっ て、EAServer で動作しているコンポーネントから結果集合を取得し、 EAServer コンポーネントとして動作している PowerBuilder ユーザ オ ブジェクトから結果集合を返します。これらのシステム オブジェクト (ResultSet と ResultSets)は、データストア オブジェクトとの間でトラ ンザクション サーバの結果集合の相互変換を簡単にするよう設計さ れており、状態情報は含まれていません。また、データベースの更新 に使用するようには設計されていません。データストア オブジェクト との間でこれらのオブジェクトに格納された結果集合を変換するに は、データストア オブジェクトの CreateFrom 関数と GenerateResultSet 関数を使用します。 GenerateResultSet について GenerateResultSet にはもう 1 つの構文があり、 EAServer とともに MASP (Method as Stored Procedure)を 使 用 す る と き に、TDS(Tabular Data Stream)の結果集合を返すために使用されます。詳細については、 『デー タウィンドウ リファレンス』マニュアルを参照してください。 結果集合を返すコンポーネント メソッドは、TabularResults モジュール を使用します。1 つの結果集合は TabularResults::ResultSet 構造体として 返されます。複数の結果集合は、TabularResults::ResultSets データ型を 使用して、一連の ResultSet 構造体として返されます。 PowerBuilder クライ アントから EAServer コンポーネント内の結 果集合にアクセス 528 TabularResults::ResultSet を返す EAServer コンポーネント メソッドに対 して、PowerBuilder で EAServer プロキシ オブジェクトを生成した場合 には、プロキシ オブジェクトのメソッドは、PowerBuilder ResultSet オブ ジェクトを返します。複数の結果集合を返すメソッドは、PowerBuilder ResultSets オブジェクトを返します。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 オブジェクト ブラウザでプロキシを表示 PowerBuilder オブジェクト ブラウザの[プロキシ]タブでは、EAServer プロキシ オブジェクトのプロパティとメソッドを表示できます。 たとえば、Sybase Virtual University サンプルの SVUBookstore コンポー ネントには、TabularResults::ResultSet 値を返すいくつかのメソッドがあ ります。このコンポーネントの EAServer プロキシ オブジェクトを作成す ると、GetMajors メソッドは、オブジェクト ブラウザでは PowerBuilder ユーザ オブジェクト関数として次のように表示されます。 SVUBookStore.GetMajors ( ) returns ResultSet 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() ds_local = CREATE datastore ds_local.CreateFrom(lrs_resultset) EAServer コンポーネ ントから結果集合を返 す EAServer に配布される PowerBuilder ユーザ オブジェクトから結果集 合を渡したり返したりするには、関数の引数または戻り値のデータ型 に ResultSet(1 つの結果集合の場合)または ResultSets(複数の結果集 合の場合)を設定します。ユーザ オブジェクトが EAServer コンポー ネントとして配布された場合には、ResultSet と ResultSets の戻り値は、 コンポーネントの IDL インタフェースでは、TabularResults::ResultSet と TabularResults::ResultSets のデータ型として表されます。 アプリケーション テクニック 529 コンポーネント インタフェースの定義 次の例では、データストア オブジェクトを作成し、その中にあるデー タを取り出し、続いて 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 コンポーネント インタフェースの定義 インタフェースの指定 方法 EAServer は、すべてのコンポーネント インタフェースを CORBA 2.0 インタフェース定義言語(IDL: Interface Definition Language)モジュー ルに格納します。IDL は、オブジェクト マネジメント グループによっ て、コンポーネント インタフェースを定義するための標準言語として 定義されています。PowerBuilder カスタム クラス ユーザ オブジェクト を EAServer コンポーネントとして配布すると、そのオブジェクトに定 義されたメソッド(関数とイベント)とインスタンス変数がコンポー ネント インタフェースに追加されます。EAServer コンポーネント ジェ ネレータがユーザにかわって IDL を記述するため、インタフェースの ために IDL を記述する必要はありません。 インタフェースに組み 込まれるもの EAServer コンポーネント ジェネレータは、ユーザ オブジェクトに宣 言されたすべてのパブリック関数をコンポーネント インタフェース に組み込みます。さらに、コンポーネントに指定した構築オプション に応じて、ジェネレータはパブリック インスタンス変数のアクセサ メ ソッドを組み込み、ユーザ イベントをメソッドとしてエクスポーズで きます。 530 PowerBuilder 第 24 章 メソッド名とメソッド の多重定義 EAServer コンポーネントの構築 IDL はメソッドの多重定義をサポートしていません。それでも、多重 定義されたメソッドを持つ EAServer に対して、PowerBuilder カスタム クラス ユーザ オブジェクトを配布できます。IDL の制約を回避するた め、多重定義されるメソッド名に対して、コンポーネント ジェネレー タは 2 つのアンダースコア(__)と一意の接尾辞を付加します。した がって、PowerBuilder オブジェクト用に生成された IDL を調べてみる と、PowerBuilder で多重定義されたメソッドに接尾辞が付加されてい ることがわかります。 多重定義されたメソッドを持つコンポーネントにスタブまたはプロキ シ オブジェクトを生成すると、クライアントが正しい名前を使用して メソッドにアクセスできるように、EAServer は IDL の接尾辞を取り除 きます。 IDL についての詳細は、EAServer のマニュアルを参照してください。 メソッド名には 2 つの連続したアンダースコアを使用しないでください EAServer は 2 つのアンダースコア(__)を予約区切り記号として扱う ため、EAServer コンポーネントとして配布する予定のカスタム クラス ユーザ オブジェクトの関数名には、2 つの連続したアンダースコアを 使用しないでください。 データ型 EAServer コンポーネントとして配布するユーザ オブジェクトのイン タフェースでは、以下のデータ型を使用できます。 • 標準のデータ型(Any データ型を除く) • 構造体 • EAServer コンポーネントとして配布されたカスタム クラス(非ビ ジュアル)ユーザ オブジェクト これらのデータ型は、パブリック インスタンス変数に限らず、パブ リック メソッドの戻り値と引数にも使用できます。プライベート型と プロテクト型のインスタンス変数とメソッドでは、PowerBuilder がサ ポートするすべてのデータ型を使用できます。 コンポーネントのパブリック インタフェースでは、Any 型はサポート されていません。さらに、ResultSet と ResultSets のオブジェクトを除 いて、コンポーネント インタフェースは、組み込みの PowerBuilder シ ステム オブジェクト(たとえば、トランザクション オブジェクトや データストア オブジェクト)を実装できません。コンポーネント イン タフェースに実装できないものとしては、それ以外にビジュアル オブ ジェクト(ウィンドウやメニューなど)もあります。 アプリケーション テクニック 531 コンポーネント インタフェースの定義 コンポーネント メソッドは、標準データ型の配列と構造体の配列を渡 し、カスタム クラス ユーザ オブジェクトを使用して配列を渡せます。 EAServer で使用されるデータ型、各データ型の対応する CORBA IDL、 および各データ型がマッピングされる PowerBuilder のデータ型のリス トについては、 『PowerScript リファレンス』マニュアルまたはオンラ イン ヘルプを参照してください。 参照渡し 引数を参照によってコンポーネント メソッドに渡せます。しかし、分 散アプリケーションと分散モデル以外のアプリケーションでは、動作 がいくぶん異なります。 参照で渡す場合には、メソッドが実行される前に変数が実際にサーバ にコピーされ、その後、メソッドが実行を完了したときにコピーして 戻されます。通常、この動作はアプリケーションからは透過的ですが、 場合によっては処理結果に影響を与えることもあります。 たとえば、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 つのコ ピーを渡して、別々にインクリメントするためです)。 読み込み専用値を渡す オブジェクトを渡す 532 読み込み専用の値を渡すときの動作は、データを変更できないことを 除けば、値渡しに似ています。データのコピーが、ネットワークを介 してサーバに渡されます。 EAServer コンポーネント内で作成されたオブジェクトをクライアント に戻すことは可能ですが、この場合はこれらのオブジェクトがインス トール済みの EAServer コンポーネントでなければなりません。EAServer コンポーネントではない PowerBuilder オブジェクトを戻そうとした場 合は、実行時エラーが出力されます。サーバから戻されたコンポーネ ントを使用するには、クライアントには、対応する EAServer プロキシ (PowerBuilder クライアントの場合)またはスタブ(非 PowerBuilder ク ライアントの場合)が必要です。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 クライアント アプリケーションは、PowerBuilder オブジェクト参照を EAServer に渡せません。したがって、PowerBuilder オブジェクト参照 を使用しても、サーバから PowerBuilder クライアントへのメッセージ のプッシュは実行できません。しかし、クライアント上の共有オブジェ クトを使用して EAServer と通信することによって、この動作をシミュ レートすることは可能です。 サーバ プッシュをシミュレートするには、クライアントは、 SharedObjectRegister 関数と SharedObjectGet 関数を使用して、共有オブ ジェクトを作成します。オブジェクトが作成されると、クライアント から共有オブジェクトにメソッドをポストして、サーバ上で処理終了 時に通知しなければならないコールバック オブジェクトを渡せます。 共有オブジェクトのメソッドは、処理を行う EAServer コンポーネン ト メソッドの同期呼び出しを行います。共有オブジェクトはクライ アント上の独立したスレッドで動作しているため、サーバ上でプロセ スを実行しながら、クライアント アプリケーションがほかの作業を 続行できます。 NULL 値のサポート PowerBuilder では、EAServer コンポーネントのメソッドが NULL 値を 関数引数として受け取るか、戻り値の型として受け取るかを指定でき ます。コンポーネント インタフェースで NULL 値をサポートするには、 EAServer コンポーネントの生成に使用されたプロジェクトのプロパ ティ シートで、 [NULL 値をサポート]チェックボックスをオンにしま す。このボックスがオフである場合には、クライアントはどの引数に も NULL 値を渡せないため、サーバは、引数に NULL を設定したり NULL 値を返せません。 コンポーネント メソッドのプロトタイプで NULL 値を許可する場合、 PowerBuilder はプロジェクト ペインタから生成する EAServer プロキ シのメソッド名に "_N" 接尾辞を追加します。このメソッドを呼び出す には、NVO のインスタンスではなく、プロキシのインスタンスを作成 する必要があります。そして、"_N" 接尾辞を持つメソッドを参照する 必要があります。たとえば、of_gen が NVO のメソッド名で、NULL 戻 り値を許可する EAServer プロキシを作成する場合は、プロキシのイン スタンスを作成し、of_gen_N を呼び出してこのメソッドを使用する必 要があります。 EAServer 検証 EAServer コンポーネントとして配布する予定のカスタム クラス ユー ザ オブジェクトを設計している場合には、EAServer で無効なコード要 素が使用されたときに、PowerBuilder で警告を出すようにできます。 EAServer 検証では、パブリック インスタンス変数とパブリック関数の システム タイプ、ビジュアル タイプ、構造体、および変数をチェック します。 アプリケーション テクニック 533 既存インタフェースの実装 EAServer 検証は、EAServer ウィザードを使用してユーザ オブジェクト を作成した場合には、デフォルトでオンになっています。チェックす るには、ユーザ オブジェクト ペインタの[デザイン]メニューを選択 し、 [EAServer 検証]がオンになっていることを確認します。オブジェ クトを保存すると、出力ウィンドウに以下のような警告が一覧表示さ れます。 ---------- コンパイラ : 情報メッセージ 情報 C0197: コンポーネント検証 警告 C0198: 適切でない Jaguar タイプ : 'window' arg type for function: 'of_badfunc' 警告 C0198: 適切でない Jaguar タイプ : 'any' return type for function: 'of_badfunc' 検証は、ユーザ オブジェクト ペインタではなく、編集中のオブジェク トに関連付けられます。オブジェクトを再び開くと、オブジェクトの 検証状態は閉じたときと同じになります。 例外の送出 EAServer に配布するユーザ オブジェクトの関数で例外を宣言すると、 その例外はメソッドのプロトタイプの一部として、CORBA IDL に変換 されます。例外は、任意の種類の EAServer クライアント アプリケー ションまたは呼び出したコンポーネントで処理できます。詳細につい ては、39 ページの「PowerBuilder での例外処理」を参照してください。 既存インタフェースの実装 新規作成 ダイアログボックスの[ターゲット]タブまたは[PB オブ ジェクト]タブの EAServer コンポーネント ウィザードを使用して、既 存インタフェースの PowerBuilder の実装を作成できます。この機能は 一般的には、Financial Fusion の CORBA IDL テンプレートとして提供 される、オンライン バンキングや証券取引のプロトコルなどの標準 API の実装を作成するのに使用されます。 インタフェースの選択 534 ウィザードの[インタフェース実装の指定]ページで[既存の EAServer リモート インタフェースを実装する]を選択し、次に、実装したい IDL インタフェースが保存されているサーバの EAServer プロファイ ルを選択します。ウィザードでパッケージのリストを拡張したときに 表示されるリストから、インタフェースを 1 つだけ選択できます。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 PowerBuilder コンポーネントの場合、普通、インタフェース名はコン ポーネント名と同じですが、インタフェースのリストがそのままサー バ上のコンポーネントのリストにマッピングされるわけではありませ ん。リストには、タイプ インタフェースのすべての IDL モジュールが 含まれます。EAServer Manager では、これらのモジュールは、左側の ペインの IDL フォルダのパッケージ名をクリックしたときに右側のペ インに表示されます。 ウィザードのオプショ ンの設定 実装するインタフェースを選択したら、コンポーネントの EAServer 名 を入力します。PowerBuilder カスタム クラス ユーザ オブジェクトの名 前は変更できません。この名前は常に、リモート インタフェースの名 前と同じになります。新規インタフェース作成時のように、パッケー ジ名、インスタンス プーリングなど、そのほか多くのオプションを設 定できます。 標準 API の PowerBuilder の実装を作成している場合、普通はリモート コンポーネントのコンポーネント名を使用しますが、同じパッケージ 名を使用してはいけません。 リモート コンポーネントのインタフェースは変更できないため、引数 に NULL 値をサポートするなど、メソッドのシグネチャが変更されて しまうようなオプションは、ウィザードでは設定できません。 ペインタでのユーザ オブジェクトの編集 ウィザードで作成したカスタム クラス ユーザ オブジェクトでは、リ モート インタフェースのパブリック属性はパブリック インスタンス 変数として表され、パブリック メソッドはパブリック関数として表さ れます。関数のスクリプトには、コンパイル エラーが発生しないよう に return ステートメントが格納されていますが、それぞれの関数を実 装するスクリプトを提供する必要があります。リモート インタフェー スにほかにも依存する要素(構造体など)が含まれている場合、ウィ ザードはユーザ オブジェクトと同じ PBL でそれらを作成します。 ユーザ オブジェクトは、ほかのカスタム クラス ユーザ オブジェクト と同様に編集できます。ユーザ オブジェクト ペインタで制約を適用さ れることはありません。ただし、インタフェースに影響するような変 更を行ってはいけません。既存インタフェースの属性とメソッドに対 応するインスタンス変数や関数を削除したり、そのモードをパブリッ クからプライベートやプロテクトに変更しないでください。関数は オーバーロードできません。また、戻り値か引数には NULL 値を使用 できません。 EAServer へのコン ポーネントの配布 ウィザードによって作成されたプロジェクトには、ウィザードがコン ポーネントを構築したインタフェースに関する情報が格納されていま す。プロジェクトを実行すると、PowerBuilder は次のことをチェック します。 アプリケーション テクニック 535 別のサーバ コンポーネントのメソッドの呼び出し • 既存 IDL インタフェースのすべてのパブリック属性とメソッド が、ユーザ オブジェクトのパブリック インスタンス変数や関数と して定義されている • IDL インタフェースで定義されたメソッドが、ユーザ オブジェク トでオーバーロードされていない これらのチェックのいずれかが失敗した場合、コンポーネントは配布 されますが、プロジェクト ペインタと出力ウィンドウに警告が表示さ れます。 異なるプロジェクトの 使い方 これらのチェックは、コンポーネント作成時に作成されたプロジェク トを使用してコンポーネントが配布された場合のみ実行されます。新 しいプロジェクトを作成したり、別のプロジェクトにコンポーネント を追加した場合は、プロジェクト実行時にはチェックは実行されませ ん。 コンポーネントと一緒に作成されたプロジェクトを使用して配布する と、新規の実装は常にサーバ上の既存の IDL を使用します。別のプロ ジェクトを使用する場合は、コンポーネントをオリジナル パッケージ に配布して、インタフェースの変更に関する警告なしに既存 IDL を上 書きすることがあるため、注意が必要です。 プロキシの生成 既存インタフェースを実装するオブジェクトのプロキシを生成し、 サーバの既存 IDL を使用するときは、プロキシは既存 IDL に基づきま す。結果として、[EAServer パッケージ名をオブジェクト名の前に追 加]オプションを選択すると、オブジェクト名に付く名前は、新しい パッケージの名前ではなく IDL モジュールの名前になります。 別のサーバ コンポーネントのメソッドの呼び出し EAServer では、サーバ コンポーネントのメソッドを使って、ほかの サーバ コンポーネントのメソッドを呼び出せます。呼び出される側の サーバ コンポーネントは、PowerBuilder コンポーネントである必要は なく、EAServer によってサポートされる言語で実装されているコン ポーネントでもかまいません。 536 PowerBuilder 第 24 章 現行のサーバのコン ポーネントにアクセス EAServer コンポーネントの構築 現行のサーバにある別の EAServer コンポーネントのメソッドにアク セスするには、PowerBuilder クライアントの場合と同じように、接続 オブジェクトを使用してコンポーネントと通信します。あるいは、 PowerBuilder が提供する、TransactionServer というトランザクション サービス コンテキスト オブジェクトを使用します。TransactionServer インタフェースが提供する CreateInstance というメソッドを使用すれ ば、ローカルで使用するほかのコンポーネントにアクセスできます。 CreateInstance は、呼び出し元のコンポーネントに適用されるものと同 じユーザ情報とパスワード情報を使用します。 トランザクション コンテキスト サービスを使用するには、 TransactionServer 型の変数を宣言し、GetContextService 関数を呼び出し てから、トランザクション コンテキスト サービスのインスタンスを作 成します。 例 コンポーネントの Activate イベントで GetContextService を呼び出 して、TransactionServer サービスをインスタンス化できます。 // インスタンス変数: // TransactionServer ts Integer rc rc = this.GetContextService("TransactionServer", ts) IF rc <> 1 THEN // エラー処理 END IF いずれかのコンポーネント メソッドから、CreateInstance を呼び出して 2 番目のコンポーネントをインスタンス化し、そのメソッドの 1 つを 呼び出せます。 // 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 を呼び出します。 アプリケーション テクニック 537 別のサーバ コンポーネントのメソッドの呼び出し EJB コンポーネント へのアクセス PowerBuilder コンポーネントは、接続オブジェクトまたは TransactionServer オブジェクトのいずれかの Lookup メソッドを使用し て、EJB コンポーネントにアクセスできます。TransactionServer オブ ジェクトの Lookup メソッドには、オプションとして、ホーム インタ フェースの名前を指定するための第 3 引数があります。この引数は、 ホーム インタフェース名が一般的な命名規約に従わない場合のみ使 用します。 このスクリプトは、Cart コンポーネントをインスタンス化し、い くつかのコンポーネント メソッドを呼び出します。次の例では、Lookup メソッドの第 2 引数に、コンポーネント名と EAServer パッケージ名を 指定しています。 例 // インスタンス変数 : //Connection myconnect CartHome MyCartHome // EJB のホーム インタフェース 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 コンポーネントへのアクセスにつ いては、570 ページの「EJB コンポーネント メソッドの呼び出し」を 参照してください。 コンポーネントを区別 するトランザクション [OTS スタイル]としてマークされた EAServer コンポーネントは、 CORBACurrent コンテキスト サービス オブジェクトの関数を使用し て、EAServer トランザクションに関する情報の作成、制御、および取 得が行えます。CORBACurrent オブジェクトは、CORBACurrent インタ フェース用に定義された数多くのメソッドを備えています。 詳細については、580 ページの「クライアントとコンポーネントを区 別するトランザクション」を参照してください。 538 PowerBuilder 第 24 章 EAServer コンポーネントの構築 コンポーネント プロパティへのアクセス ContextKeyword サー ビス オブジェクト ContextKeyword サービス オブジェクトを使用して、コンポーネントの プ ロ パ テ ィ 値 を 取 得 で き ま す。プ ロ パ テ ィ 値 を 取 り 出 す に は、 GetContextKeywords 関数を呼び出します。 ContextKeyword サービス オブジェクトを使用するには、 GetContextService 関数を呼び出し、サービス名として Keyword を使用 してから、オブジェクトへの参照を作成します。 PowerBuilder の EAServer プロパティ 次の表に、EAServer コンポーネントとして動作する PowerBuilder カス タム クラス ユーザ オブジェクトに関係するコンポーネント プロパ テ ィ を 示 し ま す。コ ン ポ ー ネ ン ト プ ロ パ テ ィ の 前 に は、文 字 列 com.sybase.jaguar.component が付けられます。EAServer Manager の コンポーネントのプロパティ ダイアログボックスの[すべてのプロパ ティ]タブには、すべてのコンポーネント プロパティの値が表示され ます。表 24-7 に示すように、いくつかのプロパティは、このダイアロ グボックスのほかのタブの項目にもマップされます。 表 24-7: PowerBuilder コンポーネントの EAServer コンポーネント プロパ ティ プロパティ auto.failover bind.thread code.set 説明 サーバが使用できなくなったときにコンポーネントを代替サーバ に転送するためのクライアント プロキシを有効にする 表示位置 トランザクショ ン(自動フェイ このプロパティは、[自動的なデマケーション / 不活性化]が有効 ルオーバ) でなければ有効にできない 自動フェイルオーバでは、冗長サーバでアプリケーションのコン ポーネントを実行できるように、アプリケーションがサーバのク ラスタを使用する必要がある。クラスタは最低 1 つのネーム サー バを含み、クライアントはネーミング サービスを使用してプロキ シ参照を解決しなければならない。詳細については、 『EAServer シ ステム管理者ガイド』マニュアルの「ロード・バランシング、フェ イルオーバ、およびコンポーネントの可用性」を参照 作成するスレッド上でコンポーネント インスタンスを常に起動さ インスタンス せるかどうかを指示する (スレッドのバ 有効な値は TRUE と FALSE である。ライブ編集の場合には、この インド ) プロパティを TRUE に設定しなければならないが、それ以外の場合 は、スケーラビリティを向上させるために FALSE に設定する必要 がある コンポーネントが使用するコード化文字セットの名前を指定する すべてのプロパ デフォルトでは、コンポーネントはサーバのコード化文字セット ティ (サーバのプロパティ ウィンドウの[一般]タブで指定)を使用す る。ヨーロッパ言語またはアジア言語では、このプロパティを iso_1 または big5 などの値に設定しなければならない場合がある アプリケーション テクニック 539 コンポーネント プロパティへのアクセス プロパティ interfaces minpool maxpool name 説明 コンポーネントが実装するインタフェースを識別する すべてのプロパ これは、IDL インタフェース名をカンマで区切ったリストであり、 ティ それぞれのインタフェース名は module::interface という書式と なる インスタンス プーリングが有効のときは、プールできるインスタ リソース ンスの最少数を指定する プールから休止中のインスタンスを解放するため、EAServer には 定期的に実行されるガベージ コレクタ スレッドがある。このス レッドが実行されるたびに、ガベージ コレクタは、休止中のイン スタンスを 1 つプールから削除する。ただし、プールが最小サイ ズに到達したときは削除されない。デフォルトは 0 インスタンス プーリングが有効のときに、プールできるインスタ リソース ンスの最大数を指定する プール サイズの最大値に到達した場合、EAServer は非アクティブ 化後に過剰インスタンスを破棄する。デフォルトは 0 で、最大プー ル サイズが有効でないことを意味する コンポーネントの名前を指定する この値の書式は package/component でなければならない pb.appname pb.class pb.cookie debug pb.librarylist pb.live_edit pb.trace pb.version 540 表示位置 一般(コンポー ネント部のみ) PowerBuilder アプリケーションの名前を指定する 一般 PowerBuilder カスタム クラス ユーザ オブジェクトの名前を指定す 一般 る すべてのプロパ ライブラリ リストのパスの作成に使用する数を提供する ティ パスの書式は次のとおり Repository\Component\package\component\Ccookie PowerBuilder デバッガでコンポーネントをデバッグできるかどう すべてのプロパ かを示す ティ PowerBuilder ライブラリ リストを指定する 一般 ライブラリ名の前に円記号(\)が付いている場合は、その位置は EAServer Repository ディレクトリからの相対指定であるとみなさ れる。ライブラリ名の前に円記号が付いていない場合は、その名 前は絶対パスを指定するとみなされる プロジェクト ペインタではなく、ユーザ オブジェクト ペインタで すべてのプロパ プロジェクトを構築できるかどうかを指定する ティ 545 ページの「ライブ編集」を参照 コンポーネントに対するログ収集動作のトレース オプションを指 定する(現在無効) コンポーネントが作成された PowerBuilder のバージョンを指定す る すべてのプロパ ティ すべてのプロパ ティ PowerBuilder 第 24 章 プロパティ pooling EAServer コンポーネントの構築 説明 コンポーネントがプールされているかどうかを示す 表示位置 インスタンス pooling プロパティに TRUE が設定された場合は、コンポーネント は常にプールされ、CanBePooled イベントは発生しない。pooling プ ロパティに FALSE が設定された場合は、CanBePooled イベントが 発生するため、プーリングの拒否を選択できる sharing tx_vote プロパティに FALSE が設定された場合は、各メソッドの後 でコンポーネントがプールされる。それ以外の場合は、トランザ クションの最後にプールされる 共有コンポーネントであるかどうかを示す インスタンス sharing プロパティに TRUE が設定された場合は、すべてのクライ アントが 1 つのコンポーネント インスタンスを共有する。共有コ ンポーネントにプーリング オプションは適用されない 共有コンポーネントをサービスにするには、 com.EAServer.server.services プロパティ用に指定したサービスのリ ストに共有コンポーネントを追加する state state.gs 自動的な永続格納を使用するときに、IDL 型の名前を指定する 永続性 PowerBuilder では、名前の付いている型はユーザ定義の構造体で、 永続するすべてのデータをカプセル化しなければならない。 [永続 性]タブ ページで[自動永続状態]を選択し、[状態]テキスト ボックスに構造体の名前を入力して[OK]をクリックすると、ペー ジ上にあるほかのプロパティがデフォルト値に設定される。自動 的な永続格納を使用する場合、PowerBuilder コンポーネントのス テートフル フェイルオーバがサポートされる。詳細については、 『EAServer プログラマーズ・ガイド』マニュアルの「コンポーネン トの永続状態の管理」の章を参照 state データ型を取得し設定する state 構造体のメソッド名で、2 項 永続性(State メ 目のカンマ区切りのリストとして指定される ソッド) デフォルトは getState、setState stateless EJB セッション Beans と、コントロール インタフェース CtsComponents::ObjectControl を使用する非 EJB コンポーネントの みに適用される インスタンス このプロパティを設定すると、tx_vote プロパティを FALSE に設定 するのと同じ結果になるが、activate イベントと deactivate イベント も無効になる。コンポーネントをステートレスに指定する場合は、 このプロパティを設定しないこと。かわりに、pooling を TRUE に、 tx_vote を FALSE に設定する アプリケーション テクニック 541 コンポーネント プロパティへのアクセス プロパティ storage 説明 表示位置 リモート データベース サーバからコンポーネントの状態情報を読 永続性(スト み書きするコンポーネントの名前を指定する レージ・コン 自動的な永続格納を使用するとき、または EAServer の組み込み格 ポーネント、接 納コンポーネントに実装を任せてコンポーネント管理による永続 続キャッシュ、 テーブル) 性使用するときに必要となる。デフォルトは CtsComponents/JdbcStorage thread.safe timeout tx_outcome また、格納コンポーネントが使用する接続キャッシュとテーブル を指定する 複数の呼び出しを同時に処理できるかどうかを示す インスタンス 詳細については、501 ページの「Concurrency プロパティ」を参照 (同時実効性) メソッド呼び出しの後、次のメソッド呼び出しまでの間に、アク ティブなコンポーネント インスタンスが自動的に非アクティブに されずにアイドル状態でいられる時間を指定する トランザクションがロールバックされたときに、 CORBA::TRANSACTION_ROLLEDBACK 例外をクライアントに送 出するかどうかを決定する リソース(イン スタンス・タイ ムアウト) すべてのプロパ ティ 以下の設定を使用できる always デフォルト。トランザクションがロール バックされる と、サーバからクライアントに例外が送出される • failed トランザクションがロール バックされても、クライアント に例外が送出されない。この設定を使用する場合、RollbackWork トランザクション プリミティブを呼び出した後で説明メッセー ジ付きの別の例外を発生するように、コンポーネントをコー ディングできる • failed 設定を有効にしても、コンポーネントのリクエストによるト ランザクションをコミットできない場合は、CORBA システム例外 が送出されることがある tx_timeout 542 ロールバックされたトランザクションの例外をクライアントに送 りたくない場合や、別の例外を送出する必要がある場合、このプ ロパティを failed に設定できる。この設定は、トランザクションが ロールバックされた後で、クライアントが出力パラメータを得ら れるようにする必要のある場合に役立つ。例外が送出される場合 は、出力パラメータを使用できない EAServer トランザクションの最大継続時間を指定する リソース(トラ ンザクション・ 各メソッドが復帰した後でタイムアウトがチェックされる タイムアウト) PowerBuilder 第 24 章 プロパティ tx_type EAServer コンポーネントの構築 説明 表示位置 EAServer トランザクションに対するコンポーネントの関与を示す トランザクショ ン 有効な値は、以下のとおり • not_supported • supports • requires • requires_new • mandatory • user-managed • never tx_vote type コンポーネントで自動的なデマケーション/不活性化をサポートす トランザクショ ン([自動分離 / るかどうかを示す 非アクティブ tx_vote に TRUE が設定された場合は、コンポーネントは、 化]チェック TransactionServer サービス オブジェクトのメソッドを明示的に呼 び出すことによって、トランザクション状態とコンポーネントの ボックスがオン である場合は、 非アクティブ化を制御する必要がある このプロパティ tx_vote に FALSE が設定された場合は、各メソッド呼び出しの後で、 の値は FALSE) EAServer は コ ン ポ ーネントを自動的に非アクティブにする。 SetComplete はデフォルトで呼び出されるため、SetComplete を明示 的に呼び出して非アクティブにする必要はない。SetAbort を呼び出 せば、デフォルト状態に上書きできる コンポーネントのタイプを指定する 一般 EAServer は PowerBuilder オブジェクトのプロパティを pb に設定す る Web サービスとしての NVO のエクスポーズ EAServer コンポーネント ウィザードでは、生成されるコンポーネント を Web サービスとしてエクスポーズできます。 このウィザードの[EAServer コンポーネントを Web サービスとしてエ クスポーズ]ページには、生成されたコンポーネントを EAServer 5.0 で Web サービスとして設定したり一覧表示したりするためのチェッ クボックスと 3 つのテキスト ボックス フィールドがあります。表 248 にこれらのフィールドを示します。これらのフィールドは、[Web サービスとしてコンポーネントをエクスポーズする]チェックボック スをオンにすると有効になります。 アプリケーション テクニック 543 Web サービスとしての NVO のエクスポーズ 表 24-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 コンポーネントにある場合、EAServer 5 では、そのコ ンポーネントを Web サービスとしてエクスポーズできません。「Can't find prefix for 'http://DefaultNamespace'」といったエラー メッセージが表 示されます。 544 PowerBuilder 第 24 章 EAServer コンポーネントの構築 コンポーネントのテストとデバッグ この節では、コンポーネントをテストするための 3 つの方法について 説明します。 • ライブ編集 • リモート デバッグ • EAServer ログへのメッセージ出力 EAServer コンポーネントのトラブルシューティング コ ン ポ ー ネ ン ト の ト ラ ブ ル シ ュ ー テ ィ ン グ に つ い て の 詳 細 は、 EAServer の『トラブルシューティング ガイド』マニュアルを参照して ください。 ライブ編集 コンポーネントをテストまたはデバッグするには、ライブ編集という PowerBuilder の機能を利用すれば、ユーザ オブジェクト ペインタでプ ロジェクトを自動的に作成できます。ライブ編集が有効であれば、対 応 す る ユ ー ザ オ ブ ジ ェ ク ト を 保 存 す る た び に、PowerBuilder は EAServer コンポーネントのプロジェクトを作成します。ジェネレータ は、EAServer に PBD を配布しないかわりに、必要なオブジェクト定義 を含む PBL へのアクセス方法を EAServer に指示します。 サービス コンポーネント ライブ編集を利用しても、サービス コンポーネントとしてセットアッ プしたコンポーネントはテストできません。サービス コンポーネント は、サーバの稼動中は常に使用されているため、ユーザ オブジェクト ペインタで行った変更の保存はできません。 ライブ編集を有効にす る方法 ユーザ オブジェクトのライブ編集を有効にするには、次の手順を実行 する必要があります。 1 EAServer コンポーネントを生成したいユーザ オブジェクトを含む プロジェクトを作成します。 EAServer への配布を可能にする既存の PBL を使用したり、新規プ ロジェクトを作成してテスト用に使用したりできます。 アプリケーション テクニック 545 コンポーネントのテストとデバッグ 2 必要に応じて、プロジェクトのライブ編集ライブラリ リストを修 正します。 リモート マシン上にあるサーバでコンポーネントをテストしてい る場合には、PBL の位置を EAServer に通知する必要があります。 このためには、プロジェクト ペインタで、コンポーネントのプロ パティ シートにある[高度なオプション]ページ(下図参照)の ライブラリ リストを修正します。 ここで指定するライブラリ リストは、Universal Naming Convention (UNC)名を使用する、絶対パス名を含んでいる必要があります。 UNC 名の書式は \\servername\sharename\path\file です。 デフォルトでは、ライブ編集ライブラリ リストは、アプリケーショ ン ライブラリ リストに基づいています。使用しているサーバが ローカルである場合には、ライブ編集ライブラリ リストを修正す る必要はありません。 3 ユーザ オブジェクト ペインタで、コンポーネントの生成に使用す るプロジェクトを指定します。 プロジェクト名は、 [EAServer プロジェクト]フィールドに入力し ます。このフィールドは、ユーザ オブジェクト プロパティ シート の[全般]プロパティ ページ(下図参照)にあります。 指定するプロジェクト名は、以下の要件を満たす必要があります。 546 • EAServer コンポーネント プロジェクトであること • ユーザ オブジェクト ペインタで現在開いているユーザ オブ ジェクトを含んでいること • プロジェクトのライブラリ リストは、現行のアプリケーショ ン ライブラリ リストと一致すること PowerBuilder 第 24 章 EAServer コンポーネントの構築 コンポーネントの生成 方法 ユーザ オブジェクト ペインタで EAServer コンポーネントを生成する には、 [ファイル|上書き保存]を選択します。 コンポーネントを生成 すると何が起きるか ユーザ オブジェクト ペインタでプロジェクトを作成すると、以下の処 理が行われます。 • 保存した非ビジュアル オブジェクトを記述する 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 にコンポーネントを配布しても、コンポーネントを デバッグできます。 アプリケーション テクニック 547 コンポーネントのテストとデバッグ ライブ編集についての詳細は、545 ページの「ライブ編集」を参照し てください。 コンポーネントをデ バッグするための準備 デバッガの起動 リモート コンポーネントのデバッグを始める前に、ご使用の構成が以 下の条件を満たすかどうかをチェックしてください。 • 配布されるコンポーネントの開発に使用したものと同じバージョ ンのアプリケーションと PBL を使用している。配布された複数の コンポーネントを同じセッション内でデバッグしたい場合には、 それらのコンポーネントは、すべて同じバージョンの PBL、同じ アプリケーション名、および同じライブラリ リストを使用して作 成されたものでなければならない • プロジェクト ペインタのコンポーネント プロパティのページで、 [リモート デバッグをサポート]チェックボックスがオンになって いる。デバッグ オプションを設定するには、プロジェクト ウィ ザードで[リモートデバッグをサポート]チェックボックスをオ ンにする方法もある • 配布されたコンポーネントに含まれるメソッドとプロパティを実 行するクライアント アプリケーションがある。このアプリケー ションとしては、互換性のある開発ツールで作成されたコンパイ ル済みの実行ファイル、または別の PowerBuilder セッションで実 行されている PowerBuilder アプリケーションでもよい デバッグを始めるには、配布されたコンポーネントを含むターゲット を開きます。ペインタバーの[リモートを開始]ボタンをクリックし、 ウィザードを完了します。選択できるコンポーネントは、PowerBuilder で[リモート デバッグ をサポート]をオンにして生成されたコンポー ネントだけです。 [リモート デバッグをサポート]はセキュリティ設 定の 1 つであり、コンポーネントにデバッグ情報を追加しません。コ ンポーネントをテストするときに[リモート デバッグをサポート]を オンにします。コンポーネントをユーザのサイトに配布するときには、 [リモート デバッグをサポート]をオフにして、ユーザにコードがわ からないようにします。 ローカル アプリケーションをデバッグするときのようにブレークポ イントを設定してから、リモート コンポーネントを呼び出すクライア ント アプリケーションを起動します(まだ実行されていない場合)。 548 PowerBuilder 第 24 章 ローカル デバッグと の違い EAServer コンポーネントの構築 ローカル アプリケーションとリモート アプリケーションのデバッグ には、2 つの主な違いがあります。 • • デバッガを起動しても、デバッガは最小化されない 新規インスタンス ビューには、デバッグ中のコンポーネントの各 インスタンスが表示される。インスタンスごとに、コンポーネン ト名とパッケージ名、インスタンス番号、およびその現在の状態 (アイドル、実行中、または一時停止)が表示される。複数のイン スタンスがある場合には、現在デバッグ中のインスタンスが黄色 の矢印で示される サポートされていない機能 メモリ内のオブジェクト ビュー、式の評価、および変数値の変更はサ ポートされていません。 状態について インスタンス ビューには、コンポーネントごとに各インスタンスの状 態が示されます。 • コンポーネントは休止中か、インスタンス プール内にあ アイドル る コンポーネントは、現在コードを実行している • 実行中 • 一時停止 コンポーネントはブレークポイントで一時停止して、デ バッガ操作を待機している インスタンスが破棄されると、インスタンス ビューから取り除かれま す。 複数のインスタンス 同時に複数のコンポーネント インスタンスを一時停止させることは 可能ですが、デバッガで行う操作は、ブレークポイントに到達した最 初のインスタンスにだけ作用します。このインスタンスは、インスタ ンス ビューの黄色の矢印によって示されます。メソッドが完了する か、[実行の継続]をクリックした場合には、現行のインスタンスは キュー内の次のインスタンスに変わります。 インスタンス ビューで新規インスタンスをダブルクリックしても、1 つのインスタンスから別のインスタンスにコンテキストを変更できま す。別のコンポーネント インスタンスへの呼び出しを除いて、インス タンス ビューに呼び出されたインスタンスが一時停止したことが示 されている場合には、この方法を利用できます。 アプリケーション テクニック 549 データの印刷 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 で動作している場合は、データストア を使用してデータをリモート サーバに印刷できます。 550 PowerBuilder 第 24 章 EAServer コンポーネントの構築 プラットフォームに関する注意 次の例は、HP-UX または AIX 上では機能しません。これらのプラット フォームでは、EAServer が Windows の機能を利用しない PowerBuilder 実行環境を使用するため、印刷などのグラフィック処理はサポートし ていません。データストア印刷関数を使用した印刷は、現在 Solaris だ けでサポートしています。ただし、SaveAs 関数と PDF SaveAsType を 使用すれば、データストア オブジェクトをすべての UNIX プラット フォームで印刷できます。 詳細については、555 ページの「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 で印刷する場合、印刷結果は、データウィンドウ オブジェ クトで定義したフォントとレイアウトになります。 アプリケーション テクニック 551 データの印刷 スペース 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 環境変数の作成を行わなければなりません。 プリンタへのアクセス の追加 552 ルート ユーザで、Solaris admintool ユーティリティを使用して Solaris 上 のプリンタへのアクセスを追加します。詳細については、Solaris のマ ニュアルを参照してください。 PowerBuilder 第 24 章 dwprint.ini の設定 EAServer コンポーネントの構築 $EAServer/bin ディレクトリの dwprint.ini ファイルは、データウィンド ウ印刷用の環境設定ファイルです。このファイルは、Microsoft Windows のプリンタ環境設定方法に厳密に従っています。その結果、このファ イルには[windows] 、 [devices]、 [ports]の各セクションが用意されて おり、各セクションにプリンタの適切なエントリを指定しなければな りません。 通常、このファイルのほかのセクションを変更する必要はありません。 ただし、いくつかの問題を解決するために、ほかのセクションの追加 または変更を行います。たとえば、[intl]セクションに次のようなエ ントリを追加して日付形式を変更できます。 [intl] sShortDate=m/d/yyyy // 4 桁の年を設定します。 dwprint.ini 内のエントリは、.WindU ファイル内のエントリに基づいて います。このファイルの設定方法についての詳細は、Wind/U User’s Guide のサイト http://www.bristol.com/support/windu/wu_ug/ch13.htm を参照してく ださい。 ポートの指定 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: = アプリケーション テクニック 553 データの印刷 プリンタの種類を定義 済みのポートに合わせ る [devices]セクションには、現在設定されているすべてのプリンタのリ ストを記述します。各行には、プリンタのユーザ定義のエリアス、お よび 3 つの引数としてプリンタ機種、プリンタ モード(PCL4、PCL5、 または PostScript)、プリンタが接続されている 1 つまたは複数のポー トが記述されます。 プリンタ機種は、プリンタで使用されるプリンタ記述ファイル(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: 554 PowerBuilder 第 24 章 プリンタ オプション の設定 EAServer コンポーネントの構築 dwprint.ini ファイルには、 [windows]、 [devices]、 [ports]の各セクショ ンで定義した機種ごとに環境設定セクションを記述しなければなりま せん。環境設定セクションでは、部数、印刷の向き、ページ サイズ、 DPI などの、プリンタのデフォルト設定情報を指定します。 たとえば、先ほどの例で使用された color_lj プリンタの場合は、次のよ うに環境設定セクションを追加します。 [color_lj,PostScript] 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 の印刷機能を利用して印刷でき ます。 アプリケーション テクニック 555 EAServer へのコンポーネントの配布 GNU Ghostscript distiller の使い方 GNU Ghostscript distiller を使用するには、Ghostscript ファイルおよびデ フォルト PostScript プリンタ ドライバと関連ファイルをサーバ上の PowerBuilder ランタイム ファイルと同じディレクトリにインストール しておく必要があります。Ghostscript メソッドは、UNIX ではサポート されていません。 XSL-FO の使い方 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 上で稼動している EAServer ホス トに配布できます。開発に使用したコンピュータの PowerBuilder VM のバージョンが、サーバ上でも使用できる必要があります。 PowerBuilder VM には、PBVM100.DLL、PBJAG100.DLL、 PBDWE100.DLL など、実行時に必要な PowerBuilder ファイルが用意 されています。UNIX の場合、共有ライブラリは libpbvm100x.ext、 libdwe100x.ext、などと呼ばれ、ext は各 UNIX プラットフォームの共 有ライブラリ拡張子です。EAServer は PowerBuilder ランタイム ファ イルを使用します。PowerBuilder ランタイム ファイルは、ファイル名 の最後に x が付き、印刷を含む Window API の呼び出しやグラフィッ ク処理をサポートしていません。 556 PowerBuilder 第 24 章 EAServer コンポーネントの構築 EAServer は、同一サーバ上で PowerBuilder VM の複数のバージョンを サポートします。異なるバージョンの PowerBuilder で作成されたコン ポーネントは、必要なバージョンの PowerBuilder VM がサーバ上で使 用できる限り、同一サーバ上で共存できます。 PowerBuilder 10 から EAServer にコンポーネントを配布するときは、コン ポーネントは使用している PowerBuilder VM のバージョンに関連付けら れます。EAServer Manager では、コンポーネントのプロパティ シートの [すべてのプロパティ] タブ ページの com.sybase.jaguar.component.pb.version プロパティが 10.0 に設定されます。 PowerBuilder 開発環境を使用しないで PowerBuilder コンポーネントを EAServer に配布する場合は、EAServer Manager のコンポーネントのプ ロパティ シートに、正しい VM のバージョンを指定できます。 開発環境で使った PowerBuilder VM のバージョンがないサーバでは、 PowerBuilder コンポーネントを配布しても、そのコンポーネントはイ ンスタンス化できません。 EAServer コンポーネ ントの配布について コンポーネントを EAServer に配布するには、プロジェクトを新規作成 して構築します。新規プロジェクトでは、組み込まれるオブジェクト の一覧を表示し、生成されたコンポーネントを格納する出力ライブラ リの名前を指定します。 データウィンドウの定義の有効化 データウィンドウ オブジェクトを動的に参照するスクリプトの場合 は、ウィザードまたはペインタの[統合 PBD に参照されないオブジェ クトを含める]ボックスをオンにして、データウィンドウの定義がコ ンポーネントで使用できるようにしなければなりません。 コンポーネントの配布 方法 コンポーネントを EAServer に配布するには、ウィザードによって作成 されたプロジェクトを開いて、 [デザイン|プロジェクトの配布]を選 択します。 EAServer への配布後 の処理内容 コンポーネントを EAServer に配布すると、コンポーネント ジェネレー タによって以下の処理が行われます。 • 配布用に選択した非ビジュアル オブジェクトを記述する CORBA IDL を生成 この IDL は、さらにスタブとスケルトンの作成に使用されます。 IDL ファイル、スタブ、およびスケルトンの名前は、オブジェク トの名前に基づいています。 コンポーネント ジェネレータは、EAServer のインストール ディレ クトリの Repository サブディレクトリに新しい IDL を格納します。 アプリケーション テクニック 557 EAServer へのコンポーネントの配布 • EAServer コンポーネントのプロパティを記述する PROPS ファイ ルを生成 PROPS ファイルは、EAServer のインストール ディレクトリのサブ ディレクトリに格納されます。このサブディレクトリのパスを次 に示します。Repository\Component\package-name • 配布されたコンポーネントに対して 1 つまたは複数の PBD ファイ ルを生成 PBD ファイルは、EAServer のインストール ディレクトリのサブ ディレクトリに格納されます。このサブディレクトリのパスを次 に示します。Repository\Component\package\component\Ccookie ここで、cookie は構築の生成番号を表します。ライブラリ名が修飾 されていない(パスが指定されない)場合には、コンポーネント ジェネレータは名前の前に円記号(\)を付けます。デフォルトで は、EAServer は最新版のコンポーネントを使用します。 ディスク スペースを再度割り当てるには、Sybase 社の Web サイト の サイト www.sybase.com からダウンロードできる CookieMonster (英語版) EAServer リポジトリ の後処理 というサービス コンポーネントを使用して、不要になったディレクト リを削除します。あるいは、次の手順で不要ディレクトリを削除して もかまいません。 ❖ 不要なディレクトリと PBD ファイルを削除するには 1 最新のディレクトリ以外のディレクトリをすべて削除します。 2 残りのディレクトリの名前を C1 に変更します。 3 4 コンポーネントのコー ド セットの変更 558 EAServer Manager のコンポーネントのプロパティ シートにある [すべてのプロパティ]タブ ページで、pb.cookie プロパティの値 を 1 に設定します。 EAServer を再起動します。 PowerBuilder によって配布された EAServer コンポーネントは、自動的 にサーバのコード セットを使用します。コンポーネントに別のコー ド セットを使用させたい場合は、コンポーネントの com.sybase.jaguar.component.code.set プロパティに適切な値を設定しま す。このプロパティを設定するには、EAServer Manager のコンポーネ ント プロパティ ダイアログボックスを使用します。[すべてのプロパ ティ]タブを選択し、com.sybase.jaguar.component.code.set プロパティ を追加して、big5 や iso_1 などの適切な値を指定します。 PowerBuilder 第 24 章 EAServer コンポーネントの構築 EAServer が utf-8 コード セットを使用して起動され、コンポーネント でユーロまたは英国ポンドの記号、あるいはその両方を含んでいる文 字列を返す場合は、code.set プロパティに cp1252 を設定します。 アプリケーション テクニック 559 EAServer へのコンポーネントの配布 560 PowerBuilder 第 2 5 章 EAServer クライアントの構築 この章について この章では、EAServer コンポーネントにアクセスする PowerBuilder クライアントの作成方法について説明します。セキュリティで保 護された接続については、第 26 章「PowerBuilder クライアントで の SSL の使い方」を参照してください。 内容 項目 EAServer クライアントの構築について EAServer への接続 EAServer プロキシ オブジェクトの生成 コンポーネント メソッドの呼び出し JaguarORB オブジェクトの使い方 クライアントとコンポーネントを区別するトランザクション サーバ メッセージ返送の要求 エラー処理 クライアント アプリケーションの配布 ページ 561 563 566 568 575 580 583 588 593 EAServer クライアントの構築について PowerBuilder アプリケーションは、EAServer コンポーネントのク ライアントの役割を果たします。サーバ上のコンポーネントに関 連付けられたメソッドにアクセスするには、PowerBuilder クライ アントは、サーバに接続し、コンポーネントをインスタンス化し、 コンポーネント メソッドを呼び出す必要があります。 EAServer への接続には、接続オブジェクトのインスタンスを使用 するのが一般的ですが、CORBA 互換クライアントを作成する場合 には、JaguarORB オブジェクトを使用してサーバへの接続を確立 することも可能です。 JaguarORB オブジェクトを使うと、 PowerBuilder クライアントは、C++ クライアントと同じ方法で EAServer にアク セスできます。 アプリケーション テクニック 561 EAServer クライアントの構築について この章で説明する技法を使えば、EAServer で実行する EJB コンポーネ ントのクライアントを構築できます。EAServer やほかの J2EE 準拠の サーバで EJB コンポーネントのクライアントを構築する方法について は、第 29 章「EJB クライアントの構築」を参照してください。 ウィザードの使い方について PowerBuilder には、EAServer クライアントの開発に役立つ 2 つのウィ ザードがあります。 • 接続オブジェクト ウィザード サーバへの接続に必要なコードを追 加する • クライアントからアクセスする EAServer コンポーネントのプロキシ オブジェクトを構築するため のプロジェクトの作成に役立つ EAServer プロキシ ウィザード 開発プロセスについて EAServer クライアン トの構築手順 EAServer クライアントを構築して配布するには、以下の手順をすべて 実行する必要があります。 1 EAServer 接続オブジェクト ウィザードを使用して、Connection オ ブジェクトから継承した標準クラスのユーザ オブジェクトを作成 します。その後で、このオブジェクトを、接続を確立するスクリ プトの中で使用できます。 テンプレート アプリケーション スタート ウィザードを使用して クライアント アプリケーションを作成した場合は、そのウィザー ドで接続オブジェクトを作成できます。 562 2 EAServer プロキシ ウィザードを使用して、プロキシ オブジェクト を作成するためのプロジェクト作成します。続いてプロキシ オブ ジェクトを生成します。 3 ユーザ インタフェースの実装に必要なウィンドウ、メニュー、お よびスクリプトを作成します。 4 EAServer コンポーネント インスタンスの作成と、クライアントか ら 1 つまたは複数のコンポーネント メソッドの呼び出しを行うた めに必要なコードを記述します。 5 クライアントのテストとデバッグを行います。 PowerBuilder 第 25 章 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:9000" myconnect.application = "PB_pkg_1" アプリケーション テクニック 563 EAServer への接続 myconnect.userID = "bjones" myconnect.password = "mypass" ll_rc = myconnect.ConnectToServer() IF ll_rc <> 0 THEN MessageBox(" 接続失敗 ", ll_rc) END IF 接続オブジェクト プ ロパティの設定 表 25-1 に EAServer と通信する際の、接続オブジェクト プロパティを 設定するためのガイドラインを示します。 表 25-1: EAServer の接続オブジェクト プロパティ プロパティ名 Application Driver Location 説明 EAServer コンポーネントに 使用するデフォルト パッ ケージ EAServer ドライバの名前 サーバのホスト名とポート 番号をコロンで区切ったも の 例 "PB_pkg_1" "jaguar" "Jagserver:9000" "iiop://srv1:9000" "iiops://srv3:9001" Location プロパティには、 "http://srv5:1080" 以下のいずれかの書式を使 用する。絶対パス URL も指 "iiop://s1:9000;iiop://s2:9000" 定できる iiop://host:port iiops://host:port http://host:port https://host:port Password UserID Options 複数の接続を確立 564 EAserver の負荷分散とフェ イルオーバのサポートを利 用する際、サーバの位置をセ ミコロンで区切ってリスト 形式で指定することも可能 "mypass" EAServer のパスワード "bjones" EAServer のユーザ ID 1 つまたは複数の EAServer "ORBLogFile='jaglog.log'" ORB プロパティ設定 PowerBuilder では、複数の接続オブジェクトをインスタンス化できま す。したがって、1 つのクライアント アプリケーションで複数の接続 を確立できます。たとえば、2 つの別個の接続オブジェクトをインス タンス化して、2 台の別々のサーバ にクライアントを接続することも 可能です。 PowerBuilder 第 25 章 EAServer クライアントの構築 設定オプション 接続オブジェクトまたは JaguarORB オブジェクトのいずれかを使用し て EAServer に接続するときは、EAServer C++ クライアント ORB を使 用することになります。そのプロパティは、接続オブジェクトの Options 文字列に設定するか、JaguarORB の Init 関数を使用して設定で きます。 使用するコード セッ トの変更 以前のバージョンでは、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 プロファイルの作成方法について は、497 ページの「EAServer プロファイルの作成」を参照してください。 接続オブジェクトの Constructor イベントは、of_getconnectioninfo 関数を 呼び出して、指定したソースから格納済みの接続情報を取得します。 アプリケーション テクニック 565 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 プロキシ オ ブジェクトについて 566 各 EAServer コンポーネントには、クライアント アプリケーション内 に対応するプロキシ オブジェクトがあります。EAServer コンポーネン トにアクセスするには、EAServer プロキシを通じて通信する必要があ ります。 PowerBuilder 第 25 章 EAServer クライアントの構築 クライアント アプリケーションには、EJB コンポーネントに対応する 2 つのプロキシ オブジェクト(ホーム インタフェース用とリモート イ ンタフェース用)があります。たとえば、Cart という名前の EJB コン ポーネントは、CartHome と Cart という 2 つのプロキシを生成します。 EJB コンポーネントにアクセスするには、これら 2 つのプロキシを介 して通信する必要があります。 EAServer クライアントのプロキシ オブジェクトは、新規プロジェクト を作成してから生成する必要があります。新規プロジェクトでは、組 み込まれるオブジェクトの一覧を表示し、生成されたプロキシ オブ ジェクトを格納する出力ライブラリの名前を指定します。 EAServer プロキシ ウィザードの使い方 EAServer プロキシ ウィザードは、EAServer プロキシ オブジェクトを 作成するためのプロジェクトの作成に役立ちます。このウィザードを 使うと、EAServer サーバに接続して、クライアントからアクセスでき るようにしたいコンポーネントを選択できます。プロジェクトを作成 したら、続いてプロジェクト ペインタを使用してプロジェクト設定を 修正し、プロキシ ライブラリを作成できます。 EJB クライアントの構築 EAServer やほかの J2EE 準拠のサーバで EJB コンポーネントのサービ スを利用できる EJB クライアントを構築するには、EJB クライアント プロキシ ウィザードを使います。詳細については、第 29 章「EJB ク ライアントの構築」を参照してください。 メソッド名の予約語 PowerBuilder で作成されなかった EAServer コンポーネント用にプロキ シを生成すると、PowerBuilder の予約語を使用するメソッドの名前が 変更されます。プロキシ ジェネレータは、これらのメソッド名の先頭 にアンダースコア(_)を自動的に追加します。たとえば、コンポーネ ントに destroy という名前のメソッドがある場合、プロキシのメソッド は _destroy になります。 TO 句の配列の使い方 CORBA IDL では TO 句がサポートされていないため、TO 句を使用す る配列を含む PowerBuilder コンポーネントのプロキシを生成する場 合、プロキシ オブジェクトは範囲を単一値として表します。たとえば、 Int ar1[5 TO 10] は Int ar1[6] と表します。この [6] は、配列の要 素数を表しています。クライアント アプリケーションは、範囲ではな く単一値を使用して配列を宣言しなければなりません。 アプリケーション テクニック 567 コンポーネント メソッドの呼び出し モジュール名の付加 コンポーネントを定義する IDL モジュールの名前を、作成したプロキ シ オブジェクトの名前の前に付加しておくと、名前が類似するプロキ シ オブジェクトどうしを容易に判別できます。たとえば、CTSSecurity モジュールの SessionInfo コンポーネントを選択して、ウィザードかプ ロジェクト ペインタの[EAServer パッケージ名をオブジェクト名の前 に 追 加]オ プ シ ョ ン を オ ン に す る と、プ ロ キ シ オ ブ ジ ェ ク ト が ctssecrity_sessioninfo という名前になります。一部の EAServer シ ステム モジュール(現在のところ、CtsComponents と XDT)では、名 前の二重定義を避ける目的から、常にモジュール名がオブジェクトに 付加されます。 パッケージ名と IDL モジュールの名前は普通は同じですが、異なって いてもかまいません。いずれの場合にも、前に付加されるのは IDL モ ジュールの名前です。 例外の除外 EAServer コンポーネントのなかには、クライアント アプリケーション で処理できる例外を送出するものが数多くあります。例外を処理しな い既存のクライアント アプリケーションでプロキシを生成して使用 したい場合、または構築しているクライアント内で例外を宣言したく ない場合は、ウィザードかプロジェクト ペインタで、生成されたプロ キシから例外を除外できます。クライアントでのエラー処理について の詳細は、588 ページの「エラー処理」を参照してください。 データ型マッピング EAServer コンポーネント インタフェースはすべて、標準の CORBA IDL で定義されます。EAServer で使用されるデータ型、各データ型の対応 する CORBA IDL、および各データ型がマッピングされる PowerBuilder のデータ型のリストについては、 『PowerScript リファレンス』マニュ アルまたはオンライン ヘルプを参照してください。 コンポーネント メソッドの呼び出し EAServer への接続が確立され、プロキシ オブジェクトかオブジェクト が作成された後ではじめて、クライアント アプリケーションはサーバ コンポーネントを使用できます。 コンポーネント メソッドの呼び出し ほとんどのコンポーネント タイプでメソッドを呼び出す際は、以下の 操作を行うのに必要な PowerScript 文を実行する必要があります。 568 PowerBuilder 第 25 章 1 EAServer クライアントの構築 CreateInstance メソッドを使用して、コンポーネントのインスタンス を作成する 2 メソッドを呼び出す EJB コンポーネント メソッドは、別の方法で呼び出します。570 ペー ジの「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 アプリケーション テクニック 569 コンポーネント メソッドの呼び出し 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 メソッドを呼び出す方法については、第 29 章 「EJB クライアントの構築」を参照してください。 570 PowerBuilder 第 25 章 ホーム インタフェー ス名の指定 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 を排他的に使用します。 アプリケーション テクニック 571 コンポーネント メソッドの呼び出し エンティティ 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() 572 PowerBuilder 第 25 章 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 関数を使用する必要があります。 アプリケーション テクニック 573 コンポーネント メソッドの呼び出し 例外の処理 EJB コンポーネントのリモート インタフェースに、エラーか警告が示 される場合があります。EJB コンポーネントから送出された標準例外 は、CORBA システム例外にマッピングされます。また EJB コンポー ネントが、ユーザ定義の例外を送出する場合もあります。EAServer コ ンポーネントから送出された例外の処理については、588 ページの「エ ラー処理」を参照してください。 EAServer 内の PowerBuilder コンポーネントからの EJB コンポーネント の呼び出しについては、538 ページの「EJB コンポーネントへのアク セス」を参照してください。 インスタンスの破棄 プロキシ オブジェク トのインスタンスの破 棄 EAServer コンポーネントを使い終わったら、DESTROY 文を使用して EAServer プロキシ オブジェクトを明示的に破棄するか、PowerBuilder のガベージ コレクション機能を利用してオブジェクトを自動的にメ モリから消去できます。いずれの場合でも、クライアントサイド プロ キシ オブジェクトの破棄は、サーバ コンポーネントの有効期間に影響 を与えません。サーバ コンポーネントの破棄は、EAServer によって処 理されます。 コンポーネントのイン スタンスの非アクティ ブ化 コンポーネントの自動的なデマケーション / 不活性化設定が無効であ り、しかもコンポーネントがまだクライアントにバインドされている 間にクライアント アプリケーションを閉じた(コンポーネントが SetComplete も SetAbort も呼び出さなかった)場合には、コンポーネン トは非アクティブにされません。コンポーネントのインスタンスを非 アクティブにするには、次のいずれかの操作を行います。 574 • クライアント アプリケーションの Close イベントで、 (SetComplete か SetAbort を呼び出して)コンポーネントを非アクティブにする サーバ コンポーネントのメソッドを呼び出します。 • コンポーネントの Timeout プロパティを 0 に設定してしまうと、コ ンポーネントがタイムアウトしなくなるので、0 以外の値に設定し ます。 PowerBuilder 第 25 章 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 ポート番号です。 アプリケーション テクニック 575 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 システ ム管理者ガイド』マニュアルのネーミング サービスの節を参照して ください。 576 PowerBuilder 第 25 章 例 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:9000;iiop://JagTwo:9000'', my_corbaobj) //Manager インタフェースへのオブジェクト参照を制限 ll_return = my_corbaobj._narrow(my_manager, "SessionManager/Manager") // セッション オブジェクト参照を作成 my_session = my_manager.createSession("jagadmin", "") // リモート インタフェースへの // プロキシ オブジェクト参照の 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 に対して効果的に実行します。 アプリケーション テクニック 577 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:9000", & my_corbaObj) my_corbaObj._narrow(my_mgr, "SessionManager/Manager" ) my_Session = my_mgr.createSession("jagadmin", "") my_corbaObj = my_session.lookup("Cart") my_corbaObj._narrow(my_CartHome, "shopping/CartHome") my_corbaObj = my_CartHome.create() my_Cart.addItem() 接続オブジェクトの使い方 接続オブジェクトの Lookup 関数を使用して、EJB コンポーネントの ホーム インタフェースへの参照を取得できます。570 ページの「EJB コンポーネント メソッドの呼び出し」を参照してください。 ネーミング サービス API によるインスタンス化 CosNaming インタ フェースと SessionManage イン タフェースのプロキシ の取得 CORBA ネーミング サービス API を使用してプロキシをインスタンス 化するには、ネーミング サービス インタフェースのプロキシを生成し て、生成したプロキシをクライアントのライブラリ リストに含める必 要があります。EAServer プロキシ ウィザードを使用して CosNaming モ ジュールのプロキシ プロジェクトを作成し、プロキシ ライブラリを作 成するためのプロジェクトを作成して、プロキシ ライブラリをクライ アント ターゲットのライブラリ リストに追加します。SessionManager モジュールにもプロキシが必要です。 初期状態のネーミング コンテキストの取得 ORB の初期化後、Resolve_Initial_References 関数を呼び出して初期状態 の ネ ー ミ ン グ コ ン テ キ ス ト を 取 得 し、_Narrow を 使 用 し て そ れ を CORBA ネーミング コンテキスト インタフェースへの参照に変換しま す。次の例に示すように、クラス名に omg.orb を含めて、CosNaming パッケージを識別しなければなりません。 578 PowerBuilder 第 25 章 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:9000'") 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("jagadmin","") my_corbaobj._narrow(my_jagcomp, "mypackage/n_jagcomp") my_jagcomp.getdata() アプリケーション テクニック 579 クライアントとコンポーネントを区別するトランザクション クライアントとコンポーネントを区別するトランザクション クライアント アプリケーションおよび[OTS スタイル]としてマーク された EAServer コンポーネントは、CORBACurrent コンテキスト サー ビス オブジェクトの関数を使用して、EAServer トランザクションに関 する情報の作成、制御、および取得が行えます。CORBACurrent オブ ジェクトは、CORBACurrent インタフェース用に定義された数多くの メソッドを備えています。 2 フェーズ コミット クライアントまたはコンポーネントをマークしたトランザクションの コンポーネントは、OTS/XA トランザクション コーディネータを使用 するサーバ上で実行されていなければなりません。このトランザク ション コーディネータは、システム障害から保護するため、すべての 参加者からの詳細レコードを使用する、2 フェーズ コミット プロトコ ルをサポートします。準備フェーズでは、トランザクション コーディ ネータがトランザクションの各参加者から、そのトランザクションが コミットできるという保証を得て、準備レコードをログに書き込みま す。コミット フェーズでは、コーディネータはすべての参加者に対し、 リソースが解放され、トランザクションがコミットされ、コミット レ コードがログに記録されることを通知します。 2 フェーズ コミットを使用するコンポーネントは、 XA 準拠の PowerBuilder データベース インタフェースを使用してデータベースに接続しなけ ればなりません。Windows NT の場合、Oracle 8.0.x(8.1.x ではなく)で は Oracle O73 インタフェースと O84 インタフェースを使用でき、Sun の JRE 1.2 と jConnect 5.2 では JDB interface for JDBC を使用できます。 コンポーネントが UNIX ホスト上で実行されている場合は、Sybase Adaptive Server Enterprise CT-LIB インタフェース(SYJ)を使用できま す。 OTS/XA トランザクション コーディネータは、接続キャッシュではな く XA リソースを使用してトランザクションを管理します。XA リソー スの作成と管理についての詳細は、 『EAServer システム管理者ガイド』 マニュアルを参照してください。 コンポーネントを OTS スタイルにする トランザクションを管理する EAServer コンポーネントを作成するに は、EAServer プロジェクト ウィザードかプロジェクト ペインタの [OTS スタイル]ボックスをオンにします。また、コンポーネント配布 後、EAServer Manager のコンポーネントのプロパティ シートで、 [ト ランザクション]タブの[OTS スタイル]を選択することも可能です。 CORBACurrent オブ ジェクトの初期化 CORBACurrent コンテキスト サービス オブジェクトの関数を呼び出す 前に、GetContextService 関数を使用してオブジェクトのインスタンスを 作成し、次に Init 関数を使用してそのインスタンスを初期化する必要が あります。 580 PowerBuilder 第 25 章 EAServer クライアントの構築 OTS スタイルのコンポーネントが管理するトランザクションでは、Init 関数を引数なしで呼び出します。 GetContextService("CORBACurrent", myCorbCurr) myCorbCurr.Init() クライアントを区別するトランザクションでは、Init 関数に引数を指定 して呼び出さなければなりません。引数は、すでに接続を確立した接 続オブジェクトのインスタンスか有効な EAServer ホストを識別する URL です。 移植性が高いため、接続オブジェクトを使用する方法がよく用いられ ます。 myCorbCurr.Init( myconnect ) // または myCorbCurr.Init( "iiop://localhost:9000") トランザクションの開 始と終了 クライアントかコンポーネントを区別するトランザクションを開始す るには 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() アプリケーション テクニック 581 クライアントとコンポーネントを区別するトランザクション // サーバ上で処理を実行 // 成功か失敗かを検査 ... IF lb_success THEN 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 は、同じ実行コンテキスト内にある別のスレッドか ら呼び出せます。次の例では、トランザクションが同じスレッドに再 度関連付けられています。 582 PowerBuilder 第 25 章 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 と通信することによって、この動作をシミュレート することは可能です。クライアント上の共有オブジェクトがサーバか らデータをプルするため、このテクニックはクライアント プルとみな すことができます。 アプリケーション テクニック 583 サーバ メッセージ返送の要求 動作 サーバ プッシュをシミュレートするには、クライアントは、 SharedObjectRegister 関数と SharedObjectGet 関数を使用して、共有オブ ジェクトを作成します。オブジェクトが作成されたら、クライアント 上のメイン スレッドは、共有オブジェクトのメソッドの非同期呼び 出しを行って、コールバック オブジェクトを渡します。このコール バック オブジェクトは、サーバ上で処理が終了したときに通知され ます。共有オブジェクトのメソッドは、処理を行う EAServer コン ポーネント メソッドの同期呼び出しを行います。共有オブジェクト はクライアント上の別のスレッドで動作しているため、サーバ上でプ ロセスを実行しながら、クライアント上のメイン スレッドはほかの 作業を続行できます。 EAServer の非同期処理 次の例では、POST を使用してクライアント上の共有オブジェクトのメ ソッドを非同期で呼び出します。POST の使用は、EAServer コンポー ネントへの呼び出しのコンテキストではサポートされていません。 EAServer で の 非 同 期 処 理 に つ い て は、EAServer の マ ニ ュ ア ル で、 ThreadManager モジュールと MessageService モジュールに関する項目 を参照してください。 例 次の例では、共有オブジェクトを使用して、EAServer コンポーネント メソッドに対して非同期リクエストを行い、データをクライアント ア プリケーション ウィンドウに返す方法を示します。 クライアント アプリケーションのウィンドウ クライアント アプリケーションには、w_employee というウィンドウが あり、従業員データをデータウィンドウ コントロールに表示します。 ユーザがこのウィンドウの[検索]ボタンをクリックすると、クライ アントは、EAServer と通信する共有オブジェクトを作成します。さら に、ユーザ オブジェクトのインスタンスも作成します。このインスタ ンスは、共有オブジェクトのコールバックの処理に使用されます。 インスタンス変数 w_employee ウィンドウには、以下の定義されたインスタンス変数があ ります。 uo_sharedobject iuo_sharedobject uo_callback iuo_callback 584 PowerBuilder 第 25 章 [検索]ボタン EAServer クライアントの構築 [検索]ボタンは、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 return ll_rv アプリケーション テクニック 585 サーバ メッセージ返送の要求 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") 586 PowerBuilder 第 25 章 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 アプリケーション テクニック 587 エラー処理 エラー処理 PowerBuilder は、EAServer に接続しているクライアントが使用できる 3 階層のエラー処理を提供します。 • EAServer で実行されているコンポーネントから送出された例外を、 try/catch/finally ブロックを使用して処理するメカニズム システム エラーと実行時エラーはすべて、RuntimeError 型から派 生したオブジェクトに変換されます。 • EAServer 接続のコンテキストで発生するエラーを処理する、接続 オブジェクトと JaguarORB オブジェクトの Error イベント • ほかのメカニズムでトラップされなかったエラーを処理する、ア プリケーション オブジェクトの SystemError イベント PowerBuilder では、エラーに関する情報は組み込みの Error 構造に記録 されます。この構造体は、Error イベントと SystemError イベントによっ て使用されます。 クライアントができる こと クライアント アプリケーションは、さまざまな方法で通信エラーを処 理できます。たとえば、クライアントがサーバに接続し、オブジェク トのメソッドを呼び出そうとしたのにそのオブジェクトが存在しな かった場合は、サーバとの接続を解除し、別のサーバに接続して操作 を再試行する方法があります。あるいは、クライアントがユーザにメッ セージを表示して、次に起こることを制御する機会をユーザに与える 方法もあります。 クライアントが操作の再開のために新しいサーバに接続している場 合、エラー発生時には、新しいサーバ上でリモート オブジェクトをイ ンスタンス化してから、リモート オブジェクトのメソッドを呼び出す 必要があります。 エラーが処理される場 所 588 次に、PowerBuilder が EAServer クライアントでエラー処理コードを実 行するシーケンスを示します。 1 接続オブジェクトまたは JaguarORB オブジェクトのコンテキスト でエラーが発生し、そのオブジェクトの Error イベントに関連付け られているスクリプトがある場合は、イベント スクリプトがあれ ば、それが実行されます。 2 以下のいずれかが真の場合、RuntimeError またはその子孫のアク ティブな例外ハンドラが起動されます。 • Error イベントのスクリプトが作成されていない • Error イベントのアクション引数が ExceptionFail! に設定され ている PowerBuilder 第 25 章 • 3 EAServer クライアントの構築 接続オブジェクトまたは JaguarORB オブジェクトのコンテキ ストでエラーが発生しない 例外ハンドラがない場合、または既存の例外ハンドラがその例外 を処理しない場合、アプリケーション オブジェクトの SystemError イベントが実行されます。SystemError イベントのスクリプトが作 成されていない場合は、アプリケーション エラーが起きて、アプ リケーションは終了します。 システム例外ハンドラ PowerBuilder には、致命的なシステム エラーの捕捉を試みる、システ ム例外ハンドラがあります。このハンドラは、個々のクライアント接 続のトラブルによるサーバ停止の防止に役立ちます。クライアント接 続時に致命的なエラーが発生するたびに、PowerBuilder は、サーバを 停止させたりほかのクライアント接続を妨げたりすることなく、クラ イアント接続の終了を試みます。トラブルが発見されたら、クライア ント上のほかの実行時エラーの場合と同様に、システム例外ハンドラ はアプリケーション オブジェクト内で SystemError イベントを発生さ せます。 コンテキスト対応のエ ラー処理 try/catch メカニズムを利用すると、発生した場所でエラーを処理でき、 コンポーネントから送出されたエラーが、クライアント アプリケー ションで致命的なエラーになる可能性を最小限に抑えることも可能で す。接続オブジェクトの Error イベントをスクリプトで実行させる方法 は正確性が低く、Error イベントのアクション引数を ExceptionFail! に設 定しない限り、try/catch 例外ハンドラを無視してしまいます。 したがって、Error イベントはスクリプトで実行せずに、コードに try/catch ブロックを追加して、もっとも効果的なエラー処理を実現し なければなりません。GetMessage 関数を使用して、例外のエラー メッ セージを取得できます。 例外についての詳細は、39 ページの「PowerBuilder での例外処理」を 参照してください。 作成したエラー処理コードでは発生したすべてのエラーをトラップで きるわけではないため、必ず、アプリケーション オブジェクトの SystemError イベントのスクリプトを作成する必要があります。 アプリケーション テクニック 589 エラー処理 CORBA 例外の処理 CORBA は、コンポーネントがエラーまたは警告を通知するための標 準的な方法を提供します。CORBA は 2 種類の例外をサポートします。 • システム例外 • ユーザ定義の例外 システム例外は、サーバで生成される標準エラーのセットの 1 つです。 これらの例外は、CORBA 仕様で定義されています。 ユーザ定義例外は、コンポーネントの IDL で定義されるエラーまたは 警告です。ユーザ定義例外は新しいデータ型であり、例外が生成され たときにクライアントに返される一連のデータ要素を表します。 システム例外 PowerBuilder では、CORBA システム例外は RuntimeError オブジェクト から継承した一連のオブジェクトにマッピングされます。このような 例外のリストを参照するには、PowerBuilder オブジェクト ブラウザの [システム]タブで「corbasystemexception」を選択し、ポップアップ メ ニューで[階層の表示]を選択して、ツリービュー項目を拡張します。 PowerBuilder の CORBASystemException オ ブ ジ ェ ク ト の 名 前 は、 CORBA/IIOP 仕様にアンダースコア文字を省略して定義されている CORBA シ ス テ ム 例 外 の 名 前 に マ ッ ピ ン グ さ れ ま す。た と え ば、 PowerBuilder CORBACommFailure 例外は CORBA_COMM_FAILURE 例 外にマッピングします。CORBA 例外についての詳細は、OMG Web site のサイト www.omg.org からダウンロードできる CORBA/IIOP 仕様を参照 してください。 コンポーネントのメソッドを呼び出すときには、次に示すような例外 に対してエラー処理を実行できます。 TRY ... // メソッドの呼び出し CATCH (corbacommfailure cf) // コンポーネントによる EAServer トランザクションの異常終了 // またはトランザクションのタイムアウト。 // 必要であれば トランザクションを再試行 CATCH (corbatransactionrolledback tr) // 多くの場合はトランザクションを再試行 CATCH (corbaobjectnotexist one) // 存在しないコンポーネントを初期化しようと // したときに受け取る。また、 // オブジェクト参照の有効期限が切れた場合に // メソッドを呼び出したときも受け取る // これは、コンポーネントがステートフルで、 // 有限の Instance Timeout プロパティが 590 PowerBuilder 第 25 章 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 イベントのス クリプトを作成できます。 接続オブジェクト ウィザードは、カスタム接続オブジェクトを作成し ます。565 ページの「ウィザードを使用した接続オブジェクトの作成」 を参照してください。 アプリケーション テクニック 591 エラー処理 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 イベント スクリプトは、メッセージを表示し て、ユーザに通信エラーを引き起こした条件を知らせ、ユーザに次に 起こることを制御する機会を与えます。ユーザの入力に応じて、クラ イアント アプリケーションは、実行を中断するか、エラーを無視して 処理を続行します。 592 PowerBuilder 第 25 章 EAServer クライアントの構築 string ls_logline = " システム エラー : " ls_logline += String(error.number) + " " + error.text 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 ユーザーズ ガイド』マニュアルを参照してください。ア プリケーションと一緒に配置する必要があるファイルについては、第 41 章「アプリケーションとコンポーネントの配布」を参照してくださ い。 アプリケーション テクニック 593 クライアント アプリケーションの配布 594 PowerBuilder 第 2 6 章 PowerBuilder クライアントでの SSL の使い方 PowerBuilder クライアントは、Secure Sockets Layer(SSL)を使用 して EAServer に接続できます。ほかのセキュリティ機能の中で も、SSL は、証明書に基づくサーバ認証、証明書に基づく任意の クライアント認証、およびネットワーク経由で送信される任意の データの暗号化を提供します。 内容 項目 EAServer とのセキュアな接続 PowerBuilder での SSL 接続 セキュアな接続の確立 SSL コールバックの使い方 セッション セキュリティ情報の取得 ページ 595 597 601 604 608 EAServer とのセキュアな接続 SSL プロトコルでは、デジタル認証に基づく公開鍵の暗号化と認 証のアルゴリズムを利用して、安全に接続できます。SSL は「ラッ パー」プロトコルであり、ほかのプロトコル用のパケットは、SSL パケットの内部に埋め込むことによって保護されます。たとえば、 HTTPS は、各 HTTP パケットを SSL パケット内に埋め込むことに よって保護される HTTP です。同様に、IIOPS は、SSL 内に埋め込 まれた IIOP です。 EAServer の組み込み SSL ドライバは、動的ネゴシエーション、 キャッシュ セッション、共有セッション、および X.509 デジタル 証明書サポートによるクライアント / サーバの認証をサポートし ます。 EAServer でのセキュリティの概要および EAServer と SSL につい ての詳細は、 『EAServer セキュリティ管理およびプログラミング・ ガイド』マニュアルを参照してください。 アプリケーション テクニック 595 EAServer とのセキュアな接続 SSL プロトコルについての詳細は、Netscape DevEdge Web のサイト http://developer.netscape.com/ でセキュリティのマニュアルを参照してく ださい。 保護の質 EAServer パッケージ、コンポーネント、およびメソッドの保護の質 (QOP: quality of protection)は、EAServer Manager で設定できます。QOP は、クライアントがコンポーネントのビジネス ロジックにアクセスす るために満たさなければならない、最低レベルの暗号化および認証を 構築します。たとえばコンポーネントに対する QOP を設定するには、 コンポーネントのプロパティ シートの[すべてのプロパティ]ページ で com.sybase.jaguar.component.qop プロパティを追加し、EAServer が提 供する sybpks_intl などのセキュリティ特性を設定します。 サーバでの QOP の設定について、および EAServer が提供するセキュ リティ特性のリストについては、 『EAServer セキュリティ管理および プログラミング・ガイド』マニュアルを参照してください。この章で は、クライアントでの QOP の設定について説明します。 SSL の証明書に基づ く認証 EAServer Manager では、リスナを設定し、そのリスナにセキュリティ プロファイルを関連付けることで、セキュアな IIOP または HTTP ポー トを構成できます。プロファイルは、目的のサーバでの接続終了を確 認するためにクライアントに送信されるセキュリティ証明書と、その ほかのセキュリティ設定を指定します。 PowerBuilder クライアントには、デジタル証明書の管理のために公開 鍵基盤(PKI: Public key Infrastructure)システムが必要です。EAServer 証明書データベースを管理する Security Manager、または Entrust Technologies 社(http://www.entrust.com/)から個別に入手できる Entrust/Entelligence を使用できます。 PKI およびセキュアなポートと認証オプションの設定についての詳細 は、 『EAServer セキュリティ管理およびプログラミング・ガイド』マ ニュアルを参照してください。 クライアント側のイン ストール要件 596 EAServer は、いくつかのクライアント ランタイム ファイルを提供し ます。PowerBuilder クライアントの SSL サポートは、C++ クライアン トの ORB を介して提供されるので、PowerBuilder SSL クライアントが 動作するコンピュータには SSL および C++ ランタイム ファイルをイ ンストールする必要があります。このインストールには、クライアン ト側のセキュリティ データベース、SSL サポート ライブラリ、クライ アント側の Security Manager などが含まれます。また、アプリケーショ ンの実行時にクライアント ライブラリが読み込まれるように、クライ アントのインストールを構成する必要もあります。詳細については、 『インストール ガイド』マニュアルを参照してください。 PowerBuilder 第 26 章 PowerBuilder クライアントでの SSL の使い方 PowerBuilder での SSL 接続 PowerBuilder は、セキュアな接続に使用する 2 つのシステム オブジェ クトを提供します。 • SSLServiceProvider サービス オブジェクト SSLServiceProvider オブ ジ ェ ク ト は、EAServer の CtsSecurity::SSLServiceProvider イ ン タ フェースの実装です。このインタフェースについての詳細は、Web ブラウザでお使いのサーバ(http://hostname:portnumber/ir)に接続 して、EAServer インタフェース リポジトリ ドキュメントを参照し てください。 SSLServiceProvider オブジェクトの GetGlobalProperty および SetGlobalProperty 関数を使用して、グローバル SSL プロパティを設 定します。設定または取得、あるいはその両方が可能なグローバル プロパティについては、597 ページの「SSL プロパティ」を参照し てください。 また、接続オブジェクトまたは JaguarORB オブジェクトに対して、 SSL プロパティを Options 文字列で指定して、接続レベルで設定す る こ と も で き ま す。対 話 型 の ア プ リ ケ ー シ ョ ン で は 一 般 に、 SSLServiceProvider オブジェクトは SSLCallback オブジェクトとと もに使用されます。ユーザとの対話操作を提供しないアプリケー ションでは、接続レベルで SSL 設定を構成するのが普通です。接 続レベルでのプロパティの設定については、600 ページの「ORB プロパティ」を参照してください。 • SSLCallback オブジェクト EAServer で、コールバック メソッドを 使用してクライアントに追加情報を要求する場合は、SSLCallBack オブジェクトのインスタンスにコールバック メソッド用の独自の ロジックを実装できます。SSLCallback オブジェクトは、EAServer の CtsSecurity::SSLCallback インタフェースの実装です。 SSL プロパティ 表 26-1 に、SetGlobalProperty または GetGlobalProperty を使用して設定ま たは取得できるプロパティを示します。SSL 接続では、qop(quality of protection)プロパティを設定しなければなりません。また、このプロ パティを取得するためのコールバックを実装しない場合は、pin プロパ ティを設定する必要があります。選択したセキュリティ レベルをサ ポートするサーバ アドレスに接続する必要もあります。これについて は、600 ページの「セキュアなサーバ アドレス」に記載されています。 アプリケーション テクニック 597 PowerBuilder での SSL 接続 PowerBuilder セッションでのグローバル プロパティの設定 PowerBuilder でクライアント アプリケーションを実行している場合、 PowerBuilder のセッション時にグローバル プロパティを設定できるの は一度だけです。グローバル SSL プロパティを設定するコードをテス トするたびに、PowerBuilder を再起動する必要があります。 設定されていないプロパティか、誤って設定されているプロパティが ある場合は、SSL コールバック メソッドが呼び出されます。SSLCallback オブジェクトのインスタンスを指定していない場合は、デフォルトの コールバック実装によって接続試行が中断されます。 表 26-1: SSL プロパティのリスト プロパティ callbackImpl certificateLabel qop cacheSize SessLingerTime SessShareCount pin 説明 取得 SSLCallback オブジェクトのインスタンス。詳細については、604 可 ページの「SSL コールバックの使い方」を参照してください。 相互認証が必要な接続で使用するクライアント証明書。ラベル 可 は、PKCS #11 トークンの X.509 証明書およびプライベート キー を識別する単純な名前 相互認証で必要このプロパティを設定せずに接続の相互認証を 要求すると、コールバック メソッド getCertificateLabel が呼び出さ れ、使用可能な証明書名の配列が入力パラメータとして渡される 使用するセキュリティ特性の名前。SSL で必要。詳細については、 599 ページの「セキュリティ特性の選択」を参照してください。 SSL セッション ID のキャッシュのサイズ。デフォルトは 100 前回の接続で使用したセッション ID エントリをキャッシュに保 管する期間(秒単位)。デフォルトは 28800 秒(8 時間) 同じセッション ID を同時に使用できる SSL セッションの数。デ フォルトは 10 PKCS #11 トークンの PIN 設定 可 可 可 可 可 可 可 可 可 可 不可 可 これは、クライアント認証のために PKCS #11 トークンにログイ ンする場合、および信頼情報を取得する場合に必要。SSL で必要 availableQop availableQopDesc availableVersions 598 このプロパティが設定されていない場合は、any が設定される。 また、誤って設定されている場合は、コールバック メソッド getPin が呼び出される 使用可能なセキュリティ特性のリスト。qop プロパティには、こ 可 のリスト内の値のみ設定できる 使用可能なセキュリティ特性の説明のリスト。availableQop プロ 可 パティの値と同じ順序で指定する SSL ランタイム エンジンでサポートされる SSL プロトコル バー 可 ジョンのリスト 不可 不可 不可 PowerBuilder 第 26 章 プロパティ 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 プロパティを取得します。 アプリケーション テクニック 599 PowerBuilder での SSL 接続 セキュアなサーバ ア ドレス qop 設定で要求されるセキュリティ レベルと同じまたはそれ以上のレ ベルのサーバ リスナにのみ接続できます。JaguarORB.string_to_ オブ ジェクトを使用して SessionManager::Manager インタフェースのプロシ キのインスタンスを作成する場合、サーバ アドレスで指定されるリス ナでは、クライアントの qop 設定と一致するセキュリティ プロファイ ルを使用しなければなりません。 ORB プロパティ 接続オブジェクトまたは JaguarORB オブジェクトのいずれかを使用し て EAServer に接続する場合、EAServer の C++ クライアント 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'" 600 PowerBuilder 第 26 章 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" ) アプリケーション テクニック 601 セキュアな接続の確立 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 を設定 する必要があります。604 ページの「SSL コールバックの使い方」を 参照してください。 サーバへの接続 602 セキュアなセッションを開始すると、クライアントおよびサーバは SSL ハンドシェイク プロセスでメッセージを交換します。クライアン トは、サーバとの通信で必要とされる情報を提供し、サーバはクライ アントに対してサーバ自身の認証を行ったうえで、プロセスを継続し ます。サーバがクライアント認証を必要とする場合は、プロセスを継 続する前にクライアントが認証されなければなりません。必要な認証 が完了すると、クライアントおよびサーバは、暗号化、復号化、およ び SSL セッションの不正箇所の検出に使用する、双方で対称的なキー を作成します。このプロセスで発生する例外を取り込むには、try-catch ブロックに ConnectToServer 呼び出しを置く必要があります。 PowerBuilder 第 26 章 PowerBuilder クライアントでの SSL の使い方 セキュアな接続が確立したら、接続オブジェクトの location プロパティ で iiop ではなく iiops を使用します。サーバは一般的には、ポート 9001 または 9002 でセキュアな接続要求を待機します。次の例では、グ ローバル変数として宣言された接続オブジェクト 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:9001" 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 文を次のような文で置き換えます。 アプリケーション テクニック 603 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 プロキシを作成します。 604 PowerBuilder 第 26 章 ❖ PowerBuilder クライアントでの SSL の使い方 CTSSecurity モジュールに対してプロキシを作成するには 1 新規作成 ダイアログボックスの[プロジェクト]ページで[EAServer プロキシ ウィザード]を選択し、[ターゲット]ドロップダウン リストボックスから対象のクライアント アプリケーションを選択 します。 2 いずれかの EAServer ホストに接続し、CTSSecurity モジュールを選 択します。 CTSSecurity モジュールは、すべてのサーバで使用可能な標準モ ジュールです。 ウィザードでの操作を完了し、プロジェクトを作成します。 3 システム ツリーに表示されるプロキシ オブジェクトのうち、 Sessioninfo オブジェクトはすべての SSLCallback 関数に渡されま す。 SSLCallback オブジェクトの実装 4 つのコールバック関数があります。 表 26-2: SSL コールバック関数 関数 呼び出しのタイミング GetCertificateLabel サーバがクライアント認証を要求しているが、クラ イアント アプリケーションにクライアント認証用の 証明書ラベルが設定されていない場合 クライアント アプリケーションにアカウント情報属 性が設定されていない場合 GetCredentialAttribute GetPin アプリケーション テクニック この属性は、クライアント アプリケーションで SSLServiceProvider オブジェクトを使用して UseEntrustId プロパティを設定した場合に使用され る。Entrust ID を使用している場合のみ GetCredentialAttribute が便利。Entrust および PKCS 11 トークンについての詳細は、『EAServer セキュリ ティ管理およびプログラミング・ガイド』マニュア ルを参照してください。 PKCS11 トークンがログインされず、PIN が SSLServiceProvider オブジェクトのプロパティとし て設定されていない場合。また、ログイン セッショ ンがタイムアウトした場合にも呼び出される 605 SSL コールバックの使い方 関数 呼び出しのタイミング TrustVerify サーバ内部での SSL 信頼確認チェックが失敗して、 サーバの証明書チェーンを確認できない場合、また は Sybase の PKCS11 トークンにログインするための pin が設定されていないか正しくない場合、 TrustVerify は SSL プロトコルを使用する場合も呼び 出すことができる サーバ認証は SSL ハンドシェイク プロセスで必要 な手順なので、任意の SSL プロトコルを使用してい るときに TrustVerify を呼び出すことができる。ユーザ は、内部チェックをオーバーライドして SSL 接続を 続行するかどうかを選択できる 以上の各関数は、SSLCallback クラスによって実装されており、デフォ ルトの実装があります。コールバックを使用する場合は、その関数を 実装する必要があります。各関数の実装例については、 『PowerScript リ ファレンス』マニュアルまたはオンライン ヘルプを参照してくださ い。 ❖ SSLCallBack クラスを実装するには 1 デフォルトの実装 新規作成 ダイアログボックスの[PB オブジェクト]ページから [標準クラス]を選択します。 2 標準クラス データ型の選択 ダイアログボックスで[SSLCallback] を選択し、[OK]をクリックします。 3 セッション情報をユーザに提供し、ユーザから必要な認証情報を 返させるための、コールバック関数のコードを記述します。 4 実装するそのほかのコールバック関数に対して、手順 3 を繰り返 します。 実装を提供していない場合、または実装から空の文字列が返された場 合は、コールバックのデフォルトの実装が使用されます。 GetCertificateLabel および GetCredentialAttribute の場合、引数リストには、 コールバックに対して有効な戻り値である文字列値の配列が含まれま す。これらのコールバックのデフォルトの実装は、この配列が空の場 合、例外を送出し、配列が空でない場合は、その配列の最初の要素を 返します。その結果、配列の最初の要素がサーバで受け入れ可能であ れば、接続プロセスは継続しますが、受け入れ可能でなければ失敗し ます。 TrustVerify の場合、デフォルトの実装は現行の接続を拒否します。 606 PowerBuilder 第 26 章 例外の処理 PowerBuilder クライアントでの SSL の使い方 GetPin、GetCertificateLabel、および GetCredentialAttribute の実装では、要 求された情報をユーザが提供できない場合には、ユーザ側で接続を キャンセルできるようにする必要があります。これを実現するには、 関数の実装内で例外を送出し、ConnectToServer 呼び出しを置く try-catch ブロック内でその例外を取り込みます。コールバック関数内で送出し た例外によって、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 このような宣言を行う理由は、コールバック オブジェクトはその文字 列名によってのみ参照されるので、技術的には非参照オブジェクトで あり、実行ファイルには含まれないためです。宣言した変数をコード で使用する必要はありません。 アプリケーション テクニック 607 セッション セキュリティ情報の取得 セッション セキュリティ情報の取得 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) 608 "port" ) "ciphersuite" ) "certificateLabel" "UserData" ) "tokenName" ) "useEntrustID" ) PowerBuilder 第 2 7 章 COM/COM+ コンポーネントの構築 この章について この章では、PowerBuilder を使用して、COM/COM+ コンポーネン トを構築する方法について説明します。 内容 項目 ページ 609 COM/COM+ コンポーネントの構築について 612 コンポーネント オブジェクト モデルについて 616 コンポーネント インタフェースの定義 620 COM コンポーネントからデータベースへのアクセス 624 トランザクションのサポート 627 別のサーバ コンポーネントのメソッドの呼び出し 628 セキュリティ問題 プロジェクト ペインタでの COM/COM+ コンポーネントの構 629 築 633 PowerBuilder COM オブジェクトの実行 634 PowerBuilder COM サーバの配布 635 クライアントから PowerBuilder COM サーバへのアクセス COM/COM+ コンポーネントの構築について ビジネス ロジックを含むカスタム クラス ユーザ オブジェクトを PowerBuilder で開発すると、そのオブジェクトを COM サーバまた は COM+ アプリケーションとしてパッケージ化することができま す。 Windows 2000 や Windows XP などの COM+ をサポートしているプ ラットフォームでは、COM+ アプリケーションを構築して COM+ に配布できます。 この章以降では、COM と COM+ をサポートしているコンポーネ ントのことを、COM コンポーネントと呼んでいます。 アプリケーション テクニック 609 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+ のターゲット ウィザードまたはオブジェクト ウィザード を使用して、新規のユーザ オブジェクトを作成した場合、以下のとお りとなります。 ウィザードを使用する タイミング 610 • オブジェクトには、Activate と Deactivate という、2 つの新しいイ ベントがあります。 • オブジェクトは、COM の検証のサポートを有効にしています。 • ウィザードの最終ページのボックスをオンにした場合には、ウィ ザードは To-Do リストに項目を追加することによって、開発のす べてのステップを実行するよう注意を促します。 新規オブジェクト 単一の新規カスタム クラス ユーザ オブジェクトを 含むサーバを構築する場合には、ターゲット ウィザードまたはオブ ジェクト ウィザードを使用して、その機能を利用します。 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 複数の新規カスタム クラス ユーザ オブジェクトを含むサーバを構築 する場合にターゲット ウィザードまたは オブジェクト ウィザードを 使用すると、オブジェクトごとに異なるプロジェクトが作成されます。 したがって、いずれか 1 つのプロジェクトにすべてのオブジェクトを 追加し、それ以外のプロジェクトは破棄する必要があります。 また、ターゲット ウィザードもオブジェクト ウィザードも使用せずに 新規カスタム クラス ユーザ オブジェクトを作成し、その後でプロジェ クト ウィザードまたはプロジェクト ペインタを使用してプロジェク トを作成することもできます。 ユ ー ザ オ ブ ジ ェ ク ト ペ イ ン タ で は、COM の 検 証 を 有 効 に し て、 Activate イベントと Deactivate イベントをユーザ定義イベントとして 追加することができます。詳細については、619 ページの「COM の検 証」を参照してください。 COM サーバとして配布する 1 つまたは複数のカス タム クラス ユーザ オブジェクトがある場合は、それらのオブジェク トが、616 ページの「コンポーネント インタフェースの定義」および それ以降の節で説明する要件を満たしていることを確認してくださ い。新規のユーザ オブジェクトに関しては、ユーザ オブジェクト ペ インタで COM の検証を有効にし、Activate イベントと Deactivate イベ ントをユーザ定義イベントとして追加します。サーバの構築準備がで きたら、プロジェクト ウィザードを使用してプロジェクトを設定しま す。 既存オブジェクト 開発プロセスについて 1 つまたは複数のカスタム クラス ユーザ オブジェクトから PowerBuilder COM サーバを構築および配布するには、以下の手順を実行する必要が あります。 1 新規カスタム クラス ユーザ オブジェクトを作成するか、または既 存のユーザ オブジェクトを開きます。 ターゲット ウィザードまたはオブジェクト ウィザードを使用す る場合には、新規オブジェクトの作成と配布に使用するプロジェ クト オブジェクトも作成します。 2 ユーザ オブジェクト ペインタでユーザ オブジェクトのスクリプ トを記述します。 616 ページの「コンポーネント インタフェースの定義」を参照し てください。 アプリケーション テクニック 611 コンポーネント オブジェクト モデルについて 3 場合によっては、同じアプリケーションで追加のユーザ オブジェ クトの作成とスクリプトの記述を行います。 4 ウィザードを使わずにユーザ オブジェクトを作成した場合は、 COM/COM+ プロジェクト ウィザードまたはプロジェクト ペイン タを使用してプロジェクトを作成します。 629 ページの「プロジェクト ペインタでの COM/COM+ コンポー ネントの構築」を参照してください。 5 プロジェクトを開いて、必要であれば、選択されたオブジェクト とそのプロパティのリストを修正し、プロジェクトを作成します。 6 サーバを配布します。 634 ページの「PowerBuilder COM サーバの配布」を参照してくだ さい。 コンポーネント オブジェクト モデルについて Microsoft コンポーネント オブジェクト モデル(COM)は、ソフトウェ ア コンポーネントが互いにサービスを提供するための標準的な方法 を定義します。実行環境、レジストリ エントリ、およびタイプ ライブ ラリ(オプション)を提供すれば、どの PowerBuilder カスタム クラス ユーザ オブジェクトでも、COM オブジェクトとして使用できます。 PowerBuilder や Visual Basic などの COM 準拠ツールで作成したクライ アントは、COM オブジェクトのビジネス ロジックを使用できます。そ れには、COM オブジェクトのインスタンスを作成し、そのインタ フェースによってエクスポーズされているメソッドを呼び出します。 サポートするインタフェースによって、COM オブジェクトは、Java と C++ のクライアントからも使用できます。 COM+ は、より多くのリソース管理タスクに対処し、スレッド プーリ ング、オブジェクト プーリング、ジャストインタイムのオブジェクト のアクティブ化を実現することで、COM を拡張したものです。 612 PowerBuilder 第 27 章 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 サーバには、複数のカス タム クラス ユーザ オブジェクトを含めることができます。ユーザ オ ブジェクトをコーディングした後で、プロジェクト ペインタを使用し て、すべてのオブジェクト用の 1 つの自己登録型 DLL を生成します。 構築コンピュータ上で実行する場合には、作成した COM サーバは、 COM+ に直接配布できます。また、COM+ パッケージを作成すること もできます。COM サーバ内の PowerBuilder COM オブジェクトは、実 行時セッションを共有できます。また、同じ COM クライアントから 作成されたオブジェクト間で参照を受け渡すこともできます。 PowerBuilder COM サーバ COM サーバには、埋め込み PowerBuilder 動的ライブラリ(PBD)ファ イルも含まれています。PBD ファイルは、選択したすべてのカスタム クラス ユーザ オブジェクトとそれに依存するコンパイル済みオブ ジェクトに加えて、レジストリとタイプ ライブラリの情報も含みま す。 アプリケーション テクニック 613 コンポーネント オブジェクト モデルについて PowerBuilder カ ス タ ム ク ラ ス ユ ー ザ オ ブ ジェクトから作成されたオートメーション サーバには、1 つのオブ ジェクトだけが含まれています。ユーザ オブジェクトを記述した後、 そのオブジェクトを含む PBL からランタイム ライブラリを作成し、続 いてプロジェクト ペインタを使用して、レジストリ ファイルとオプ ションのタイプ ライブラリ ファイルを作成します。オートメーション サーバを配布するとき、ユーザのコンピュータに合わせてレジストリ ファイルをカスタマイズし、そのレジストリ ファイルを実行してオー トメーション サーバを登録します。 オートメーション サーバ PowerBuilder オートメーション サーバまたは PowerBuilder COM サー バに加えて、サーバが必要とするほかの PowerBuilder ランタイム ファ イルもあわせて、仮想マシンを配布します。 ディスパッチ、デュア ル、カスタムの各イン タフェース オートメーション サーバは、ディスパッチ インタフェース(dispinterface ともいう)を使用します。これによって、ユーザは、IDispatch という 標準 COM インタフェースの Invoke メソッドを使用して、サーバ上の メソッドを呼び出すことができます。 COM サーバでは、ディスパッチベースのインタフェースよりも高いパ フォーマンスを提供する、カスタム インタフェースまたはデュアル イ ンタフェースを使用できます。カスタム インタフェースは、サーバの インタフェース内のメソッドへのポインタが格納された仮想テーブル (VTBL または vtable ともいう)を介して、サーバ上のメソッドへのア クセスを提供します。デュアル インタフェースを使用すれば、クライ アントは、IDispatch::Invoke または仮想テーブルのどちらを使用しても、 メソッドを呼び出すことができます。 詳細については、632 ページの「カスタム インタフェースとデュアル インタフェースの選択」を参照してください。 サーバ間の相違のまと め 614 表 27-1 に、PowerBuilder オートメーション サーバと、デュアル インタ フェースまたはカスタム インタフェースを使用する PowerBuilder COM サーバとの相違をまとめます。 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 表 27-1: オートメーション サーバと COM サーバの比較 機能 インプロセス サーバのサポート IDL ファイルの生成 C++ クライアントのサポート Java クライアントのサポート PowerBuilder クライアントのサ ポート Visual Basic 4 クライアントのサ ポート Visual Basic 5 カスタム インタ フェースのサポート インスタンス変数およびメソッ ド引数タイプとしての PowerBuilder 構造体のサポート すべての C 言語データ型のサ ポート 埋め込みタイプ ライブラリのサ ポート 自己登録サーバ DCOM のサポート # EAServer のサポート COM+ のサポート 別個のプロキシ / スタブ DLL が 必要 PowerBuilder ランタイム DLL が 必要(最低限 PBVM100.DLL と その依存ライブラリ) ライブラリ ペインタで作成した アプリケーション ランタイム ラ イブラリの配布が必要 オートメー ション サー COM サーバ バ(ディス (デュアル パッチ イン インタ タフェース) フェース) Yes* Yes No Yes No Yes Yes Yes Yes Yes COM サーバ (カスタム インタ フェース) Yes Yes Yes No No Yes Yes No No No Yes 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 実行 DLL(PBVM100.dll)は、インプロセス サーバです。 # PowerBuilder 実行 DLL を収容するために、代理ホストを使用する必要があります。 アプリケーション テクニック 615 コンポーネント インタフェースの定義 コンポーネント インタフェースの定義 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 ); インスタンス変数 616 COM オブジェクトは自分のデータをエクスポーズしないため、カスタ ム クラス ユーザ オブジェクト内のパブリック インスタンス変数は、 COM オブジェクトにおいて変数値を取得および設定するためのイン タフェース メソッドとして表現します。変数のアクセサ メソッドをイ ンタフェースとしてエクスポーズするための指定は、プロジェクト ウィザードまたはプロジェクト ペインタの[オブジェクト]プロパ ティ ページで行います。 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 パブリック変数が書き込み可能である場合には、Put メソッドがエクス ポーズされます。プライベート変数とプロテクト変数、privateread ま たは protectedread として宣言された変数、および privatewrite または protectedwrite として宣言された変数の場合には、メソッドは生成され ません。変数がパブリックに読み込み可能である場合には、Get メソッ ドがエクスポーズされます。たとえば、オブジェクトに以下のインス タンス変数があるとします。 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] 表 27-2 で示すように PowerBuilder のデータ型は COM のデータ型に マップします。 表 27-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 データ型) アプリケーション テクニック SAFEARRAY(COM データ型) 617 コンポーネント インタフェースの定義 PowerBuilder データ型 ResultSet COM のデータ型(バリアント) LPDISPATCH カスタム クラス ユーザ オブジェ LPDISPATCH クト * Any サポートなし グローバル構造体 サポートなし OLEObjects サポートなし * カスタム クラス ユーザ オブジェクトは、同じ COM アパートメントの同じクライア ント内(つまり、同じスレッド内)で作成する必要があります。 コーディング上の制約 ユーザ オブジェクトを COM コンポーネントとして配布する場合に は、コードで使用できない要素がいくつかあります。 関数の多重定義は使用 できない COM は、COM オブジェクトへのインタフェースにおいて、関数の多 重定義をサポートしていません。ユーザ オブジェクト(およびその先 祖)内の各関数の名前は一意でなければなりません。PowerBuilder COM オブジェクトは単一のインタフェースしか持ちません。同じ名前で あってもシグネチャが異なる複数の関数は、複数のインタフェースが 必要となります。 先祖変数と先祖関数の 表現方法 子孫ユーザ オブジェクトから PowerBuilder COM オブジェクトを生成 すると、先祖と子孫のパブリック インスタンス変数と関数がその COM オブジェクトに表現されます。一部のコンポーネント メソッドは先祖 オブジェクトから派生したものになりますが、そのことはクライアン トからは見えません。上述の関数の多重定義の制約によって、子孫オ ブジェクトの関数は先祖オブジェクトの関数を上書きはできますが、 オーバーロードすることはできません。 引数と戻り値のデータ 型 COM オブジェクトとして配布する非ビジュアル オブジェクトに関連 付けられたメソッドは、以下のデータ型を持つ引数を受け取ることが できます。 618 • 標準の OLE オートメーション データ型 • カスタム クラスの(非ビジュアル)ユーザ オブジェクト PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 COM コンポーネント メソッドは、PowerBuilder 構造体または Any 型の 引数または戻り値を受け取ることができません。引数として Any 変数 を受け取ったり、Any 変数を返したりする PowerBuilder 非ビジュアル オブジェクト上で定義された関数は、そのオブジェクトのローカルな コードからは呼び出せますが、クライアントまたはそのほかの COM コ ンポーネントからこれらの関数にアクセスすることはできません。 コンポーネント メソッドへの引数には、ビジュアル オブジェクト (ウィンドウやメニューなど) 、および大半のシステム タイプ(Transaction オブジェクトや DataStore オブジェクトなど)も指定できません。サ ポートされている唯一のシステム タイプは、ResultSet オブジェクトで す。 コンポーネント メソッドの戻り値には、任意の標準データ型を指定で きます。また、カスタム クラス(非ビジュアル)ユーザ オブジェクト も指定できます。 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 検証がチェックされた状態で作成されます。 アプリケーション テクニック 619 COM コンポーネントからデータベースへのアクセス ログ ファイルへのエラー記録 COM+ で動作している COM オブジェクトによって生成されたエラー を、Windows シ ス テ ム の ア プ リ ケ ー シ ョ ン ロ グ に 出 力 す る に は、 ErrorLogging サービス コンテキスト オブジェクトのインスタンスを作 成し、その log メソッドを呼び出します。たとえば、次のようになり ます。 ErrorLogging el this.GetContextService("ErrorLogging", el) el.log(" この文字列をログに書き込みます ") 例外情報の自動記録 サーバで実行している PowerBuilder コンポーネントが引き起こす例外 の種類および例外の位置に関する情報は、自動的にサーバ ログに記録 されます。これらの例外についての最低限の情報を取得するためにエ ラー ログ サービスを実行する必要はありません。 COM コンポーネントからデータベースへのアクセス COM+ のトランザクション管理サポートを活用するには、COM+ がサ ポートするデータベース インタフェースのいずれかを使用してデー タベースに接続する必要があります。PowerBuilder で開発したコン ポーネントのデータベース接続の詳細については、 『データベースとの 接続』マニュアルを参照してください。 PowerBuilder で開発された COM コンポーネントは、データストアを使 用して、データベースとの対話処理を行うことができます。データス トア は非表示のデータウィンドウ コントロールです。つまり、データ ウィンドウ コントロールと同じように動作しますがビジュアル属性 を持ちません。データストア オブジェクトを分散アプリケーションで 使用すると、データベース処理を、各クライアント コンピュータ上で はなくリモート サーバ上で行うことができます。 トランザクション サーバ環境におけるデータベース アクセスに デー タストア を使用する方法についての詳細は、516 ページの「データス トアの使い方」を参照してください。 620 PowerBuilder 第 27 章 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) を使用するとき、結果集合を戻すのに使用する別の構文もあります。 表 27-3 に、これらのオブジェクトの対話方法を示します。 表 27-3: 結果集合オブジェクト 使用する変数の タイプ ResultSet OLEObject アプリケーション テクニック 使用方法 COM コンポーネントに定義されたメソッド(関数)の戻 り値として使用する。データは ADO Recordset としてマー シャリングされる ResultSet を返す COM コンポーネント上のメソッドから 返された ADO Recordset を保持する。OLEObject は、 MoveFirst などの ADO Recordset 関数を使用して操作でき る 621 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 コンポーネント上の 622 PowerBuilder 第 27 章 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() アプリケーション テクニック 623 トランザクションのサポート 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+ は、 コンポーネントのデータベース操作がトランザクションの一部として 実行されるようにします。 トランザクション サービス コンテキス ト オブジェクトの使 い方 624 COM+ で動作する PowerBuilder コンポーネントは、トランザクション コンテキスト サービスを使用して、トランザクションを制御できま す。PowerBuilder COM オブジェクトが作成するコンテキスト オブジェ クトによって、PowerBuilder コンポーネントは Microsoft DTC を利用す ることができます。TransactionServer オブジェクトによって、COM+ で動作する COM オブジェクトは、オブジェクトに関連付けられてい るコンテキストにアクセスできるため、トランザクションとアクティ ブ化をより厳しく管理できます。また、セキュリティ コンテキストに 関しても部分的に制御が可能です。 PowerBuilder 第 27 章 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 が発行 されるまでは、アクティブ状態を保ちます。 アプリケーション テクニック 625 トランザクションのサポート 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+ プロジェクト ウィザードまたはプロ ジェクト ペインタで設定します。設定可能な値は、表 27-4 のとおりで す。 表 27-4: コンポーネント トランザクション プロパティの値 トランザクションの 種類 [サポートなし] [サポート] 626 説明 コンポーネントはトランザクションの一部として実 行されない。コンポーネントが、トランザクション 内部で実行中の別のコンポーネントによってアク ティブにされた場合には、その新しいインスタンス の作業は既存のトランザクションの外部で行われる コンポーネントは COM+ トランザクションのコンテ キスト内で実行できるが、コンポーネントのメソッ ドを実行するために接続は必要ない。コンポーネン トがクライアントによって直接インスタンス化され た場合には、COM+ はトランザクションを開始しな い。コンポーネント A がコンポーネント B によって インスタンス化され、コンポーネント B はトランザ クション内部で実行されている場合には、コンポー ネント A は同じトランザクション内で実行される PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 トランザクションの 種類 説明 [必要] コンポーネントは常にトランザクション内で実行さ れる。コンポーネントがクライアントによって直接 インスタンス化された場合には、新しいトランザク ションが始まる。コンポーネント A がコンポーネン ト B によってアクティブにされ、しかも B はトラン ザクション内で実行されている場合には、A は同じ トランザクション内で実行される。B がトランザク ション内で実行されていない場合には、A は新しい トランザクション内で実行される [新規が必要] コンポーネントがインスタンス化されるたびに、新 しいトランザクションが始まる。コンポーネント A がコンポーネント B によってアクティブにされ、B がトランザクション内部で実行されている場合に は、A は B のトランザクションの結果に影響されな い新しいトランザクションを開始する。B がトラン ザクション内で実行されていない場合には、A は新 しいトランザクション内で実行される トランザクションの仕組みについての詳細は、MSDN Library のサイト http://msdn.microsoft.com/library/default.asp に あ る Microsoft COM+ の マ ニュアルを参照してください。 別のサーバ コンポーネントのメソッドの呼び出し COM+ では、あるサーバ コンポーネントのメソッドが、別のサーバ コ ンポーネントのメソッドを呼び出すことができます。この別のサーバ コンポーネントは、PowerBuilder コンポーネントである必要はなく、 COM+ によってサポートされている任意の言語で実装できます。 OLEObject オブジェ クトの使い方 別のコンポーネントのメソッドにアクセスするには、クライアントか らコンポーネントを呼び出す場合と同様に、OLEObject 型の変数を宣 言し、ConnectToNewObject 関数を呼び出して、コンポーネントに接続し ます。ConnectToNewObject は、サーバ オブジェクトのトランザクショ ン コンテキストを自動的に継承します。 アプリケーション テクニック 627 セキュリティ問題 TransactionServer オ ブジェクトの使い方 現行のサーバ内の別のコンポーネントのメソッドにアクセスするには、 PowerBuilder が提供する、TransactionServer というトランザクション サービス コンテキスト オブジェクトを使用できます。 TransactionServer イ ンタフェースが提供する CreateInstance というメソッドを使用すれば、 ロ ー カ ル で 使 用 す る ほ か の コ ン ポ ー ネ ン ト に ア ク セ ス で き ま す。 CreateInstance は、呼び出し元のコンポーネントに適用されるのと同じ ユーザ情報とパスワード情報を使用します。 セキュリティ問題 COM+ に配布するコンポーネントを開発するときには、ロールを定義 して、特定のトランザクションの実行を許可されるユーザまたはユー ザのグループを決定することができます。コンポーネントを配布する ときには、COM+ Component Services ツールで特定のユーザにロールを 割り当てます。 プロジェクト ペイン タまたはウィザードで の権限の設定 ウィザードを使用して COM/COM+ プロジェクトを作成した場合に は、コンポーネントを呼び出すクライアントのセキュリティ資格を チェックするよう、COM+ に指示することができます。プロジェクト ペインタでは、[COM+ コンポーネント]と[COM+ パッケージ]の プロパティ ページで、コンポーネントとパッケージの 2 つのレベルで のチェックを指定することができます。 セキュリティを有効にするには、Microsoft Management Console 内で COM アプリケーションにロールを追加し、ユーザをそのロールに割り 当て、そのロールをコンポーネントに与えます。 プログラムによるセ キュリティ 628 PowerBuilder がトランザクション サービス オブジェクトで提供してい る関数をコンポーネント内で使用すれば、呼び出し側に特定のメソッ ドを呼び出す権限があるかどうか、プログラムで判定することができ ます。IsSecurityEnabled は、コンポーネントのセキュリティが有効であ るかどうかを判定します。IsCallerInRole は、コンポーネントのメソッド を呼び出すクライアント プロセスまたはサーバ プロセスが、呼び出し 権限を持つロールに含まれるどうかを判定します。 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 IsCallerInRole は、現行のメソッドの直接の呼び出し側のロールを調べ ます。クライアントがコンポーネント上のメソッドを呼び出し、その メソッドがデータベースにアクセスする場合には、データベースへの アクセス権は、クライアントではなく、コンポーネントのセキュリティ コンテキストによって決定されます。PowerBuilder がトランザクショ ン サービス オブジェクトに提供する追加関数によって、コンポーネン トは、クライアントに権限のない操作を実行する前に、クライアント のセキュリティ コンテキストを判断することができます。 ImpersonateClient は、クライアントのセキュリティ コンテキストを判断 します。IsImpersonating は、コンポーネントがそのクライアントのセ キュリティ コンテキスト内で動作しているかどうかを判断します。ま た、RevertToSelf は、コンポーネントのセキュリティ コンテキストを復 元します。 偽装 プロジェクト ペインタでの COM/COM+ コンポーネント の構築 PowerBuilder COM サーバは、プロジェクト ペインタで構築します。 ユーザ オブジェクトの作成時にプロジェクトを作成しなかった場合 には、COM/COM+ プロジェクト ウィザードを使用して作成できます。 [プロジェクト]タブの[COM/COM+ コンポーネント]アイコンを選 択すれば、プロジェクト ペインタで COM コンポーネントを直接作成 するプロジェクトを設定できます。 COM サーバに組み込みたい 1 つまたは複数のオブジェクトに対して、 COM/COM+ プロジェクトをすでに作成している場合には、プロジェク ト ペインタで修正し、必要に応じてオブジェクトを追加します。 プロジェクト ペインタのワークスペースは読み取り専用の領域であ り、ウィザードで選択したオプション、またはペインタのオブジェク トの選択 ダイアログボックスおよびプロパティ ダイアログボックス で選択したオプションが表示されます。PowerBuilder COM サーバを構 築する際、このワークスペースには、構築プロセスの各ステップのス テータスとオブジェクト検査レポートも表示されます。 ❖ PowerBuilder COM サーバ プロジェクトを定義および構築するには 1 アプリケーション テクニック 新規作成 ダイアログボックスの[プロジェクト]タブから [COM/COM+ コンポーネント ウィザード]を選択します。 629 プロジェクト ペインタでの COM/COM+ コンポーネントの構築 2 プロジェクトの名前と位置を含む、プロジェクト プロパティを指 定します。 3 サーバに組み込みたい 1 つまたは複数のオブジェクトを選択しま す。 4 各オブジェクトのプロパティを指定し、必要なら COM+ の配布オ プションも指定して、[完了]をクリックします。 プロパティを指定する際には、ウィザードの状況依存ヘルプまた は以下の項目を参考にしてください。 プロパティ インタフェース オプ ション 構築オプション コンポーネントの登録 COM+ の配布オプショ ンとパッケージ オプ ション COM+ トランザクショ ンの設定 COM+ セキュリティ 参照箇所 632 ページの「カスタム インタフェースと デュアル インタフェースの選択」と 616 ペー ジの「インスタンス変数」 632 ページの「埋め込み PBD の設定」 631 ページの「コンポーネントの自動登録」 631 ページの「COM+ にコンポーネントを配 布」 626 ページの「コンポーネントがトランザク ションをサポートするかどうかの指定」 628 ページの「セキュリティ問題」 5 [ファイル|開く]を選択し、作成したばかりのプロジェクトを選 択して、プロジェクト ペインタを開きます。 正しいオブジェクトが選択されていることを確認するには、メ ニューバーから[編集|オブジェクトの選択]を選択します。 6 [編集|プロパティ]を選択してウィザードで設定したプロパティ を確認し、必要なら修正します。 一部の高度な COM+ パッケージ プロパティは、プロジェクト ペイ ンタでのみ設定できます。 7 プロジェクト ペインタで[配布]ボタンをクリックして、 PowerBuilder COM サーバを構築します。 こ の 構 築 プ ロ セ ス で は、選 択 し た 各 ユ ー ザ オ ブ ジ ェ ク ト の PowerBuilder COM オブジェクトを含む PowerBuilder COM サーバ (DLL)と IDL ファイルが作成されます。COM+ への配布を指定 し、COM+ がコンポーネントを生成するコンピュータ上にインス トールされ動作している場合、コンポーネントはサーバに直接配 布されます。このとき、追加の配布ファイルが作成されることも あります。 630 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 PowerBuilder COM サーバに含まれる埋め込み型 PBD ファイルに は、カスタム クラス ユーザ オブジェクトと、それらのオブジェク トが参照する補助オブジェクトに加えて、埋め込みのタイプ ライ ブラリも含まれています。 オブジェクト呼び出し後のプロジェクトの構築 開発環境で COM オブジェクトを呼び出すと、COM オブジェクトは PowerBuilder と同じプロセスで管理されるので PowerBuilder が終了す るまでメモリに残ります。オブジェクトを呼び出してから変更し、プ ロジェクト ペインタで再生成しようとすると、コンパイル エラーとリ ンク エラーが発生します。プロジェクトを構築する前に、PowerBuilder をシャットダウンして再起動し、メモリからオブジェクトを解放して ください。 コンポーネントの自動登録 プロジェクト ウィザードまたはプロジェクト ペインタでは、構築に成 功したときに、生成されたすべての PowerBuilder COM オブジェクトを 自動登録するように指定できます。これによって、使用コンピュータ でのコンポーネントのテストが簡単になります。使用コンピュータ上 で不必要なレジストリ エントリが作成されるのを避けるため、このオ プションを選択するのは、PowerBuilder COM サーバのテスト準備が完 了してからにしてください。 COM+ にコンポーネントを配布 正常に構築されたコンポーネントは、COM+ に自動的に配布できます。 アプリケーションを Microsoft Windows Installer(MSI)ファイルにエク スポートし、これを使って別のコンピュータ上の COM+ サーバにパッ ケージをインポートできます。次にアプリケーション プロキシを MSI ファイルとしてエクスポートし、それをクライアント コンピュータ上 にインストールすると、リモートの COM+ サーバにアクセスできるよ うになります。COM+ コンポーネントの配布についての詳細は、MSDN Library のサイト http://msdn.microsoft.com/library/default.asp にある Microsoft COM+ のマニュアルを参照してください。 アプリケーション テクニック 631 プロジェクト ペインタでの COM/COM+ コンポーネントの構築 カスタム インタフェースとデュアル インタフェースの選択 COM オブジェクトを生成するときには、クライアントにカスタム イ ンタフェースとデュアル インタフェースのどちらをエクスポーズす るのかを選択する必要があります。PowerBuilder COM オブジェクトで は、現在、どちらのインタフェース タイプでも、標準の OLE オート メーション データ型しか使用できません。 カスタム インタ フェース カスタム インタフェースは、サーバ オブジェクトの仮想関数テーブル (VTBL)へのアクセスを通じて、ディスパッチベースのインタフェー スより高いパフォーマンスと、デュアル インタフェースよりすっきり した使用モデルを提供します。クライアントを C++ などのコンパイル 言語で記述する場合、または Visual Basic などのツールでカスタム イ ンタフェースのサポートを活用する場合には、カスタム インタフェー スの使用を考えてください。 カスタム インタフェースを使用する PowerBuilder COM オブジェクト は、COM によって提供される標準のマーシャル処理を使用します。 デュアル インタ フェース デュアル インタフェースを使用すれば、プログラマは、仮想関数テー ブルとディスパッチ インタフェースのどちらを使用しても、COM オ ブジェクト内のメソッドを呼び出すことができます。デュアル インタ フェースは、広範囲のクライアントをサポートし、メソッドへの高速 アクセスを提供します。 埋め込み PBD の設定 COM サーバに含まれる埋め込み PowerBuilder 動的ライブラリ(PBD) ファイルには、選択したコンパイル済みのすべてのカスタム クラス ユーザ オブジェクトとその依存オブジェクトが含まれています。追加 の未参照オブジェクトを PBD に組み込むには、[ライブラリ]プロパ ティ ページで、そのオブジェクトを含むライブラリを選択します。選 択したライブラリ内のすべてのオブジェクトが PBD に含められます。 ライブラリに関連付けられた PowerBuilder リソース(PBR)ファイル の名前を指定できます。PBR ファイルは、ビットマップなどの動的に 割り当てられたリソースのリストを含むテキスト ファイルです。詳細 については、825 ページの「リソースについて」を参照してください。 632 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 PowerBuilder COM オブジェクトの実行 PowerBuilder COM オ ブ ジ ェ ク ト の イ ン ス タ ン ス を 設 定 す る た め、 PowerBuilder 仮想マシン(PBVM100.dll)は、COM サーバ DLL に埋め 込まれた PBD からカスタム クラス オブジェクトをロードし、適切な セッション情報とインスタンス情報を作成します。クライアントが PowerBuilder COM オブジェクトのメソッドを呼び出すと、そのメソッ ドは PowerBuilder 仮想マシンをコールバックし、適切な PowerScript コードを実行します。 PowerBuilder COM サーバは、COM の single-threaded apartment(STA) モデルを使用しています。実行時セッションは、同じスレッド上に作 成されたオブジェクト間で共有できます。クライアントが PowerBuilder COM オブジェクトのインスタンスを要求すると、PowerBuilder COM サーバは実行時セッションを確立し、その実行時セッション中にカス タム クラス ユーザ オブジェクトのインスタンスを作成します。サー バが同じスレッドから COM オブジェクトのインスタンスに対する新 しいリクエストを受け取ると、既存の実行時セッションを使用して、 オブジェクトをインスタンス化します。 いずれの場合も、個々のクライアントは異なる PowerBuilder 仮想マシ ン セッションを使用します。 メモリの割り当て クライアントが PowerBuilder COM サーバから PowerBuilder COM オブ ジェクトのインスタンスを初めて要求すると、サーバは PowerBuilder 仮想マシンをロードし、メモリ ブロックを割り当て、実行時セッショ ンを開始します。PowerBuilder 仮想マシン、キャッシュ メモリ、およ び実行時セッションに約 4 MB のメモリが割り当てられます。 オブジェクトが同じ実行時セッションを共有できる場合には、それ以 降のリクエストでは追加のメモリ割り当てが不要になります。 それ以降のリクエストにおいて、リクエストが別のクライアントまた はスレッドから作成されたなどの理由で、PowerBuilder COM オブジェ クトを別の COM アパートメントで作成する必要がある場合、オブジェ クトは新しい実行時セッションでインスタンス化されます。新しい各 セッションは、PowerBuilder 仮想マシンのインスタンスとキャッシュ メモリを共有するため、約 200 KB のメモリを消費するだけで済みま す。 アプリケーション テクニック 633 PowerBuilder COM サーバの配布 PowerBuilder COM サーバの配布 PowerBuilder COM サーバを生成したら、COM 対応のクライアント ア プリケーションを使用して、PowerBuilder COM オブジェクトを作成 し、それらのメソッドにアクセスすることができます。COM 対応の任 意のアプリケーションでサーバを使用したり、サーバをパッケージと して COM+ に配布することができます。 COM 対応のアプリケーションによる PowerBuilder COM サーバの使い 方 ❖ COM 対応のアプリケーションで PowerBuilder COM サーバを使用するには 1 PowerBuilder COM サーバをユーザのコンピュータに配布します。 2 PowerBuilder 仮想マシン(PBVM100.dll)とそのほかの必要なモ ジュール(PBDWE100.dll や必要なデータベース ソフトウェアな ど)を、PowerBuilder COM サーバをインストールしたコンピュー タに配布します。 3 PowerBuilder COM サーバをユーザのコンピュータに登録します。 4 PowerBuilder COM サーバ内の PB オブジェクト関数を呼び出すク ライアント アプリケーションを記述します。 635 ページの「クライアントから PowerBuilder COM サーバへのア クセス」を参照してください。 PowerBuilder COM サーバの登録 PowerBuilder COM サーバを配布する ときには、レジストリに情報を追加して、COM がサーバ オブジェクト のインスタンスを作成できるようにする必要があります。PowerBuilder COM サーバは自己登録型なので、登録ファイルを別に作成する必要は ありません。PowerBuilder COM サーバを登録するには、次のように REGSVR32 ユーティリティを使用します。 regsvr32.exe path_to_server\mycomserver.dll リモート クライアントからサーバにアクセスする場合には、レジスト リをさらに変更する必要があり、サーバへのリモート アクセス用にク ライアントの設定が必要になる場合もあります。詳細については、639 ページの「DCOM での PowerBuilder COM サーバとオブジェクトの使 い方」を参照してください。 634 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 テスト用の自動登録 テスト目的の場合には、 [全般]プロパティ ページにあるチェックボッ クスをオンにします。これにより、サーバが生成されるとそのサーバ は開発コンピュータに自動登録されます。使用コンピュータ上で不必 要なレジストリ エントリが作成されるのを避けるため、このオプショ ンを選択するのは、PowerBuilder COM サーバのテスト準備が完了して からにしてください。 クライアントから PowerBuilder COM サーバへのアクセス COM 準拠のツールで作成したクライアントは、PowerBuilder COM コ ンポーネント上のメソッドにアクセスできます。COM+ の場合、クラ イアントは Microsoft Windows Installer を必要とします。COM サーバが クライアント マシンに登録されているか、COM+ アプリケーション プ ロキシ ファイルがインストールされていなければなりません。 リモート クライアントから PB COM サーバにアクセスする方法につ いては、639 ページの「DCOM での PowerBuilder COM サーバとオブ ジェクトの使い方」を参照してください。 以下の例では、Visual Basic または C++ から PowerBuilder COM オブジェ クトにアクセスする方法を示します。これらの例では、ccuo_employee と いうユーザ オブジェクトから生成され、PB100.employee というプログ ラム ID を持つ PowerBuilder COM オブジェクトを使用します。 PowerBuilder クライアントの作成方法と、同じ COM オブジェクトの使 用例については、第 28 章「COM/COM+ クライアントの構築」を参照 してください。 クライアントとしての Visual Basic Visual Basic では、そのプログラム ID を使用して登録オブジェクトに 接続できます(実行時バインド)。Visual Basic 5 以降では、そのクラス 名も使用できます(事前バインド)。 ❖ Visual Basic で PowerBuilder COM オブジェクトにアクセスするには 1 アプリケーション テクニック 次のどちらかを実行します。 635 クライアントから PowerBuilder COM サーバへのアクセス • オブジェクトを宣言し、そのプログラム ID を使用して接続し ます。 Dim EmpObj As Object Set EmpObj = CreateObject("PB100.employee") • PowerBuilder COM オブジェクトに対して生成されたタイプ ラ イブラリへの参照をプロジェクトに追加し、そのクラス名を使 用してオブジェクトのインスタンスを宣言します(Visual Basic 5 以降)。 Dim EmpObj As New CoEmployee 2 接続が確立されたことを確認します。 Dim response 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 636 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 MIDL コンパイラは、IDL ファイル内の全オブジェクトのインタフェー スの定義を含んでいるヘッダ ファイル(employee.h)、およびオブジェ クトに関連付けられた CLSID とインタフェース ID(IID)を定義する C ファイル(employee_i.c)を生成します。 そのほかのファイル MIDL コンパイラはプロキシ/スタブ コードも(employee_p.c と dlldata.c に)生成します。ただし、C++ クライアント実行ファイルを作成した り、PowerBuilder 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; アプリケーション テクニック 637 クライアントから PowerBuilder COM サーバへのアクセス virtual /* [id] */ HRESULT STDMETHODCALLTYPE f_teststring( /* [retval][out] */ BSTR __RPC_FAR *retval) = 0; }; EXTERN_C const CLSID CLSID_CoEmployee; Client.cpp 次のサンプル クライアント ファイルでは、MIDL によって 生成された、PowerBuilder COM オブジェクトの C/C++ 定義を使用して います。client.cpp に示されている COM API 呼び出しについての詳細 は、Microsoft ソフトウェア開発キットの資料を参照してください。 #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); 638 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 // インタフェース ptr を解放 pDIEmployee->Release(); CoFreeUnusedLibraries(); // 完了 CoUninitialize(); return 0; } DCOM での PowerBuilder COM サーバとオブジェクトの使い方 DCOM を使用すれば、リモート クライアントから PowerBuilder COM オブジェクトをアクティブにすることができます。オブジェクトは、 指定されたホスト コンピュータ上のサーバ プロセスでアクティブに する必要があります。アウト オブ プロセス サーバ(EXE ファイル) はサーバ プロセスを作成しますが、インプロセス サーバ(DLL ファ イル)は代理プロセス下で動作させる必要があります。 COM は、PowerBuilder COM サーバ DLL のホストとして使用できる汎 用の代理ホスト(DLLHOST.EXE)を提供しています。代理ホストを 使用するように、PowerBuilder COM サーバにマークを付けることは、 PowerBuilder COM オブジェクトをリモート クライアントからアクセ スを可能にするための最も重要なステップです。DCOM 環境設定ユー ティリティ(DCOMCNFG.EXE)を使用して、位置、セキュリティ、お よび識別情報の値を変更できますが、多くの場合にはデフォルトのま まで十分です。詳細については、DCOMCNFG ユーティリティのオンラ イン ヘルプを参照してください。 PowerBuilder COM サーバが代理ホストを 使用できるようにする PowerBuilder COM サーバが代理ホストを使用できるようにするには、 2 つの方法があります。 • レジストリ エディタ(REGEDIT32.EXE)を使用して、PowerBuilder COM サーバのレジストリ エントリ AppID を編集する • Microsoft Visual C++ 5.0 以降に付属する OLE/COM オブジェクト ビューア(OLEVIEW.EXE)を使用する コンピュータのレジストリを手作業で編集すると、コンピュータの構 成の一部または全部が動作不能になることがあるため、一般には OLEVIEW の使用をお勧めします。 アプリケーション テクニック 639 クライアントから PowerBuilder COM サーバへのアクセス ❖ レジストリ エディタを使用して、COM サーバが代理プロセスを使用できる ようにするには 1 サーバの生成に使われたプロジェクトを開き、 [全般]プロパティ ページから PowerBuilder COM サーバの AppID 値をコピーします。 2 REGEDIT.EXE を実行し、 マイ コンピュータ \HKEY_CLASSES_ROOT\AppID の位置にある サーバの AppID キーを探して選択します。 3 メニューバーから[編集|新規作成|文字列の値]を選択します。 4 名前に DllSurrogate を入力し、データ フィールドは空のままに しておきます。 データ フィールドが空である場合、COM はデフォルトの代理ホス ト(DLLHOST.EXE)を使用します。AppID 値のキーは次のように なります。 名前 (デフォルト) DllSurrogate ❖ データ PowerBuilder 10 が生成したサーバ :servername.dll "" OLE/COM オブジェクト ビューアを使用して、COM サーバが代理プロセス を使用できるようにするには 1 OLEVIEW.EXE を実行します。 2 リストビューでオートメーション オブジェクトを展開し、 PowerBuilder COM サーバのオブジェクトを選択します。 3 PowerBuilder COM サーバに関連付けられたオブジェクトを選択し ます。 4 [Implementation]タブを選択します。 5 [Inproc Server]タブを選択し、[Use Surrogate Process]チェック ボックスをオンにします。 クライアント コン ピュータを設定して、 リモート PowerBuilder COM オ ブジェクトをアクティ ブにする 640 リモート コンポーネントをアクティブにするには、クライアント アプ リケーションが、オブジェクトのクラス識別子(CLSID)を、リモー ト ホストに対するアクティブ化リクエストに指定して渡す必要があ ります。 PowerBuilder 10 や C++ で作成されたクライアントなど、一部のクライ アントは、リモート オブジェクトのインスタンスを作成するときに、 メソッド呼び出しでオブジェクトの CLSID を使用できます。これらの クライアント アプリケーションは、クライアント側の環境設定を必要 としません。 PowerBuilder 第 27 章 COM/COM+ コンポーネントの構築 多くのクライアントは、オブジェクトの CLSID ではなく、オブジェク トの名前(ProgID)によってオブジェクトを参照します。このような 場合、リモート アクティブ化リクエストを行うためには、クライアン ト コンピュータのレジストリに、ProgID を CLSID にマップするため に必要な情報が含まれていなければなりません。必要なレジストリ情 報をクライアント コンピュータに追加するには、次のどちらかの方法 を使用します。 • リモート アクセスを必要とするクライアント コンピュータごとに、 PowerBuilder COM サーバを登録します。 この方法を使用するには、適切なバージョンの PBVMn0.dll がイン ストールされていなければなりません。 • PowerBuilder COM サーバが登録されているホスト上で、 REGEDIT.EXE を使用して、必要なレジストリ情報を .REG ファイ ルにエクスポートし、続いてリモート アクセスを必要とする各ク ライアント コンピュータのレジストリに、これらのファイルをコ ピーおよびインポートします。 PowerBuilder COM オブジェクトごとに、以下のレジストリ キーを エクスポートします。 HKEY_CLASSES_ROOT\PB100.objectname HKEY_CLASSES_ROOT\PB100.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 6 以降のクライアントは、ConnectToNewRemoteObject 関数 を使用してリモート オブジェクトをアクティブにすることができま す。この部分のコードは次のようになります。 OLEObject remobj remobj = CREATE OLEObject remobj.ConnectToNewRemoteObject("myremotehostname", ”PB10.employee”) & PowerBuilder 7 以降のクライアントの場合は、リモート オブジェクト の CLSID 文字列を classname パラメータに指定できます。 remobj.ConnectToNewRemoteObject("myremotehostname", ”clsid:0EA53FED-646A-11D2-BF8E-00C04F795006”) アプリケーション テクニック & 641 クライアントから PowerBuilder COM サーバへのアクセス classname パラメータにオブジェクトの CLSID を指定すると、クライ アント側での環境設定は不要になります。 C++ を使用したリ モート オブジェクト に接続 生成された PowerBuilder COM サーバの IDL ファイルから作成された ヘッダ ファイルを使用する C++ クライアントは、アクティブ化リクエ ストで、リモート オブジェクトの CLSID を使用できます。 COSERVERINFO MULTI_QI OLECHAR LPTSTR ServerInfo; mqi[1]; wszHostName[MAXFILE]; pszHost=NULL; memset(&ServerInfo,0,sizeof(ServerInfo)); pszHost =GetUserRequestedHostName(); mbstowcs(wszHostName,pszHost,MAXFILE); 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); 642 PowerBuilder 第 2 8 章 COM/COM+ クライアントの構築 この章について この章では、COM または COM+ サーバ コンポーネントにアクセ スする PowerBuilder クライアントの構築方法について説明しま す。 内容 項目 COM/COM+ クライアントの構築について COM サーバへの接続 COM コンポーネントとのやり取り クライアントからのトランザクション制御 ページ 643 644 645 646 COM/COM+ クライアントの構築について PowerBuilder アプリケーションは、COM サーバのクライアントと して機能できます。COM サーバは、PowerBuilder またはそのほか の COM に準拠したアプリケーション開発ツールを使用して作成 できます。また、リモート コンピュータ上でインプロセス サーバ として、または COM+ 環境でローカルに実行できます。 アプリケーション スタート ウィザードを使用すれば、COM およ び COM+ クライアントを簡単に構築できます。 クライアント コンピュー タを設定してリモート コ ンポーネントにアクセス アプリケーション テクニック COM コンポーネントがリモート コンピュータ上で動作している 場合、クライアント コンピュータは、そのメソッドに透過的にア クセスできなければなりません。そのためには、クライアント側 にサーバに対応するローカルのプロキシ DLL を用意し、クライア ント コンピュータのレジストリにリモート サーバを識別するエ ントリを登録する必要があります。クライアント コンピュータは、 Windows 2000 または Windows XP 上で動いていなければなりませ ん。 643 COM サーバへの接続 コンポーネントが COM+ にインストールされている場合は、COM+ コ ンポーネント サービス ツールを使用して 、クライアント コンピュー タ 上 に ア プ リ ケ ー シ ョ ン プ ロ キ シ を イ ン ス ト ー ル す る Microsoft Windows インストーラ(MSI)ファイルを作成します。 サーバが COM+ にインストールされていない場合は、クライアント ファイルとプロキシ ファイルをクライアントにコピーし、サーバを代 理プロセスで動作させるように設定する必要があります。詳細につい ては、639 ページの「DCOM での PowerBuilder 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 644 PowerBuilder 第 28 章 COM/COM+ クライアントの構築 EmpObj = CREATE OLEObject li_rc = EmpObj.ConnectToNewObject("PBcom.employee") IF li_rc < 0 THEN DESTROY EmpObj MessageBox(" オブジェクトへの接続に失敗 ", & " エラー :" + 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)は、データストア オブジェクトと の間でトランザクション サーバの結果集合の変換を簡単にするため に設計されたものであり、状態情報を含んでいません。 アプリケーション テクニック 645 クライアントからのトランザクション制御 詳細については、621 ページの「結果集合の受け渡し」を参照してく ださい。 実行時エラー処理 OLE オートメーション オブジェクト、COM オブジェクト、または COM+ コンポーネントとして実行されているカスタム クラス ユーザ オブジェクトからの実行時エラー情報は、オブジェクトを保持するコ ンテナに例外として(オートメーション オブジェクトの場合は、例外 または機能エラーとして)レポートされます。PowerBuilder SignalError 関数への呼び出しも、コンテナにレポートされます。PowerBuilder オ ブジェクトによって生成された実行時エラーを処理するには、OLE ク ライアントの ExternalException イベントを記述します。 OLE オブジェクトまたは COM オブジェクトにおける実行時エラー処 理についての詳細は、384 ページの「エラー処理」を参照してください。 クライアントからのトランザクション制御 PowerBuilder クライアントは、OLEObject 型ではなく、OleTxnObject 型 の変数を使用して COM オブジェクトに接続することによって、COM+ サーバ上のトランザクションを明示的に制御できます。 COM+ のインストールが必要 COM+ がクライアント コンピュータにインストールされていないと、 OleTxnObject での ConnectToNewObject 呼び出しは失敗します。 OLEObject オブジェクトから派生した OleTxnObject オブジェクトに は、クライアントがトランザクション制御に参加するための 2 つの関 数(SetComplete と SetAbort)が追加定義されています。クライアント が SetComplete を呼び出すと、そのトランザクションは、トランザク ションの別の参加者が SetAbort を呼び出していなければコミットされ ますが、そうでない場合は失敗します。クライアントが SetAbort を呼 び出すと、トランザクションは常に中断します。 例 次の例では、 ボタンの Clicked イベントによって OleTxnObject 型の 変数を作成し、サーバ上の PowerBuilder COM オブジェクトに接続し、 オブジェクト上のいくつかのメソッドを呼び出しています。すべての メソッドが復帰すると、クライアントは SetComplete を呼び出して、 サーバとの接続を切断します。 646 PowerBuilder 第 28 章 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 呼び出し によってトランザクションがコミットされます。 アプリケーション テクニック 647 クライアントからのトランザクション制御 648 PowerBuilder 第 7 部 Web アプリケーションの開発 第 7 部では、PowerBuilder で Web アプリケーションを 開発するためのツールとテクニックについて説明します。 第 2 9 章 EJB クライアントの構築 この章について この章では、J2EE 準拠のアプリケーション サーバ上で動作する Enterprise JavaBeans コンポーネント用の PowerBuilder クライアン トの構築方法について説明します。この章で説明するオブジェク トの関連情報については、 『PowerBuilder エクステンション リファ レンス』 マニュアルおよびオンライン ヘルプを参照してください。 内容 項目 EJB クライアントの構築について ライブラリ探索パスへの pbejbclient100.pbd の追加 EJB プロキシ オブジェクトの生成 Java VM の作成 サーバへの接続 コンポーネント メソッドの呼び出し 例外処理 クライアント管理のトランザクション クライアントのデバッグ ページ 651 653 655 663 666 667 672 674 675 EJB クライアントの構築について PowerBuilder アプリケーションは、J2EE 準拠のアプリケーション サーバ上で実行する EJB 1.1 または 2.0 コンポーネントに対するク ライアントとして動作することが可能です。この機能は、Sybase が 提供する PowerBuilder エクステンション ファイルに依存します。 PowerBuilder エクステンション ファイルは、PowerBuilder Native Interface(PBNI)を使用して開発されたものです。EJB クライアン ト を 作 成 す る た め に PBNI に 関 す る 知 識 は 必 要 あ り ま せ ん。 PowerBuilder エクステンションについての詳細は、 『PowerBuilder エクステンション リファレンス』マニュアルに記載されていて、 また、PBNI についての詳細は、『PowerBuilder ネイティブ インタ フェース プログラマーズ ガイドとリファレンス』マニュアルに記 載されています。 アプリケーション テクニック 651 EJB クライアントの構築について EAServer 用 EJB クライアント EAServer 用の EJB クライアントを開発する場合、この章で説明するテ クニックを使用することができます。また、PowerBuilder 接続オブジェ クトと EAServer プロキシ オブジェクトを使用するクライアントを作 成することもできます。 EJB クライアント エクステンションは Java 対応のラッパーであるた め、より柔軟に EJB と通信できます。たとえば、EJB クライアントは、 EJB プロキシを介して EJB メソッド呼び出しから返された Java クラス を操作できます。 EJB クライアントが存在するコンピュータ上に JRE をインストールす る必要がないので、PowerBuilder 接続オブジェクトはより小さくなり、 配備しやすくなります。また、PowerBuilder 接続オブジェクトを使用 すると、JRE ロードによる遅滞が生じないために、サーバへの接続も 速くなります。 PowerBuilder 接続オブジェクトを使用した EAServer 上で動作する EJB コンポーネント用の EJB クライアント構築についての詳細は、第 25 章 「EAServer クライアントの構築」を参照してください。 pbejbclient100.pbx と pbejbclient100.pbd サーバに接続して EJB コンポーネントと通信するためには、クライア ントは DLL ファイル、pbejbclient100.pbx に実装されているクラスの セットを使用します。この DLL を使用するには、DLL をアプリケー ションのパスに置き、さらに、クライアント アプリケーションのライ ブラリ探索パスに pbejbclient100.pbd ファイルを追加する必要がありま す。PBD は DLL のラッパーとして機能し、これにより、PowerBuilder クライアントは DLL 内のクラスを PowerBuilder カスタム クラス ユー ザ オブジェクトのように使用できます。 EJB プロキシ オブ ジェクトについて PowerBuilder クライアントは、リモート EJB コンポーネントのメソッ ド呼び出しを EJB コンポーネントのローカル プロキシ オブジェクト に任せます。各 EJB コンポーネントは最小限、クライアント アプリ ケーション内で、ホーム インタフェース用プロキシとリモート インタ フェース用プロキシによって表されます。たとえば、Cart という EJB コンポーネントには、CartHome と Cart の 2 つのプロキシがあります。 それぞれのプロキシには、これらのインタフェースのパブリック メ ソッドのシグネチャのみが含まれます。 さらに、ホーム インタフェースとリモート インタフェースによって使 用される例外と補助クラスに対しても、プロキシが生成されます。詳 細については、655 ページの「EJB プロキシ オブジェクトの生成」を 参照してください。 652 PowerBuilder 第 29 章 プロセスの概要 EJB クライアントの構築 EJB クライアントを構築するには、以下の手順をすべて実行する必要 があります。 1 ワークスペースと PowerScript ターゲットを作成します。 2 pbejbclient100.pbd を、ターゲットのライブラリ探索パスに追加し ます。 3 プロキシ オブジェクトの構築のためのプロジェクトを作成します。 4 プロキシ オブジェクトを生成するためにプロジェクトを作成します。 5 クライアント アプリケーションのユーザ インタフェースを実装 するために必要なウィンドウを作成します。 6 Java VM をインスタンス化します。 7 サーバへの接続を確立し、EJB を検索します。 8 EJB コンポーネントのインスタンスを作成し、クライアントから コンポーネント メソッドを呼び出します。 9 クライアントのテストとデバッグを行います。 ライブラリ探索パスへの pbejbclient100.pbd の追加 PowerBuilder をインストールすると、pbejbclient100.pbx と pbejbclient100.pbd ファイルは、Shared\PowerBuilder ディレクトリに配 置されます。EJB クライアント アプリケーションを構築する場合、 pbejbclient100.pbx を別の場所にコピーする必要はありませんが、アプ リケーションの探索パス内のディレクトリに、クライアント実行ファ イルとともにこのファイルを配布する必要があります。 pbejbclient100.pbd ファイルは、クライアント アプリケーションのライ ブラリ リストに含める必要があります。テンプレート アプリケーショ ン ウィザードを使用して、EJB クライアント ターゲットを作成し、 ウィザード内で PBD ファイルを追加できます。アプリケーション ウィ ザードを使用するか、既存のターゲットがある場合、ターゲットのプ ロパティ ダイアログボックスで、ライブラリ リストに PBD ファイル を追加できます。 アプリケーション テクニック 653 ライブラリ探索パスへの pbejbclient100.pbd の追加 ❖ pbejbclient100.pbd を新規ターゲットの探索パスに追加するには 1 新規作成 ダイアログボックスで、[テンプレート アプリケーショ ン ウィザード]アイコンを選択し、ウィザードの指示に従って[ラ イブラリ探索パス]ページまで進みます。 2 参照( [...])ボタンをクリックし、Shared\PowerBuilder ディレクト リに移動します。 3 [ファイルの種類]ドロップダウン リストの[PB ダイナミック ラ イブラリ]を選択し、pbejbclient100.pbd を選び、 [開く]をクリッ クします。 ウィザードを終了します。 4 ❖ pbejbclient100.pbd を既存のターゲットの探索パスに追加するには 1 システム ツリー内でクライアント ターゲットを右クリックし、ポッ プアップ メニューから[プロパティ]を選択します。 2 [ライブラリ リスト]ページで参照([...])ボタンを選択し、 Shared\PowerBuilder ディレクトリに移動します。 3 [ファイルの種類]ドロップダウン リストの[PB ダイナミック ラ イブラリ]を選択し、pbejbclient100.pbd を選び、ダイアログボッ クスを閉じます。 pbejbclient100.pbd を追加すると、システム ツリーには以下のオブジェ クトが表示されます。 オブジェクト EJBConnection EJBTransaction JavaVM 654 説明 EJB サーバに接続し EJB を特定するために使用する javax.transaction.UserTransaction インタフェースにマッ プする。EJB クライアントからトランザクションを制 御するために使用する Java VM のインスタンスを作成するために使用する PowerBuilder 第 29 章 EJB クライアントの構築 EJB プロキシ オブジェクトの生成 EJB プロキシ オブジェクトを生成するには、EJB クライアント プロキ シ プロジェクトを作成する必要があります。EJB クライアント プロキ シ プロジェクトの作成には、プロジェクト ペインタかウィザードを使 用します。 EJB プロキシ プロジェクトの使い方 EJB クライアント プロキシ プロジェクトを新規に作成するには、新規 作成 ダイアログボックスの[プロジェクト]ページから次のいずれか を選択します。 • [EJB クライアント プロキシ]アイコン • [EJB クライアント プロキシ ウィザード]アイコン [EJB クライアント プロキシ]アイコンを選択すると、EJB プロキシ用 のプロジェクト ペインタが開きます。このプロジェクト ペインタを使 用すると、プロジェクトの作成、オプションの指定、およびプロキシ ライブラリの構築ができます。 [EJB クライアント プ ロキシ]アイコン ❖ プロジェクト ペインタで EJB クライアント プロキシ プロジェクトを作成す るには 1 新規作成 ダイアログボックスの[プロジェクト]ページで、 [EJB クライアント プロキシ]アイコンをダブルクリックします。 2 EJB を指定するには、 [編集|オブジェクトの選択]を選択し、テ キストボックスに、com.sybase.jaguar.sample.svu.SVULogin や portfolio.MarketMaker など、コンポーネントのリモート インタフェー スの完全修飾名を入力します。 3 [クラスパス]ボックスに、EJB のスタブを含むディレクトリまた は JAR ファイルのパスを入力し、[OK]をクリックします。 スタブ ファイルがディレクトリに格納され、EJB の完全修飾名が packagename.beanname である場合、packagename を含むディレクト リを入力します。 4 アプリケーション テクニック プロキシ オブジェクトを格納する PBL を指定するには、[編集| プロパティ]を選択し、ターゲットのライブラリ リスト内のライ ブラリの格納場所を指定します。 655 EJB プロキシ オブジェクトの生成 生成された各プロキシ名の先頭に追加する接頭辞を任意に指定で きます。接頭辞を追加すると、指定した EJB に関連付けられたプ ロキシの特定が容易になり、クラス名と PowerBuilder 予約語の衝 突を避けることができます。ただし、例外のプロキシ、ストリーム オ ブジェクトのプロキシ、および EJBHome、EJBObject、EJBMetaData、 Handle、HomeHandle のプロキシなど、この EJB 固有でないプロキ シ名には、接頭辞は追加されません。 5 ダイアログボックスを閉じて、 [ファイル|すべて保存]を選択し てプロジェクトを保存します。 新規プロジェクトは、プロキシが生成される EJB コンポーネントを一 覧にし、生成されたプロキシ オブジェクトを格納する出力ライブラリ 名を指定します。 EJB クライアント プロキシ ウィザードを使用すると、プロジェクトを 容易に作成できます。 [EJB クライアント プ ロキシ ウィザード] アイコン ❖ 656 ウィザードを使用して EJB クライアント プロキシ プロジェクトを作成するには 1 新規作成 ダイアログボックスの[プロジェクト]ページで[EJB クライアント プロキシ ウィザード]アイコンをダブルクリック し、ウィザードの最初のページで[次へ]をクリックします。 2 プロジェクト オブジェクトを格納するライブラリを選択し、 [次へ] をクリックします。 3 プロジェクト名を指定し、必要に応じてプロジェクトの説明を指 定して、[次へ]をクリックします。 PowerBuilder 第 29 章 4 EJB クライアントの構築 次に示すように、テキストボックスに、cocoPortfolio.Portfolio など、コンポーネントのリモート インタフェースの完全修飾名を 入力します。 コンポーネントのホーム インタフェース名は、標準の命名規約に 従って自動的に入力されます。必要であれば、ウィザードでこの 名前を変更できます。 5 EJB スタブを格納した JAR ファイル、または EJB スタブ パッケー ジを格納したディレクトリを参照して選択します。 スタブ ファイルがディレクトリに格納され、EJB の完全修飾名が packagename.beanname である場合、packagename を含むディレクト リを入力します。 6 生成された各プロキシ名の先頭に追加する任意の接頭辞を指定 し、[次へ]をクリックします。 接頭辞を追加すると、指定した EJB に関連付けられたプロキシの 特定が容易になり、クラス名と PowerBuilder 予約語の衝突を避け ることができます。ただし、例外のプロキシ、サポートしている クラスのプロキシ、および EJBHome、EJBObject、EJBMetaData、 Handle、HomeHandle のプロキシなど、この EJB 固有でないプロキ シ名には、接頭辞は追加されません。 7 アプリケーション テクニック 既存のライブラリを参照して選択し、 [次へ]をクリックし、 [完了] をクリックします。 657 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 658 説明 すべての EJB ホーム インタフェースの基本クラスであ る、javax.ejb.EJBHome インタフェースのプロキシ javax.ejb.EJBMetaData インタフェースのプロキシ。 EJBMetaData を使用すると、クライアントは、EJB の ホーム インタフェース、EJB のホーム インタフェース とリモート インタフェースのクラス オブジェクト、お よびエンティティ Bean の主キー クラスを取得し、Bean がセッション オブジェクトまたはステートレス セッ ション オブジェクトかどうかが判断可能になる すべての EJB リモート インタフェースの基本クラスで ある、javax.ejb.EJBObject インタフェースのプロキシ PowerBuilder 第 29 章 オブジェクト Handle HomeHandle EJB クライアントの構築 説明 javax.ejb.Handle インタフェースのプロキシ。EJB への堅 牢で永続的な参照を提供する javax.ejb.HomeHandle インタフェースのプロキシ。ホーム オブジェクトへの堅牢で永続的な参照を提供する これらのインタフェースについての詳細は、javax.ejb package のサイト http://java.sun.com/j2ee/sdk_1.3/techdocs/api/index.html に掲載のマニュアル を参照してください。 プロジェクトは、Java クラスのプロキシ名へのマッピングを格納する 構造体も生成します。この構造体は内部的に使用されるものなので、 変更しないでください。 ejb2pb100 ツールの使い方 プロキシの生成には、ejb2pb100 コマンドライン ツールを使用する方法 もあります。このツールを使用した場合、以下が生成されます。 • 指定した EJB のホーム インタフェースとリモート インタフェー スのプロキシ、および EJB が依存するクラスのプロキシ(.srx ファ イル) • ejbname_ejb_pb_mapping.srs という名前の PowerBuilder 構造体オブ ジェクト。この場合、ejbname は EJB 名。この構造体は、Java クラ ス名と PowerBuilder プロキシ名との間のマッピング テーブルをホ ストする • ejbproxies.txt という名前のテキスト ファイル。エラーが発生した 場合は、ejbproxies.err という名前のテキスト ファイル これらのファイルは、コマンドの呼び出し元のディレクトリ内に生成 されます。構文は次のとおりです。 ejb2pb100 [ -classpath pathlist ] EJBName [EJBHomeName][ prefix ] D:\Program Files のように、pathlist 引数にスペースが含まれる場合は、 pathlist を引用符で囲む必要があります。EJBName は、完全修飾リモー ト インタフェース クラス名です。標準の命名規約に従ったホーム イ ンタフェース名を使用する場合、完全修飾ホーム インタフェース名の 引数 EJBHomeName はオプションです。オプションの prefix を指定す ると、生成されたプロキシ名の先頭に接頭辞が追加されます。 アプリケーション テクニック 659 EJB プロキシ オブジェクトの生成 たとえば、次のステートメントは、EAServer 上の cocoPortfolio パッケー ジ内の Portfolio クラスのプロキシを生成します。Portfolio クラスの ホーム インタフェースとリモート インタフェースのプロキシには、接 頭辞として pf_ が追加され、生成されたファイルは D:\work\proxies ディレクトリに書き込まれます。 cd D:\work\proxies ejb2pb100 -classpath "D:\Program Files\Sybase\EAServer\ html\classes" cocoPortfolio.Portfolio pf_ EJB のホーム クラスとリモート クラス、およびそれに従属するクラス は、指定したクラス パスに置く必要があります。 プロキシを生成した後に、生成したプロキシをターゲットにインポー トするには、クライアントを含むライブラリを選択し、ポップアップ メニューから[インポート]を選び、表示されたダイアログボックス から .srx ファイルを選びます。.srx ファイルをインポートする順序に は注意が必要です。ほかのクラスに従属するプロキシは、その従属す るクラスのプロキシをインポートした後でないとインポートできませ ん。 生成されたプロキシの表示方法 生成されたプロキシはシステム ツリーに表示されます。プロキシ ノー ドを展開すると、EJB コンポーネントのホーム インタフェースとリ モート インタフェースのメソッドのシグネチャ、およびプロキシを生 成したほかのすべてのオブジェクトのメソッドのシグネチャが表示さ れます。 660 PowerBuilder 第 29 章 予約語との衝突 EJB クライアントの構築 コンポーネントのメソッド名が PowerBuilder の予約語と衝突する場 合、メソッドを PowerBuilder にインポートできるように、プロキシ内 のメソッド名に文字列 _j が追加されます。たとえば、Java Iterator クラ スには Next メソッドがあり、このメソッドは、PowerBuilder の予約語 NEXT と衝突します。プロシキ内で、このメソッドには next_j という 名前が付けられます。 アプリケーション テクニック 661 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 配列を宣言し、その配列をパラメータと して渡します。 662 PowerBuilder 第 29 章 EJB クライアントの構築 Java VM の作成 EJB コンポーネントを呼び出す場合、事前に JavaVM クラスの CreateJavaVM メソッドを使用して Java VM を作成する必要があります。 最初の引数は、Java VM によって使用されるクラスパスの先頭に追加 するクラスパスを指定する String 型です。 Java VM がすでにロードされている場合 Java VM がすでに実行されている場合、クラスパス引数は無視されま す。 createJavaVM の第 2 引数は、デバッグ情報をテキスト ファイルに書き 出すかどうかを指定する Boolean 型の引数です。675 ページの「クライ アントのデバッグ」を参照してください。 これ以外に、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]ページで確認できます。クラスパスは、以 下のパスを結合して作成されます。 アプリケーション テクニック 663 Java VM の作成 ランタイム Java VM クラスパス • Java VM の起動時にプログラムによって追加されるクラスパス。た とえば、CreateJavaVM メソッドに渡すクラスパス • PowerBuilder ランタイム スタティック レジストリ クラスパス。こ のパスは、pbjvm100.dll に組み込まれる。このパスには、実行時に EJB ク ラ イ ア ン ト、お よ び Java VM を 使 用 す る そ の ほ か の PowerBuilder 機能に必要なクラスが含まれる • PowerBuilder システム クラスパス。このパスは、PowerBuilder のイ ンストール時にインストールされる Windows レジストリ キー内に 保存される。このパスには、設計時に JSP ターゲットおよび JDBC 接続などの Java 関連の PowerBuilder 機能に必要なクラスが含まれ る • PowerBuilder ユーザ クラスパス。このパスは、システム オプション ダイアログボックスの[Java]ページで指定するパス • システムの CLASSPATH 環境変数 • 現行ディレクトリ 実行時に、GetJavaClasspath メソッドを使用すると、Java VM が使用し ているクラスパスを判断できます。Java VM は、実行時に以下のクラ スパスを使用します。 • Java VM の起動時にプログラムによって追加されるクラスパス • PowerBuilder ランタイム スタティック レジストリ クラスパス • システムの CLASSPATH 環境変数 • 現行ディレクトリ 実行時の Java クラスパスについての詳細は、869 ページの「Java サポー ト」を参照してください。 サーバが必要とするク ラス クラスパスには、EAServer 4.2 用の EJB クライアントが必要とするク ラスが含まれます。別の J2EE サーバを使用する場合、アプリケーショ ン サーバが必要とするクラスをシステムの CLASSPATH にさらに追加 する必要があります。たとえば、次のようになります。 • WebLogic の場合、weblogic.jar。このファイルは、サーバ上の wlserver6.1\lib または weblogic700\server\lib にインストールされる • WebSphere の場合、JAR ファイルが、サーバ上の websphere\appserver\lib にインストールされる クライアント上での各アプリケーション サーバに対して必要なファ イルについての詳細は、サーバのマニュアルを参照してください。 664 PowerBuilder 第 29 章 例 EJB クライアントの構築 この例では、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) アプリケーション テクニック 665 サーバへの接続 サーバへの接続 EJB サーバに接続し EJB を検索するには、EJBConnection クラスを使用 します。EJBConnection クラスには、次の 4 つのメソッドがあります。 ConnectToServer、DisconnectServer、Lookup、および GetEJBTransaction で す。 サーバへの接続を確立するには、以下の操作を行うために必要な PowerScript ステートメントを実行する必要があります。 1 EJBConnection クラスのインスタンスを宣言します。 2 EJBConnection オブジェクトのプロパティを設定します。 3 CREATE 文を使用して、EJBConnection オブジェクトをインスタン ス化します。 4 ConnectToServer メソッドを呼び出して、サーバへの接続を確立し ます。 5 エラーの有無をチェックします。 クラスパス要件 アプリケーション サーバに接続し、EJB オブジェクトを作成するには、 システムの CLASSPATH 環境変数または createJavaVM の classpath 引数 に、EJB スタブ ファイルの格納場所(ディレクトリまたは JAR ファイ ル)を含める必要があります。また、使用するアプリケーション サー バが、クライアントコンピュータ上でクラスまたは JAR ファイルを利 用できるようにし、それらをクラスパスに追加することが必要な場合 もあります。詳細については、663 ページの「開発環境における Java VM クラスパス」を参照してください。 初期コンテキストの設 定 初期コンテキストの設定に使用される文字列は、EJB サーバに依存し ます。次の表に、サンプル文字列値を示します。詳細については、サー バのマニュアルを参照してください。 サーバ EAServer WebLogic WebSphere 例 666 INITIAL_CONTEXT_FACTORY 値 com.sybase.ejb.InitialContextFactory weblogic.jndi.WLInitialContextFactory com.ibm.websphere.naming.WsnInitialContextFactory 次のスクリプトは、EAServer への接続を示しています。このスクリプ トでは、接続プロパティを設定して、初期コンテキストの作成、サー バのホスト名とポート番号の識別、ユーザ ID とパスワードの識別を行 います。 PowerBuilder 第 29 章 EJB クライアントの構築 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=jagadmin" 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 アプリケーション テクニック EJBConnection の lookup メソッドを使用して、コンポーネントの ホーム インタフェースにアクセスします。 667 コンポーネント メソッドの呼び出し 2 ホーム インタフェース上で create または findByPrimaryKey メソッド を呼び出して、コンポーネントのインスタンスを作成または検索 し、コンポーネントのリモート インタフェースへの参照を取得し ます。 3 リモート インタフェースでビジネス メソッドを呼び出します。 このプロシージャは、pbejbclient100.jar ファイルを使用します。この ファイルは、設計時および実行時に pbjvm100.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 のインスタンス の作成や検索 668 セッション Bean は、クライアントのリクエストに応答して作成されま す。クライアントは、通常の場合、そのクライアント セッションの持 続中はセッション Bean を排他的に使用します。エンティティ Bean は、 データベースに保存される永続情報を表します。クライアントは、ほ かのクライアントと同時にエンティティ Bean を使用します。エンティ ティ Bean は、クライアントの有効期限が終了しても持続するため、エ ンティティ Bean のインスタンスが存在する場合は主キーのクラス名 を使用してこれを検索し、エンティティ Bean のインスタンスが存在し ない場合は新規に作成する必要があります。 PowerBuilder 第 29 章 EJB クライアントの構築 セッション 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 アプリケーション テクニック 669 コンポーネント メソッドの呼び出し 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) 670 PowerBuilder 第 29 章 EJB クライアントの構築 戻り値 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 メソッドととも に使用できます。 たとえば、次のようなクラスがある場合、 アプリケーション テクニック 671 例外処理 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 コンポーネントのメソッドの実行時に発生したエラーは、例外プ ロキシにマップされ、呼び出し側のスクリプトに送出されます。また、 サーバへの接続に失敗したり、コンポーネントが見つけられなかった り作成できなかった場合も、pbejbclient100.pbx 内のすべてのクラスの メソッドは例外を送出します。 EJB プロキシ プロジェクトを構築すると、ホーム インターフェースと リモート インタフェースのプロキシ、EJB によって参照される Java ク ラスのプロキシ、先祖クラスのプロキシ、および EJB とそのサポート するクラスによって送出される可能性のある例外のプロキシが生成さ れます。次の例外プロキシは、システム ツリー内に表示される例外プ ロキシの一部です。 672 PowerBuilder 第 29 章 プロキシ名 createexception ejbexception finderexception remoteexception removeexception 例外の捕捉 EJB クライアントの構築 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 処理されない例外 例外ハンドラがない場合、または既存の例外ハンドラがその例外を処 理しない場合、アプリケーション オブジェクトの SystemError イベン トが実行されます。SystemError イベントにスクリプトが記述されてい ない場合は、アプリケーション エラーが起きて、アプリケーションは 終了します。 アプリケーション テクニック 673 クライアント管理のトランザクション クライアント管理のトランザクション 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 674 PowerBuilder 第 29 章 EJB クライアントの構築 トランザクションに関 する情報の取得 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) アプリケーション テクニック 675 クライアントのデバッグ 676 PowerBuilder 第 3 0 章 PowerBuilder での Web アプリ ケーション開発 この章について この章では、PowerBuidler での Web アプリケーション開発に使え る方法について概要を説明します。 内容 項目 Web アプリケーションの作成 Web サービス Web ターゲット JSP ターゲット Web データウィンドウ データウィンドウ Web コントロール ActiveX データウィンドウ プラグイン PowerBuilder ウィンドウ プラグイン PowerBuilder ウィンドウ ActiveX ページ 677 678 678 679 680 681 682 682 683 Web アプリケーションの作成 PowerBuilder には、Web アプリケーション作成のためのいくつか のツールが用意されています。この節では、これらのツールの概 要を説明し、詳細情報の参照場所を示します。 アプリケーション テクニック 677 Web サービス Web サービス Web サービスは、インターネット テクノロジを活用して分散ソフト ウェア コンポーネントが自動で相互にやりとりするサービスと大ま かに定義されます。そうしたソフトウェア コンポーネントを使用する と、株式市況の取得、インターネットでのカタログの在庫検索、航空 会社とレンタカーの予約サービスの統合などのビジネス ロジックを 実行できます。アプリケーション用のコンポーネントを作成しなくて も、インターネット経由で既存のコンポーネントを使用できます。 PowerBuilder アプリケーションは、インターネット経由でアクセスさ れる Web サービスを利用するクライアントとして機能できます。 SOAP と WSDL を利用すると、1 つのエンティティとしてリモートで 発行された関数の集まりを PowerBuilder アプリケーションに含めるこ とができます。Web サービスは、アプリケーションまたはほかの Web サービスから送信されたリクエストを受信して応答します。JSP ター ゲットで Web サービスを使用することもできます。 Web サービスについての詳細は、第 31 章「Web サービス クライアン トの構築」および『Web ターゲットと JSP ターゲットでの作業』マニュ アルを参照してください。 Web ターゲット Web ターゲットは、Web サイト作成のためのファイルとコンポーネン トの集まりです。Web ターゲットは、データベース データの統合、ク ライアント サイド イベントとサーバ サイド イベントのスクリプト作 成、および中間層のサーバに保存されているコンポーネントのメソッ ドの呼び出しによって、動的な対話型コンテンツを配布できます。 標準的な HTML ページや、クライアント サイドとサーバ サイドのス クリプト、Web データウィンドウ、EAServer コンポーネント(Enterprise JavaBeans を含む)、および ActiveX コンポーネントを包括できる複雑 な Web ページを作成できます。 Web ターゲット オブジェクト モデルでは、複数のアプリケーション サーバに対するサーバ サイドのプログラミングがサポートされてい るため、Web ターゲットを複数のサーバに配布できます。Web アプリ ケーションの動的コンテンツを提供するには、JavaScript でスクリプト を作成するか、任意の ECMA 準拠スクリプト(DynaScript、VBScript、 JScript など)を作成します。 678 PowerBuilder 第 30 章 PowerBuilder での Web アプリケーション開発 Web ターゲット オブジェクト モデルの 4GL 拡張は、EAServer に配布 するアプリケーション専用の機能です。これらの拡張機能は、サーバ サイドのイベント処理を提供し、Web ターゲットのユーザ インタ フェースで選択された内容を基に自動的にサーバ サイド コードを生 成します。 Web ターゲットについての詳細は、 『Web ターゲットと JSP ターゲット での作業』マニュアルを参照してください。 JSP ターゲット JavaServer Pages(JSP)テクノロジを利用すれば、迅速かつ容易な方法 で静的コンテンツと動的コンテンツを持つ Web ページを作成できま す。JSP は、通常 HTML または XML での静的マークアップ、および スクリプト形式の Java コンテンツまたは Java コンポーネントの呼び 出し、あるいはその両方を含むテキストベースの文書です。JSP は Java サーブレット API を拡張したもので、すべての Java API とコンポーネ ントにアクセスできます。 Web ベースのアプリケーションにおいて数多くの方法で JSP を使用で きます。一般に JSP は、J2EE アプリケーション モデルの一部として中 間層の Web サーバで実行し、クライアントからの HTTP リクエストに 応答して、トランザクション サーバの Enterprise JavaBeans(EJB)コ ンポーネントのビジネス メソッドを呼び出します。 PowerBuilder を使用して作成された JSP ページは、JavaServer Pages 仕 様のバージョン 1.2、Java Servlet 仕様のバージョン 2.3、および JDK 1.3 以降をサポートします。PowerBuilder では、JSP 1.2 の形式を使用する カスタム タグ ライブラリもサポートしています。JSP ターゲットを Web アプリケーションとして EAServer、Apache Tomcat、またはコマン ド行配布機能を設定できる任意の JSP 1.2 サーバに配布できます。 Web ターゲットについての詳細は、 『Web ターゲットと JSP ターゲット での作業』マニュアルを参照してください。 アプリケーション テクニック 679 Web データウィンドウ Web データウィンドウ Web データウィンドウは、Web アプリケーションのシンクライアント データウィンドウの実装です。Web データウィンドウは、クライアン ト上で PowerBuilder DLL を必要とせずに、PowerBuilder データウィン ドウのデータ操作、提示、およびスクリプト作成機能の大部分を提供 します。 Web データウィンドウは、以下のような、個別のコンピュータ上で実 行できるいくつかのソフトウェア コンポーネントのサービスを利用 します。 • アプリケーション サーバかトランザクション サーバで実行され る Web データウィンドウ サーバ コンポーネント • 動的ページ サーバ • Web サーバ • Web ブラウザ • データベース サーバ コンポーネントは非ビジュアル ユーザ オブジェクトであり、 データストアを使用して取得と更新の処理を行い、HTML を生成しま す。開発者は、PowerBuilder かカスタム コンポーネントに付属の汎用 コンポーネントを使用できます。 Web データウィンドウの機能を活用するには、いくつかの方法があり ます。 • Web データウィンドウのデザイン タイム コントロール Web ターゲット では、Web データウィンドウのデザイン タイム コントロールを使 用して、Web データウィンドウ コンポーネントにアクセスする サーバ サイド スクリプトを作成できます。これは、最も簡単に Web データウィンドウを使用できる方法です。 • Web ターゲット オブジェクト モデルのコーディング Web ターゲット では、Web ターゲット オブジェクト モデルを使用して Web デー タウィンドウのコンポーネントにアクセスするためのサーバ サイ ド スクリプトを記述できます。Web ターゲット オブジェクト モデ ルには、Web データウィンドウのコンポーネントのコード作成を 容易にする、定義済みオブジェクトとメソッドのセットがありま す。 • Web データウィンドウのコンポーネント自体のコーディング 直 接 Web データウィンドウのコンポーネントにアクセスするサーバ サイド スクリプトを記述できます。 680 PowerBuilder 第 30 章 • PowerBuilder での Web アプリケーション開発 独自の HTML ジェネレータの記述 PowerBuilder で 提 供 さ れ て い る サンプル PBL を基にして、アプリケーションに必要なメソッドを 提供するユーザ独自の HTML ジェネレータを作成できます。 Web データウィンドウについての詳細は、『データウィンドウ プログ ラマーズ ガイド』マニュアルを参照してください。 データウィンドウ Web コントロール ActiveX データウィンドウ Web コントロール ActiveX は、Internet Explorer で使 用できる完全対話形式のデータウィンドウ コントロールです。このコ ントロールは、リッチ テキスト提示様式を除く PowerBuilder データ ウィンドウのすべての機能を実装します。 データウィンドウ Web コントロール ActiveX は、検索引数によるデー タ検索とデータ更新をサポートします。開発者は、編集様式、表示書 式、および入力条件則を使用でき、データウィンドウを操作するため の PowerBuilder メソッドの大部分を利用できます。ファイル システム の対話にかかわるいくつかの関数がサポートされていないため、Web ActiveX は、ActiveX コントロールの中では安全にスクリプト実行でき るコントロールとして分類されています。 データウィンドウ Web コントロールには、いくつかのデータウィンド ウ Web コントロールで共有できるデータベース接続を作成するため の、データウィンドウ トランザクション オブジェクト コントロール が含まれています。 Web ActiveX は CAB ファイルとして提供され、これを使ってクライア ント ブラウザはコントロールをインストールして登録します。ユーザ が CAB ファイルを参照する Web ページをダウンロードすると、ブラ ウザは必要であれば CAB ファイルもダウンロードし、そのファイルを アンパックして、コントロールを登録します。 データウィンドウ Web コントロール ActiveX についての詳細は、 『デー タウィンドウ プログラマーズ ガイド』マニュアルを参照してくださ い。 アプリケーション テクニック 681 データウィンドウ プラグイン データウィンドウ プラグイン データウィンドウ プラグインは、これまでに生成されて Web サーバに 保存されている Powersoft レポート(PSR)を表示します。PSR ファイ ルがすでに生成されているため、データベース アクセスは必要ありま せん。このプラグインは、読み込み専用アクセスのみをサポートし、 ユーザはレポートの表示、印刷、保存は可能ですが、修正することは できません。 プラグインは、Netscape Navigator をはじめとする Netscape プラグイン に対応するブラウザなら、どんなブラウザでも使用できます(Microsoft Internet Explorer 5.5 Service Pack 2 以降のバージョンでは、Netscape プ ラグインをサポートしていません)。クライアント ブラウザに必要な ファイルは、データウィンドウ プラグインの DLL だけです。 詳細については、第 33 章「データウィンドウ プラグインの使い方」を 参照してください。 PowerBuilder ウィンドウ プラグイン PowerBuilder ウィンドウ プラグインは、 クライアント ワークステーショ ンの HTML ページに PowerBuilder ウィンドウを表示する PowerBuilder アプリケーションを実行します。プラグインは、Netscape Navigator を はじめとする Netscape プラグインに対応するブラウザなら、どんなブ ラウザでも使用できます(Microsoft Internet Explorer 5.5 Service Pack 2 以降のバージョンでは、Netscape プラグインをサポートしていませ ん)。プラグインのセキュリティ バージョンを使うと、インターネッ トを介してダウンロードされる PowerBuilder アプリケーションがクラ イアント システムを損傷したり、クライアント ワークステーション上 の情報にアクセスするといったことが防止されます。 アプリケーションがチャイルド ウィンドウから起動される場合は、 ウィンドウ プラグイン内のアプリケーションでほとんどの PowerBuilder 機能を実行できます。アプリケーションは、任意の PowerBuilder ウィ ンドウの実行、情報の表示、入力データの受け付け、データベースの 更新を行います。データベースへのアクセスは、クライアント ワーク ステーション上でクライアントがデータベースに接続することで開始 されます。 682 PowerBuilder 第 30 章 PowerBuilder での Web アプリケーション開発 プラグインの最大の弱点は、ファット クライアントを必要とすること です。ファット クライアントは、PowerBuilder ランタイム DLL か共有 ライブラリと、PowerBuilder ウィンドウ プラグイン DLL か共有ライブ ラリを必要とするブラウザ クライアントです。 詳細については、第 32 章「PowerBuilder ウィンドウ プラグインの使い 方」を参照してください。 PowerBuilder ウィンドウ ActiveX PowerBuilder ウィンドウ ActiveX は、ActiveX をサポートする Web ブラ ウザを使用するときに、HTML ページ内でのグラフィカル インタ フェースを提供します。また、ウィンドウとデータウィンドウ プラグ インの全機能のほかに、JavaScript や VBScript を使って、PowerBuilder のチャイルド ウィンドウのイベントと関数のサブセットにアクセス するための機能を提供します。この中には、ウィンドウ ActiveX コン トロールにあるチャイルド ウィンドウの関数とイベントを呼び出す ためのメソッドが含まれます。 アプリケーションがチャイルド ウィンドウから起動される場合は、 PowerBuilder ウィンドウ ActiveX 内のアプリケーションでほとんどの PowerBuilder 機 能 を 実 行 で き ま す。ア プ リ ケ ー シ ョ ン は、任 意 の PowerBuilder ウィンドウの実行、情報の表示、入力データの受け付け、 データベースの更新を行います。データベースへのアクセスは、クラ イアント ワークステーション上でクライアントがデータベースに接 続することで開始されます。 ウィンドウ プラグインと同様、ウィンドウ ActiveX の最大の弱点は、 ファット クライアントを必要とすることです。ファット クライアント は、PowerBuilder ランタイム DLL と PowerBuilder ウィンドウ ActiveX を必要とするブラウザ クライアントです。 詳細については、第 34 章「PowerBuilder ウィンドウ ActiveX の使い方」 を参照してください。 アプリケーション テクニック 683 PowerBuilder ウィンドウ ActiveX 684 PowerBuilder 第 3 1 章 Web サービス クライアントの構築 この章について この章では、PowerBuilder アプリケーションで Web サービスを使 用する方法について説明します。この章で説明するオブジェクト の関連情報については、 『PowerBuilder エクステンション リファレ ンス』マニュアルおよびオンライン ヘルプを参照してください。 内容 項目 Web サービスについて PBSoapClient100.pbd をライブラリ探索パスに追加する Web サービス プロキシ オブジェクトの生成 SOAP サーバへの接続 Web サービス メソッドの起動 Web サービスの作成 例外処理 UDDI 照会 API の使い方 ページ 685 687 688 692 693 694 694 695 Web サービスについて Web サービスを使用すると、開発したアプリケーションから呼び 出される一般的なタスクを実行するために、新たにビジネス ロ ジックを作成しなくても、インターネット上かローカル ネット ワーク上の既存のコンポーネントを使用することができます。 Web サービスは、SOAP(Simple Object Access Protocol)が登場し た とき に 生ま れ たも の で す。SOAP は XML(Extensible Markup Language)を利用し、通常は、トランスポートとして HTTP(Hypertext Transfer Protocol)を使用します。SOAP を介して Web サービスを 起動するには、データ型のシリアライズとデシリアライズ、およ び SOAP メッセージの構築と解析が必要です。 アプリケーション テクニック 685 Web サービスについて Web サービスの利点の 1 つとして、WSDL(Web Services Description Language)を使用してサービスをその中に記述できるということがあ ります。WSDL は、XML 文法を使用し、メッセージを交換できる通信 エンドポイントの集まりとして Web サービスを定義します。WSDL サービス定義は、分散システムをドキュメント化し、アプリケーショ ン通信に関連する細部を自動化する方法を示す役割をします。 Sybase の EAServer と Web サービス・ツールキットを使用することに より、これらの記述をアプリケーションに組み込み、UDDI(Universal Description, Discovery, and Integration)を使用する Web サイトに登録す ることができます。使用しているブラウザを使って UDDI レジストリ サイトにアクセスし、開発中のアプリケーションに必要なサービスを 検索できます。 SOAP、WSDL、および UDDI により、アプリケーション間のインタ フェースが、異なるプラットフォーム間で標準化されるため、サード パーティのコンポーネントを簡単に使用できるようになります。 PowerBuilder は以下の Web サービス規格をサポートしています。 • SOAP 1.1 • WSDL 1.1 • HTTP または HTTPS PowerScript ターゲットまたは JSP ターゲットから Web サービスにア クセスできます。PowerBuilder で作成した JSP アプリケーションで Web サービスにアクセスする方法の詳細については、 『Web ターゲットと JSP ターゲットでの作業』マニュアルの JSP ターゲットに関する章、ま たはオンライン ヘルプの JSP ページのオーサリングに関するトピック を参照してください。 Web サービス クライアントの構築について PowerBuilder アプリケーションは、インターネット経由でアクセスさ れる Web サービスを利用するクライアントとして機能します。SOAP と WSDL を利用すると、1 つのエンティティとしてリモートで発行さ れた関数のコレクションを PowerBuilder アプリケーションに含めるこ とができます。Web サービスは、アプリケーションまたはほかの Web サービスから送信されたリクエストを受信して応答します。 686 PowerBuilder 第 31 章 PBSoapClient100.pbd と pbsoapclient100.pbx Web サービス クライアントの構築 SOAP を介して Web サービスを起動するには、データ型のシリアライ ズとデシリアライズ、および XML ベースの SOAP メッセージの構築 と解析が必要です。PBSoapClient100.pbd と pbsoapclient100.pbx を使用 すると、Web サービス クライアント プロキシがこれらのタスクをかわ りに実行してくれるので、SOAP 仕様やそのスキーマ、XML スキーマ 仕様、または WSDL 仕様とそのスキーマに関する詳しい知識がなくて も Web サービスを利用できます。 PBSoapClient100.pbd をライブラリ探索パスに追加する PowerBuilder をインストールすると、pbsoapclient100.pbx ファイルと PBSoapClient100.pbd ファイルが Shared\PowerBuilder ディレクトリに インストールされます。Web サービス クライアント アプリケーション を作成する際に、pbsoapclient100.pbx を別の場所にコピーする必要はあ りませんが、そのアプリケーションの探索パス上のディレクトリにク ライアント実行ファイルとともに配布する必要があります。 PBSoapClient100.pbd をアプリケーション探索パスに追加するには、シ ステム ツリー内のクライアント ターゲットを右クリックし、ポップ アップ メニューから[プロパティ]を選択します。Shared\PowerBuilder ディレクトリに移動し、[ファイルの種類]ドロップダウン リストか ら「*.pbd」を選択し、「PBSoapClient100.pbd」を選択します。 PBSoapClient100.pbd を追加したら、以下のオブジェクトがシステム ツ リーに表示されます。 オブジェクト soapconnection soapexception アプリケーション テクニック 説明 SOAP サーバとの接続に使用される soapconnection から送出された例外の捕捉に使 用される 687 Web サービス プロキシ オブジェクトの生成 Web サービス プロキシ オブジェクトの生成 Web サービス プロキ シ オブジェクトの作 成 Web サービス プロキシを新しく作成するには、新規作成 ダイアログ ボックスの[プロジェクト]ページから[Web サービス プロキシ ウィ ザード]アイコンを選択します。Web サービス プロキシ ウィザードで プロキシを作成することにより、PowerScript で Web サービスを使用で きるようになります。各ポートに対して 1 つのプロキシが作成されま す。 ウィザードで以下の指定を行います。 • アクセスする WSDL ファイル • 選択する WSDL ファイル内のサービス • 使用する 1 つまたは複数のポート • ポート名に付く接頭辞(プロキシ名になる) • プロキシの配布先の PowerBuilder ライブラリ 新規作成 ダイアログボックスの[プロジェクト]ページから[Web サービス プロキシ]アイコンを選択することもできます。[Web サー ビス プロキシ]アイコンを選択すると、Web サービスのプロジェクト ペインタが開きます。ここからプロジェクトを作成し、オプションを 指定し、プロキシ ライブラリを構築できます。新規プロジェクトは、 Web サービスと、プロキシが生成されるポートを一覧にし、生成され るプロキシ オブジェクトを格納する出力ライブラリの名前を指定し ます。 Web サービス プロジェクトの作成にウィザードを使用した場合でも ペインタを使用した場合でも、最後のステップとして、ペインタ バー の[配布]アイコンをクリックするか、メニュー バーから[デザイン| プロジェクトの配布] を選択して、 プロキシ オブジェクトを構築します。 ウィザードでの UDDI ブラウザの使い方 PowerBuilder では、 PowerScript ターゲットと JSP ターゲットの Universal Description, Discovery, and Integration(UDDI)レジストリにアクセスで きます。UDDI サービスは業界全体の取り組みであり、企業間統合の ための標準を提供します。また、Web サービスのデータベースにアク セスするための、標準インタフェースを定義します。 Web サービス プロキシ ウィザードと JSP Web サービス プロキシ ウィ ザードには、UDDI ブラウザが組み込まれています。これらのウィザー ドの[WSDL ファイルの選択]ページ上、または Web サービス プロキ シ プロジェクトのプロパティ ダイアログボックスの[Web サービス] ページ上の[UDDI から検索する]ボタンをクリックすると、UDDI 検 索ページが表示されます。UDDI 検索ページには、表 31-1 に示す検索 フィールドとオプションがあります。 688 PowerBuilder 第 31 章 Web サービス クライアントの構築 表 31-1: UDDI の検索フィールドとオプション 検索フィールドまたは オプション UDDI プロファイル クエリ URL 検索 カテゴリ 単語の検索 大文字 / 小文字の区別 ソート 最大行数 説明 UDDI オペレータの名前を含む編集可能なドロッ プダウン リスト。UDDI プロファイルには、クエ リ URL を関連付けることができる。このドロップ ダウン リストでは、Microsoft と IBM のパブリッ ク UDDI レジストリの定義済みプロファイルを選 択できる Web サービスを検索する Web サービス レジスト リの URL が表示されるテキスト ボックス。 [UDDI プロファイル]ドロップダウン リストで定義済み のプロファイルを選択した場合、そのプロファイ ルに関連付けられている URL がここに表示され る。クエリ URL を入力して[プロファイルの保 存]ボタンをクリックすることにより、プロファ イルにその URL を関連付けることもできる UDDI の検索で使用するキーワードを入力するた めのテキスト ボックス 「サービス名」 (デフォルト)または「ビジネス名」 を含むドロップダウン リスト チェックボックス オプション。オンにすると、 [検 索]テキストボックスの現在の値が完全一致で検 索される チェックボックス オプション。オンにすると、 [検 索]テキストボックスの現在の値が大文字と小文 字を区別して検索される ラジオボタン オプション。検索結果を昇順または 降順にソートする スピン ボタン オプション。返される検索結果の数 をここに指定した数に制限する UDDI 検索で次に表示されるページは、キーワードをビジネス名と サービス名のどちらで検索するかによって異なります。 • ビジネス名検索の場合 [ビジネス名]ページに、検索条件に一致す るビジネス名と説明のリストが表示されます。ビジネス名を選択 して[次へ]をクリックすると、 [サービスの選択]ページにサー ビス名のリストが表示されます。このリストには、各サービスの 説明と WSDL ファイル名も含まれます。 • サービス名検索の場合 [サービスの選択]ページにサービス名のリ ストが表示されます。このリストには、各サービスのビジネス名、 説明、および WSDL ファイル名も含まれます。 アプリケーション テクニック 689 Web サービス プロキシ オブジェクトの生成 [サービスの選択]ページでサービスを選択すると、UDDI の検索が終 了します。ウィザードの残りのページで選択を続けてください。 Web サービス プロキシ オブジェクトのプロパティ ダイアログボック スの[Web サービス]ページには、Web サービス プロキシ ウィザード で選択した WSDL ファイルが表示されます。この WSDL ファイルは、 UDDI 検索ウィザードを使用して変更することもできます。UDDI 検索 ウィザードには、Web サービス プロキシ ウィザードの UDDI の検索 ページと同じ検索オプションと検索結果リストがあります。 生成されたプロキシ 生成されたプロキシはシステム ツリーに表示されます。プロキシ ノー ドを拡張すると、メソッドのシグネチャを表示できます。 XML メソッドのエリ アス PowerBuilder は大文字と小文字を区別しませんが、XML と SOAP は大 文字と小文字を区別します。そこで、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 690 PowerBuilder 第 31 章 データ型マッピング Web サービス クライアントの構築 Web サービス プロキシ ジェネレータにより、XML と PowerBuilder 間で データ型のマッピングが行われます。XML のデータ型はすべて World Wide Web Consortium Web のサイト www.w3.org/1999/XMLSchema と Web の サイト http://www.w3.org/2001/XMLSchema に基づいています。 マッピングは次の表のとおりに行われます。 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) PowerBuilder のデータ型 boolean int uint long ulong longlong decimal (-999999999999999999 ~ 999999999999999999) float double decimal real double string gYear、gYearMonth、gMonthDay、gDay、anyURI、QName、 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 アプリケーション テクニック date time datetime blob 691 SOAP サーバへの接続 配列の配列 PowerBuilder は、XML とは異なり、可変長一次元配列のみサポートし ます。WSDL ファイルの配列が固定長の一次元である場合、PowerBuilder は自動的にこれを可変長配列に変換します。WSDL ファイルの配列が 多次元配列の場合、戻り値の型は無効になり、使用できません。 関数プロトタイプで、PowerBuilder は配列型を PowerBuilder any 型とし て表示します。戻り値を保持する適切な型の配列を宣言することが必 要です。 SOAP サーバへの接続 アクセスする Web サービスのホストである SOAP サーバに接続するに は SoapConnection クラスを使用します。SoapConnection オブジェクト の SetOptions メソッドを使用して、HTTPS 接続のユーザ ID やパスワー ドなどのオプションを設定できます。Web サービスにアクセスするク ライアント プロキシ インスタンスを作成するには、CreateInstance メ ソッドを使用します。 例 以下のスクリプトにより、SOAP サーバ上の Web サービスへの接続が 作成されます。CreateInstance メソッドで定義されるエンドポイントを使 用して、接続プロパティが設定されます。エンドポイントが CreateInstance メソッドで定義されない場合、プロキシに格納されているデフォルト URL が使用されます。このスクリプトでは、SetOptions メソッドによ り、ログ ファイルが指定されています。戻り値がメッセージ ボックス に表示されます。 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.SetOptions("SoapLog=~"C:\mySoapLog.log~"") // SOAP のデータ交換を記録するトレース ファイルを設定 // string を "" にすると、この機能は無効になる 692 PowerBuilder 第 31 章 Web サービス クライアントの構築 rVal = Conn.CreateInstance(proxy_obj, & "syb_currencyexchangeport", str_endpoint) // プロキシ オブジェクトの作成 try amount = proxy_obj.getrate("us","japan") // サービスの起動 messagebox(" 現在の為替レート ", "1 US ドル "& + " = " + string(amount) + " 日本円 ") catch ( SoapException e ) messagebox (" エラー ", "Web サービスを起動できません。") // エラー処理 end try destroy conn Web サービス メソッドの起動 SoapConnection を使って、 Soap_proxy オブジェクトが作成され、 SetOptions メソッドで設定した SOAP 接続オプションが使用されます。Web サー ビスのプロキシ オブジェクトが作成されると、クライアント アプリ ケーションは、その Web サービスにアクセスできるようになります。 Web サービス メソッドを起動するには、プロキシ オブジェクトに以下 の情報を含めることが必要です。 • サービスのエンドポイント。WSDL ファイルから取得 • SOAP メソッド呼び出しで使用される名前空間定義 • 構造体定義(必要な場合) • 戻される各構造体配列のインスタンス変数。戻される配列がすべ て any 型であるため • 1 つ以上の SOAP メソッドと、対応するエリアス文字列 アプリケーション テクニック 693 Web サービスの作成 Web サービスの作成 PowerBuilder には、カスタム クラス(非ビジュアル)ユーザ オブジェ クトを開発して、それらを EAServer コンポーネントとして配布したり Web サービスとしてエクスポーズしたりするためのツールがありま す。コンポーネントは、Windows および UNIX オペレーティング シス テム上で動作している EAServer に配布できます。詳細については、第 24 章「EAServer コンポーネントの構築」を参照してください。 EAServer 上の既存のコンポーネントに対しては、EAServer Manager を 使用して Java Beans を生成します。その後、EAServer の Web サービ ス・ツールキットを使って、Web サービスとその場所を記述して、 EAServer コンポーネントの WSDL ファイルを生成できます。ここで も、Web サービスに対して、クライアント アプリケーションにアクセ スできるクライアント プロキシを作成します。クライアント プロキシ は、Web サービスや EAServer コンポーネントを記述する WSDL ドキュ メントを使用します。これで、クライアント アプリケーションは Web サービスを使用できるようになります。詳細については、 『EAServer プ ログラマーズ・ガイド』マニュアルと EAServer の『Web サービス・ ツールキット・ユーザーズ・ガイド』マニュアルを参照してください。 例外処理 Web サービスのメソッドの実行時に発生するエラーは SoapException オブジェクトに変換され、呼び出したスクリプトに送出されます。 PBSoapClient100.pbx に含まれるすべてのクラスのメソッドも、サーバ への接続が失敗したときや Web サービスが検索されなかったり作成 できなかったときなどに、SoapException オブジェクトを送出できま す。 例外の捕捉 694 クライアント アプリケーションは、さまざまな方法で通信エラーを処 理できます。たとえば、クライアントがサーバに接続し、オブジェク トのメソッドを呼び出そうとしたときにそのオブジェクトが存在しな かった場合は、サーバとの接続を解除し、別のサーバに接続して操作 を再試行する方法があります。あるいは、クライアントがユーザにメッ セージを表示して、次に起こることを制御する機会をユーザに与える 方法もあります。 PowerBuilder 第 31 章 Web サービス クライアントの構築 エラー発生時にクライアントが操作の再開のために新しいサーバに接 続している場合、新しいサーバ上でリモート オブジェクトをインスタ ンス化してから、リモート オブジェクトのメソッドを呼び出す必要が あります。 処理されない例外 例外ハンドラがない場合、または既存の例外ハンドラがその例外を処 理しない場合、アプリケーション オブジェクトの SystemError イベン トが実行されます。SystemError イベントにスクリプトが記述されてい ない場合は、アプリケーション エラーが起きて、アプリケーションは 終了します。 UDDI 照会 API の使い方 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”) 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 アプリケーション テクニック 695 UDDI 照会 API の使い方 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 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\ 696 PowerBuilder 第 31 章 Web サービス クライアントの構築 %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 アプリケーション テクニック 697 UDDI 照会 API の使い方 698 PowerBuilder 第 3 2 章 PowerBuilder ウィンドウ プラグイン の使い方 この章について この章では、Web ページにプラグイン アプリケーションとして表 示される PowerBuilder アプリケーションの開発、テスト、および 配布の方法について説明します。 内容 はじめに アプリケーション テクニック 項目 PowerBuilder ウィンドウ プラグインについて PowerBuilder ウィンドウ プラグインのインストールと設定 セキュリティ PowerBuilder ウィンドウ プラグインの使い方 PowerBuilder ウィンドウ プラグイン アプリケーションの開発 と配布 PowerBuilder アプリケーションの作成 HTML ページの作成 サーバの設定 ユーザのワークステーションの設定 ページ 700 705 706 707 708 717 720 721 この章では、HTML と URL について、および Web ブラウザが Web サーバからページをどのように取得するかについての知識を有 し、Web サーバにアクセス可能な環境であることを前提にしてい ます。 699 PowerBuilder ウィンドウ プラグインについて PowerBuilder ウィンドウ プラグインについて PowerBuilder ウィンドウ プラグインを使用すると、Netscape プラグイ ンをサポートするブラウザで表示される PowerBuilder チャイルド ウィ ンドウを Web ページに表示できます。 Internet Explorer Microsoft Internet Explorer 5.5 Service Pack 2 以 降 の バ ー ジ ョ ン は、 Netscape プラグインをサポートしていません。そのため、それらのブ ラウザでは、PowerBuilder ウィンドウ プラグインを使用して PSR レ ポートを表示することはできません。 700 PowerBuilder 第 32 章 機能 PowerBuilder ウィンドウ プラグインの使い方 PowerBuilder チャイルド ウィンドウには、データウィンドウ、OLE オ ブジェクト、ActiveX(OCX)コントロール、およびツリー コントロー ルなどの使い慣れたコントロールがすべて含まれます。また、チャイ ルド ウィンドウからポップアップ ウィンドウまたはレスポンス ウィ ンドウを開くことも可能です。 ユーザがチャイルド ウィンドウやほかのウィンドウのコントロール と対話すると、スタンドアロン PowerBuilder アプリケーションのコン トロールとまったく同じように、そのイベント スクリプトが実行され ます。プラグイン アプリケーションからデータベースへのアクセス は、クライアントの定義済みデータベース接続を使用してローカルで 実行されます。 アプリケーション内のオブジェクトを、1 つまたは複数の PowerBuilder 動的ライブラリ(PBD: PowerBuilder Dynamic Library)に含めることが できます。 標準バージョンとセ キュリティ バージョ ン PowerBuilder ウィンドウ プラグインには、標準バージョンとセキュリ ティ バージョンの 2 種類があります。 標準 PowerBuilder ウィンドウ プラグイン 標 準 PowerBuilder ウ ィ ン ド ウ プラグインは、PowerBuilder チャイルド ウィンドウを HTML ページ に表示します。標準ウィンドウ プラグインは、NPPBA100.DLL で実装 されます。 セキュリティ PowerBuilder ウィンドウ プラグイン セキュリティPowerBuilder ウィンドウ プラグインは、標準 PowerBuilder ウィンドウ プラグインの セキュリティ バージョンです。セキュリティ バージョンを使用する と、インターネットを介してダウンロードされる PowerBuilder アプリ ケーションがクライアント システムを損傷したり、クライアント ワー クステーション上の情報にアクセスしたりすることが防止されます。 セキュリティ ウィンドウ プラグインは、NPPBS100.DLL で実装されま す。 PowerBuilder ウィンドウ プラグインのセキュリティ バージョンを使用す るときの留意事項については、706 ページの「セキュリティ PowerBuilder ウィンドウ プラグインの使い方」を参照してください。 サポートするブラウザ PowerBuilder ウィンドウ プラグインでは、Netscape Navigator バージョ ン 3.x 以降の、Netscape プラグインをサポートするブラウザを使用す る必要があります。Microsoft Internet Explorer 5.5 Service Pack 2 以降の バージョンは、Netscape プラグインをサポートしていません。 アプリケーション テクニック 701 PowerBuilder ウィンドウ プラグインについて セキュリティ 標準 PowerBuilder ウィンドウ プラグインは、セキュリティ機能を実装 していないアプリケーションなので、ローカルのファイルにアクセス し、ローカルのアプリケーションを実行できます。このような処理は、 制御のない Web 環境では好まれないことが多いですが、アクセスが制 御される企業イントラネットでは許容される場合もあります。 セキュリティが重要視されるサイトの場合は、PowerBuilder ウィンド ウ プラグインのセキュリティ バージョンを使用してアプリケーショ ンを構築してください。 セキュリティ モードで常に動作するイベントがある PowerBuilder 10 では、標準ウィンドウ プログラムを使用していたとし ても、アプリケーションの Open イベントおよびコントロール用のい くつかの Constructor イベントがセキュリティ モードで動作します。ア プリケーションのロジックが、これらのイベントでの安全性に欠ける 動作(ファイルを開いて書き込みを行うなど)を実行する機能に依存 する場合には、イベント メッセージが自分に対して表示されるように してください。このイベント メッセージは、プラグインが標準モード に戻ったときに処理されます。 セキュリティ PowerBuilder ウィンドウ プラグインの詳細については、 706 ページの「セキュリティ PowerBuilder ウィンドウ プラグインの使 い方」を参照してください。 プラグインとなるアプリケーションの種類 HTML フォームでは、限られたユーザ インタフェースを介した対話処 理しかできません。PowerBuilder ウィンドウ プラグインは、HTML を 超える能力を提供します。リッチ ユーザ インタフェース設計で開発さ れたアプリケーション ウィンドウを、Web ページに表示できます。ク ライアント ワークステーションで定義されているデータ ソースにア クセスできます。 例 702 アプリケーションには以下のものがあります。 • マスタ データウィンドウと詳細データウィンドウを持つデータ解 析ウィンドウ • ユーザによる選択を、ツリービュー、リストビュー、およびピク チャ リストボックス コントロールから行うユーザ インタフェー スの設計 • サーバ上のデータを処理するデータ入力フォーム PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 • クライアント定義によるデータベース接続(ネットワークまたは ローカル)を使用してクライアント マシン上のデータを処理する データ入力フォーム • PowerBuilder の OLEControl コントロールを使用して ActiveX コン トロールを表示するウィンドウ PowerBuilder ウィンドウ プラグインの機能 PowerBuilder ウィンドウ プラグインは、Web ページ上にあらかじめ割 り当てられた固定領域内に PowerBuilder のチャイルド ウィンドウを表 示します。ユーザはページ上のコントロールと対話でき、ウィンドウ とそのコントロールの PowerBuilder スクリプトはどの PowerBuilder コ ー ド で も 実 行 で き ま す。ユ ー ザ が 別 の Web ペ ー ジ に 移 る と、 PowerBuilder ウィンドウは閉じ、PowerBuilder DLL がメモリからアン ロードされます。 プラグインを HTML ページに含めるには、HTML Embed 要素を使いま す。Embed 要素は PowerBuilder オブジェクトを収めた 1 つまたは複数 の PBD の名前、およびページに表示されるチャイルド ウィンドウ オ ブジェクトの名前を指定します。 PowerBuilder ウィンドウ プラグインは Netscape プラグイン API を実装 し、この API をサポートするブラウザが必要です。詳細は、701 ペー ジの「サポートするブラウザ」を参照してください。 クライアントとサーバ の対話の詳細 表 32-1 に、PowerBuilder ウィンドウ プラグインを含む HTML ドキュ メントが表示される際にクライアントとサーバとの間で行われる処理 について詳しく示します。 表 32-1: ウィンドウ プラグインのクライアント / サーバ間トランザクション 手順 1 クライアントの動作 Web ブラウザがサーバに HTML ドキュメントを要求する 2 ブラウザは MIME の種類を受信 し、HTML ドキュメントを受信 する準備をする ブラウザは HTML ドキュメント を受信し、それを表示する 3 アプリケーション テクニック サーバの応答 サーバはドキュメントの MIME の種類(text/html)を識別する ヘッダを送信する サーバは HTML ドキュメントを 送信する — 703 PowerBuilder ウィンドウ プラグインについて 手順 4 クライアントの動作 ブラウザは Embed 要素を認識し、 ページ上にプラグインのための 領域を確保し、PBD ファイルを サーバに要求する サーバの応答 サーバは、PBD の MIME の種類 を識別するヘッダを送信する。 ヘッダは以下のいずれかである • 標準ウィンドウ プラグイン application/vnd.powerbuilder10 • セキュリティ ウィンドウ プラグ イン application/vnd.powerbuilder10-s 5 ブラウザは MIME の種類を受信 し、PBD ファイルを受信する準 備をする サーバは PBD ファイルを送信す る 6 ブラウザは PBD ファイルを受信 する ブラウザは、自分のプラグイン ディレクトリから MIME タイプ に対応する DLL を探す。手順 4 のサーバの応答を参照 ブラウザはプラグイン DLL を ロードする プラグインが PowerBuilder 配布 DLL を探してロードする Embed 要素に LIBRARY 属性が含 まれる場合、クライアントは指 定された PBD ファイルを要求す る ブラウザは MIME の種類を受信 し、追加 PBD ファイルを受信す る準備をする PowerBuilder は Embed 要素で指 定されたチャイルド ウィンドウ を表示する チャイルド ウィンドウはその Open スクリプトを実行する スクリプトが CommandParm 関数 を呼び出す場合、PowerBuilder は Embed 要素の COMMANDPARM 属性の値をブラウザに問い合わ せる — 7 8 9 10 11 12 13 14 704 — — — サーバは PBD の MIME の種類を 識別するヘッダを送信する。手 順 4 のサーバの応答を参照 サーバは PBD ファイルを送信す る — — — PowerBuilder 第 32 章 要件 PowerBuilder ウィンドウ プラグインの使い方 PowerBuilder ウィンドウ プラグインは、PowerBuilder ランタイム DLL およびプラグイン DLL を使用して、PowerBuilder のフル機能を提供し ます。 PowerBuilder ウィンドウ プラグインを含むページを参照する各クライ アントで、ローカル マシンにインストールされる以下のソフトウェア をサポートする必要があります。 • PowerBuilder ランタイム DLL • Web ブラウザのプラグイン ディレクトリに入っている ウィンド ウ プラグイン DLL PowerBuilder ウィンドウ プラグインは、開発者がクライアント マシン のセットアップを管理するイントラネット アプリケーションで特に 便利です。 サポートされる各プラットフォーム上でのクライアント マシンの設 定の詳細については、721 ページの「ユーザのワークステーションの 設定」を参照してください。 名前 PowerBuilder ウィンドウ プラグイン DLL の名前は、使用しているもの が標準バージョンかセキュリティ バージョンかによって異なります。 表 32-2: PowerBuilder ウィンドウ プラグイン DLL コンポーネント 標準 PowerBuilder ウィンドウ プラグイン セキュリティ PowerBuilder ウィンドウ プラ グイン 名前 NPPBA100.DLL NPPBS100.DLL PowerBuilder ウィンドウ プラグインのインストールと設定 PowerBuilder のインストール時に標準セットアップを選択した場合、 PowerBuilder ウィンドウ プラグインはコンピュータにインストールさ れません。プラグインをインストールするには、PowerBuilder のカス タム インストールを実行し、 [コンポーネントの選択]ページで[Web プラグイン]チェックボックスをオンにします。インストールするプ ラグインとコントロールを選択するには、そのページの[変更]ボタ ンをクリックします。 この節では、プラグインのインストール後に行う必要がある設定作業 について説明します。 アプリケーション テクニック 705 セキュリティ PowerBuilder ウィンドウ プラグインの使い方 インストール先 PowerBuilder ウィンドウ プラグイン DLL は、PowerBuilder10.0\Internet Tools\Plugins ディレクトリにインストールされます。Netscape がイン ストール済みの場合は、PowerBuilder インストール プログラムによっ てプラグインのコピーが Web ブラウザの Plugins ディレクトリにイン ストールされる場合もあります。 ブラウザがインストールされていない場合、またはインストール プロ グラムがブラウザを見つけられなかった場合には、Netscape をインス トールして、プラグインをブラウザの Plugins ディレクトリにコピーす るか移動しなければなりません。 PowerBuilder 配布 DLL PowerBuilder ウィンドウ プラグインは、PowerBuilder ランタイム DLL (PBVM100.DLL、PBDWE100.DLL など)の場所を認識していなければ なりません。セットアップ プログラムはブラウザを検出するとレジス トリに適切な修正を加えますが、セットアップ プログラムがブラウザ を検出できなかった場合には、開発者側で修正を行わなければなりま せん。これには 2 つの方法があります。 • Windows レジストリで、ブラウザの実行ファイルに対するアプリ ケーション パス キーに PowerBuilder ランタイム DLL のディレク トリを追加する • システム パスに PowerBuilder ランタイム DLL のディレクトリを 追加する セキュリティ PowerBuilder ウィンドウ プラグインの使い方 使い方 セキュリティ PowerBuilder ウィンドウ プラグインを使用するアプリ ケーションを開発、配布するには、標準の PowerBuilder ウィンドウ プ ラグインの場合と同じ基本手順(707 ページの「PowerBuilder ウィンド ウ プラグイン アプリケーションの開発と配布」を参照)に従います。 唯一の相違点は、セキュリティ PowerBuilder ウィンドウ プラグインが、 特殊なバージョンの標準のウィンドウ プラグイン DLL を使用するこ と で す。セ キ ュ リ テ ィ バ ー ジ ョ ン の ウ ィ ン ド ウ プ ラ グ イ ン は、 NPPBS100.DLL です。 機能上の制約 706 セキュリティ PowerBuilder ウィンドウ プラグインを使用すると、クラ イアント ワークステーションで実行する PowerBuilder アプリケーショ ンの機能がかなり制約され、クライアント システムへの印刷以外のア クセスは拒否されます。このため、セキュリティ ウィンドウ プラグイ ンがすべての状況で有効であるとは限りません。 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 セキュリティ PowerBuilder ウィンドウ プラグインを使用した場合、表 32-3 に示す動作が制限されます。 表 32-3: セキュリティ ウィンドウ プラグインの制約 動作 外部関数 PowerScript 関数 データベース接続 インターネット アク セス 電子メール OLE ダイナミック データ エクスチェンジ (DDE) 制約 外部関数を呼び出すと実行エラーが発生する 一定の PowerScript 関数を呼び出すと実行エラーが 発生する データベースにアクセスする関数を呼び出すと実 行エラーが発生する セキュリティ PowerBuilder ウィンドウ プラグイン を使用するアプリケーションでは、現行の Web サー バにしかインターネット接続できない PowerScript の Mail 関数を呼び出すと実行エラーが 発生する PowerScript の OLE 関数を呼び出すと実行エラーが 発生する PowerScript の DDE 関数を呼び出すと実行エラーが 発生する PowerBuilder ウィンドウ プラグイン アプリケーション の開発と配布 基本手順 プラグイン アプリケーションの開発には、主な 4 つの作業があります。 ❖ PowerBuilder ウィンドウ プラグイン アプリケーションを作成および配布す るには 1 PowerBuilder アプリケーションを作成、テスト、および構築します。 2 PowerBuilder アプリケーション ウィンドウを埋め込む HTML ペー ジを作成します。 3 内容の種類(MIME の種類)を登録し、アプリケーションの HTML ページと PBD ファイルを所定のディレクトリにコピーして、Web サーバを構成します。 4 すべてのクライアント ワークステーション上で、標準またはセキュ リティ PowerBuilder ウィンドウ プラグイン DLL と PowerBuilder 配 布 DLL をインストールします。 アプリケーション テクニック 707 PowerBuilder アプリケーションの作成 結果のコンポーネント セットアップがすべて終了すると、表 32-4 に示すコンポーネントが サーバおよびクライアント コンピュータに設定されます。 表 32-4: PowerBuilder プラグイン用のサーバとクライアントの環境設定 コンピュータ サーバ クライアント コンポーネント MIME の種類が登録されている 登録の方法については、720 ページの「MIME の種類の指 定」を参照 HTML ページに PBD の Embed 要素がある 1 つまたは複数の PBD にアプリケーション オブジェクト が収められている ブラウザのプラグイン ディレクトリ内の PowerBuilder プラ グイン DLL プラットフォーム用の配布キットを使用してインストール した PowerBuilder 配布 DLL システム パスにリストされた PowerBuilder 配布 DLL の ディレクトリ データベース接続ソフトウェア、OLE サーバ、カスタム コ ントロールなど、プラグイン アプリケーションで必要とな るその他のソフトウェア 次の手順 この章では、以降、PowerBuilder ウィンドウ プラグイン アプリケー ションを開発、配布するための以下の 4 つの手順について説明します。 • PowerBuilder アプリケーションの作成 • HTML ページの作成 • サーバの設定 • ユーザのワークステーションの設定 PowerBuilder アプリケーションの作成 PowerBuilder ウィンドウ プラグイン アプリケーションは、Web ページ に表示されるチャイルド ウィンドウから始まります。ウィンドウで、 コントロールの表示、およびイベントのスクリプトの記述が行えます。 スクリプトからは、ほかのウィンドウを開く、ファイルを読み書きす る、クライアント マシン上のほかのプログラムを実行するなどの操作 が行えます。 708 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 プラグイン アプリケーションの設計の選択 プラグインとして使用するアプリケーションの設計は、通常開発する PowerBuilder アプリケーションとほとんど変わりませんが、以下の点 について、いくつかの制限事項と留意事項があります。 ウィンドウ管理 • ウィンドウ管理 • オブジェクト • スクリプトと変数 • データ アクセス • 外部ファイル 初期チャイルド ウィンドウ 初期ウィンドウは、ブラウザ フレーム内に 存在するチャイルド ウィンドウでなければなりません。 以下のことが可能です。 • チャイルド ウィンドウでタイトル バーを使用する。ただし、チャ イルド ウィンドウでは、コントロール メニュー、最大化ボタン、 または最小化ボタンは使用しない • チャイルド ウィンドウから、ポップアップ ウィンドウまたはレス ポンス ウィンドウを開く。メイン ウィンドウまたは MDI ウィン ドウは開けない 以下の制限があります。 • チャイルド ウィンドウのメニューを配置する • 初期ウィンドウから別のチャイルド ウィンドウを開く ウィンドウを閉じる クライアントが別の Web ページを参照すると、現 行の Web ページのチャイルド ウィンドウは閉じますが、ほかのウィン ドウはアプリケーションを閉じない限り、開いています。これらのウィ ンドウは、チャイルド ウィンドウの Close イベントまたは CloseQuery イベントで閉じなければなりません。 戻り値を設定して、CloseQuery イベントでチャイルド ウィンドウが閉 じないようにする処理は行わないでください。ブラウザが別のページ に移らないようにしたり、ビューからウィンドウを削除できないよう にしたりすることはできません。ユーザが前のページに戻ったときに、 アプリケーションの別のインスタンスが起動されます。 オブジェクト PBD 内のオブジェクト プラグイン アプリケーションは、PBD の中の すべてのオブジェクトにアクセスします。関数、構造体、ユーザ オブ ジェクトにもアクセスできます。 アプリケーション テクニック 709 PowerBuilder アプリケーションの作成 プラグイン アプリケーションは、SQLCA トラ ン ザ ク シ ョ ン オ ブ ジ ェ ク ト や メ ッ セ ー ジ オ ブ ジ ェ ク ト な ど、 PowerBuilder がインスタンスを作成するシステム オブジェクトにアク セスします。 システム オブジェクト Embed 要素のオプションの APPLICATION 属性を使用して、PBD のアプリケーション オブジェク トの名前を指定できます。APPLICATION 属性を使用すると、プラグ イン アプリケーションはアプリケーション オブジェクトの Open イベ ントと Close イベントにアクセスできます。 アプリケーション オブジェクト APPLICATION 属性を指定しないと、以下のようになります。 • プラグイン アプリケーションはアプリケーション オブジェクトに アクセスできなくなり、SystemError や Idle などのイベントが利用 できない。アプリケーション オブジェクトでグローバルに定義さ れている変数と関数を処理できない • アプリケーション オブジェクトのほかのスクリプトは、PowerBuilder でテストを行う際に必要となる。アプリケーション オブジェクト のスクリプトで、アプリケーションのセットアップを行うことが できない APPLICATION 属性の指定については、717 ページの「Embed 要素の属 性」を参照してください。 スクリプトと変数 グローバル変数 Embed 要素の APPLICATION 属性を使用して PBD の アプリケーション オブジェクトを指定すると、プラグイン アプリケー ションはアプリケーションで使うグローバル変数とグローバル関数に アクセスできます。 APPLICATION 属性を指定しないと、プラグイン アプリケーションは グローバル変数を使えません。すべての変数をインスタンス、共有、 またはローカルに定義しなければなりません。 APPLICATION 属性の指定については、717 ページの「Embed 要素の属 性」を参照してください。 初期ウィンドウの参照 PowerBuilder は、初期チャイルド ウィンドウの インスタンスを保持する変数を作成しないので、スクリプトで名前を 使用して初期チャイルド ウィンドウを参照することはできません。逆 に、Open 関数のスクリプトを記述してウィンドウのインスタンスを生 成すれば、そのインスタンスを変数に代入して参照できます。 したがって、以下のスクリプトは、ウィンドウ変数 w_mychild が存在し ないため、実行時エラーになります。 // 以下のスクリプトは、実行時エラーとなります。 710 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 w_mychild.title = "The initial window" 以下のようにスクリプトを記述すると、エラーを回避できます。 // チャイルド ウィンドウ自体で this.title = "The initial window" // または title = "The initial window" // チャイルド ウィンドウのコントロール内で parent.title = "The initial window" アプリケーションをセットアップするスクリプト DBMS への接続を含め、 アプリケーションのセットアップはすべてチャイルド ウィンドウで 行わなければなりません。最初に実行されなければならないスクリプ ト可能なイベントは、ウィンドウの中のコントロールのコンストラク タです。次に、ウィンドウの Open イベントが実行されます。 Activate イベントはチャイルド ウィンドウでは実行されません。した がって、チャイルド ウィンドウにアプリケーションのセットアップ コードを置かないでください。 データ アクセス アプリケーションから DBMS にアクセスする場合、各クライアントは データ ソースに接続しなければなりません。その接続は、サーバでは なくクライアント マシン上で定義される必要があります。データ ソー スはローカル DBMS かネットワーク DBMS です。 クライアント マシンから DBMS に接続する方法については、『データ ベースとの接続』マニュアルを参照してください。 コントロールの Constructor イベントは、ウィンドウの Open イベント の前に実行されます。ウィンドウの Open イベントで DBMS に接続し た場合、Constructor イベントではデータが得られません。ウィンドウ の Open イベントでコントロールのデータを取得するか、Constructor イ ベントまたはウィンドウの Open イベントからイベントをポストして ください。 外部リソースのパス ファイルに指定するパスは、クライアント ワークステーションで有効 でなければなりません。 アプリケーションで外部ファイルとして画像を使用する場合、その画 像は PowerBuilder オブジェクトに指定されたパスで取得できなければ なりません。外部ファイルを使用するのではなく、画像リソースを PBD に構築することもできます。これについては、714 ページの「動的ラ イブラリの構築」を参照してください。 アプリケーションでローカル ファイルを読み書きする場合、それらの ファイルのパスは各クライアント マシンで有効なものでなければな りません。 アプリケーション テクニック 711 PowerBuilder アプリケーションの作成 パスで、マップされたドライブ名を使用してネットワーク ドライブが 参照されている場合、すべてのクライアントがアプリケーションと同 じドライブ名を使用する必要があります。また、サーバ名をパスで指 定することもできます。 たとえば、o: が \\marketing\drive に割り当てられている場合、以下の パスはどちらも有効です。ただし、ドライブ名は変更の可能性がある ので、サーバ名を指定している 2 番目のパスの方が永続的な利用が可 能です。 O:\pbapps\connect.bmp \\marketing\drive\pbapps\connect.bmp ウィンドウ ペインタでの開始ウィンドウの定義 PowerBuilder で作成するほかのウィンドウと同様に、起動ウィンドウ の作成にもウィンドウ ペインタを使います。 ❖ ❖ 起動ウィンドウ(または専用のウィンドウ)を作成するには 1 PowerBuilder でウィンドウ オブジェクトを新規作成します。 2 プロパティ ビューのウィンドウの[全般]タブで、ウィンドウの 種類を「child!」に設定します。 3 必要であれば、ほかのコントロールを追加します。 4 ウィンドウとコントロールのイベント スクリプトを記述します。 既存のアプリケーションをプラグインとして実行できるように変換するには 1 最初に表示されるウィンドウの種類を「child!」に変更します。 2 Embed 要素の APPLICATION 属性を指定しない場合は、以下の両 方の操作を行います。 • グローバル変数への参照を削除する • アプリケーションのセットアップ コードを、アプリケーショ ンの Open イベントまたは MDI フレーム イベントからチャイ ルド ウィンドウの Open イベントに移動します。 APPLICATION 属性の指定については、717 ページの「Embed 要素 の属性」を参照してください。 3 712 アプリケーションの設計によっては、ほかのウィンドウを開く方 法を設計し直さなければならない場合もあります。 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 チャイルド ウィンドウにメニューを配置することはできません。チャ イルド ウィンドウはアクティブ ウィンドウとはみなされず、Activate イベントは発生しません。チャイルド ウィンドウにはタイトル バーを 表示でき、最小化、最大化、サイズ変更ができます。プラグイン環境 では、以下のように、チャイルド ウィンドウは Web ページ上の WIDTH 属性と HEIGHT 属性で割り当てられる領域に常に制限されます。 チャイルド ウィンド ウについて • ウィンドウを最大化すると、WIDTH 属性と HEIGHT 属性で割り当 てられた領域内で最大表示される • ウィンドウを最小化すると、ウィンドウのアイコンとタイトルが プラグインに割り当てられた領域の下端に表示される • チャイルド ウィンドウのサイズを変更できる場合は、枠線をド ラッグしてウィンドウを割り当て領域より小さくできる(割り当 て領域より大きくすることはできない) したがって、チャイルド ウィンドウの最小化、最大化、またはサイズ 変更は有効とはいえません。 PowerBuilder でのアプリーションのテスト 作成したアプリケーションをクライアント ブラウザで実行する前に、 PowerBuilder でチャイルド ウィンドウを開くメイン ウィンドウを定義 して、アプリケーションをテストできます。 ❖ PowerBuilder ウィンドウ プラグイン アプリケーションをテストするには 1 種類がメイン(デフォルト)のウィンドウ オブジェクトを新規作 成します。 2 プラグインの起動チャイルド ウィンドウを開く Open イベントの スクリプトを記述します。 Open(w_child) 3 アプリケーション テクニック ウィンドウ ペインタで、ウィンドウ サイズを以下のように設定す ると便利です。 • メイン ウィンドウのサイズは、チャイルド ウィンドウを十分 に表示できるサイズにする • チャイルド ウィンドウを左上隅に配置する。このように設定 するには、プロパティ ビューの[その他]タブの[位置]フィー ルドを使用する 713 PowerBuilder アプリケーションの作成 4 [プレビュー]ボタンをクリックするか、[ファイル|実行 / プレ ビュー]を選択して、テスト ウィンドウを実行します。 PowerBuilder でのデバッグ PowerBuilder デバッガを使用するには、ウィンドウだけを実行するの ではなく、アプリケーションを実行する必要があります。メイン ウィ ンドウを開くスクリプトで、アプリケーション オブジェクトを定義し ます。次に、 [実行]コマンドか[デバッグ]コマンドを使用してアプ リケーションをテストできます。 動的ライブラリの構築 『ユーザーズ ガイド』マニュアルでは、動的ランタイム ライブラリ (PBD)を構築する方法について説明しています。この手順は、プラグ イン アプリケーションの場合と同じです。この節では、プラグイン ア プリケーション用の PBD を構築するために必要な選択項目について 説明します。 Web 環境では、ファイル サイズが重要であることを覚えておいてくだ さい。 PBL 内でのオブジェ クトの編成 PowerBuilder リソー ス(PBR)ファイル の使用 714 アプリケーションを構築する前に、アプリケーションで使用するオブ ジェクトをシステム ツリーまたはライブラリ ペインタで PBL に編成 しておかなければなりません。PBL はプラグイン アプリケーションの PBD のソースになります。最適なライブラリを作成するには、以下の 点に留意します。 • ファイル サイズを最小化するには、アプリケーションで使用する オブジェクトのみを入れる。不要なオブジェクトは削除する • 動的に作成されるオブジェクト(データストアで使用されるデー タウィンドウ オブジェクトなど)またはデータウィンドウのコン トロールに動的に割り当てられるオブジェクトをすべて含める • 先祖オブジェクトを入れる コントロールによっては、画像に外部ファイルを使用する場合もあり ます。たとえば、ピクチャ リストボックス コントロール、ツリービュー コントロール、ピクチャ コントロール、ピクチャボタン コントロー ル、ポインタ、データウィンドウ オブジェクトのビットマップ オブ ジェクトです。プラグイン アプリケーションで外部ファイルの画像を 使用する場合、クライアントで同じ画像が同じシステム パス上にない ことがあります。 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 クライアント マシンにピクチャをインストールするかわりに、1 つま たは複数の PowerBuilder リソース(PBR: PowerBuilder Resource)ファ イルを使用して、PBD に画像を組み込むことができます。画像を組み 込むと PBD はサイズは大きくなりますが、独立して機能します。 構築する動的ランタイム ライブラリは実行ファイルではないため、 PBR ファイルにデータウィンドウ オブジェクトを含める必要はあり ません。作成後の PBD には、ソース PBL 内のすべての PowerBuilder オブジェクトが含まれます。 ネットワーク上の画像やその他のリソース PBD にファイルを組み込むかわりに、広くアクセスされるネットワー ク ディレクトリにファイルを格納することも可能です。ただし、この 場合、ファイルへのパスは、PowerBuilder オブジェクトでのパスと同 じでなければなりません。つまり、Windows 環境では、各クライアン トが同じドライブ名でネットワーク ドライブをマップしなければな りません。あるいは、サーバ名をパスで指定することもできます。 ❖ PBR ファイルを定義するには 1 〔Shift〕+〔F6〕を押してファイル PowerBuilder エディタを開くか、 ほかのテキスト エディタを開き、拡張子 .PBR の新しいファイル を作成します([テキスト エディタ]アイコンはツールバーに追加 できます)。 2 画像やほかのリソースを、各行に一覧表示します。パスとファイ ル名を、オブジェクトのプロパティ シートかスクリプトで指定さ れるとおり正確に表示します。 ショートカット オブジェクトのプロパティ ビューを表示し、 〔Ctrl〕+〔C〕を使用 して、ファイル名をクリップボードにコピーし、エディタに貼り 付けます。 3 ファイルを保存します。 アプリケーションに複数の PBL が含まれ、各 PBL にそれぞれのリソー スを使用するオブジェクトが含まれている場合は、各 PBL に対して PBR ファイルを作成する必要があります。PBR ファイルは、1 つの PBL 内で使用されるリソースのファイル名をリストします。 PBD の構築 ライブラリ ペインタかプロジェクト ペインタでランタイム ライブラ リ(PBD)を構築します。これについては、『ユーザーズ ガイド』マ ニュアルを参照してください。以下のことに留意してください。 アプリケーション テクニック 715 PowerBuilder アプリケーションの作成 プラグイン アプリケーションには、マシ ン コード DLL ではなく PBD が必要です。 • マシン コードの選択解除 • PBR ファイルを各 PBD に指定する PBR ファイルにリストしたリ ソースを PBL 内のオブジェクトで使用する場合は、PBR 名を [ソー ス ファイル]テキストボックスに入力します。 PBR ファイルの定義およびランタイム ライブラリ(PBD)の構築方法 については、 『ユーザーズ ガイド』マニュアルで実行ファイルの作成 に関する章を参照してください。 716 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 HTML ページの作成 プラグイン アプリケーションの PowerBuilder PBD を作成、構築した ら、次にそれを表示する HTML ページを作成しなければなりません。 PowerBuilder ウィンドウを Web ページに含むには、Embed 要素を使い ます。要素の属性で、ウィンドウに割り当てる領域、PBD の名前、お よび PBD の中のチャイルド ウィンドウの名前を指定します。 Embed 要素は次のように指定します。 <EMBED SRC=plugin_tree.pbd WIDTH=370 HEIGHT=320 WINDOW=w_emp_by_dept> Embed 要素の属性 Embed 要素は、プラグインの HTML 仕様の一部です。HTML でいくつ かの標準属性を定義し、PowerBuilder で追加属性を定義します。 HTML 属性 HTML 属性で、クライアントにダウンロードするファイルの名前、お よび Web ページ上でプラグインに確保する領域を、以下のとおり指定 します。 表 32-5: HTML Embed 要素属性 HTML 属性 SRC 値 ダウンロードされるオブジェクトを識別する ブラウザは、Embed 要素を処理するときに、サーバ にリソースを要求し、コンテンツ タイプを処理す る DLL をプラグイン ディレクトリから検索する WIDTH HEIGHT PowerBuilder ウィンドウ プラグインの場合、オブ ジェクトはアプリケーションを起動するチャイル ド ウィンドウを収めた PBD である 表示するウィンドウの幅。ピクセル値で指定する 表示するウィンドウの高さ。ピクセル値で指定する WIDTH 属性と HEIGHT 属性には、チャイルド ウィンドウの幅および 高さの最大値を定義します。チャイルド ウィンドウのサイズを変更で きる場合、指定のサイズより小さくできますが、大きくはできません。 PowerBuilder 属性 Embed 要素の PowerBuilder 属性で、アプリケーションを起動するウィ ンドウ オブジェクト、追加ライブラリ、アプリケーションに渡すパラ メータ、およびアプリケーション オブジェクトの名前を、以下のとお り識別します。 アプリケーション テクニック 717 HTML ページの作成 表 32-6: PowerBuilder Embed 要素属性 PowerBuilder 属性 WINDOW LIBRARY (オプション) 値 PBD 内のチャイルド ウィンドウのクラス名 アプリケーションに必要なオブジェクトを収めた 追加 PBD を指定する URL。PBD の相対 URL では なく絶対 URL を指定しなければならない 複数の LIBRARY 属性を指定できる。アプリケー ションに必要な追加の各 PBD に対して、LIBRARY 属性を指定する。SRC に指定されたファイルの LIBRARY 属性は指定しない COMMANDPARM (オプション) APPLICATION (オプション) LIBRARY 属性を使用した HTML コードの例につ いては、719 ページの「追加属性を持つ Embed 要 素」を参照 ウィンドウに渡す文字列。ウィンドウ内からこの文 字列にアクセスするには、CommandParm 関数を呼 び出す COMMANDPARM 属性を使用した HTML コードの 例については、719 ページの「追加属性を持つ Embed 要素」を参照 PBD 内のアプリケーション オブジェクトの名前 これを使用して、プラグイン アプリケーションはア プリケーション オブジェクトの Open イベントと Close イベント、およびアプリケーションで使うグ ローバル変数とグローバル関数にアクセスできる APPLICATION 属性を使用すると、アプリケーション オブジェクトの Open イベントと Close イベントは デフォルトで実行され、上書きできない。WINDOW 属性で指定されたチャイルド ウィンドウは、アプ リケーション オブジェクトの Open イベントでは 開かない。もし開けば、アプリケーションは異常終 了する APPLICATION 属性を使用した HTML コードの例 については、719 ページの「追加属性を持つ Embed 要素」を参照 718 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 サンプル ページ 次の HTML コードは、マスタ データウィンドウ コントロールと詳細デー タウィンドウ コントロールを持つウィンドウを表示する、PowerBuilder ウィンドウ プラグインを含むページを作成します。ここでは、Embed 要素を使用して PowerBuilder ウィンドウ プラグインを指定しています。 始めの要素 <HTML> ドキュメント ヘッダ <HEAD> <TITLE>Master-Detail window</TITLE> </HEAD> <BODY> スモール イメージ <IMG SRC="undercon.gif" BORDER=0 HEIGHT=38 WIDTH=40> H1 ヘッダ <H1>Master-detail in a PB window plug-in</H1> 水平ルール <P><HR></P> パラグラフ <P> このウィンドウは、PB デモ データベースにアクセスして部門リス トを表示します。ユーザが部門の行をクリックすると、2 番目のデータ ウィンドウにその部門の従業員が表示されます。</P> パラグラフの中の Embed 要素 <P><EMBED SRC=plugin_tree.pbd WIDTH=370 HEIGHT=320 WINDOW=w_emp_by_dept> </P> サイトのホームページ へのリンク <LI>Back to <A HREF="http://www.mycompany.com/index.html">Home Page</A> </LI> 終わりの要素 </BODY> </HTML> 追加属性を持つ Embed 要素 プラグイン アプリケーションで追加ライブラリ、COMMANDPARM 文 字列、および PBD のアプリケーション オブジェクトにアクセスする ための APPLICATION 属性を使用する場合、Embed 要素を以下のとお り指定します。 <EMBED SRC=plugin_tree.pbd WIDTH=370 HEIGHT=320 WINDOW=w_emp_by_dept LIBRARY=http://www.mycompany.com/pb/extra1.pbd LIBRARY=http://www.mycompany.com/pb/extra2.pbd COMMANDPARM="Eastern region" APPLICATION=plugin_tree> アプリケーション テクニック 719 サーバの設定 サーバの設定 プラグイン アプリケーションを表示するための HTML ページを定義 したら、次に Web サーバを設定します。 MIME の種類の指定 Web サーバに所定のソフトウェアを使用して、PowerBuilder ウィンドウ プラグインの MIME の種類を登録します。表 32-7 に、使用できる MIME の種類を示します。 表 32-7: PowerBuilder ウィンドウ プラグイン MIME タイプ プラグイン 標準 PowerBuilder ウィン ドウ プラグイン セキュリティ PowerBuilder ウィンドウ プラグイン 登録する MIME の種類 application/vnd.powerbuilder10 application/vnd.powerbuilder10-s MIME のファイル拡張子は PBD です。 サーバのマニュアルによっては、MIME の種類ではなく、内容の種類 という用語を使用する場合もあります。 サーバへのファイルの 配置 PowerBuilder ライブラリと HTML ファイルをサーバ上の所定のディレ クトリにコピーします。 表 32-8: サーバ上の PBD ファイルと HTML ファイルの場所 ファイル HTML ページ 場所 HTML ドキュメント ディレクトリ Embed 要素の SRC 属 性および LIBRARY 属 性で指定される PBD ファイル HTML ドキュメント ディレクトリか、ほか の適切なディレクトリ 実行方法 HTML ページを、ページ にリンクする URL で指定 されるディレクトリにコ ピーする PBD ファイルを Embed 要 素の属性で指定したディ レクトリにコピーする URL について HTML ページに指定する URL は、Web サーバで定義さ れる論理パスです。たとえば、Windows では、PBD のシステム パスは 以下のようになります。 C:\WEBSITE\HTDOCS\PB\PLUGIN_APP.PBD htdocs がサーバのドキュメント ディレクトリに定義されれば、Embed 要素の SRC 属性を指定するとき次の相対パスを使えます。このパス は、ドキュメント ディレクトリに対する相対パスです。 pb/plugin_app.pbd 720 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 LIBRARY 属性の場合、PBD に相対 URL を指定しないでください。以 下のような絶対 URL を指定しなければなりません。たとえば、次のよ うになります。 http://www.mycompany.com/pb/plugin_app.pbd ユーザのワークステーションの設定 プラグイン アプリケーションの構築、その HTML ページの作成、およ びサーバの設定が終了したら、次はプラグイン アプリケーションを表 示できるようにクライアント ワークステーションを設定する必要が あります。 PowerBuilder ウィンドウ プラグイン アプリケーションを含む Web ページを表示するには、クライアント ワークステーションでインス トールされるソフトウェアをサポートする必要があります。また、Web サーバにも接続しなければなりません。 必要なコンポーネント PowerBuilder ウィンドウ プラグイン アプリケーションを含む Web ページを表示するには、各クライアント ワークステーションで表 32-9 に示すコンポーネントが必要です。 表 32-9: PowerBuilder ウィンドウ プラグインの表示に必要なクライアント 要件 コンポーネント インターネット接続か イントラネット接続 Netscape プラグインを サポートする Web ブラ ウザ 詳細 企業内で、またはインターネット サービス プロバ イダから利用できる ブラウザ ベンダから利用できる。以下のようなブ ラウザが必要である • Netscape Navigator バージョン 3.x 以降 • Microsoft Internet Explorer バージョン 3.x から 5.5 Service Pack 1 まで。Internet Explorer 5.5 Service Pack 2 以降のバージョンはプラグインを サポートしていない アプリケーション テクニック 721 ユーザのワークステーションの設定 コンポーネント 詳細 PowerBuilder 配布 DLL PowerBuilder ランタイム DLL をインストールす る。849 ページの「PowerBuilder ランタイム ファイ ル」を参照 PowerBuilder ランタイム DLL は、アプリケーショ ン ディレクトリか、システム パス上のディレクト リに置く。PowerBuilder ウィンドウ プラグイン DLL は、PowerBuilder ランタイム DLL の場所がわ か ら な け れ ば な ら な い。そ の た め に は、 PowerBuilder 配布 DLL のディレクトリをシステム パスに追加するか、ディレクトリをブラウザのア プリケーション パス キーに追加する(Windows レ ジストリ) 標準またはセキュリ この DLL がない場合には、NPPBA100.DLL ファイ ティ PowerBuilder ウィ ル(標準)または NPPBS100.DLL ファイル(セキュ ンドウ プラグイン DLL リティ)を Internet Tools\Plugins ディレクトリから ブラウザの Plugins ディレクトリにコピーする その他のファイル 画像ソースを PBD に入れていない場合、ファイル がオブジェクトのプロパティで指定されるパス上 になければ、そのパスにコピーする プラグイン アプリケーションがデータベースに接 続する場合、DBMS のクライアント ソフトウェア をセットアップする。クライアント マシンから 『データベース DBMS に接続する方法については、 との接続』マニュアルを参照 722 PowerBuilder 第 32 章 PowerBuilder ウィンドウ プラグインの使い方 Web ページとプラグイン アプリケーションの表示 必要なソフトウェアをインストールしたら、Web ページとプラグイン アプリケーションを表示できます。 ユーザが Web ページの URL を指定すると、以下のことが行われます。 • PowerBuilder ウィンドウに割り当てられた領域に、ページ上のテキ ストが表示される • クライアントがサーバから PBD をダウンロードする • ブラウザが Web ページ内にチャイルド ウィンドウを表示する • ウィンドウの中のコントロールと対話し、イベントのスクリプト を実行する • ユーザがページから離れると、ウィンドウが閉じ、PowerBuilder DLL がメモリからアンロードされる アプリケーション テクニック 723 ユーザのワークステーションの設定 724 PowerBuilder 第 3 3 章 データウィンドウ プラグインの 使い方 この章について この章では、データウィンドウ プラグインを使用して Powersoft レ ポート(PSR)を開発して Web ページに配布する方法について説 明します。 内容 はじめに 項目 データウィンドウ プラグインについて Powersoft レポート(PSR)の保存 HTML ページの作成 Web サーバの設定 ユーザのワークステーションの設定 ページ 725 729 730 732 733 この章では、HTML と URL について、および Web ブラウザが Web サーバからページをどのように取得するかについての知識を有 し、Web サーバにアクセス可能な環境であることを前提にしてい ます。 データウィンドウ プラグインについて データウィンドウ プラグインを使用すると、Netscape プラグイン をサポートするブラウザで表示される Powersoft レポート(PSR) を Web ページに表示できます。 PSR ファイルには、レポートの定義(ソースとオブジェクト)お よび PSR ファイル作成時のデータが含まれます。PSR ファイルを 作成するとその中にデータが保存されるので、PSR ファイルでは データベース接続は必要はありません。ただし、データは静的な ので更新できません。 サポートするブラウザ アプリケーション テクニック データウィンドウ プラグインを使用するには、Netscape プラグイ ンをサポートする Web ブラウザを使う必要があります。たとえば、 Netscape ブラウザ、Microsoft Internet Explorer バージョン 3 ~ 5.5 Service Pack 1 です。 725 データウィンドウ プラグインについて Microsoft Internet Explorer 5.5 Service Pack 2 以 降 の バ ー ジ ョ ン は、 Netscape プラグインをサポートしていません。PowerBuilder Enterprise 版を使う場合、ActiveX のデータウィンドウ Web コントロールを使用 して Internet Explorer に PSR を表示できます。詳細については、『デー タウィンドウ プログラマーズ ガイド』マニュアルを参照してくださ い。 セキュリティ データウィンドウ プラグインにはセキュリティ上の問題はありませ ん。ローカル アプリケーションを実行することもありません。また、 ユーザがレポートをローカルに保存するように明示的に選択しない限 り、ローカル ファイルへの書き込みも行いません。 データウィンドウ プラグインは PSR ファイルしか表示しません。PSR ファイルは読み込み専用です。したがって、セキュリティ バージョン のデータウィンドウ プラグインは不要です。 制約 PSR はリッチテキスト提示様式にはできません。 データウィンドウ プラグインの機能 データウィンドウ プラグインは、レポート ペインタ、データウィンド ウ ペインタ、データウィンドウ コントロール、またはデータストアで プレビューおよび保存されたときのデータと書式を持つ PSR を表示し ます。PSR は、回転文字、色付き文字、影付け、チェックボックス編 集様式やラジオボタン編集様式など、データウィンドウ オブジェクト またはレポート オブジェクトのすべての書式を表示します。 データはレポートであり、データ入力やデータベース アクセスはあり ません。 Web ブラウザのポップアップ メニューを使用して、クライアントはレ ポートをいくつかの形式で印刷または保存できます。レポートをロー カル PSR ファイルとして保存すれば、データの検索、フィルタ、およ びソートのためのツールが揃っている InfoMaker で表示できます。デー タウィンドウ プラグインは Netscape プラグイン API を実装します。 データウィンドウ プラグインを使用するには、この API をサポートす るブラウザが必要です。詳細については、725 ページの「サポートす るブラウザ」を参照してください。 クライアントとサーバ の対話の詳細 726 表 33-1 に、データウィンドウ プラグインを含む HTML ドキュメント をユーザが表示する際に、クライアントとサーバ間で行われる処理に ついて詳しく示します。 PowerBuilder 第 33 章 データウィンドウ プラグインの使い方 表 33-1: データウィンドウ プラグインのクライアント / サーバ間トランザク ション 手順 1 2 3 4 5 6 7 8 クライアントの動作 Web ブラウザがサーバに HTML ドキュメントを要求する サーバの応答 サーバはドキュメントの MIME の種類(text/html)を識別する ヘッダを送信する サーバは HTML ドキュメントを 送信する ブラウザは MIME の種類を受信 し、HTML ドキュメントを受信 する準備をする ブラウザは HTML ドキュメント — を受信し、それを表示する ブラウザは Embed 要素を認識し、 サーバは、PSR の MIME の種類 ページ上にプラグインのための (application/datawindow)を識別 領域を確保し、PSR ファイルを するヘッダを送信する サーバに要求する ブラウザは MIME の種類を受信 サーバは PSR ファイルを送信す る し、PSR ファイルを受信する準 備をする Web ブラウザは PSR ファイルを — 受信する ブラウザはそのプラグイン ディ — レクトリで、MIME の種類 (application/datawindow)に対応 する DLL を検索する — Web ブラウザはプラグイン DLL をロードし、PSR ファイルを表 示する 要件 データウィンドウ プラグインを含むページを参照する各クライアン トでは、ローカル マシンにインストールしたデータウィンドウ プラグ イン DLL が必要です。 名前と位置 データウィンドウ プラグインの名前は、NPDWE100.DLL です。 PowerBuilder は、この DLL を PowerBuilder 10.0\Internet Tools\Plugins ディレクトリにインストールします。 アプリケーション テクニック 727 データウィンドウ プラグインについて データウィンドウ プラグインのインストールと設定 PowerBuilder のインストール時に標準セットアップを選択した場合、 データウィンドウ プラグインはコンピュータにインストールされま せん。プラグインをインストールするには、PowerBuilder のカスタム インストールを実行し、 [コンポーネントの選択]ページで[Web プラ グイン]チェックボックスをオンにします。インストールするプラグ インとコントロールを選択するには、そのページの[変更]ボタンを クリックします。この節では、プラグインのインストール後に行う必 要がある設定作業について説明します。 データウィンドウ プラグインは、PowerBuilder 10.0\Internet Tools\Plugins ディレクトリにインストールされます。Netscape がインストール済み の場合は、PowerBuilder インストール プログラムによってプラグイン のコピーが Web ブラウザの Plugins ディレクトリにインストールされ る場合もあります。 インストール先 ブラウザがインストールされていない場合、またはインストール プロ グラムがブラウザを見つけられなかった場合には、Netscape をインス トールして、プラグインをブラウザの Plugins ディレクトリにコピーす るか移動しなければなりません。Microsoft Internet Explorer の現行バー ジョンは、プラグインをサポートしていません。 データウィンドウ プラグインの開発と配布 実行方法 データウィンドウ プラグインの中に PSR を表示するためには、4 つの 主な作業があります。 ❖ 結果のコンポーネント 728 データウィンドウ プラグインの中に PSR を表示するには 1 PSR ファイルを保存します。 2 データウィンドウ プラグインを埋め込む HTML ページを作成し ます。 3 内容の種類(MIME の種類)を登録し、HTML ページと PSR ファ イルを所定のディレクトリにコピーして、Web サーバを構成しま す。 4 すべてのクライアント ワークステーション上にデータウィンドウ プラグイン DLL をインストールします。 セットアップがすべて終了すると、表 33-2 に示すコンポーネントが サーバおよびクライアント コンピュータに設定されます。 PowerBuilder 第 33 章 データウィンドウ プラグインの使い方 表 33-2: データウィンドウ プラグイン用のサーバとクライアントの環境設定 コンピュータ サーバ クライアント 次の手順 コンポーネント MIME の種類 application/datawindow が拡張子 PSR で登録 されている HTML ページに PSR の Embed 要素がある PSR ファイル ブラウザの Plugins ディレクトリ内のデータウィンドウ プ ラグイン DLL とサポートする DLL この章では、以降、データウィンドウ プラグインに PSR を表示するた めの以下の 4 つの手順について説明します。 • Powersoft レポート(PSR)の保存 • HTML ページの作成 • Web サーバの設定 • ユーザのワークステーションの設定 Powersoft レポート(PSR)の保存 PSR ファイルを作成するには、いくつかの方法があります。 PSR ファイルの作成 ❖ PSR ファイルを作成するには • PowerBuilder データウィンドウ ペインタまたは InfoMaker レポー ト ペインタで、以下の操作を行います。 • [ファイル|名前を付けてファイルを保存]を選択する。ファ イル名の選択 ダイアログボックスに、保存する場所、ファイ ル名、およびファイルの種類として Powersoft レポートを指定 する • [ファイル|名前を付けて行を保存]を選択する。名前を付け て保存 ダイアログボックスに、保存する場所、ファイル名、お よびファイルの種類として Powersoft レポートを指定する PSR のリソース データウィンドウ オブジェクトまたはレポート オブジェクトは、ビッ トマップ オブジェクトとカスタム ポインタを表示できます。これらの 外部リソースを、クライアント ワークステーションで利用できるよう にしなければなりません。サーバから自動ではダウンロードされませ ん。 アプリケーション テクニック 729 HTML ページの作成 外部リソースのパスは、クライアント ワークステーションで有効でな ければなりません。データウィンドウ ペインタかレポート ペインタ で、現行ディレクトリに対する相対パスを指定できます。絶対パスは ユーザのコンピュータに存在しないことがあります。 イントラネット環境では、すべてのユーザがアクセスできるネット ワークドライブに外部リソースを保存できます。Windows 環境では、 ネットワーク パスを使用して、マップされたドライブ名ではなくネッ トワーク ドライブを指定できます。 OLE オブジェクトと カスタム コントロー ル OLE サーバとカスタム コントロールを各クライアント ワークステー ションでインストール、登録する必要があります。 制約 元のデータウィンドウかレポートがリッチテキスト提示様式だった PSR は、データウィンドウ プラグインの中には使えません。 次の手順 PSR ファイルを保存したら、その PSR ファイルを表示する HTML ペー ジを作成しなければなりません。 HTML ページの作成 Embed 要素を使用して、Web ページに Powersoft レポート(PSR)を含 めます。要素の属性によって、レポートに割り当てる領域とレポート ファイル名を指定します。 Embed 要素は次のように指定します。 <EMBED src=April_sales.psr WIDTH=370 HEIGHT=320> Embed 要素の属性 Embed 要素は、プラグインの HTML 仕様の一部です。データウィンド ウ プラグインの場合、標準 HTML 属性だけを指定します。 HTML 属性 HTML 属性で、クライアントにダウンロードするファイル の名前、および Web ページ上でプラグインに確保する領域を、以下の とおり指定します。 730 PowerBuilder 第 33 章 データウィンドウ プラグインの使い方 表 33-3: データウィンドウ プラグインの HTML 属性 HTML 属性 SRC 値 ダウンロードされるオブジェクトを識別する ブラウザは、Embed 要素を処理するときに、サーバに リソースを要求し、コンテンツ タイプを処理する DLL をプラグイン ディレクトリから検索する WIDTH HEIGHT データウィンドウ プラグインの場合、オブジェクトは PSR ファイルである 表示するウィンドウの幅。ピクセル値で指定する 表示するウィンドウの高さ。ピクセル値で指定する サンプル ページ 次に、サンプル ページにデータウィンドウ プラグインを含める HTML コードを示します。Embed 要素を使用して、PSR ファイルを指定して います。 始めの要素 <HTML> ドキュメント ヘッダ <HEAD> <TITLE>On Leave report</TITLE> </HEAD> <BODY> H1 ヘッダ <H1>On Leave report</H1> パラグラフの中の Embed 要素 <P><EMBED src=DWB_att_crossout.psr WIDTH=680 HEIGHT = 350></P> 終わりの要素 </BODY> </HTML> アプリケーション テクニック 731 Web サーバの設定 Web サーバの設定 サーバを設定するには、以下の操作を行います。 MIME の種類の指定 1 MIME の種類の指定 2 サーバへのファイルの配置 Web サーバに所定のソフトウェアを使用して、データウィンドウ プラ グインの MIME の種類を登録します。PowerBuilder 10 で使用できる MIME の種類は次のとおりです。 application/datawindow10 MIME のファイル拡張子は PSR です。 サーバのマニュアルによっては、MIME の種類ではなく、コンテンツ タイプという用語を使用する場合もあります。 サーバへのファイルの 配置 PSR ファイルと HTML ファイルをサーバ上の所定のディレクトリに コピーします。 表 33-4: サーバ上の PSR ファイルと HTML ファイルの場所 ファイル HTML ページ 場所 HTML ドキュメント ディレクトリかサブ ディレクトリ Embed 要素の SRC 属性で指定される PSR ファイル HTML ドキュメント ディレクトリか、ほか の適切なディレクトリ 実行方法 HTML ページを、ページに リンクする URL で指定され るディレクトリにコピーす る PSR ファイルを Embed 要素 の属性で指定したディレク トリにコピーする URL について HTML ページに指定する URL は、Web サーバで定義さ れる論理パスです。たとえば、PSR のシステム パスは以下のようにな ります。 C:\WEBSITE\HTDOCS\PB\DWB_ATT_CROSSOUT.PSR htdocs がサーバのドキュメント ディレクトリに定義されれば、URL の 論理パスは、次のようにドキュメント ディレクトリに対する相対パス になります。 pb/dwb_att_crossout.psr 732 PowerBuilder 第 33 章 データウィンドウ プラグインの使い方 ユーザのワークステーションの設定 PSR の保存、HTML ページの作成、およびサーバの設定が終了したら、 次はデータウィンドウ プラグインを含むページを表示できるように クライアント ワークステーションを設定する必要があります。 データウィンドウ プラグインを含む Web ページを表示するユーザは、 クライアント ワークステーションでインストールされるソフトウェ アをサポートする必要があります。また、Web サーバにも接続しなけ ればなりません。 必要なコンポーネント データウィンドウ プラグインを含む Web ページを表示するには、各ク ライアント ワークステーションで表 33-5 に示すコンポーネントが必 要です。 表 33-5: データウィンドウ プラグインの表示に必要なクライアント要件 コンポーネント インターネット接 続かイントラネッ ト接続 Netscape プラグイ ンをサポートする Web ブラウザ データウィンドウ プラグイン DLL サポート DLL アプリケーション テクニック 手順 企業内で、またはインターネット サービス プロバイダ から利用できる ブラウザ ベンダから利用できる。以下のようなブラウ ザが必要である • Netscape Navigator バージョン 3.x 以降 • Microsoft Internet Explorer バージョン 3.x ~ 5.5 Service Pack 1。Internet Explorer 5.5 Service Pack 2 以降はプラ グインをサポートしていない この DLL がない場合は、NPDWE100.DLL ファイルを Internet Tools\Plugins ディレクトリからブラウザの Plugins ディレクトリにコピーする この DLL がない場合は、Shared\PowerBuilder ディレク トリからブラウザの Plugins ディレクトリに PBSHR100.DLL ファイルをコピーします。クライアン ト ワークステーションで有効でない場合は、クライア ントの Windows システム ディレクトリに次の Microsoft ランタイム ファイルをインストールします。 MSVCR71.DLL、MSVCP71.DLL、ATL71.DLL 733 ユーザのワークステーションの設定 コンポーネント その他のファイル 手順 元のデータウィンドウ オブジェクトかレポートに、外 部ファイルのビットマップ オブジェクトかカスタム ポ インタが含まれていた場合、外部ファイルをクライアン ト ワークステーションにコピーする必要がある。クラ イアント ワークステーションのパスは、PSR に保存さ れているパスに対応しなければならない 元のデータウィンドウ オブジェクトかレポートに OLE オブジェクトかカスタム コントロールが含まれていた 場合、OLE サーバかカスタム コントロールをクライア ント ワークステーションでインストール、登録する必 要がある。OLE オブジェクトのパスはクライアント ワークステーションで有効でなければならない Web ページと PSR の 表示 PSR をデータウィンドウ プラグインの中に表示しながら、以下の操作 を行えます。 • スクロールバーを使用して PSR のデータを操作する • PSR のソースが編集可能なデータウィンドウ オブジェクトであっ た場合、行とカラムの値を変更する。ただし、データベース接続 がないため、データベースのデータは更新できない • PSR を右クリックして、保存、印刷、およびナビゲートのポップ アップ メニューを表示する Web ページのレポートをローカル PSR ファイルとして保存すれば、そ の PSR ファイルを InfoMaker で開いてデータの検索、フィルタ、およ びソートが行えます。 734 PowerBuilder 第 3 4 章 PowerBuilder ウィンドウ ActiveX の使い方 この章について この章では、PowerBuilder ウィンドウ ActiveX の使い方について説 明します。 内容 項目 PowerBuilder ウィンドウ ActiveX について PowerBuilder アプリケーションの作成 HTML ページの作成 PowerBuilder ウィンドウ ActiveX のイベント サーバの設定 ユーザのワークステーションの設定 ページ 735 741 748 761 762 763 PowerBuilder ウィンドウ ActiveX について PowerBuilder ウィンドウ ActiveX を使用すると、ActiveX をサポー トするブラウザに表示される Web ページに、PowerBuilder のチャ イルド ウィンドウを表示できます。 機能 PowerBuilder ウィンドウには、データウィンドウ、OLE オブジェ クト、OCX(ActiveX)コントロール、およびツリービュー コント ロールなど、通常使用しているすべてのコントロールを表示でき ます。また、チャイルド ウィンドウからポップアップ ウィンドウ またはレスポンス ウィンドウを開くことも可能です。 ユーザがウィンドウ内のコントロールを操作すると、スタンドア ロンの PowerBuilder アプリケーションの場合と同様、そのコント ロールのイベント スクリプトが実行されます。また、HTML ペー ジ内に VBScript や JavaScript を記述することにより、PowerBuilder 関数を呼び出して PowerBuilder イベントに応答する処理を実行で きます。 アプリケーション テクニック 735 PowerBuilder ウィンドウ ActiveX について PowerBuilder ウィンドウ ActiveX アプリケーションからのデータベー ス アクセスは、クライアントのローカル定義データベース接続を使用 して行われます。 アプリケーション内のオブジェクトを、1 つまたは複数の PowerBuilder 動的ライブラリ(PBD: PowerBuilder Dynamic Library)に含めることが できます。 サポートするブラウザ PowerBuilder ウィンドウ ActiveX を利用するには、ActiveX をサポート する、Microsoft Internet Explore などのブラウザが必要です。 PowerBuilder ウィンドウ ActiveX で動作するアプリケーションの種類 HTML フォームでは、限られたユーザ インタフェースを介した対話処 理しかできません。PowerBuilder ウィンドウ ActiveX は、HTML を超 える能力を提供します。リッチ ユーザ インタフェース設計で開発され たアプリケーション ウィンドウを、Web ページに表示できます。クラ イアント ワークステーションで定義されているデータ ソースにアク セスできます。 例 736 アプリケーションには以下のものがあります。 • マスタ データウィンドウと詳細データウィンドウを持つデータ解 析ウィンドウ • ユーザによる選択を、ツリービュー、リストビュー、およびピク チャ リストボックス コントロールから行うユーザ インタフェー スの設計 • サーバ上のデータを処理するデータ入力フォーム • クライアント定義によるデータベース接続(ネットワークまたは ローカル)を使用してクライアント マシン上のデータを処理する データ入力フォーム • PowerBuilder の OLEControl コントロールを使用して ActiveX コン トロールを表示するウィンドウ PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 PowerBuilder ウィンドウ ActiveX の機能 PowerBuilder ウィンドウ ActiveX は、Web ページ上にあらかじめ割り 当てられた固定領域内に PowerBuilder のチャイルド ウィンドウを表示 します。ユーザはページ上のコントロールと対話でき、ウィンドウと そのコントロールの PowerBuilder スクリプトはどの PowerBuilder コー ドでも実行できます。ユーザが別の Web ページに移ると、PowerBuilder ウィンドウは閉じ、PowerBuilder DLL がメモリからアンロードされま す。 PowerBuilder ウィンドウ ActiveX は、HTML Object 要素を使用して HTML ページに貼り付けられます。HTML Object 要素は、PowerBuilder オブジェクト、HTML ページに表示されるチャイルド ウィンドウの名 前、および PowerBuilder アプリケーション オブジェクト(オプション) を含んだ 1 つまたは複数の PBD を指定します。 セキュリティ セキュリティが設定されていないアプリケーションでは、ローカル ファイルへのアクセスおよびローカル アプリケーションの実行が可 能です。このような処理は、制御のない Web 環境では好まれないこと が多いですが、アクセスが制御される企業イントラネットでは許容さ れる場合もあります。PowerBuilder ウィンドウ ActiveX には、セキュ リティ付き(PBRXS100.OCX)とセキュリティなし(PBRX100.OCX) の 2 種類があります。セキュリティ付きの場合は厳しい制約があり、 クライアント ワークステーションへのアクセスが認められていませ ん。 セキュリティ モードで常に動作するイベントがある PowerBuilder では、標準バージョンのウィンドウ ActiveX を使用して いたとしても、アプリケーションの「Open イベント」およびコント ロール用のいくつかの「Constructor イベント」がセキュリティ モード で動作します。アプリケーションのロジックが、書き込み用のファイ ル オープンなど、これらのイベントでの非セキュリティ活動を実行す る能力に依存する場合には、イベント メッセージをアプリケーション やコントロールに対してポストするようにしてください。このイベン ト メッセージは、ウィンドウ ActiveX が標準モードに戻ったときに処 理されます。 要件 PowerBuilder ウィンドウ ActiveX は、ActiveX そのものと PowerBuilder 仮想マシンを使用して、PowerBuilder のあらゆる機能を提供します。 各クライアントが PowerBuilder ウィンドウ ActiveX の貼り付けられた ページを参照するには、以下の支援ソフトウェアがローカル マシンに インストールされている必要があります。 アプリケーション テクニック 737 PowerBuilder ウィンドウ ActiveX について • PowerBuilder 仮想マシン(PBVM100.DLL とサポート ファイル) • PowerBuilder ウィンドウ ActiveX PowerBuilder ウィンドウ ActiveX は、開発者がクライアント マシンの セットアップを管理するイントラネット アプリケーションで特に便 利です。 PowerBuilder ウィンドウ ActiveX のインストールと設定 PowerBuilder のインストール時に標準セットアップを選択した場合、 PowerBuilder ウィンドウ ActiveX コントロールはコンピュータにイン ストールされません。ActiveX コントロールをインストールするには、 PowerBuilder のカスタム インストールを実行し、 [コンポーネントの選 択]ページで[Web プラグイン]チェックボックスをオンにします。 インストールするプラグインとコントロールを選択するには、その ページの[変更]ボタンをクリックします。 この節では、ウィンドウ ActiveX のインストール後に行う必要がある 設定作業について説明します。 インストール先 PowerBuilder ウィンドウ ActiveX ファイル(セキュリティ付きおよび セキュリティなしの両バージョン)は、\Sybase\shared\PowerBuilder に インストールされます。 ActiveX の登録 PowerBuilder ウィンドウ ActiveX で開発を行うには、マシンに ActiveX を登録しなければなりません。PowerBuilder オブジェクト ブラウザを 使用すると、登録状況をチェックできます。オブジェクト ブラウザを 開いて、 [OLE]タブを選択し、OLE カスタム コントロール項目を展開 します。ActiveX が登録されていれば、ツリー ビューの中に PowerBuilder Window Control または PowerBuilder Secure Window Control として表示 されます。クラス情報ノードを展開すると、現在登録されているコン トロールのバージョンを確認できます。 ActiveX をマシンに登録していない場合には、PowerBuilder 内から登録 するか、MS-DOS の regsvr32 コマンドを使用して登録できます。 738 PowerBuilder 第 34 章 ❖ PowerBuilder ウィンドウ ActiveX の使い方 PowerBuilder 内から ActiveX を登録するには 1 PowerBuilder から新規または既存のアプリケーションを開きます。 次に、新規または既存のウィンドウを開きます。 2 メニューから[挿入|コントロール| OLE]を選択します。 オブジェクトの挿入 ダイアログボックスが表示されます。 3 [コントロールの挿入]タブを選択して、 [登録]ボタンをクリッ クします。 参照 ダイアログボックスが表示されます。 4 System ディレクトリ内の OCX の保存場所に移り、PBRX100.OCX か PBRXS100.OCX のどちらかを選択して、 [開く]をクリックし ます。 OCX がうまく登録されないと、エラー メッセージが表示されます。 ❖ MS-DOS の regsvr32 コマンドを使用して ActiveX を登録するには • 引数として OCX のフル パスを指定して、MS-DOS の regsvr32.exe コマンドを実行します。たとえば、次のようにスクリプトを記述 します。 regsvr32.exe C:\Windows\System32\pbrx100.ocx PowerBuilder ウィンドウ ActiveX アプリケーションの開発と配布 PowerBuilder ウィンドウ ActiveX アプリケーションの開発には、主な 4 つの作業があります。 ❖ PowerBuilder ウィンドウ ActiveX アプリケーションの作成および配布を行 うには 1 PowerBuilder アプリケーションを作成、テスト、および構築します。 2 PowerBuilder アプリケーション ウィンドウなどを貼り付ける HTML ページを作成します。 3 アプリケーションで使用する HTML ページと PBD ファイルを適 切なディレクトリにコピーして、Web サーバの設定を行います。 4 すべてのクライアント アプリケーション上で、PowerBuilder ウィ ンドウ ActiveX コントロールと PowerBuilder ランタイム DLL をイ ンストールします。 アプリケーション テクニック 739 PowerBuilder ウィンドウ ActiveX について 結果のコンポーネント セットアップがすべて終了すると、表 34-1 に示すコンポーネントが サーバおよびクライアント コンピュータに設定されます。 表 34-1: PowerBuilder ウィンドウ ActiveX アプリケーション用のサーバお よびクライアントの環境設定 コンピュータ サーバ クライアント コンポーネント ウィンドウまたはレポートの Object 要素を貼り付けた HTML ページと PBD ファイル インストールおよび登録された PowerBuilder ウィンドウ ActiveX(オプション) チャイルド ウィンドウとほかの PowerBuilder オブジェク トを含んだ 1 つまたは複数の PBD ファイル インストールおよび登録された PowerBuilder ウィンドウ ActiveX 第 41 章「アプリケーションとコンポーネントの配布」で 記述されているようにインストールした PowerBuilder ラ インタイム DLL システム パスに記述された PowerBuilder ランタイム DLL のディレクトリ Microsoft DLL: MFC42.DLL MSVCRT.DLL URL.DLL URLMON.DLL データベース接続ソフトウェア、OLE サーバ、ActiveX コ ントロールなど、PowerBuilder ウィンドウ ActiveX アプリ ケーションで必要なその他のアプリケーション 740 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 PowerBuilder アプリケーションの作成 PowerBuilder ウィンドウ ActiveX アプリケーションは、Web ページに 表示されるチャイルド ウィンドウから起動します。ウィンドウ内に は、コントロールを配置してイベント スクリプトを記述できます。ス クリプトからは、ほかのウィンドウを開く、ファイルを読み書きする、 クライアント マシン上のほかのプログラムを実行するなどの操作が 行えます。 アプリケーションのデザイン PowerBuilder ウィンドウ ActiveX 用に設計するアプリケーションは、通 常開発する PowerBuilder アプリケーションとほとんど変わりません が、いくつかの制限事項と留意事項があります。この節では、以下の 項目について説明します。 ウィンドウ管理 • ウィンドウ管理 • スクリプトと変数 • データ アクセス • 外部ファイル 初期チャイルド ウィンドウ 初期ウィンドウは、ブラウザ フレーム内に 存在するチャイルド ウィンドウでなければなりません。 以下の制限があります。 • チャイルド ウィンドウのメニューを配置する • 初期ウィンドウから別のチャイルド ウィンドウを開く 以下のことが可能です。 • チャイルド ウィンドウでタイトル バーを使用する。ただし、チャ イルド ウィンドウでは、コントロール メニュー、最大化ボタン、 または最小化ボタンは使用しない • チャイルド ウィンドウから、ポップアップ ウィンドウまたはレス ポンス ウィンドウを開く。メイン ウィンドウまたは MDI ウィン ドウは開けない アプリケーション テクニック 741 PowerBuilder アプリケーションの作成 ウィンドウを閉じる クライアントが別の Web ページを参照すると、現 行の Web ページのチャイルド ウィンドウは閉じますが、ほかのウィンド ウはアプリケーションから閉じない限り、開いています。これらのウィン ドウは、チャイルド ウィンドウの Close イベントまたは CloseQuery イベ ントで閉じなければなりません。 戻り値を設定して、CloseQuery イベントでチャイルド ウィンドウが閉 じないようにする処理は行わないでください。ブラウザが別のページ に移らないようにしたり、ビューからウィンドウを削除できないよう にしたりすることはできません。ユーザが前のページに戻ったときに、 アプリケーションの別のインスタンスが起動されます。 オブジェクト PBD 内のオブジェクト PowerBuilder ウ ィ ン ド ウ ActiveX ア プ リ ケ ー ションは、PBD の中のオブジェクトすべてにアクセスできます。関数、 構造体、ユーザ オブジェクトにもアクセスできます。 システム オブジェクト PowerBuilder ウ ィ ン ド ウ ActiveX ア プ リ ケ ー ションは、SQLCA Transaction オブジェクトや Message オブジェクトな ど、PowerBuilder がインスタンスを生成するシステム オブジェクトに アクセスできます。 PowerBuilder ウィンドウ ActiveX アプ リケーションは、アプリケーション オブジェクトのプロパティである グローバル変数にアクセスできます。 アプリケーション オブジェクト PowerBuilder では、開発中は現行のアプリケーション オブジェクトが 必要ですが、アプリケーションで使用されるのは Open イベントとグ ローバル変数だけです。アプリケーション オブジェクトのほかのスク リプトは、PowerBuilder でテストを行う際に必要となります。 スクリプトと変数 アプリケーションをセットアップするスクリプト HTML で PBAPPLICATION パラメータを指定すると、PowerBuilder ウィンドウ ActiveX はチャイ ルド ウィンドウを開く前に、アプリケーションの Open イベントを発 生させます。このイベントを利用して、データベース接続の構築およ びグローバル変数の初期化を行うことができます。 HTML で開くウィンドウを指定する アプリケーションの Open イベントでウィンドウを開かないでください。 HTML で PBAPPLICATION パラメータを指定しないと、DBMS への接 続などアプリケーションのセットアップをすべてチャイルド ウィン ドウ内で行わなければなりません。スクリプトが記述可能なイベント で、最初に発生するのはウィンドウのコントロールの Constructor イベ ントで、次に発生するのは、そのウィンドウの Open イベントです。 742 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 Activate イベントは、チャイルド ウィンドウに対しては発生しません。 したがって、そこでアプリケーションのセットアップを行わないでく ださい。 グローバル変数 PowerBuilder ウィンドウ ActiveX アプリケーション は、グローバル変数にアクセスできます。 PowerBuilder は、初期チャイルド ウィンドウの インスタンスを保持する変数を作成しないので、スクリプトで名前を 使用して初期チャイルド ウィンドウを参照することはできません。逆 に、Open 関数のスクリプトを記述してウィンドウのインスタンスを生 成すれば、そのインスタンスを変数に代入して参照できます。 初期ウィンドウの参照 したがって、以下のスクリプトは、ウィンドウ変数 w_mychild が存在し ないため、実行時エラーになります。 // 以下のスクリプトは、実行時エラーとなります。 w_mychild.title = "The initial window" 次のスクリプトはエラーになりません。 // チャイルド ウィンドウ自体で this.title = "The initial window" // または title = "The initial window" // チャイルド ウィンドウのコントロール内で parent.title = "The initial window" データ アクセス アプリケーションから DBMS にアクセスする場合、各クライアントは データ ソースに接続しなければなりません。その接続は、サーバでは なくクライアント マシン上で定義される必要があります。データ ソー スは、ローカルまたはネットワーク DBMS のどちらでもかまいませ ん。 クライアント マシンから DBMS に接続する方法については、『データ ベースとの接続』マニュアルを参照してください。 ウ ィ ン ド ウ の Open イ ベ ン ト が 発 生 す る 前 に、コ ン ト ロ ー ル の Constructor イベントが発生します。つまり、ウィンドウの Open イベン トで DBMS に接続した場合、Constructor イベントはデータを取得でき ません。ウィンドウの Open イベントでコントロールのデータを取得 するか、Constructor イベントまたはウィンドウの Open イベントからイ ベントをポストしてください。 アプリケーション テクニック 743 PowerBuilder アプリケーションの作成 ファイルに指定するパスは、クライアント ワークステーションで有効 でなければなりません。 外部リソースのパス アプリケーションで外部ファイルとして画像を使用する場合、その画 像は PowerBuilder オブジェクトに指定されたパスで取得できなければ なりません。外部ファイルを使用するかわりに、PBD に画像リソース を組み込むことも可能です。 アプリケーションでローカル ファイルを読み書きする場合、それらの ファイルのパスは各クライアント マシンで有効なものでなければな りません。 Windows 環境で、ネットワーク ドライブを参照するパスに、割り当て られたネットワーク ドライブのドライブ名を使用すると、すべてのク ライアントでそれと同じドライブ名を使わなければなりません。また、 サーバ名をパスで指定することもできます。 たとえば、o: が \\marketing\drive に割り当てられている場合、以下の パスはどちらも有効です。ただし、ドライブ名は変更の可能性がある ので、サーバ名を指定している 2 番目のパスの方が有効です。 O:\pbapps\connect.bmp \\marketing\drive\pbapps\connect.bmp ウィンドウ ペインタでの開始ウィンドウの定義 PowerBuilder 内のアプリケーション用の開始ウィンドウを作成します。 ❖ ❖ 744 アプリケーションの開始ウィンドウを作成するには 1 PowerBuilder でウィンドウ オブジェクトを新規作成します。 2 プロパティ ビューのウィンドウの[全般]タブで、ウィンドウの 種類を「child!」に設定します。 3 必要な場合は、ほかのコントロールを追加します。 4 ウィンドウとコントロールのイベント スクリプトを記述します。 既存のアプリケーションを PowerBuilder ウィンドウ ActiveX として実行で きるように変換するには 1 開いているウィンドウの種類を「child!」に変更します。 2 アプリケーションのセットアップ コードを、アプリケーションの Open イベントまたは MDI フレーム イベントからチャイルド ウィ ンドウの Open イベントに移動します。 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 アプリケーションの設計によっては、ほかのウィンドウを開く方法を 設計し直さなければならない場合もあります。 チャイルド ウィンドウにメニューを配置することはできません。チャ イルド ウィンドウはアクティブ ウィンドウとはみなされず、Activate イベントは発生しません。チャイルド ウィンドウには、タイトル バー を設定できます。また、最小化、最大化、およびサイズ変更も可能で す。ただし、PowerBuilder ウィンドウ ActiveX 環境では、チャイルド ウィンドウは、Web ページ上に指定された WIDTH 属性と HEIGHT 属 性によって割り当てられる領域内に表示されます。したがって、以下 のように制限されます。 チャイルド ウィンド ウについて • ウィンドウを最大化すると、WIDTH 属性と HEIGHT 属性で割り当 てられた領域内で最大表示される • ウィンドウを最小化すると、ウィンドウのアイコンとタイトルが ActiveX コントロールに割り当てられた領域の下端に表示される • チャイルド ウィンドウのサイズを変更できる場合は、枠線をドラッ グしてウィンドウを割り当て領域より小さくできる(割り当て領 域より大きくすることはできない) したがって、チャイルド ウィンドウの最小化、最大化、またはサイズ 変更は有効とはいえません。 PowerBuilder でのアプリーションのテスト 作成したアプリケーションをクライアント ブラウザで実行する前に、 PowerBuilder でチャイルド ウィンドウを開くメイン ウィンドウを定義 して、アプリケーションをテストできます。 ❖ PowerBuilder ウィンドウ ActiveX アプリケーションをテストするには 1 PowerBuilder の中で、種類がメイン(デフォルト)のウィンドウ オブ ジェクトを新規作成します。 2 チャイルド ウィンドウを開くスクリプトを Open イベントに記述 します。 Open(w_child) 3 ウィンドウ ペインタで、ウィンドウ サイズを以下のように設定す ると便利です。 • アプリケーション テクニック メイン ウィンドウのサイズは、チャイルド ウィンドウを十分 に表示できるサイズにする 745 PowerBuilder アプリケーションの作成 • チャイルド ウィンドウを左上隅に配置する。この設定は、プ ロパティ シートの[位置]タブで行う 4 [実行]アイコンをクリックして、テスト ウィンドウを実行します。 PowerBuilder でのデバッグ PowerBuilder デバッガを使用するには、ウィンドウだけを実行するの ではなく、アプリケーションを実行する必要があります。メイン ウィ ンドウを開くスクリプトで、アプリケーション オブジェクトを定義し ます。その後、 [実行]または[デバッグ]コマンドを使用してアプリ ケーションをテストします。 PBL 内でのオブジェ クトの編成 Web 環境では、ファイルのサイズが重要です。クライアントはアプリ ケーションを実行する場合、そのアプリケーションをごく最近実行し たばかりでキュッシュされているとき以外は、実行のたびにアプリ ケーションをダウンロードします。 アプリケーションを構築する前に、ライブラリ ペインタを使用して、 アプリケーションで使用する、PBL 内のオブジェクトを整理します。 PBL は、PowerBuilder ウィンドウ ActiveX アプリケーションの PBD の ソースになります。ファイル サイズを最小限に抑えるには、アプリ ケーションで使用するオブジェクトだけを入れ、不要なオブジェクト は削除します。以下のことを行う必要があります。 PowerBuilder リソー ス(PBR)ファイル の使用 • データストアで使用されるデータウィンドウ オブジェクトなど、 動的に作成されるオブジェクト、またはデータウィンドウ コント ロールおよびプロキシ オブジェクトに動的に割り当てられるオブ ジェクトをすべて入れる • 先祖オブジェクトを入れる コントロールによっては、画像に外部ファイルを使用する場合もあり ます。たとえば、ピクチャ リストボックス コントロール、ツリービュー コントロール、ピクチャ コントロール、ピクチャボタン コントロー ル、ポインタ、データウィンドウ オブジェクトのビットマップ オブ ジェクトです。プラグイン アプリケーションで外部ファイルの画像を 使用する場合、クライアントで同じ画像が同じシステム パス上にない ことがあります。 クライアント マシンにピクチャをインストールするかわりに、1 つま たは複数の PowerBuilder リソース(PBR: PowerBuilder Resource)ファ イルを使用して、PBD に画像を組み込むことができます。画像を組み 込むと PBD はサイズは大きくなりますが、独立して機能します。 746 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 作成するのは実行ファイルではなく PBD なので、リソース ファイル にデータウィンドウ オブジェクトを含める必要はありません。作成後 の PBD には、ソース PBL 内のすべての PowerBuilder オブジェクトが 含まれます。 ネットワーク上の画像やそのほかのリソース PBD にファイルを組み込むかわりに、広くアクセスされるネットワー ク ディレクトリにファイルを格納することも可能です。ただし、この 場合、ファイルへのパスは、PowerBuilder オブジェクトでのパスと同 じでなければなりません。つまり、Windows 環境では、各クライアン トは、ネットワーク ドライブが割り当てられた同じドライブ名を使用 しなければなりません。パスにサーバ名を指定することも可能です。 ❖ PBR ファイルを定義するには 1 〔Shift〕+〔F6〕を押してファイル エディタを開くか、ほかのテキス ト エディタを開き、拡張子 .PBR の新しいファイルを作成します。 2 画像やほかのリソースを、各行に一覧表示します。オブジェクト のプロパティ ビューまたはスクリプトに表示される同じ形式でパ スとファイル名を記述します。 ショートカット オブジェクトのプロパティ ビューを表示し、 [編集|コピー] (Windows では〔Ctrl〕+〔C〕)を使用して、ファイル名をクリップ ボードにコピーします。次に、このファイル名をエディタに貼り 付けます。 3 ファイルを保存します。 アプリケーションに複数の PBL が含まれ、各 PBL にそれぞれのリソー スを使用するオブジェクトが含まれている場合は、各 PBL に対して PBR ファイルを作成する必要があります。PBR ファイルは、1 つの PBL 内で使用されるリソースのファイル名をリストします。 PBD の構築 システム ツリー、プロジェクト ペインタ、またはライブラリ ペイン タを使用して、動的ライブラリ(PBD)を構築します。構築する手順 は次のとおりです。 • マシン コードの選択解除 PowerBuilder ウィンドウ ActiveX アプリ ケーションには、マシン コード DLL ではなく PBD が必要です。 アプリケーション テクニック 747 HTML ページの作成 • PBR ファイルを各 PBD に指定する PBR ファイルにリストしたリ ソースを PBL 内のオブジェクトで使用する場合は、PBR 名を [ソー ス ファイル]テキストボックスに入力します。 PBR ファイルの定義および動的ライブラリ(PBD)の構築方法につい ては、『ユーザーズ ガイド』マニュアルで実行ファイルの作成に関す る章を参照してください。 HTML ページの作成 PowerBuilder ウ ィ ン ド ウ ActiveX ア プ リ ケ ー シ ョ ン の PowerBuilder PBD を作成および構築したら、次はそれを表示する HTML ページを作 成する必要があります。 Web ページに PowerBuilder ウィンドウを貼り付けるには、Object 要素 を使います。要素属性には、PowerBuilder ウィンドウ ActiveX のクラ ス ID、ウィンドウに割り当てる領域、PBD 名、PBD 内のチャイルド ウィンドウ名、ライブラリ リスト、および PowerBuilder のバージョン を指定します。 Object 要素のサンプルを以下に示します。 <OBJECT NAME="PBRX1" WIDTH=225 HEIGHT=83 CLASSID="CLSID:AAAA1304-AAAA-1000-8000-080009AC61A9"> <PARAM NAME="_Version" VALUE="65536"></PARAM> <PARAM NAME="_ExtentX" VALUE="5962"></PARAM> <PARAM NAME="_ExtentY" VALUE="2164"></PARAM> <PARAM NAME="_StockProps" VALUE="0"></PARAM> <PARAM NAME="PBWindow" VALUE="w_helloworld"></PARAM> <PARAM NAME="LibList" VALUE="http://www.company.com/rknnt.pbd;"></PARAM> <PARAM NAME="PBApplication" VALUE="hello"></PARAM> <PARAM NAME="PBVersion" VALUE="100"></PARAM> </OBJECT> Object 要素の属性 Object 要素は、HTML で ActiveX コントロールを指定するときに一緒に 指定します。これによって、いくつかの標準属性を定義し、PowerBuilder で追加属性を定義します。 748 PowerBuilder 第 34 章 HTML 属性 PowerBuilder ウィンドウ ActiveX の使い方 HTML 属性では、クラス ID、名前、および Web ページ上で PowerBuilder ウィンドウ ActiveX に割り当てる領域を指定します。 表 34-2: Object 要素の HTML 属性 HTML 属性 NAME CLASSID 値 スクリプトで参照される場合またはフォームの一部と して発行される場合のオブジェクト名 登録される ActiveX コントロールのクラス ID 構文は次のとおりです。 CLSID:class_id CODEBASE WIDTH HEIGHT 登録済みの ActiveX コントロールのクラス ID 値を検 索する場合には、PowerBuilder オブジェクト ブラウザ の[OLE]タブを使用できる。OLE カスタム コント ロール項目を展開し、次に PowerBuilder Window Control 項目または PowerBuilder Secure Window Control 項目を 展開する。クラス ID は、クラス情報分岐の GUID 項目 の値になる クライアント マシンに PowerBuilder ウィンドウ ActiveX がない場合にダウンロードする OCX または CAB ファイルの場所を識別する URL クライアント マシンには PowerBuilder 仮想マシンが必 要。また、システム パス上にそのほか必要な DLL が 存在しなければならない 表示するウィンドウの幅。ピクセル値で指定する 表示するウィンドウの高さ。ピクセル値で指定する WIDTH 属性と HEIGHT 属性には、チャイルド ウィンドウの幅および 高さの最大値を定義します。チャイルド ウィンドウのサイズを変更で きる場合、指定のサイズより小さくできますが、大きくはできません。 Param 要素 PowerBuilder ウィンドウ ActiveX のプロパティを指定するには、Param 要素などを設定します。Param 要素によって、アプリケーションを起 動するウィンドウ オブジェクト、アプリケーション オブジェクト、追 加ライブラリ、および PowerBuilder ウィンドウ ActiveX に渡す追加パ ラメータを識別できます。表 34-3 に、PowerBuilder 固有の Param 要素 を示します。 アプリケーション テクニック 749 HTML ページの作成 表 34-3: PowerBuilder ウィンドウ ActiveX の Param 構成要素 プロパティ PBWINDOW LIBLIST PBAPPLICATION (オプション) PBVERSION DISPLAYRUNTIME MESSAGES (オプション) COMMANDPARM (オプション) 値 PBD 内のチャイルド ウィンドウのクラス名 アプリケーションで必要な PowerBuilder 動的ライブ ラリ(PBD ファイル)のリスト。複数指定する場合 はセミコロンで区切る PowerBuilder アプリケーション オブジェクト PowerBuilder DLL のバージョン(例:100) Boolean 型の値。実行時エラーを表示するかどうかを 指定する ウィンドウに渡す文字列。ウィンドウ内からこの文 字列にアクセスするには、CommandParm 関数を呼び 出す Object 要素の記述 コーディング時のエラーを最小限に抑えるには、PowerSite エディタ、 ActiveX Control Pad、Front Page などの ActiveX 対応の HTML エディタ を使用して Object 要素やパラメータを記述します。 750 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 基本ページ 次のサンプル ページには、PowerBuilder ウィンドウ ActiveX が貼り付 けてあります。 以下は、このページを作成するための HTML コードです。Object 要素 を使用して、PowerBuilder ウィンドウ ActiveX を指定していることに 注目してください。 <HTML> <HEAD> <TITLE>Employee List</TITLE> </HEAD> <BODY> <H1>PowerBuilder window ActiveX</H1> <P> <OBJECT ID="PBRX1" NAME="PBRX1" WIDTH=357 HEIGHT=269 CLASSID="CLSID:AAAA1304-AAAA-1000-8000-080009AC61A9"> <PARAM NAME="_Version" VALUE="65536"> <PARAM NAME="_ExtentX" VALUE="9440"> <PARAM NAME="_ExtentY" VALUE="7112"> アプリケーション テクニック 751 HTML ページの作成 <PARAM NAME="_StockProps" VALUE="0"> <PARAM NAME="PBWindow" VALUE="w_emplist"> <PARAM NAME="LibList" VALUE="http://www.company.com/rknnt.pbd;"> <PARAM NAME="PBApplication" VALUE="rknnt"> <PARAM NAME="PBVersion" VALUE="100"> </OBJECT> </BODY> </HTML> クライアント側のスクリプト HTML ページに JavaScript または VBScript を追加することにより、 PowerBuilder ウィンドウ ActiveX 内に表示されるウィンドウと対話で きます。以下のことを行うことができます。 • ウィンドウ内で発生するイベントに応答するためのイベント ハン ドラを記述する • PowerScript 関数を呼び出して、ポインタ情報の取得、印刷、再描 画の設定、およびタイマー設定を行う • InvokePBFunction 関数を呼び出して、ユーザ定義ウィンドウ関数を 起動する • TriggerPBEvent 関数を呼び出して、ウィンドウでユーザ イベントを 発生させる ActiveX のプロパティ、イベント、および関数の表示 ウィンドウ ActiveX をマシンに登録しているときには、PowerBuilder オ ブジェクト ブラウザの[OLE]タブを使用して、ウィンドウ ActiveX のプロパティ、イベント、および関数のリストを見ることができます。 イベント ハンドラの 記述 HTML ページには、PowerBuilder ウィンドウ ActiveX を制御するため に、JavaScript または VBScript イベント ハンドラを記述できます。 コーディング例の前提条件 次のコード例は、HTML ページに Form という名前の buttonForm が含 まれていることを想定したものです。このフォームには、複数の入力 要素として、passedFlags、passedXPos、および passedYPos が含まれます。 752 PowerBuilder 第 34 章 ❖ PowerBuilder ウィンドウ ActiveX の使い方 PowerBuilder ウィンドウ ActiveX を制御する JavaScript イベント ハンド ラを記述するには 1 PowerBuilder ウィンドウ ActiveX を HTML ページに挿入して、必 要なすべてのプロパティを指定します。 <OBJECT NAME="PBRX1" WIDTH=225 HEIGHT=83 CLASSID="CLSID:AAAA1304-AAAA-1000-8000080009AC61A9"> <PARAM NAME="_Version" VALUE="65536"> <PARAM NAME="_ExtentX" VALUE="5962"> <PARAM NAME="_ExtentY" VALUE="2164"> <PARAM NAME="_StockProps" VALUE="0"> <PARAM NAME="PBWindow" VALUE="w_helloworld"> <PARAM NAME="LibList" VALUE="http://www.company.com/rknnt.pbd;"> <PARAM NAME="PBApplication" VALUE="rknnt"> <PARAM NAME="PBVersion" VALUE="100"> </OBJECT> 2 HTML ページのヘッダに、イベントが発生したときに呼び出され る関数を記述します。 次の関数サンプルは、Clicked イベントの引数の表示のみを実行し ます。 function wasClicked(flags, xpos, ypos) { document.buttonForm.passedFlags.value = flags; document.buttonForm.passedXPos.value = xpos; document.buttonForm.passedYPos.value = ypos; } 3 HTML ページの本体に、イベントが発生したときに関数を呼び出 すイベント ハンドラを記述します。 <SCRIPT LANGUAGE="JavaScript" FOR="PBRX1" Event="Clicked(flags, xpos, ypos)"> <!-wasClicked(flags, xpos, ypos); --> </SCRIPT> コーディング スタイル 次に示すように、イベント ハンドラ内にすべてのコードを記述し て、関数呼び出しを省略することも可能です。 アプリケーション テクニック 753 HTML ページの作成 ❖ PowerBuilder ウィンドウ ActiveX を制御する VBScript イベント ハンドラ を記述するには 1 PowerBuilder ウィンドウ ActiveX を HTML ページに挿入して、必 要なすべてのプロパティを指定します。 <OBJECT NAME="PBRX1" WIDTH=225 HEIGHT=83 CLASSID="CLSID:AAAA1304-AAAA-1000-8000080009AC61A9"> <PARAM NAME="_Version" VALUE="65536"> <PARAM NAME="_ExtentX" VALUE="5962"> <PARAM NAME="_ExtentY" VALUE="2164"> <PARAM NAME="_StockProps" VALUE="0"> <PARAM NAME="PBWindow" VALUE="w_helloworld"> <PARAM NAME="LibList" VALUE="http://www.company.com/rknnt.pbd;"> <PARAM NAME="PBApplication" VALUE="rknnt"> <PARAM NAME="PBVersion" VALUE="100"> </OBJECT> 2 HTML ページの本体に、イベントを処理するイベント ハンドラを 記述します。 次の関数サンプルは、Clicked イベントの引数の表示のみを実行し ます。 <SCRIPT LANGUAGE="VBScript"> <!-Sub PBRX1_Clicked(flags, xpos, ypos) document.buttonForm.passedFlags.value = flags document.buttonForm.passedXPos.value = xpos document.buttonForm.passedYPos.value = ypos end sub --> </SCRIPT> PowerScript 関数の呼 び出し PowerBuilder ウィンドウ ActiveX では、ActiveX コントロールに表示さ れるウィンドウ上で、以下の PowerScript 関数を呼び出すことができま す。 • PointerX ウィンドウの左端からポインタまでの距離を戻す • PointerY ウィンドウの上端からポインタまでの距離を戻す • Print ウィンドウを印刷する • SetRedraw 変更が加えられるたびにウィンドウを自動的に再描 画するかどうかを切り替える • Timer ウィンドウの Timer イベントを、指定した間隔で繰り返し 発生させる 754 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 これらの関数の詳細については、『PowerScript リファレンス』マニュ アルを参照してください。 すべての ActiveX コントロールと同様、 PowerBuilder ウィンドウ ActiveX では、AboutBox 関数を呼び出してコントロールについての情報を参照 できます。 コーディング例の前提条件 次のコード例は、PowerBuilder ウィンドウの Timer イベントによって 呼び出されるスクリプトをすでに作成していることを想定したもので す。 ❖ JavaScript を使用して PowerScript 関数を呼び出すには 1 PowerScript 関数を呼び出す関数を記述します。 次の例では、PowerScript の Timer 関数を呼び出します。 <SCRIPT LANGUAGE="JavaScript"> <!-var cumSeconds = 0; function setPBTimer( f ) { var li_return var li_interval li_interval = parseInt(f.timerInterval.value); li_return = PBRX1.Timer(li_interval); if (li_return != 1) { alert(" タイマーの設定に失敗しました "); } } //--> /SCRIPT 2 その関数を呼び出す関数、アンカー、またはボタンのスクリプト を記述します。 次の例では、フォーム上のボタンを使用して、手順 1 で定義した、 タイマー間隔をリセットする関数を呼び出します。 <FORM NAME="clockForm"> <P>Timer Interval: <INPUT TYPE=Text NAME="timerInterval" Size="5"> <P><INPUT TYPE=BUTTON VALUE="Set Timer" ONCLICK="setPBTimer(this.form)"> </FORM> アプリケーション テクニック 755 HTML ページの作成 ❖ VBScript を使用して PowerScript 関数を呼び出すには 1 PowerScript 関数を呼び出す関数を記述します。次の例では、 PowerScript の Timer 関数を呼び出します。 <SCRIPT LANGUAGE="VBScript"> <!-dim cumSeconds cumSeconds = 0 Sub pbSetTime() dim li_return dim li_interval li_interval = clockForm.timerInterval.value li_return = pbrx1.Timer(li_interval) if li_return 1 THEN msgBox " タイマーの設定に失敗しました " end if end sub //--> </SCRIPT> 2 その関数を呼び出す関数、アンカー、またはボタンのスクリプト を記述します。 次の例では、フォーム上のボタンを使用して、手順 1 で定義した、 タイマー間隔をリセットする関数を呼び出します。 <FORM NAME="clockForm"> <P>Timer Interval: <INPUT TYPE=Text NAME="timerInterval" Size="5"> <HR> <P>Mirror of PB Time: <INPUT TYPE=Text NAME="pbTime" Size="8"> <HR> <P>INPUT TYPE=BUTTON VALUE="Set Timer" onClick="call pbSetTime()"> </FORM> ユーザ定義関数の呼び 出し PowerBuilder ウィンドウ ActiveX には、InvokePBFunction 関数がありま す。この関数は、ユーザ定義ウィンドウ関数を呼び出します。 VBScript と JavaScript の違い ユーザ定義関数に引数がある場合、JavaScript では、SetArgElement 関数 を使用して引数を指定しなければなりません。つまり、InvokePBFunction 関数で明示的に引数を指定することはできません。 756 PowerBuilder 第 34 章 ❖ PowerBuilder ウィンドウ ActiveX の使い方 ユーザ定義関数を呼び出す JavaScript を記述するには 1 必要な場合は、ウィンドウ関数を定義します。 次の例は、PowerBuilder ウィンドウの中で、パラメータとして文字 列を受け取る関数 of_arg をすでに定義していることを想定したも のです。 2 InvokePBFunction 関数を呼び出す JavaScript 関数を記述し、実際に 呼び出すユーザ定義関数を指定します。 次の例では、引数を初期化し、ウィンドウ関数 of_arg を呼び出し ます。 function invokeFunc(f) { var retcd; var rc; var numargs; var theFunc; var theArg; retcd = 0; numargs = 1; theArg = f.textToPB.value; PBRX1.SetArgElement(1, theArg); theFunc = "of_arg"; retcd = PBRX1.InvokePBFunction(theFunc, numargs); rc = parseInt(PBRX1.GetLastReturn()); if (rc != 1) { alert(" エラー。空の文字列 "); } PBRX1.ResetArgElements(); } 3 JavaScript 関数を呼び出す関数、アンカー、またはフォーム ボタン を記述します。たとえば、次のようになります。 <FORM> <P> このテキストを PowerBuilder にコピーします。 <INPUT TYPE=Text NAME="textToPB" SIZE="20"> <P><INPUT TYPE=BUTTON VALUE="Invoke Func" ONCLICK="invokeFunc(this.Form)"> </FORM> JavaScript での引数の定義 JavaScript で記述する場合、関数とイベントの引数は、SetArgElement 関 数を呼び出して定義します。 アプリケーション テクニック 757 HTML ページの作成 ❖ ユーザ定義関数を呼び出す VBScript を記述するには 1 必要な場合は、ウィンドウ関数を定義します。 次の例は、PowerBuilder ウィンドウの中で、パラメータとして文字 列を受け取る関数 of_arg をすでに定義していることを想定したも のです。 2 InvokePBFunction 関数を呼び出す VBScript 関数を記述し、実際に呼 び出すユーザ定義関数を指定します。 次の例では、引数を初期化し、ウィンドウ関数 of_arg を呼び出し ます。 Sub invokeFunction() Dim retcd Dim myForm Dim args(1) Dim rc Dim numargs Dim theFunc Dim rcfromfunc retcd = 0 numargs = 1 rc = 0 theFunc = "of_arg" Set myForm = Document.buttonForm args(0) = buttonForm.textToPB.value retcd = PBRX1.InvokePBFunction(theFunc, numargs, args) rc = PBRX1.GetLastReturn() if rc 1 then msgbox " エラー。空の文字列 " end if PBRX1.ResetArgElements() end sub 3 関数、アンカー、またはクリックして VBScript 関数を呼び出す フォーム ボタンのスクリプトを記述します。たとえば、次のよう になります。 <FORM NAME="buttonForm"> <P><INPUT TYPE=Text NAME="textToPB" SIZE="20"> <P><INPUT TYPE=BUTTON VALUE="Invoke Function" ONCLICK="call invokeFunction()"> /FORM </FORM> 758 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 PowerBuilder ウィンドウ ActiveX には、TriggerPBEvent 関数があります。 この関数は、ウィンドウ上でユーザ イベントを発生させます。 ユーザ イベントの呼 び出し ❖ ユーザ イベントを発生させる JavaScript を記述するには 1 必要な場合は、ウィンドウのユーザ イベントを定義します。 次の例は、PowerBuilder ウィンドウの中で、引数として文字列を受 け取るユーザ イベント ue_arg をすでに定義していることを想定し たものです。 2 ユーザ イベントを呼び出す関数を記述します。次の例では、引数 を初期化し、ユーザ イベント ue_arg を呼び出します。 function triggerEvent(f) { var retcd; var rc; var numargs; var theEvent; var theArg; retcd = 0; numargs = 1; theArg = f.textToPB.value; PBRX1.SetArgElement(1, theArg); theEvent = "ue_arg"; retcd = PBRX1.TriggerPBEvent(theEvent, numargs); rc = parseInt(PBRX1.GetLastReturn()); if (rc != 1) { alert(" エラー。空の文字列 "); } PBRX1.ResetArgElements(); } 3 TriggerPBEvent 関数を呼び出す関数、アンカー、またはフォーム ボ タンのスクリプトを記述します。たとえば、次のようになります。 <FORM> <P><INPUT TYPE=Text NAME="textToPB" SIZE="20"> <P><INPUT TYPE=BUTTON VALUE="Trigger Event" ONCLICK="triggerEvent(this.Form)"> </FORM> ❖ ユーザ イベントを発生させる VBScript を記述するには 1 必要な場合は、ウィンドウのユーザ イベントを定義します。 次の例は、PowerBuilder ウィンドウの中で、引数として文字列を受 け取るユーザ イベント ue_arg をすでに定義していることを想定し たものです。 アプリケーション テクニック 759 HTML ページの作成 2 ユーザ イベントを呼び出す関数を記述します。次の例では、引数 を初期化し、ユーザ イベント ue_arg を呼び出します。 Sub TrigEvent( ) Dim retcd Dim myForm Dim args(1) Dim rc Dim numargs Dim theEvent retcd = 0 numargs = 1 rc = 0 theEvent = "ue_arg" Set myForm = Document.buttonForm args(0) = buttonForm.textToPB.value retcd = PBRX1.TriggerPBEvent(theEvent, numargs, args) rc = PBRX1.GetLastReturn() if rc 1 then msgbox " エラー。空の文字列 " end if PBRX1.ResetArgElements() end sub 3 関数、アンカー、またはクリックして VBScript 関数を呼び出す フォーム ボタンのスクリプトを記述します。たとえば、次のよう になります。 <FORM NAME="buttonForm"> <P><INPUT TYPE=Text NAME="textToPB" SIZE="20"> <P><INPUT TYPE=BUTTON VALUE="Trigger Event" ONCLICK="call TrigEvent()"> </FORM> 760 PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 PowerBuilder ウィンドウ ActiveX のイベント PowerBuilder ウィンドウ ActiveX は、チャイルド ウィンドウ内で発生 するいくつかのイベントに応答できます。これらのイベントは、アウ トバウンド イベントです。まず、PowerBuilder ウィンドウ内で発生し、 次に PowerBuilder ウィンドウ ActiveX 内で発生します。これらのイベ ントに応答する JavaScript または VB Script コードを追加できます。表 34-4 にこれらのイベントを示します。 表 34-4: PowerBuilder ウィンドウ ActiveX のイベント イベント Activate Clicked 発生する状況 ウィンドウがアクティブになる直前に発生する 有効化された表示可能オブジェクトが配置されていない、 ウィンドウ内の領域をユーザがクリックしたときに発生す る Close ウィンドウが閉じられるときに発生する Deactivate ウィンドウが非アクティブになったときに発生する DoubleClicked 有効化された表示可能オブジェクトが配置されていない、 ウィンドウ内の領域をユーザがダブルクリックしたときに 発生する Hide ウィンドウが非表示になる直前に発生する Key ユーザがキーを押したときに挿入ポイントがライン エ ディットになければ発生する MouseDown 有効化された表示可能オブジェクトが配置されていない、 ウィンドウ内の領域でユーザがマウスの左ボタンを押した ときに発生する PBMouseMove ウィンドウ内でポインタが移動したときに発生する PBMouseUp 有効化された表示可能オブジェクトが配置されていない、 ウィンドウ内の領域でユーザがマウスの左ボタンを放した ときに発生する RButtonDown 有効化された表示可能オブジェクトが配置されていない、 ウィンドウ内の領域でユーザがマウスの右ボタンを押した ときに発生する Resize ユーザまたはスクリプトによって、ウィンドウが開かれた とき、またはウィンドウのサイズが変更されたときに発生 する Show スクリプトがウィンドウに対して Show 関数を実行したと き、ウィンドウが表示される直前に発生する SystemKey 挿入ポイントがライン エディットにないときに、ユーザが 〔Alt〕または〔Alt〕+ 別のキーを押すと発生する Timer Timer 関数が呼び出されてから指定の秒数が経過したとき に発生する アプリケーション テクニック 761 サーバの設定 サーバの設定 サーバのセットアップでは、サーバ上にファイルを配置します。 サーバの適切なディレクトリに、PowerBuilder ライブラリ、PowerBuilder ウィンドウ ActiveX モジュール、および HTML ファイルをコピーする 必要があります。 表 34-5: サーバ上の PBD ファイルと HTML ファイルの場所 ファイル HTML ページ Param 要素の LibList 属 性で指定した PBD ファ イル PowerBuilder ウィンド ウ ActiveX モジュール 762 場所 HTML ドキュメント ディレクトリ。HTML ペー ジを、ページにリンクする URL で指定される ディレクトリにコピーする Web サーバ アプリケーションのアプリケーショ ン パスまたはシステム パスに指定されたディレ クトリ HTML ドキュメントのディレクトリ、または Object 要素の CODEBASE 属性に指定されたその 他のディレクトリ PowerBuilder 第 34 章 PowerBuilder ウィンドウ ActiveX の使い方 ユーザのワークステーションの設定 ユーザが PowerBuilder ウィンドウ ActiveX などの貼り付けられた Web ページを表示するには、クライアント ワークステーションへの支援ソ フトウェアのインストールと、Web サーバへの接続が必要です。 表 34-6: PowerBuilder ウィンドウ ActiveX を表示するためのクライアント 要件 コンポーネント インターネット接続か イントラネット接続 ActiveX をサポートす る Web ブラウザ PowerBuilder ランタイ ム DLL PowerBuilder ウィンド ウ ActiveX モジュール その他のファイル 詳細 企業内で、またはインターネット サービス プロバ イダから利用できる ブラウザ ベンダから入手できる。Microsoft Internet Explorer など ランタイム ファイルをインストールする。849 ペー ジの「PowerBuilder ランタイム ファイル」を参照 PowerBuilder ランタイム DLL は、アプリケーショ ン ディレクトリか、システム パス上のディレクト リに置く。PowerBuilder ウィンドウ ActiveX は、 PowerBuilder 仮想マシンおよびその他必要なラン タイム DLL にアクセスできなければならない。こ のため、PowerBuilder ランタイム DLL 用のディレ クトリをシステム パスに追加するか、ランタイム DLL を Windows\System32 ディレクトリに配置す る PBRX100.OCX ファイルをクライアント ワークス テーションにコピーして登録する。または、Object 要素に CODEBASE 属性を追加する。これにより、 ページがロードされたときに、ブラウザはこの ファイルをダウンロードし、登録する 画像ソースを PBD に入れていない場合、ファイル がオブジェクトのプロパティで指定されるパス上 になければ、そのパスにコピーする PowerBuilder ウィンドウ ActiveX アプリケーション でデータベースに接続する場合は、DBMS に合わ せてクライアント ソフトウェアをセットアップす る。クライアント マシンから DBMS に接続する方 法については、『データベースとの接続』マニュア ルを参照 アプリケーション テクニック 763 ユーザのワークステーションの設定 Web ページと PowerBuilder ウィンドウ ActiveX アプリケーションの 表示 必要なソフトウェアをインストールすると、ユーザは PowerBuilder ウィンドウ ActiveX アプリケーションが貼り付けられた Web ページを 表示できます。 ユーザが Web ページの URL を指定すると、以下のことが行われます。 764 • PowerBuilder ウィンドウに割り当てられた領域に、ページ上のテキ ストが表示される • クライアントがサーバから PBD をダウンロードする • ブラウザが Web ページ内にチャイルド ウィンドウを表示する • ウィンドウの中のコントロールと対話し、イベントのスクリプト を実行する • ユーザが別のページに移ると、ウィンドウが閉じ、PowerBuilder DLL や共有ライブラリがメモリからアンロードされる PowerBuilder 第 8 部 全般的なテクニック 第 8 部では、日本語仕様、印刷処理、アクセシビリティ 要件、および Windows のレジストリを扱うテクニックに ついて説明します。InfoMaker で使用する様式とアクショ ンの作成についても説明します。 第 3 5 章 アプリケーションの国際化 この章について この章では、複数の言語向けのアプリケーションを開発および配 布するときに発生する問題についていくつか説明します。 内容 項目 国際化アプリケーションの開発 Unicode の使い方 ユーザ インタフェースの国際化 ページ 767 768 774 国際化アプリケーションの開発 複 数 の 言 語 で 配 布 す る ア プ リ ケ ー シ ョ ン を 開 発 す る と き は、 PowerBuilder に組み込まれている Unicode サポートを利用できま す。また、開発プロセスの 2 つのフェーズにも注目する必要があ ります。 アプリケーション テクニック • 1 つ目は国際化のフェーズです。ここでは、アプリケーション のコードの作成を始める前にデザインの問題を考慮します。 • 2 つ目はローカライゼーションのフェーズです。このフェーズ は、国際化アプリケーションの開発フェーズが完了したとき から始まり、アプリケーションの翻訳と配布の処理を行いま す。 767 Unicode の使い方 Unicode の使い方 Unicode は、世界のほとんどの言語のテキストを表示できる文字エン コーディング スキームです。PowerBuilder は、Unicode 文字をサポー トしています。したがって、アプリケーションの同一ページに複数の 言語の文字を表示したり、さまざまな国に向けた配布に適した柔軟な ユーザ インタフェースを作成したり、複数の言語のデータを処理する ことができます。 Unicode について Unicode が開発されるまでは、多数の異なるエンコーディング システ ムがあり、その多くが互いに競合していました。たとえば、エンコー ディング システムが異なるために、同じ数字が別の文字で表示される ことがありました。Unicode は、サポートされているすべての記述言語 で、それぞれの文字に対して固有の番号を提供します。複数のスクリ プトで記述できる言語の場合、Unicode は、サポートされているそれぞ れのスクリプトの個々の文字に固有の番号を提供します。 サポートされている言語およびスクリプトについての詳細は、Unicode Web のサイト http://www.unicode.org/onlinedat/languages-scripts.html を参照 してください。 エンコーディング形式 768 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 第 35 章 エンコーディング ス キーム アプリケーションの国際化 エンコーディング スキームは、エンコーディング形式内のバイトをシ リアル化する方法を指定します。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 データに変換されなければ なりません。 アプリケーション テクニック 769 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 770 PowerBuilder 第 35 章 カタログ データ型の エンコーディング アプリケーションの国際化 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 です。 アプリケーション テクニック 771 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 セッション ビュー、およびデバッグ ウィンドウで、複数の言語を表示 することはできません。 772 PowerBuilder 第 35 章 アプリケーションの国際化 スクリプト ビュー、テキスト エディタ、ソース エディタ、データベー ス ペインタの 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 に変換 されます。 JSP ターゲットでは、オーサリング ツール (HTML エディタ)が Unicode を使用できるので、1 つのページに複数の言語のテキストを挿入でき ます。エディタに入力したテキストは UTF-8 エンコーディングで保存 されます。ただし、ほかのエンコーディング スキームの JSP ファイル をエディタにインポートすることもできます。これらのエンコーディ ングのテキストは、自動的に UTF-8 に変換されます。 アプリケーション テクニック 773 ユーザ インタフェースの国際化 XML 文字列のエン コーディング XML パーサは、windows-1253 のように 8 ビット文字コードを使用する 文字列を解析することができません。たとえば、次の宣言を持つ文字 列は解析できません。 string ls_xml ls_xml += '<?xml version="1.0" encoding="windows1253"?>' UTF16-LE などの Unicode エンコーディング値を使用してください。 ユーザ インタフェースの国際化 国際的に配布するアプリケーションを作成するときに、ユーザ インタ フェースのデザインで考慮すべき点は 2 つあります。 物理的デザイン • ユーザ インタフェースの物理的なデザイン • アプリケーションの対象者の文化的基準 ユーザ インタフェースの物理的なデザインには、次のものを含める必 要があります。 • メニュー項目のテキスト、リスト、ラベルが翻訳されたときに文 字列が長くなっても収めることができる柔軟なウィンドウおよび オブジェクト たとえば、元が英語のウィンドウからウィンドウを継承し、ロー カライズする配布用に言語を変更できます。通常は、メニュー項 目、リスト、またはラベルのサイズを英語の文字列の長さの 1.3 倍 にしておけば、ほとんどの言語のテキストを収めることができま す。 • 文化的意識 RightToLeft バージョンの Windows で簡単に使用できるウィンドウ ユーザ インタフェースの文化的なデザインには、対象者にとって許容 できることとできないこと、または意味があることを認識することが 要求されます。 たとえば、手のひらを表示する手のアイコンは、ある文化では「停止」 を意味しますが、別の文化では、 「拒否」を示します。同様に、黄色は ある文化では「注意」を意味しますが、別の文化では「幸福と繁栄」 を意味します。 774 PowerBuilder 第 3 6 章 利用しやすいアプリケーションの作成 この章について この章では、障害のあるユーザにも利用しやすいアプリケーショ ンを作成するためのガイドラインと要件についての情報を提供し ます。また、利用しやすいアプリケーションの作成を支援するた めに PowerBuilder が提供する機能について説明し、追加情報の入 手先も示します。 内容 項目 アクセシビリティの課題についての理解 ソフトウェアおよび Web アプリケーションのアクセシビリ ティ要件 PowerBuilder を使用した利用しやすいソフトウェア アプリ ケーションの作成 VPAT について 製品のアクセシビリティのテスト ページ 775 778 780 784 784 アクセシビリティの課題についての理解 障害のある人にも利用しやすいソフトウェア アプリケーションお よび Web ページを設計および開発する場合は、一般に 4 種類の障 害について考慮する必要があります。 アプリケーション テクニック • 視覚障害 • 聴覚障害 • 運動障害 • 認知障害または学習障害 775 アクセシビリティの課題についての理解 視覚障害 目の不自由なアプリケーション ユーザには、視覚に問題のないユーザ が利用できるすべてのグラフィック イメージおよびビデオに対応す る同等物をテキストの形式で用意する必要があります。このテキスト は、グラフィック形式で提供されている情報と概念の上で同等の内容 を伝える必要があります。それにより、ユーザは、画面読み上げソフ トウェアや点字リーダなどの補助技術を使用して情報を完全に利用で きます。すべてのユーザ インタフェース(UI)要素には、テキストま たはメニュー形式の同等物が必要です。また、目の不自由なユーザは、 視覚に問題のないユーザがマウスで行うような入力をキーボードから 行う必要があります。 色覚に障害のあるユーザに対応するには、色を情報伝達の唯一の手段 として使用するのを避ける必要があります。色で伝える情報を補完す る手段として、グラフやその他のイメージで色以外に塗りつぶしパ ターンを使用するのも 1 つの方法です。色だけで警告またはその他の 内容を提示する代わりに、音声通知を使用することもできます。 ハイ コントラストのサポートを有効にすると、色覚障害のあるユーザ や弱視ユーザが、デフォルトのシステム カラーおよびフォントを調整 して、ウィンドウまたは Web ページの領域を区別しやすくすることが できます。弱視のユーザは、ハードウェアまたはソフトウェアの拡大 鏡を使用して、ディスプレイ上のピクセルを拡大します。また、代替 テキストを使用して、イメージに表示される情報の一部を取得します。 聴覚障害 耳の聞こえないユーザや難聴のユーザには、音声情報を視覚的に表現 する必要があります。たとえば、音声による警告の代わりに、視覚的 な通知をアプリケーションで提供しなければならない場合がありま す。テキストを点滅させるのも 1 つの方法ですが、点滅速度は一定の 範囲内にする必要があります。これは、発作性疾患のあるユーザに問 題が発生するのを避けるためです。オーディオ トラックは、文字化す る必要があります。また、場合によってはビデオにクローズド キャプ ションが必要です。 聴覚障害を支援する技術には、音声情報をテキストまたは手話に変換 できる音声認識製品があります。同様に重要なのは、コンピュータと 電話を接続し、入力された ASCII テキスト出力をボー(Baudot)コー ドに変換する TTY/TDD モデムです。ボー コードは、聴覚障害者が電 話での会話に通常使用しているものです。 776 PowerBuilder 第 36 章 利用しやすいアプリケーションの作成 運動障害 運動機能が限られているユーザにとって、ハードウェアおよびメディ アを扱うのはしばしば困難ですが、一般に、最大の課題となるのは入 力です。運動障害のあるユーザは、その障害に応じて、場合によって は音声認識を使用したり、電子スイッチ、トラック ボール、または ジョイ スティックによってオンスクリーン キーボードを使用したり する必要があります。また、入力のペースが遅い可能性があるので、 タイマーおよび応答時間を調整できるようにしなければなりません。 インテリジェント機能が組み込まれているシステムでは、要求される 入力の数を減らすためのキューを提供できます。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 を参照してください。 アプリケーション テクニック 777 ソフトウェアおよび 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 のガイドラインを満たすように努力することを推奨しています。 778 PowerBuilder 第 36 章 利用しやすいアプリケーションの作成 フランスの法令 フランス政府も、障害のある人向けの 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/508standards.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/criteres_accessiweb/92_access iweb_lineaire/ を参照してください。 アプリケーション テクニック 779 PowerBuilder を使用した利用しやすいソフトウェア アプリケーションの作成 PowerBuilder を使用した利用しやすいソフトウェア アプ リケーションの作成 MSAA 標準 PowerBuilder は、Windows および Web アプリケーションにアクセシビ リティ機能を組み込むために必要なインフラストラクチャおよびプロ パティを提供します。この機能を使用すると、アプリケーションを Microsoft Active Accessibility(MSAA)バージョン 2 に一般的に準拠さ せることができます。MSAA は、Windows 標準で、アクセシビリティ 支援ツールがユーザ インタフェース要素についての情報を取得する 方法、およびプログラムがアクセシビリティ支援ツールに情報を公開 する方法を定義します。 PowerBuilder の標準コントロールは、次の表に示すように、必要な Microsoft Active Accessibility のプロパティをすべてサポートしています。 表 36-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 をサポートする (たとえば、チェック ボックスはオンのときの値 を持ちます) 780 PowerBuilder 第 36 章 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)の リストです。 表 36-2: PowerBuilder ビジュアル コントロールとそのデフォルト ロール AccessibleRole カタログ データ PowerBuilder ビジュアル コントロール (列挙体)値 animationrole! アニメーション checkbuttonrole! チェックボックス pushbuttonrole! コマンドボタン clientrole! データウィンドウ comboboxrole! ドロップダウン リストボックス ドロップダウン ピクチャ リストボックス comboboxrole! textrole! エディットマスク diagramrole! グラフ groupingrole! グループボックス progressbarrole! 水平プログレスバー、垂直プログレス バー アプリケーション テクニック 781 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 カタロ グ データ型変数の値を取ります。 データウィンドウでのアクセシビリティ サポートには、いくつか制限 があります。 • 782 ナビゲーション関数 accNavigate では、Spatial Nabigation(画面上の 場所を起点にしたキーボードによるナビゲーション)はサポート されていません。キーボード ナビゲーションが論理タブのシーケ ンスに従う論理的なナビゲーションは、詳細区域のカラムについ てのみサポートされています。タブ値が 0 に設定されているカラ ムはユーザによる更新ができないので、キーボードからはアクセ スできません。 PowerBuilder 第 36 章 利用しやすいアプリケーションの作成 • ラベル、段組み、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") 配布 アクセシブル アプリケーションを配布する場合には、pbacc100.dll ファイルを必ず配布する必要があります。 詳細情報 詳細については、Microsoft の Accessibility Web のサイト http://www.microsoft.com/japan/enable を参照してください。また、 WebAim Web のサイト http://www.webaim.org も参照してください。 アプリケーション テクニック 783 VPAT について VPAT について 自主的製品アクセシビリティ テンプレート(VPAT)は、米国連邦政府 の調達用に提供される製品がアクセシビリティ要件に準拠しているか を連邦政府職員が事前に評価するのに役立つように設計されたリスト です。VPAT は、さまざまなタイプの製品についてアクセシビリティ要 件に準拠するための基準を示します。また、自社製品が VPAT の基準 を満たしているかについて、企業がチェックしたりコメントを追加し たりできるカラムがあります。 VPAT は、ソフトウェア アプリケーションとオペレーティング システ ム、Web ベースのインターネット情報とアプリケーション、およびそ の他のタイプの製品で利用できます。VPAT に記入する必要がない場合 でも、自社製品のタイプについてのテンプレートを参照することで、 ソフトウェアおよび Web アプリケーションに対する 508 条の要件を明 確に理解することができます。 詳細情報 さまざまな VPAT を確認するには、Information Technology Industry Council Web のサイト http://www.itic.org/policy/vpat.html を参照してください。 IT 製品の全 VPAT のサンプルを確認するには、Sybase accessibility のサ イト http://www.sybase.com/accessibility を参照してください。 製品のアクセシビリティのテスト MSAA 2.0 ソフトウェア開発キット(SDK)には、アプリケーション が MSAA に準拠していることを確認するためのツールが複数含まれ ています。たとえば、AccExplorer、Accessible Event Watcher、Object Inspector などがあります。これらのツールは、Microsoft Web のサイト http://msdn.microsoft.com/library/default.asp?url=/downloads/list/accessibility.as p から利用できます。 障害のあるユーザにとってのアプリケーションの動作を直接テストす るには、さまざまな方法を使用できます。たとえば、テキストのみの ブラウザを使用したり、キーボードだけを使って入力したり、JAWS、 Window-Eyes、Hal、または Supernova などの画面読み上げソフトウェ アを使ってアプリケーションを使用したりすることができます。 Web サイトが 508 条および WCAG 1.0 に準拠しているかどうかをテス トするために使用できる商用アプリケーションもいくつかあります。 784 PowerBuilder 第 36 章 詳細情報 利用しやすいアプリケーションの作成 WCAG 1.0 の準拠についてテストするためのチェックリストについて は、W3C Web のサイト http://www.w3.org/TR/1999/WAI-WEBCONTENT19990505/full-checklist を参照してください。W3C Web サイトにも、ア クセシビリティをテストするためのリストと評価ツールがあります。 アプリケーション テクニック 785 製品のアクセシビリティのテスト 786 PowerBuilder 第 3 7 章 印刷 この章について この章では、PowerScript の組み込み関数を使用して、リストやレ ポートを印刷する方法について説明します。 内容 項目 印刷関数 印刷の基礎 ページ 787 789 789 790 791 792 ジョブの印刷 タブの使い方 印刷ジョブの停止 高度な印刷技法 印刷関数 PowerScript 言語では、帳票やレポートの作成のための組み込み関数 を用意しています。わずか 3 つの関数(PrintOpen、Print、PrintClose) を用いるだけで、使用プリンタのデフォルトのフォントで表(タ ブラ)形式のレポートを印刷できます。ほかの関数を用いると、複 数のテキストフォント、文字サイズ、スタイルが使用できるだけ でなく、罫線やピクチャを用いた帳票やレポートが作成できます。 表 37-1 は印刷用の関数のリストです。 表 37-1: PowerScript 印刷関数 関数 Print PrintBitMap PrintCancel PrintClose PrintDatawindow アプリケーション テクニック 説明 Print 関数には 5 種類の構文がある。タブを 1 個指 定できる構文が 3 つ、タブを 2 個指定できる構文が 1 つある 指定されたビットマップを印刷する 指定された印刷ジョブを取り消す 印刷ジョブの現行ページをプリンタ(またはスプー ラ)に送り、印刷ジョブを終了する 指定されたデータウィンドウを印刷ジョブとして 印刷する 787 印刷関数 関数 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 リファレンス』マニュアル を参照してください。 788 PowerBuilder 第 37 章 印刷 印刷の基礎 印刷処理は、すべて印刷領域に基づいて定義されます。印刷領域とは、 物理的な印刷ページから余白を除いた領域のことです。たとえば、ペー ジのサイズが 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 関数の間には、タブ付きま たはタブなしで文字列を印刷する単純な印刷関数、あるいはレポート に罫線、オブジェクト、ピクチャーなどを加える複雑な印刷関数が呼 び出されます。 アプリケーション テクニック 789 タブの使い方 タイトルの印刷方法 各ページの上部にタイトルを印刷するときには、印刷される行数をカ ウントし、一定の行数(たとえば 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) 790 PowerBuilder 第 37 章 印刷 以下のステートメントは、印刷領域の左端から 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 関数は、現行ページをプリンタまたはプリント スプーラに送 PrintCancel 関数の使 い方 PrintCancel 関数は、印刷ジョブを終了し、印刷されずに残った出力を すべて破棄します。PrintCancel 関数は、処理が終了する前にエンド ユー ザに対して印刷を取り消す手段を提供します。通常この関数は、グロー バル変数を定義して、印刷ジョブの処理中にその変数の値を定期的に チェックすることによって呼び出されます。 り、印刷ジョブを終了して、印刷を開始したウィンドウをアクティブ 状態にします。PrintClose 関数呼び出しを実行した後では、そのジョブ 番号を参照する関数呼び出しがすべて無効となります。 StopPrint が Boolean 型のグローバル変数であるものとします。以下の ステートメントは、StopPrint グローバル変数をチェックし、StopPrint 変数の値が TRUE になったらジョブを取り消します。 アプリケーション テクニック 791 高度な印刷技法 IntJobNbr JobNbr = PrintOpen() // グローバル変数の初期値を設定します。 StopPrint = FALSE // 印刷処理を行います。 Do While ... . . . // グローバル変数をテストします。 // 値が TRUE の場合、印刷ジョブをキャンセルします。 // スクリプトの実行を止めます。 If StopPrint then PrintCancel(JobNbr) Return End If Loop 高度な印刷技法 PowerBuilder で複雑なレポートを作成するときには、これまでに紹介 した以外の関数も必要となりますが、比較的簡単に作成できます。 PowerScript 関数を使用して、ジョブに対するフォントの定義、フォン ト間隔と行間隔の指定、ページ上へのオブジェクトの配置、テキスト やオブジェクトを配置する正確な位置の指定を行うことができます。 フォントの定義と設定 これまでの例では、プリンタのデフォルト フォントを使用しました が、各印刷ジョブにつき最大 8 つのフォントを定義することや、その ジョブの実行中にフォントを切り替えることが可能です。 さらに、印刷ジョブの実行中は、必要に応じて何度でもフォントの再 定義ができます。このため、使用プリンタで使用可能なフォントをす べて、印刷ジョブにおいて使用できます。ただし、フォントを再定義 するとパフォーマンスが多少低下するので、PrintOpen 関数を呼び出し た時点でフォントを定義し、印刷ジョブの実行中にフォントを変更し ないようにしてください。 フォントを定義するには、Integer 型変数に PrintDefineFont 関数が返した 値を設定し、次に PrintSetFont 関数を使用してフォントを変更します。 792 PowerBuilder 第 37 章 印刷 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) 描画オブジェクトの印 刷 印刷ジョブでは、以下の描画オブジェクトが使用できます。 • 直線 • 長方形 • 丸長方形 • 楕円 • ピクチャ アプリケーション テクニック 793 高度な印刷技法 印刷ジョブで描画オブジェクトを配置するときには、まず最初に描画 オブジェクトを配置し、次にテキストを加えます。たとえば、印刷領 域内に長方形を描き、次にその長方形の内部に罫線とテキストを加え ます。オブジェクトは輪郭線だけのように見えますが、実際には塗り つぶされています(空白が入っています)。したがって、オブジェクト をテキストや別のオブジェクトの上に重ねて配置すると、そのテキス トや別のオブジェクトは覆い隠されてしまいます。 注意 :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) 794 PowerBuilder 第 3 8 章 初期設定ファイルと Windows レジ ストリの管理 この章について この章では、PowerBuilder アプリケーションの環境設定とデフォ ルト設定を管理する方法について解説します。 内容 項目 環境設定とデフォルト設定について 初期設定ファイルでの情報の管理 Windows レジストリでの情報の管理 ページ 795 796 797 環境設定とデフォルト設定について PowerBuilder アプリケーションは、セッションをまたがってエン ド ユーザの環境設定とデフォルト設定を保存できます。たとえば、 アプリケーションはそのアプリケーションの表示と動作の形態を 管理する設定や、データベースに接続するためにデフォルトのパ ラメータを格納する設定を保持しています。PowerBuilder アプリ ケーションは、初期設定ファイルや Windows レジストリでこのよ うな情報を管理できます。 データベース接続パラメー タ トランザクション オブジェクトの値は、通常の場合、外部ファイ ルから値を取得して設定する必要があります。たとえば、アプリ ケーションを開発しているときは PowerBuilder 初期設定ファイル から、またアプリケーションを配布するときはアプリケーション 固有の初期設定ファイルから値を設定できます。 初期設定ファイル内のデータベース接続パラメータについての詳 細は、182 ページの「外部ファイルからの値の読み込み」を参照し てください。 Windows レジストリにデータベース接続パラメータを登録したり 取得する方法については、797 ページの「Windows レジストリで の情報の管理」を参照してください。 アプリケーション テクニック 795 初期設定ファイルでの情報の管理 ツールバーの設定 PowerBuilder では、ツールバーの設定に関する情報の取得や修正を行 うための関数が用意されています。これらの関数を使用して、現行の ツールバーの設定情報の保存と復元ができます。 詳細については、80 ページの「ツールバー設定の保存と復元」を参照 してください。 保存可能なほかの設定 データベース接続パラメータとツールバーの設定情報のほかに、アプ リケーション特有の設定情報を保存できます。たとえば、色、フォン トの表示設定やエンド ユーザの環境設定情報などを保持できます。 初期設定ファイルでの情報の管理 初期設定ファイルにア クセスする関数 PowerBuilder には、初期設定ファイルを使用してアプリケーション設 定を管理するための関数が用意されています。 表 38-1: PowerBuilder 初期設定ファイル関数 関数 ProfileInt ProfileString SetProfileString 説明 プロファイル ファイルの設定値を Integer 型で取得する プロファイル ファイルの設定値を String 型で取得する プロファイル ファイルに値を書き込む これらの関数についての詳細は、 『PowerScript リファレンス』マニュ アルを参照してください。 レジストリでの ProfileString 関数の使い方については、796 ページの「初 期設定ファイルにアクセスする関数」を参照してください。 APP.INI の書式 以下の例では、APP.INI という名前のプロファイルで、アプリケーショ ンの情報を管理しています。このファイルは、アプリケーションの表 示形態を管理するための環境設定の情報が記述されています。ファイ ルには、4 つのカラー設定が記述された [Preferences] セクションがあり ます。 [Preferences] WindowColor=Silver BorderColor=Red BackColor=Black TextColor=White 796 PowerBuilder 第 38 章 以下のスクリプトでは、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 レジストリを使用してアプリケーション 設定を管理するための関数が用意されています。 表 38-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 アプリケーション テクニック 797 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) 798 & & & & & & & & & PowerBuilder 第 3 9 章 InfoMaker の様式とアクションの作成 この章について この章では、PowerBuilder で様式を作成して InfoMaker ユーザに提 供する方法について説明します。 内容 項目 フォーム様式について フォーム様式でのデータウィンドウ コントロールの命名 フォーム様式の作成および使用 既存の様式の修正 最初からの様式の作成 様式の完成 様式の使い方 ページ 799 803 804 805 807 808 812 フォーム様式について InfoMaker には、ユーザが洗練されたフォームを作成できるよう に、組み込みフォーム様式があります。PowerBuilder を使用する と、開発者は独自のフォーム様式を作成して、InfoMaker ユーザに 提供できます。このようなカスタム フォーム様式を使うと、フォー ム内で特定の標準を使うように指定して、InfoMaker ユーザに対し て機能を追加できます。たとえば、以下のように指定できます。 • 各フォーム内の開発者の組織のロゴ表示 適当な位置にロゴを配置したカスタム フォーム様式を作成で きる • 組み込みフォーム様式で提供されるツールバーの再構成 組み込みフォーム様式を修正してカスタム フォーム様式とし て保存できる アプリケーション テクニック • フォーム内でのドラッグ アンド ドロップ • フォーム内でのピクチャボタン、編集コントロール、および そのほかのコントロールの配置 799 フォーム様式について PowerBuilder ウィンドウ内でできることは、ほとんどすべてカスタム フォーム様式内でもできます。 フォーム様式 フォーム様式が構成さ れる方法 InfoMaker のユーザはデータを管理するのにフォームを使用します。 フォーム内でデータを表示、追加、削除、および更新できます。各 フォームはフォーム様式を基礎としており、以下の項目を指定します。 • たとえば、フリーフォーム、グリッド、またはマスタ / 詳細提示様 式などデータを提示する方法 • フォームを実行するときに使用可能なメニューとツールバー • そのフォーム内でユーザがコマンドボタンにアタッチできるアク ション PowerBuilder でフォーム様式を作成します。フォーム様式は次の 2 つ のもので構成されています。 • ウィンドウ • メニュー 図 39-1: PowerBuilder フォーム様式 ウィンドウについて ウィンドウはフォームの土台の役割を果たしま す。ウィンドウには特別な名前をもつ 1 つまたは複数のデータウィン ドウ コントロールがあります。フォーム様式の中心となるのはこの データウィンドウ コントロールです。ユーザはこの特別なデータウィ ンドウ コントロールを通じて、データをフォーム内で表示または変更 します。 この章では、この特別なデータウィンドウ コントロールをセントラル データウィンドウ コントロールと呼ぶことにします。セントラル デー タウィンドウ コントロールには、サポートされている名前のセットか ら名前を付けなければなりません。 セントラル データウィンドウに加えて、ウィンドウには PowerBuilder 上のウィンドウ内に配置できるコマンドボタン、ラジオボタン、ユー ザ オブジェクト、およびピクチャなどすべてのコントロールを配置で きます。 メニューについて フォームを実行する場合、メニューから項目を取り 除けます。メニューをメニュー ペインタで作成して、そのフォーム様 式が基礎としているウィンドウにそのメニューを関連付けます。 800 PowerBuilder 第 39 章 InfoMaker の様式とアクションの作成 メニューを作成する場合、フォームが実行されているときにツール バーに表示するメニュー項目を指定できます。このツールバーは PowerBuilder ツールバーと同じように動作します。 フォーム様式には、フォーム内でコマンドボタン にアタッチできたり、スクリプト内で呼び出せるアクションがありま す。 アクションについて フォーム様式のウィンドウ内で定義する各パブリック ウィンドウ関 数を、そのフォーム様式のユーザはアクションとして使用できます。 例 たとえば、組み込み様式であるフリーフォームは以下のもので構成さ れています。 • w_pbstyle_freeform ウィンドウ • m_pbstyle_freeform メニュー w_pbstyle_freeform について w_pbstyle_freeform ウィンドウには dw_freeform という名前のデータウィンドウ コントロールがあります。 その他のコントロールはありません。 PowerBuilder ウィンドウは、以下のようにウィンドウレベルの関数を 多く定義しています。 アプリケーション テクニック 801 フォーム様式について フリーフォーム フォーム様式のユーザは、これらのウィンドウ関数を それぞれ、InfoMaker 内でアクションとして使用できます。 m_pbstyle_freeform メニューでは、フリー フォーム様式を基礎とするフォームの実行時に、メニュー項目および ツールバー項目が使用できます。 m_pbstyle_freeform について たとえば、m_pbstyle_freeform には、 [検索条件の設定]項目が[行]メ ニューにあり、この項目はツールバーにも表示されます。 InfoMaker ユーザがフォームを実行するとき、フォーム内で行を検索す るのに使用する選択条件を入力するために、 [検索条件の指定]を選択 できます。 802 PowerBuilder 第 39 章 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 有効な組み合わせ . フォーム様式内では、表 39-1 の 4 つのデータウィン ドウの組み合わせの内 1 つを使用しなければなりません。 表 39-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 803 フォーム様式の作成および使用 フォーム様式の作成および使用 ❖ フォーム様式を作成および使用するには 1 次のどちらかを実行します。 • 既存のフォーム様式からウィンドウとメニューをコピーする • 新規にウィンドウを作成して、サポートされている名前を持つ 1 つか 2 つのデータウィンドウ コントロールをその中に配置 する 2 ウィンドウがフォーム様式の基礎としての役割を果たしているこ とを示す特別なコメントをつけて保存します。 3 ウィンドウにコントロールを追加したり、メニューを修正したり、 アクションとして動作するウィンドウ関数を定義したりなどし て、フォーム様式を拡張します。 4 フォーム様式の中で使用するすべてのオブジェクト(ウィンドウ、 ユーザ オブジェクト、およびメニューなど)を、InfoMaker ユーザ に対して様式ライブラリとして定義するライブラリにコピーしま す。 5 InfoMaker ユーザに対する探索パスを様式ライブラリに追加します。 InfoMaker ユーザが新たにフォームを作成する場合は、開発者の定 義したフォーム様式が新規フォーム ダイアログボックスに表示さ れます。ユーザは開発者が作成した様式を基礎としてフォームを 作成できます。 この章の後の箇所では、これらの操作手順について説明します。 804 PowerBuilder 第 39 章 InfoMaker の様式とアクションの作成 既存の様式の修正 フォーム様式を作成する一番簡単な方法は、既存のフォーム様式をコ ピーして、作業することです。構造を調べて多少の変更を加えると、 短時間でフォーム様式の働きを理解できます。 ❖ 既存のフォーム様式の修正を始めるには 1 PowerBuilder 上でライブラリ ペインタを開きます。 2 フォーム様式の土台としての役割を果たすウィンドウとメニュー を開発者のアプリケーションのライブラリ探索パスにあるライブ ラリにコピーします。 組み込みフォーム様式から始める 組み込みのフォーム様式の基礎としての役割を果たすウィンドウ と メ ニ ュ ー は、IMSTYLE10.PBL に あ り ま す。こ の フ ァ イ ル は InfoMaker に同梱されて、InfoMaker 10.0 ディレクトリにインストー ルされます。この PBL のコピーを作成して、独自のフォーム様式 の基礎として使用することができます。 3 4 ウィンドウ ペインタ上でウィンドウを開き、メニュー バーから [ファイル|名前を付けて保存]を選択して新しい名前でウィンド ウを保存します。 そのウィンドウに新しい名前を付けます。 名前は自由に設定できますが、フォーム様式を定義するウィンド ウ名は、InfoMaker ユーザが使用するすべての様式ライブラリに 渡って固有の名前をつける必要があります。 5 ウィンドウに対して特別なコメントを定義します(方法について は、806 ページの「様式の基礎としてのウィンドウの識別」を参照 してください)。 6 [OK]をクリックしてウィンドウを保存します。 7 メニュー ペインタ上でメニューを開き、メニュー バーから[ファ イル|名前を付けて保存]を選択してメニューを新しい名前で保 存します。 8 新しい名前と任意のコメントを付け、 [OK]をクリックしてメ ニューを保存します。 メニューに対してはコメントを付ける必要はありませんが、作成 しているフォーム様式内で使用するときと同様に識別できるよう にしたほうがよいでしょう。 アプリケーション テクニック 805 既存の様式の修正 9 フォーム様式を拡張します(方法については、808 ページの「様式 の完成」を参照してください)。 様式の基礎としてのウィンドウの識別 InfoMaker に、ライブラリ内のウィンドウがフォーム様式の基礎として の役割を果たしていることを認識させるには、次のテキスト Style: で 始まるコメントをそのウィンドウに対して指定しなければなりませ ん。 Style: 様式を説明するテキスト Style: に続くテキストは InfoMaker の新規フォーム ダイアログボック ス内のフォーム様式のアイコンの下に表示されます。 たとえば、コメント「Style: 企業データ管理」付きの w_pbstyle_freeform ウィンドウを様式ライブラリに保存する場合には、InfoMaker ユーザが 新しいフォームを作成するときに、次のような画面が表示されます。 最初にウィンドウを保存するときとライブラリ ペインタ上のどちら の場合もコメントを指定できます。 詳細については、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照 してください。 806 PowerBuilder 第 39 章 InfoMaker の様式とアクションの作成 最初からの様式の作成 フォームの動作を一度理解すると、最初からフォームを作成できるよ うになります。 ❖ フォーム様式を最初から作成するには 1 新しいウィンドウを作成します。 2 そのウィンドウにデータウィンドウ コントロールを配置します。 3 コントロールのプロパティ ビューで、そのコントロールに特別な 名前を付けます。 特別な名前のリストについては、803 ページの「フォーム様式での データウィンドウ コントロールの命名」を参照してください。 4 必要に応じて、コントロールのプロパティを変更します。 たとえば、垂直および水平のスクロールバーを追加できます。 コントロールにデータウィンドウ オブジェクトを関連付けない 新しいフォームを作成するときに、InfoMaker ユーザがコントロー ルのデータを指定します。 5 作成するフォーム様式が 2 つのデータウィンドウ コントロールを 使用する場合は、ウィンドウ上にもう 1 つ データウィンドウ コン トロールを配置して、その名前を有効な組み合わせに合致させま す。 有効な組み合わせのリストについては、803 ページの「フォーム様 式でのデータウィンドウ コントロールの命名」を参照してくださ い。 6 ウィンドウを保存して、コメントを指定します。 方法については、806 ページの「様式の基礎としてのウィンドウの 識別」を参照してください。 アプリケーション テクニック 807 様式の完成 様式の完成 様式を完成するには、ウィンドウとメニューを拡張して必要な処理を 提供するようにします。たとえば、以下のことが可能です。 • セントラル データウィンドウ コントロールに対して作業する • ウィンドウにコントロールを追加する • アクション(フォーム様式にアクションとして表示される関数)を 定義する • メニューと関連するツールバーを修正する • ウィンドウ、コントロール、およびメニュー項目用にスクリプト を書く • ドラッグ アンド ドロップなどその他の機能をウィンドウに追加 する セントラル データウィンドウ コントロールに対する作業 特別な名前をもつデータウィンドウ コントロールは、フォームの中心 です。これらのコントロールにおいてユーザがフォーム上でデータを 操作します。 次の事柄を理解する必要があります。 フリーフォームのデー タウィンドウのサイズ を指定する方法 • フォーム上でフリーフォームのデータウィンドウのサイズを指定 する方法 • フォーム上でコントロールに対してデータを検索する方法 組み込み様式と同じように、作成するフォーム様式はすべて、フリー フォームのデータウィンドウを含んでいます。PowerBuilder のウィン ドウ ペインタ上でフリーフォームのデータウィンドウ コントロール にどのようなサイズを指定するかに関係なく、フリーフォームのデー タウィンドウは InfoMaker のフォーム ペインタ上のフォーム全体を占 めます。InfoMaker がフリーフォームのデータウィンドウを拡大して、 フォーム上のどこにでも計算フィールドなどのデータを配置できるよ うにします。 これは、PowerBuilder 上で指定するウィンドウの背景色はフォーム上 では無視されるということです。 808 PowerBuilder 第 39 章 セントラル データ ウィンドウ コント ロールに対する行の検 索 InfoMaker の様式とアクションの作成 InfoMaker ユーザがフォームを実行するとき、InfoMaker は自動的に SQLCA トランザクション オブジェクトに正しい値を与えるので、開 発者がそのためのスクリプトを書く必要はありません。セントラル データウィンドウに対して行を検索するのに必要なのは、コントロー ルのトランザクション オブジェクトを設定して、行を検索することだ けです。 たとえば、dw_freeform という名前のコントロールに対してデータを検 索するには、次のようにスクリプトを書きます。 dw_freeform.SetTransObject(SQLCA) dw_freeform.Retrieve() フォームが開くときにデータを提示するには、そのウィンドウの Open イベント内にこのスクリプトを書いてください。 トランザクション オブジェクトの詳細については、第 12 章「トラン ザクション オブジェクトの使い方」を参照してください。 コントロールの追加 フォーム様式の基礎としての役割を果たすウィンドウはすべて、少な くとも 1 つの データウィンドウ コントロールを持っています。それに 加えて、標準の PowerBuilder ウィンドウに追加できるコマンドボタン、 ユーザ オブジェクト、テキスト、編集ボックス、ピクチャ、および描 画オブジェクトなど、そのほかすべてのコントロールを追加できます。 フォームのユーザは、開発者がウィンドウ内に配置したコントロール を移動できますが、削除はできません。 同様に、ユーザはフォーム ペインタ上でフォームにコントロールを追 加できます。アクションを関連付けて、コマンドボタンおよびピクチャ ボタンを作成します。アクションを以下に説明します。 アプリケーション テクニック 809 様式の完成 アクションの定義 ユーザはカスタム フォーム様式を使用して作成されたフォームに、コ マンドボタンまたはピクチャボタンを追加したい場合があります。開 発者は、フォーム様式を作成するとき、フォーム様式にアクションを 定義して、追加したボタンで可能な動作を指定します。ユーザがボタ ンを配置するとき、リストから行いたいアクションを選択します。 アクションはパブリックなウィンドウレベル関数として実装されてい ます。 ❖ アクションを定義するには 1 ウィンドウ ペインタのスクリプト ビューで、メニューバーから [挿入|関数]を選択します。 2 ウィンドウレベル関数を定義します(方法については、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください)。 ウィンドウ関数をアクションとしてフォーム ユーザが使用できる ようにするには、関数をパブリック(public)として定義してくだ さい。定義した関数の引数はアクションのパラメータとして使用 されます。定義した各パブリック ウィンドウ関数は、フォーム ペ インタのアクションの選択 ダイアログボックス内でアクションと して一覧表示されます。 アクションとして使用できない関数の定義 フォーム内でアクションとして使用できないウィンドウ関数を定 義および使用する場合は、その関数をプライベート(private)とし て定義してください。 810 PowerBuilder 第 39 章 InfoMaker の様式とアクションの作成 メニューの使い方 開発者は、ユーザがフォームを実行するときに表示されるメニューと ツールバーを指定します。メニュー ペインタでメニューを定義し、 フォーム様式の土台として役割を果たすウィンドウに関連付けます。 フォームが実行されるとき、定義したメニュー内の各メニュー項目が 表示されます。加えて、InfoMaker は[ウィンドウ]および[ヘルプ] メニューを追加して、InfoMaker 環境下でフォームを実行するときに、 ユーザがウィンドウを操作したりオンライン ヘルプを参照できるよ うにします。 オンライン ヘルプの提供 [ヘルプ]項目をメニューバー上で定義して、[ヘルプ]ドロップダウ ン メニュー内で表示されるメニュー項目を定義できます。InfoMaker 上 でフォームを実行するときには、この[ヘルプ]項目は表示されませ んが、実行ファイルからフォームを実行するときには表示されます。 InfoMaker 実行ファイルの詳細については、『InfoMaker ユーザーズ ガ イド』マニュアルを参照してください。 ツールバー上の項目 MDI アプリケーションの場合と同様、フォームの実行時に、ツール バーにメニュー項目を表示するように指定できます。 スクリプト フォームで使用するメニューには、標準ウィンドウで使用するメ ニューに対してと同じスクリプト技術を使用します。通常、ウィンド ウとそのメニューとの間で通信するには、ウィンドウに対してユーザ イベントを定義し、メニュー オブジェクトの親ウィンドウ プロパティ を使用してフォーム ウィンドウに照会し、メニューからそのイベント を発生させます。この技術は組み込みフォーム様式で使用されます。 詳細情報 メニューとユーザ イベントの使い方の詳細については、 『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 メニューに対するツールバーの関連づけの詳細については、第 5 章 「MDI アプリケーションの構築」を参照してください。 アプリケーション テクニック 811 様式の使い方 スクリプトの記述 ウィンドウ、コントロール、およびメニュー オブジェクトに対するス クリプトは、標準ウィンドウおよびメニューに対してと同じ方法で書 きます。データウィンドウ コントロールで作業する場合は、SQLCA ト ランザクション オブジェクトのプロパティを設定する必要はありま せん。これは、ユーザがフォームを実行するときに、InfoMaker が自動 的に設定するからです。 開発者が書くスクリプトをサポートするために、ユーザ定義のグロー バル関数およびグローバル構造体を定義できます。しかし、InfoMaker にはアプリケーション オブジェクトがないので、フォーム様式はグ ローバル変数またはグローバル外部関数宣言を使用できません。 その他の機能の追加 フォームは開発者の必要に応じて洗練されたものにできます。たとえ ば、ドラッグ アンド ドロップ機能を実装したり、フォームでメールを 使用できるようにします。 ウィンドウに対して作成できる機能の詳細については、『PowerBuilder ユーザーズ ガイド』マニュアルを参照してください。 様式の使い方 フォーム様式を完成、または少なくともテストできるバージョンを完 成すると、そのフォームを使用できます。 ❖ InfoMaker ユーザが様式を使用できるようにするには 1 フォーム様式を定義するウィンドウとメニューが InfoMaker のア クセス可能なライブラリ(スタイル ライブラリ)内にあることを 確認します。 2 ウィンドウ、ユーザ オブジェクト、グローバル ユーザ定義関数な どフォーム様式内で使用するその他の PowerBuilder オブジェクト を同じライブラリに追加します。 3 InfoMaker ユーザのパスに、スタイル ライブラリを追加します。 詳細については、『InfoMaker ユーザーズ ガイド』マニュアルを参 照してください。 812 PowerBuilder 第 39 章 InfoMaker の様式とアクションの作成 カスタム フォーム様式を使用したフォームの作成 スタイル ライブラリを使用する InfoMaker ユーザが新しいフォームを 作成するときには、新規フォーム ダイアログボックスの[フォーム様 式]ボックス上にすべてのカスタム フォーム様式が表示されます。 カスタム様式と汎用アイコンが表示されます。 InfoMaker ユーザはデータ ソースとカスタム様式を選択するだけで、開 発者の作成したフォーム様式を基礎としたフォームの作成を開始でき ます。開発者は作成したフォーム様式について説明を提供しなければ なりません。 継承の理解 ユーザがフォームを作成するときは、開発者がフォーム様式に対して 作成したウィンドウの子孫ウィンドウに対して作業します。つまり、 開発者が PowerBuilder で作成したフォーム様式ウィンドウは先祖ウィ ンドウであり、InfoMaker で使用するフォーム ウィンドウは子孫ウィ ンドウということです。フォーム様式を変更した場合、その変更はユー ザがその様式を使用して次に作業するときに反映されます。 たとえば、フォーム様式にコントロールを追加した場合、ユーザが後 でその様式を使用して既存のフォームを開くときにそのコントロール が自動的に表示されるように設定できます。 注意 様式を使用してすでに作成されたフォームを無効にする変更はしない でください。 アプリケーション テクニック 813 様式の使い方 フォーム様式の使用の管理 ネットワーク上に様式ライブラリを格納して、InfoMaker ユーザ全員が 簡単にそれらを使用できるように設定できます。ネットワーク上に様 式ライブラリをセットアップするには、ネットワーク上で初期設定 ファイルを共有した状態で行います。共有様式ライブラリを参照する InfoMaker 初期設定ファイルをネットワーク上に配置してから、InfoMaker ユーザが初期設定ファイルにアクセスできるように InfoMaker ユーザ を設定します。 ❖ 組織全体でスタイルライブラリを使用できるようにするには 1 InfoMaker ユーザがアクセスできるネットワーク上のディレクト リに様式ライブラリを配置します。 2 InfoMaker を開き、ライブラリ ペインタに移動し、探索パスにすべ ての様式ライブラリがリストされていることを確認します。 3 InfoMaker を閉じます。 4 InfoMaker 初期設定ファイルを InfoMaker ユーザ全員がアクセスで きるネットワーク上のディレクトリにコピーします。 これが共有初期設定ファイルです。このファイルは[Application] セクションの StyleLib 変数にスタイル ライブラリすべてを記録し ます。 5 InfoMaker ユーザが共有初期設定ファイルにアクセスできるように セットアップします。 各 InfoMaker ユーザが InfoMaker 内で共有初期設定ファイルの位置 を指定する必要があります。 詳細については、次の「InfoMaker 上での共有 InfoMaker 初期設定 ファイルの位置の指定」を参照してください。 InfoMaker 上での共有 InfoMaker 初期設定 ファイルの位置の指定 一度共有初期設定ファイルがユーザの InfoMaker 初期設定ファイルで 定義されると、ユーザの様式ライブラリ探索パスはユーザのローカル InfoMaker 初期設定ファイルに加えて、共有初期設定ファイルで定義さ れた様式ライブラリ全部から成りたちます。ユーザが新しいフォーム を作成する場合、様式ライブラリ全部で定義されたフォーム様式が新 規フォーム ダイアログボックスに表示されます。 各 InfoMaker ユーザは、共有初期設定ファイルの位置を InfoMaker に知 らせる必要があります。 814 PowerBuilder 第 39 章 ❖ InfoMaker の様式とアクションの作成 共有 InfoMaker 初期設定ファイルの位置を指定するには 1 InfoMaker メニューバーの[ツール|システム オプション]を選択 します。 2 [全般]プロパティ ページ内で、共有 InfoMaker 初期設定ファイル へのパスを入力します。 3 [OK]をクリックします。 InfoMaker は、InfoMaker 初期設定のパスをレジストリに保存しま す。 InfoMaker ユーザが組み込みフォーム様式を使用しないようにしたい 場合もあります。つまり、開発者の組織のユーザ定義様式を基礎とす るフォームのみをユーザに使用させたいという場合です。このような 場合、新規フォーム ダイアログボックスに表示されないようにして、 組み込み様式を使用しないようにします。 組み込み様式の使用を 防ぐ ❖ 組み込み様式の表示を禁止するには 1 ネットワーク上の共有初期設定ファイルを前節で説明したように 設定します。 2 共有初期設定ファイルの [Window] セクションに次の行を追加し ます。 ShowStandardStyles = 0 共有初期設定ファイルでこの行を指定すると、新しいフォームを作成 するときに、ユーザはユーザ定義フォーム様式からのみ選択できるよ うになります。InfoMaker はユーザのローカル InfoMaker 初期設定ファ イルにある ShowStandardStyles 行を無視することに注意してください。 アプリケーション テクニック 815 様式の使い方 816 PowerBuilder 第 9 部 配布のテクニック 第 9 部では、アプリケーションを配布するためのパッ ケージ化の方法と、配布に必要なファイルについて説明 します。 第 4 0 章 配布用アプリケーションのパッケー ジ化 この章について この章では、完成した実行アプリケーションをユーザに配布する ための準備方法について説明します。 内容 項目 アプリケーションの配布について アプリケーションの実行版の作成 エンド ユーザへのアプリケーションの配布 ページ 819 820 836 アプリケーションの配布について PowerBuilder を使用すると、数多くのアプリケーション アーキテ クチャ用に、アプリケーションを開発および配布できます。 従来型のクライアント / サーバ アプリケーション インターネットと分散アプ リケーション アプリケーション テクニック この章の主なねらいは、実行ファイルを作成して、単層または 2 階層のアプリケーションを配布用にパッケージ化することです。 この章の内容は、コンパイル済みコードを使用するか疑似コード を使用するか、動的ライブラリ(PBD または DLL)を使用するか どうかとその編成方法、ビットマップやアイコンなどのリソース を別々に配布するのか、それとも PowerBuilder リソース ファイル (PBR)を使用するのか、といった決定をする際に役立ちます。 多層アプリケーションでクライアントを構築する場合には、従来 のクライアント / サーバ アプリケーションの場合と同じ選択を行 う必要があります。EAServer または COM コンポーネントを作成 している場合、あるいは PowerBuilder ウィンドウ プラグインまた は PowerBuilder ウィンドウ ActiveX を使用している場合には、821 ページの「パッケージに含まれる要素」で後述する PowerBuilder 動的ライブラリ(PBD)と PBR について知る必要があります。 819 アプリケーションの実行版の作成 詳細情報 クライアント / サーバ アプリケーション、多層アプリケーション、お よび Web アプリケーションで配布しなければならないファイルにつ いての詳細は、第 41 章「アプリケーションとコンポーネントの配布」 を参照してください。 アプリケーションの実行版の作成 以下の節では、パッケージ化のプロセスについて詳しく説明し、最終 的に作成されるアプリケーションのさまざまな選択事項について、ア ドバイスします。以下のことについて説明します。 • コンパイラの基本事項 • パッケージに含まれる要素 • パッケージ化モデルの選択 • パッケージ化モデルの実装 • 実行アプリケーションのテスト コンパイラの基本事項 アプリケーションを計画するとき、基本的に考慮する事項の 1 つとし て、ア プ リ ケ ー シ ョ ン を 生 成 す る コ ン パ イ ラ 形 式 が あ り ま す。 PowerBuilder では、Pcode とマシン コードのいずれかを選択できます。 Pcode マシン コード Pcode(中間コード)は、PowerBuilder のすべてのプラットフォームで サポートされているインタプリタ言語です。Pcode は、PowerBuilder が 個々のオブジェクトを実行可能な状態で格納する際にライブラリ (PBL ファイル)内で使用する形式と同じです。Pcode の利点は、サイ ズ、信頼性、移植性です。 PowerBuilder は、コードを生成およびコンパイルして、マシン コード の実行ファイルまたは動的ライブラリを作成します。マシン コードの 最大の利点は、実行速度の速さにあります。 PowerBuilder DLL の呼び出しはできない PowerBuilder マシン コード DLL をほかのアプリケーションから呼び 出すことはできません。 820 PowerBuilder 第 40 章 使用するコードの決定 配布用アプリケーションのパッケージ化 自分のプロジェクトにとって Pcode とマシン コードのどちらが適切か を決めるためのガイドラインを以下に示します。 • 作成したアプリケーションでスクリプト処理を集中的に行 う場合は、マシン コードを使用することを検討します。コード内 でループ構造、浮動小数点演算、整数演算、または関数の呼び出 しを使う頻度が非常に高い場合は、Pcode よりも優れた処理能力を 発揮します。アプリケーションに前述のような特徴がない場合は、 マシン コードによる処理が Pcode よりも目に見えて優れているこ とはありません。作成するアプリケーションでマシン コードを使 用するとメリットがあると考えられる場合は、ベンチマーク テス トをいくつか実行して効果を調べます。 速度 Pcode はマシン コードより速く生成されます。マシン コードを 使ってアプリケーションを配布する予定であっても、アプリケー ションのテスト用実行モジュールをすばやく作成したいときには Pcode を使用できます。 • サイズ Pcode を使って生成されるファイルは、マシン コードを 使って生成されるファイルよりサイズが小さくなります。ファイ ルのサイズが大きな問題であるコンピュータにアプリケーション を配布する場合、または Web のダウンロードまたはファイル転送 を使って配布する場合は、マシン コードの速度をあきらめ、Pcode を選択したほうがよいでしょう。 パッケージに含まれる要素 どちらのコンパイラ形式を選択した場合でも、PowerBuilder で作成す るアプリケーションは、以下の要素のいずれか 1 つまたは複数で構成 されます。 • 実行ファイル • 動的ライブラリ • リソース 特定のプロジェクトに必要な要素を決めるには、まず、各要素に関す る知識が必要です。 実行ファイルについて サーバ コンポーネントまたは Web アプリケーションとして配布する のではなく、実行ファイルとしてユーザに配布する単層または 2 階層 のアプリケーションを作成している場合には、必ず実行(EXE)ファ イルを作成することになります。 アプリケーション テクニック 821 アプリケーションの実行版の作成 この実行ファイルは、最低でもアプリケーションをターゲット プラッ トフォームでネイティブに実行するためのコードを含みます。たとえ ば、ユーザが配布されたアプリケーションを起動するときに、実行ファ イルのアイコンをデスクトップでダブルクリックすれば起動できるこ とを意味します。 実行ファイルでのその他の要素 ア プ リ ケ ー シ ョ ン 用 に 選 択 し た パ ッ ケージ化モデルの種類によって、実行ファイルは以下の要素のいずれ か 1 つまたは複数を含みます。 • アプリケーションのライブラリに入っているコンパイル済みオブ ジェクト 配布するファイルが 1 つで済むように、すべてのオブジェクトを 実行ファイルに入れたり、1 つの実行ファイルと 1 つまたは複数の 動的ライブラリにアプリケーションを分割したりできます。詳細 については、822 ページの「動的ライブラリについて」を参照して ください。 • アプリケーション用にパッケージ化した任意の動的ライブラリに 含まれるオブジェクトとリソースを検索するために、PowerBuilder の実行システムが使用する実行ライブラリ リスト • ビットマップなど、アプリケーションが使用するリソース 図 40-1: 実行ファイルの内容 動的ライブラリについ て 822 アプリケーション全体を 1 つの大きな実行ファイルに収める代わり に、そのオブジェクトの一部またはすべてを 1 つまたは複数の動的ラ イブラリで配布できます。PowerBuilder が動的ライブラリを実装する 方法は、選択するコンパイラ形式によって異なります。 PowerBuilder 第 40 章 配布用アプリケーションのパッケージ化 表 40-1: PowerBuilder 動的ライブラリ 作成コード マシン コード 実装される動的ライブラリ DLL ファイル(ダイナミック リンク ライブラリ) Pcode マシン コードの動的ライブラリは、Windows では拡張子 .dll が付加される。これらの動的ライブラリは、オペレー ティング環境における、ほかの標準的な共有ライブラリ と同様に動作する。これらの動的ライブラリは、外部の プログラムから呼び出せない点に注意する PBD(PowerBuilder 動的ライブラリ)ファイル これらの動的ライブラリは、実行時にアプリケーション にリンクされるという点で、DLL ファイルに似ている。 ただし、PBD は内部形式が異なるため、DLL とは互換性 がない 2 種類の動的ライブラリ(DLL と PDB)を 1 つのアプリ ケーション内に混在させることはできない 実行ファイルと同様、動的ライブラリに格納できるのは、オブジェク トのソースではなく、コンパイル済みのオブジェクトだけです。 アプリケーション テクニック 823 アプリケーションの実行版の作成 図 40-2: 動的ライブラリ内のコンパイル済みオブジェクト 動的ライブラリ内のその他の要素 実行ファイルとは異なり、動的ライブ ラリにはスタートアップ コードが含まれません。動的ライブラリは、 独立して実行することはできません。動的ライブラリは、アプリケー ションを実行したときに、実行ファイル内に必要なオブジェクトが見 つからない場合にアクセスされます。 動的ライブラリにはビットマップなどのリソースが含まれる場合があ ります。動的ライブラリのオブジェクトに必要なリソースを、その DLL ファイルまたは PBD ファイルに含めることができます。これによって、 動的ライブラリを、再利用可能な、独立したユニットにすることがで きます。ただし、処理効率の視点から考えると、リソースは実行ファ イル内に格納されているときの方が、実行時に速くロードされます。 図 40-3: 動的ライブラリ内のリソース 動的ライブラリを使う理由 表 40-2 に示すように、動的ライブラリの使 用を推奨する理由がいくつかあります。 824 PowerBuilder 第 40 章 配布用アプリケーションのパッケージ化 表 40-2: 動的ライブラリを使用する理由 理由 モジュール性 保守性 再利用性 柔軟性 効率性 詳細 アプリケーションを、管理のしやすい、より小さく、より 多くのモジュール型ファイルに分割できる アプリケーション コンポーネントの個別配布ができる。 ユーザにバグ修正ファイルを提供するために、影響のある 特定の動的ライブラリを配布できる 動的ライブラリは、ユーザ間だけでなく、アプリケーショ ン間でも共有できるため、複数のアプリケーションで同じ コンポーネントを再利用できる 文字列変数のみによって参照されるウィンドウ オブジェク トなど、実行時にアプリケーションによって動的にのみ参 照されるオブジェクトを提供できる このようなオブジェクトは、データウィンドウの場合を除 いて、実行ファイルに含めることはできない 以下の理由により、大規模なアプリケーションでもメモリ を効率的に使用できる • PowerBuilder では、動的ライブラリ全体をメモリ内に一 度にロードしない。その代わり、必要に応じて、動的ラ イブラリから個々のオブジェクトをロードする • 実行ファイルのサイズを小さく抑えることができるた め、ロード時間が速く、扱いやすい 動的ライブラリの編成 動的ライブラリの利用を決めたら、どのライブ ラリ(PBL ファイル)から作成するかを、PowerBuilder に指示する必 要があります。PowerBuilder は、選択した PBL ファイルからコンパイ ル済みの全オブジェクトを、DLL ファイルまたは PBD ファイル内に配 置します。 アプリケーションで一部のオブジェクトしか使用しない場合は、余分 なオブジェクトを動的ライブラリに含めてもファイルが大きくなるだ けです。その解決法は以下のとおりです。 リソースについて 1 新しい PBL ファイルを作成し、必要なオブジェクトだけをその中 にコピーする 2 動的ライブラリのソースとして、作成した新しい PBL ファイルを 使用する ウィンドウやメニューなどの PowerBuilder オブジェクトに加えて、ア プリケーションではさまざまなリソースを使います。リソースの例に は以下のものがあります。 • アプリケーション テクニック ピクチャ コントロールまたはピクチャボタン コントロールで表 示するビットマップ 825 アプリケーションの実行版の作成 • ウィンドウに割り当てるカスタム ポインタ リソースを使うときは、PowerBuilder オブジェクトとともに、アプリ ケーションの一部として配布する必要があります。 リソースの種類 PowerBuilder のアプリケーションでは、複数の異なる リソースを使用できます。表 40-3 は、リソースを、使用できるオブ ジェクトごとにリストしています。 表 40-3: PowerBuilder オブジェクトおよびリソース オブジェクト ウィンドウ オブジェクト とユーザ オブジェクト データウィンドウ オブ ジェクト MDI アプリケーションに おけるメニュー オブジェ クト 使用されるリソースの種類 アイコン(ICO ファイル) ピクチャ(BMP、GIF、JPEG、RLE、および WMF の各ファイル) ポインタ(CUR ファイル) ピクチャ(BMP、GIF、JPEG、RLE、および WMF の各ファイル) ピクチャ(BMP、GIF、JPEG、RLE、および WMF の各ファイル) リソースの配布 アプリケーションといっしょに配布するリソースの パッケージ方法を決めるときは、以下のアプローチから選択できます。 • リソースを実行ファイルに含める PowerBuilder では、実行ファイルの作成時、そのファイルに配置す るオブジェクトについて、リソース(アイコン、ピクチャ、ポイ ンタ)を明示的に参照しているかどうかが自動的に調べられます。 次に、そのようなリソースをすべて、実行ファイル内に直接コピー します。 文字列変数などを介して動的に参照されるリソースは、自動的に コピーされません。そのようなリソースを実行ファイル内にコ ピーするには、リソース(PBR)ファイルを使わなければなりま せん。これは単純なテキスト ファイルで、既存の ICO、BMP、GIF、 JPEG、RLE、WMF、および CUR の各ファイルをこの中に一覧表 示します。 PBR ファイルが完成したら、実行ファイルを作成するときは、PBR ファイルを読み込むよう PowerBuilder に指示することによって、 追加するリソースを指定します。処理効率上の理由で、ほとんど またはすべてのリソースを実行ファイルに含める場合、PBR ファ イルには、動的ライブラリ内のオブジェクトによって使用される リソースも含めることができます。 826 PowerBuilder 第 40 章 • 配布用アプリケーションのパッケージ化 リソースを動的ライブラリに含める 1 つまたは複数の動的ライブラリにリソースを直接含めたい場合 がありますが、PowerBuilder は、リソースがそのファイル内のオブ ジェクトにより明示的に参照されるときでも、作成される動的ラ イブラリ内にそのリソースを自動的にコピーしません。この特定 の DLL ファイルまたは PBD ファイル内にどのリソースを入れる かを PowerBuilder に対して指定する PBR ファイルを作成する必要 があります。 リソースを入れる動的ライブラリごとに、個別の PBR ファイルを 使用します。適切であれば、このアプローチを使って、リソース だけを含み、オブジェクトを含まない動的ライブラリを生成する こともできます。空の PBL ファイルをソースとして作業を始める だけです。 • リソース ファイルを個別のファイルで配布する これは、アプリケーションの配布時に、アプリケーションの実行 ファイルおよび動的ライブラリに加えて、さまざまな画像ファイ ルをユーザに提供することを意味します。多くのファイルを配布 することに問題がなければ、一部のファイルを修正する予定があ る場合に便利な方法です。 この方法は、実行時に必要な検索作業が多くなるため、もっとも 速い方法ではないことに注意してください。アプリケーションで リソースが必要なとき、アプリケーションは最初に実行ファイル を、次に動的ライブラリを検索します。リソースが見つからない 場合、アプリケーションは別個のファイル内で検索します。 これらの個々のファイルがどこに格納されているかを、アプリ ケーションがわかるようにしておく必要があります。そうでない 場合は、対応するリソースが表示されません。 特定のアプリケーションをパッケージ化するときは、以上のアプロー チのいずれか 1 つまたは組み合わせを利用できます。 アプリケーション テクニック 827 アプリケーションの実行版の作成 PBR ファイルを使って、動的に参照されるデータウィンドウ オブジェクト を含める 作成中の実行ファイルの中に、アプリケーションが文字列変数を介し てのみ動的に参照するデータウィンドウ オブジェクトを入れたい場 合があります。そのためには、PowerBuilder によって実行ファイル内 にコピーしたいリソースの名前とともに、そのデータウィンドウ オブ ジェクトの名前を、PBR ファイル内に一覧表示しなければなりません。 動的ライブラリを作成するときは、その必要はありません。PowerBuilder によって、ソース ライブラリ(PBL ファイル)のすべてのデータウィ ンドウ オブジェクトが、新しい DLL ファイルまたは PBD ファイル内 に自動的に含まれます。 PowerBuilder リソース ファイルの作成 PBR ファイルは、リソース名(BMP、CUR、ICO、RLE、WMF ファイ ルなど)とデータウィンドウ オブジェクトが一覧で表示されている ASCII テキスト ファイルです。PBR ファイルを作成するには、テキス ト エディタを使用します。各リソースの名前を 1 行に 1 つずつ記述し、 そのリストに拡張子 PBR を付けてファイルとして保存します。以下 は、PBR ファイルのサンプルです。 ct_graph.ico document.ico codes.ico button.bmp next1.bmp prior1.bmp ❖ PowerBuilder リソース ファイルを作成して使用する手順 1 テキスト エディタを使用して、アプリケーションで動的に参照さ れるリソース ファイルをすべて一覧表示するテキスト ファイル を作成します(ファイルの作成については、以下を参照してくだ さい)。 動的ライブラリのリソース ファイルを作成するときは、スクリプ トで動的に割り当てられたリソースだけでなく、動的ライブラリ によって使用されるすべてのリソースを一覧表示します。 2 828 プロジェクト ペインタで、リソース ファイルを指定します。動的 ライブラリと同様、実行ファイルにリソース ファイルが添付され ていることもあります。 PowerBuilder 第 40 章 配布用アプリケーションのパッケージ化 PowerBuilder がプロジェクトを構築するときは、実行ファイルまた は動的ライブラリの PBR ファイルに指定されているすべてのリ ソースを含めます。動的に割り当てられたリソースを個別に配布 する必要はありません。リソースはアプリケーションに含まれて います。 リソースを指定する リソース ファイルが現行ディレクトリにある場合は、以下のように ファイルを一覧表示するだけです。 FROWN.BMP リソース ファイルが別のディレクトリにある場合は、以下のように ファイルへのパスを指定します。 C:\BITMAPS\FROWN.BMP PBR ファイルとスクリプトのパスの一致 PBR ファイルに指定するファイル名は、スクリプトにおけるリソース の参照方法と正確に一致していなければなりません。 スクリプト内の参照にパスが使用される場合は、PBR ファイルに同じ パスを指定する必要があります。スクリプトのリソース ファイルがパ スで修飾されていない場合は、PBR ファイルでも修飾しないようにし ます。 たとえば、次のようなスクリプトがあります。 p_logo.PictureName = "FROWN.BMP" この場合、PBR ファイルは次のように記述する必要があります。 FROWN.BMP PBR ファイルの記述が下記のように異なる場合について説明します。 C:\MYAPP\FROWN.BMP この場合、スクリプトでパスが指定されていないと、PowerBuilder は 実行時にリソースを見つけることはできません。これは、PowerBuilder が実行時には単純な文字列の比較を行うためです。先ほどの例では、 スクリプトを実行するとき、PowerBuilder は実行ファイルに文字列 「FROWN.BMP」で指定されているオブジェクトを探します。実行ファイ ルでは、リソース「C:\MYAPP\FROWN.BMP」として識別されているため、 PowerBuilder はオブジェクトを見つけることができません。 この場合、実行時にはピクチャが表示されず、ウィンドウのコントロー ルは空白になります。 アプリケーション テクニック 829 アプリケーションの実行版の作成 データウィンドウ オ ブジェクトを PBR ファイルに含める データウィンドウ オブジェクトをリストに含めるには、ライブラリ名 (拡張子 PBL)の後にカッコで囲んだデータウィンドウ オブジェクト 名を付けます。たとえば、次のようになります。 sales.pbl(d_emplist) 実行ファイル作成時の現行ディレクトリにデータウィンドウ ライブ ラリがない場合は、PBR ファイルに完全修飾の参照を指定します。た とえば、次のようになります。 c:\myapp\sales.pbl(d_emplist) パッケージ化モデルの選択 前述したとおり、アプリケーションの実行版をパッケージ化するには、 たくさんのオプションがあります。もっとも一般的なパッケージ化モ デルを以下に示します。 スタンドアロンの実行 ファイル このモデルでは、オブジェクトとリソースがすべて実行ファイル内に 含まれているため、配布するファイルは 1 つだけになります。 説明図 図 40-4 に、このモデルの構造のサンプルを示します。 図 40-4: スタンドアロン実行モデル このモデルは、小規模で、簡単なアプリケーションに適してお り、管理をそれほど必要としないアプリケーションの場合には特に適 しています。そのようなプロジェクトに、このモデルを使用すると、 最高の処理効率ともっとも簡単な配布方法が保証されます。 用途 830 PowerBuilder 第 40 章 実行ファイルと外部リ ソース 配布用アプリケーションのパッケージ化 このモデルでは、すべてのオブジェクトと大部分のリソースが実行 ファイルに含まれていますが、特定のリソースについては、別個のファ イルを配布します。 説明図 図 40-5 に、このモデルの構造のサンプルを示します。 図 40-5: 外部リソースを含む実行モデル このモデルも小規模で、簡単なアプリケーションに適していま すが、変更の可能性のあるリソースの管理をサポートしているという 点で、前のモデルとは異なります。つまり、実行ファイルの修正コピー を配布しないで特定のリソースの修正コピーをユーザに配布できま す。 用途 このモデルを使うと、ほかのアプリケーションと共有しなければなら ないリソース、または、大規模で使用頻度の低いリソースを扱うこと も可能です。 実行ファイルと動的ラ イブラリ このモデルでは、アプリケーションを 1 つの実行ファイルと 1 つまた は複数の動的ライブラリ(DLL または PBD)に分割します。アプリ ケーションを分割するときは、オブジェクトとリソースをさまざまな 方法で編成できます。表 40-4 に、いくつかの方法を示します。 表 40-4: 動的ライブラリを含むオブジェクトとリソースの編成 編成の対象 オブジェクト リソース 行えること 実行ファイルにオブジェクトが含まれないようにし、すべ てのオブジェクトを動的ライブラリに配置して、管理を容 易にする。または、 アクセス頻度の高い一部のオブジェクトを実行ファイル に配置して、これらのオブジェクトへのアクセスを最適化 し、残りのオブジェクトすべてを動的ライブラリ内に配置 する 大部分またはすべてのリソースを、それらを使用するオブ ジェクトとともに、動的ライブラリ内に配置して、再利用 を簡単にする。または、 大部分またはすべてのリソースを実行ファイルに配置す る。これによって、リソースへのアクセスが最適化される アプリケーション テクニック 831 アプリケーションの実行版の作成 説明図 図 40-6 に、このモデルの構造のサンプルを示します。 図 40-6: 動的ライブラリを含む実行モデル このモデルは、アプリケーションの編成、配布、および管理に おいて柔軟に作業を行えるため、多くの大規模なプロジェクトに適し ています。 用途 たとえば、このモデルを使用すると、1 つの動的ライブラリで、アプ リケーションの特定部分に修正を加えることができます。ただし、ラ イブラリに修正を加えた場合は、必ずアプリケーション全体を再構築 し、すべての動的ライブラリを顧客に配布する必要があります。 実行ファイル、動的ラ イブラリ、および外部 リソース このモデルは、実行ファイルと動的ライブラリにすべてのリソースを 含めるかわりに、特定のリソースについて個別のファイルを配布する という点以外は、直前のモデルと同じです。 説明図 832 図 40-7 に、このモデルの構造のサンプルを示します。 PowerBuilder 第 40 章 配布用アプリケーションのパッケージ化 図 40-7: 動的ライブラリと外部リソースを含む実行モデル このモデルは、大規模なアプリケーションに適しており、特に、 特定のリソースを処理するための柔軟性が必要なアプリケーションの 場合に適しています。柔軟性が求められるのは、以下のようなリソー スです。 用途 • 修正する可能性がある • ほかのアプリケーションと共有しなければならない • 大規模で、使用頻度が低い パッケージ化モデルの実装 アプリケーションについて適切なパッケージ化モデルを決定したら、 PowerBuilder に付属のパッケージ化機能を利用して、パッケージ化モ デルを実装できます。この作業のほとんどは、プロジェクト ペインタ で行います。プロジェクト ペインタを使用すれば、実行アプリケー ションと同様に、コンポーネント、プロキシ ライブラリ、HTML ファ イルが作成できます。 アプリケーション テクニック 833 アプリケーションの実行版の作成 実行アプリケーション 用にプロジェクト ペ インタを使用する 実行アプリケーション用のプロジェクト ペインタは、以下の操作を可 能にすることによって、パッケージ化ジョブのすべての局面を編成し ます。 • 作成する実行ファイルを指定します。 • 作成する動的ライブラリ(DLL ファイルまたは PBD ファイル)を 指定します。 • 実行ファイルまたは特定の動的ライブラリに含めるリソースを指 定します。リソースの取得場所を示す適切な PBR ファイルを利用 します。 • 生成するコンパイラ形式として、マシン コードまたは Pcode を選 択します。 マシン コードでは、最適化、トレース情報、およびエラー コンテ キスト情報などの、さまざまなコード生成オプションも指定でき ます。 • 構築オプションを選択します。実行アプリケーションの生成時に、 プロジェクト ペインタを使用してアプリケーションのオブジェク トのフル再構築を行うか、インクリメンタル再構築を行うかどう かの指定も含まれます。 • パッケージ全体を再構築するときにいつでも利用できるプロジェ クト オブジェクトとして、上記の仕様を保存します。 プロジェクト ペインタの使い方の詳細については、 『PowerBuilder ユー ザーズ ガイド』マニュアルを参照してください。 個別の動的ライブラリ の構築 既存のアプリケーションに修正を加えても、そのすべての動的ライブ ラリが影響を受けるわけではありせん。システム ツリーまたはライブ ラリ ペインタのポップアップ メニューから、個別の動的ライブラリを 再構築できます。 変更が限定的で、ほかの PBL の継承オブジェクトに影響しない場合 は、更新またはバグ修正用に個別の PBD をユーザに配布できます。し かし、アプリケーションを修正するたびにフル再構築して、実行ファ イルとアプリケーションのすべての動的ライブラリを配布することを お勧めします。 834 PowerBuilder 第 40 章 配布用アプリケーションのパッケージ化 実行アプリケーションのテスト アプリケーションの実行版を作成したら、配布する前に、その動作を テストしてください。PowerBuilder の開発環境においては、すでにア プリケーションを何度も実行しているかもしれませんが、エンド ユー ザの立場になって独立したアプリケーションの実行版を実行すること は、非常に重要なことです。 アプリケーションを実行する手順は次のとおりです。 1 PowerBuilder を終了して、オペレーティング システム環境に戻り ます。 2 アプリケーションが PowerBuilder ランタイム ライブラリにアクセ スできるようにしておいてください。 そのためには、PowerBuilder 仮想マシンおよびそのほかのランタイ ム ファイルの位置が PATH 環境変数に設定されていること、また は、アプリケーションのレジストリ エントリを作成して、パスを 指定できることを確認します。 3 アプリケーションの実 行をトレースする 任意のネイティブ アプリケーションの場合と同じように、アプリ ケーションの実行ファイルを実行します。 問題を見つけやすくするため、PowerBuilder では、トレースとプロファ イルの機能を提供しています。これらの機能は開発環境で利用でき、 アプリケーションの実行版を実行するときにも利用できます。アプリ ケーションの実行ファイルに問題がなくても、この機能を利用して、 アプリケーションの動作に関する監査証跡を生成することをお勧めし ます。実行のトレースの詳細については、 『PowerBuilder ユーザーズ ガ イド』マニュアルを参照してください。 アプリケーション テクニック 835 エンド ユーザへのアプリケーションの配布 エンド ユーザへのアプリケーションの配布 アプリケーションの実行版をユーザに配布する場合には、各種のファ イルとプログラムをすべてコンピュータやネットワーク上の適切な位 置にインストールする必要があります。 配布プロセスを自動化 する 配布プロセスを自動化する場合、InstallShield などのソフトウェア配布 アプリケーションを利用することもできます。通常、そのようなアプ リケーションでは、ユーザがアプリケーションを実行するときに必要 となる実行ファイル、リソース ファイル、データ ソース、およびコン フィグレーション ファイルがすべてインストールされます。また、 ユーザの初期設定(INI)ファイルとレジストリも更新されます。 インストール チェックリスト 以下のチェックリストを使用すると、必要なものをすべてインストー ルしたかどうか確認できます。読みやすくするために、チェックリス トは以下の項目に分類されています。 環境要素をインストー ルする • 環境要素をインストールする • アプリケーション要素をインストールする チェックリスト項目 PowerBuilder のランタイ ム DLL のインストール 詳細 PowerBuilder の実行システムを含む、すべての DLL ファイルを、各ユーザのコンピュータにイ ンストールする。DLL ファイルは、PowerBuilder アプリケーションを、開発環境の外で、独立し て実行するために必要になる。これは、Pcode で 生成されたアプリケーションだけでなく、マシ ン コードで生成されたアプリケーションにも該 当する ランタイム DLL のインストールについての詳細 は、849 ページの「PowerBuilder ランタイム ファ イル」を参照 管理リリースの処理。 開発環境で PowerBuilder の管理リリースを使っている場合は、その管理 リリースのランタイム DLL をユーザに提供して おく必要がある 836 PowerBuilder 第 40 章 チェックリスト項目 データベース インタ フェースのインストール インストールする ODBC ドライバの設定 配布用アプリケーションのパッケージ化 詳細 各ユーザのコンピュータには、ODBC インタ フェースおよびその他のネイティブなデータ ベース インタフェースなど、アプリケーション が必要とするデータベース インタフェースをイ ンストールする データベース インタフェースのインストールに ついての詳細は、第 41 章「アプリケーションと コンポーネントの配布」を参照。データベース インタフェースについての詳細は、 『データベー スとの接続』マニュアルを参照 ODBC インタフェースおよび 1 つまたは複数の ODBC ドライバをユーザのコンピュータにイン ストールする場合、ODBC ドライバも設定しな ければならない。ドライバの設定作業には、各 ドライバを介してアクセスされる特定のデータ ソースの定義も含まれる ODBC ドライバの設定についての詳細は、 『デー タベースとの接続』マニュアルを参照 必要に応じたネットワー アプリケーションがサーバのデータベースまた ク アクセスの設定 はその他のネットワーク サービスにアクセスす る必要がある場合は、各ユーザのコンピュータ を正しく接続しておく必要がある オペレーティング システ 特定のアプリケーションでは、処理効率上また ムまたはウィンドウ シス はその他の理由により、オペレーティング シス テムの設定 テムまたはウィンドウ システムの側で特別な調 整が必要になる場合がある。そのようなアプリ ケーションに該当する場合は、各ユーザのコン ピュータを調整しておく必要がある アプリケーション テクニック 837 エンド ユーザへのアプリケーションの配布 アプリケーション要素 をインストールする チェックリスト項目 実行アプリケーションの コピー 詳細 実行アプリケーションを構成するファイルのコ ピーを作成し、それを各ユーザのコンピュータ にインストールする。インストールするファイ ルには、以下のものがある • 実行(EXE)ファイル • 動的ライブラリ(DLL ファイルまたは PBD ファイル) • 個別に配布するリソース ファイル(ICO、 BMP、GIF、JPEG、RLE、WMF、または CUR など) 管理リリースの処理。 これらのファイルを定 期的に修正する計画がある場合は、それらの最 新バージョンをネットワーク上のサーバからコ ピーして、ユーザのコンピュータにコピーする プロセスを自動化することもできる 追加ファイルのコピー このロジックをアプリケーション内で直接構築 することも考えられる。また、PowerBuilder のラ ンタイム DLL の更新ファイルをユーザのコン ピュータにコピーすることも考えられる アプリケーションが使用する追加ファイルのコ ピーを作成し、各ユーザのコンピュータにイン ストールする。インストールするファイルには、 以下のものがある • 初期設定(INI)ファイル • ヘルプ(HLP)ファイル • ほかに、テキスト ファイルやサウンド ファイ ルなど、さまざまなファイルが考えられる アクセスするローカル データベースのコピー ファイルの使用法によっては、特定のファイル をローカルではなく、サーバにインストールす る場合もある アプリケーションがローカル データベースにア クセスする必要がある場合は、そのデータベー スを構成するファイルをコピーし、各ユーザの コンピュータにインストールする その場合は、適切なデータベース インタフェー スもインストールし、正しく設定しておく必要 がある 838 PowerBuilder 第 40 章 配布用アプリケーションのパッケージ化 チェックリスト項目 詳細 アクセスするほかのプロ アプリケーションが任意の外部プログラムにア グラムのインストール クセスする必要がある場合、各外部プログラム を、すべてのユーザのコンピュータかサーバに インストールする また、プログラムを正常に動作させるために必 要な設定も行う。たとえば、ActiveX コントロー ルの登録が必要な場合もある。詳細については、 846 ページの「ActiveX コントロールの配布」を 参照 アプリケーションに必要 アプリケーションが使用するさまざまなファイ なファイルを検索できる ルは、アプリケーションが検索できるパス上に ようにする インストールしておく必要がある • アプリケーションが特定のパスによってファ イルを参照する場合は、そのパス上にファイ ルをインストールする • アプリケーションが名前のみによってファイ ルを参照する場合は、現行のパスなど、アプ リケーションが検索できるパスにファイルを インストールする アプリケーションの値に Windows レジストリを利用して、アプリケー よる、システム レジスト ション パスなどアプリケーションで必要な情報 を管理する場合は、アプリケーションの値でレ リの更新 ジストリを更新する アプリケーションのアイ ユーザがアプリケーションを起動できるよう コンの設定 に、各ユーザのコンピュータのウィンドウ シス テムを使って、実行ファイルのアイコンを希望 の場所に表示する 代替方法として、ユーザはウィンドウ システム 下で、ネイティブ アプリケーションと同じその ほかの方法で、アプリケーションを起動するこ ともできる アプリケーション テクニック 839 エンド ユーザへのアプリケーションの配布 配布済みアプリケーションの起動 ユーザは、配布されたアプリケーションを、ほかの Windows アプリ ケーションと同じ方法で実行できます。たとえば、エクスプローラで 表示される実行ファイルをダブルクリックしたり、アプリケーション のショートカットをデスクトップに作成して、そのショートカット ア イコンをダブルクリックしたりできます。 ユーザがショートカットを作成する場合は、 [ショートカット]プロパ ティ ページの[リンク先]テキスト ボックスで実行ファイルへのパス が指定され、 [作業フォルダ]テキスト ボックスで Powersoft ランタイ ム DLL の場所が指定されている必要があります。 840 PowerBuilder 第 4 1 章 アプリケーションとコンポーネント の配布 この章について この章では、ユーザのコンピュータやサーバにアプリケーション とコンポーネントを配布する際に必要な情報について説明しま す。PowerBuilder ランタイム ファイルのパッケージ化に使用する ツールについて説明し、さまざまなターゲットに対して配布が必 要なファイルをリスト表示します。 これらのファイル リストは、新しいデータベース インタフェース が使用可能になったときなど、場合によっては更新する必要があ ります。これらの変更についての詳細は、PowerBuilder の使用し ているバージョンの『リリース ノート』を参照してください。 Web ターゲットの配布についての詳細は、 『Web ターゲットと JSP ターゲットでの作業』マニュアルを参照してください。 内容 アプリケーション テクニック 項目 アプリケーション、コンポーネント、およびサポート ファイ ルの配布 PowerBuilder ランタイム パッケージャ PowerBuilder ランタイム ファイル データベース接続 Java サポート PowerBuilder エクステンション PDF と XSL-FO のエクスポート データウィンドウ Web コントロール ActiveX プラグインと PowerBuilder ウィンドウ ActiveX コントロール EAServer 上の PowerBuilder コンポーネント PowerBuilder COM サーバ PowerBuilder オートメーション サーバ EAServer 上の Web データウィンドウ COM+ または IIS 上の Web データウィンドウ ページ 842 846 849 851 869 871 872 875 876 878 881 882 883 885 841 アプリケーション、コンポーネント、およびサポート ファイルの配布 アプリケーション、コンポーネント、およびサポート ファイルの配布 配布するアプリケーションの種類に関わらず、動的ライブラリ、BMP ファイルや ICO ファイルのようなリソース、オンライン ヘルプ ファ イル、初期設定ファイルなどの任意のサポート ファイルも一緒に配布 しておく必要があります。アプリケーションの種類によって、必要な サポート ファイルのセットが違います。 配布の計画 第 40 章「配布用アプリケーションのパッケージ化」には、動的ライブ ラリ、Pcode(中間コード)またはマシン コード、リソース ファイル の使い方など、PowerBuilder 実行アプリケーションを配布する際の決 定に役立つ情報が含まれています。また、必要な要素がすべてインス トールされているか確認するためのチェックリストも用意されていま す。 Web アプリケーションまたはトランザクション サーバのコンポーネ ントを配布する場合には、上記章の中の PowerBuilder 動的ライブラリ (PBD)および PowerBuilder リソース ファイル(PBR)についての情報 を参照してください。また、このマニュアルまたは『データウィンド ウ プログラマーズ ガイド』マニュアルのコンポーネントやプラグイン に関する記述も参考にしてください。 842 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 表 41-1: コンポーネントとプラグインに関連する記述 アプリケーションの種類 EAServer コンポーネント 参照先 556 ページの「EAServer へのコンポーネ ントの配布」 COM コンポーネント 634 ページの「PowerBuilder COM サーバ の配布」 データウィンドウ プラグイン ア 第 33 章「データウィンドウ プラグイン プリケーション の使い方」 PowerBuilder ウィンドウ プラグ 第 32 章「PowerBuilder ウィンドウ プラ イン グインの使い方」 PowerBuilder ウィンドウ ActiveX 第 34 章「PowerBuilder ウィンドウ ActiveX の使い方」 Web データウィンドウおよび 『データウィンドウ プログラマーズ ガイ データウィンドウ Web コント ド』マニュアル ロール ActiveX この章での情報の見つ け方 この章は、インストール環境を作成するサードパーティのソフトウェ ア パッケージによるインストール プログラムのプログラミングを支 援する目的で作成されています。ここでは、各コンピュータに必要な ファイル、そのファイルの保存場所、インストール先、作成しなけれ ばならないレジストリ設定を説明します。また、PowerBuilder には、ア プリケーションに必要なファイルのパッケージ化に役立つツールが用意 されています。 このツールについての詳細は、 846 ページの「PowerBuilder ランタイム パッケージャ」を参照してください。 アプリケーションと一緒に配布するファイルの情報を参照するには、 表 41-2 を参考にしてください。 アプリケーション テクニック 843 アプリケーション、コンポーネント、およびサポート ファイルの配布 表 41-2: 配布に必要な PowerBuilder ファイル シナリオ すべての PowerBuilder クライア ント アプリケーション データベース サーバ上のデータ にアクセスする PowerBuilder ク ライアント アプリケーション EJB、SOAP Web サービス、お よび XML サービス用 PowerBuilder クライアント PDF または XSL-FO 形式でデー タを保存する PowerBuilder クラ イアント データウィンドウ Web コント ロール ActiveX を使用する Web アプリケーション PowerBuilder プラグインまたは ウィンドウ ActiveX を使用する Web アプリケーション PowerBuilder 内に作成される EAServer コンポーネント PowerBuilder 内に作成される COM コンポーネント EAServer と Web データウィンド ウを使用する Web アプリケー ション 参照節 849 ページの「PowerBuilder ランタイム ファイル」 851 ページの「データベース接続」 871 ページの「PowerBuilder エクステン ション」 872 ページの「PDF と XSL-FO のエクス ポート」 875 ページの「データウィンドウ Web コ ントロール ActiveX」 876 ページの「プラグインと PowerBuilder ウィンドウ ActiveX コント ロール」 878 ページの「EAServer 上の PowerBuilder コンポーネント」 881 ページの「PowerBuilder COM サー バ」 883 ページの「トランザクション サーバ に必要なファイル」 884 ページの「動的ページ サーバに必要 なファイル」 ASP および COM+ または IIS と、 885 ページの「COM+ または IIS サーバ Web データウィンドウを使用す で必要なファイル」 る Web アプリケーション 886 ページの「ASP サーバに必要なファ イル」 インストール先パスと 配布先パス この章で、いくつかの表の後に記載されているインストール先パスは、 デフォルトのインストール先を選択して PowerBuilder をインストール したときに、ファイルがインストールされる場所を示しています。ア プリケーションのインストール プログラムを作成する場合は、この場 所から目的とする場所にファイルをコピーできます。 配布先パスは、作成したアプリケーションまたはコンポーネントをイ ンストールする際に、コンピュータ上でこれらのファイルをインス トールすることができる場所を示しています。 844 PowerBuilder 第 41 章 App Path レジストリ キー アプリケーションとコンポーネントの配布 表によっては、レジストリ エントリのリストが後ろに記載されていま す。このレジストリ エントリは、アプリケーションまたはコンポーネ ントが必要なファイルを見つけられるように、インストール プログラ ムを使用して作成する必要があります。Windows 上で実行されるとき、 アプリケーションは、以下の場所で以下の順序に従ってサポート ファ イルを探します。 1 実行ファイルがインストールされているディレクトリ 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 という新しい文字列値を作成します。以下の例は、Adaptive Server 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\sybase\ SQL Anywhere 8\win32\;" アプリケーション テクニック 845 PowerBuilder ランタイム パッケージャ REG ファイルについて .REG 拡張子を持つレジストリ更新ファイルを使用すると、情報をレジ ストリにインポートできます。この章のレジストリ キーの例で使用し ている形式は、レジストリ更新ファイルの形式とよく似ていますが、 これらの例は更新ファイルとしての使用を意図したものではありませ ん。レジストリ更新ファイルのデータ値文字列のパス名には、一般に、 円記号が 1 つではなく 2 つ組み合わされて使用され、デフォルトの文 字列値はアット マーク(@)で表されます。 例を参考にして、インストール プログラムで追加または更新するレジ ストリ キーを決定してください。 ActiveX コントロール の配布 アプリケーションが ActiveX コントロール、OLE コントロール、また は OCX コントロールを使用する場合には、以下の作業が必要です。 • アプリケーションと一緒にコントロール ファイルを配布する • 各コントロールを登録しておく • 必要なファイルをターゲット コンピュータのシステム ディレク トリに配置しておく 自己登録を行わないコントロールを使用するアプリケーションの場合 は、セットアップ プログラムによって各ユーザのコンピュータに手動 で登録する必要があります。自己登録を行うコントロールかどうかを 調べるには、コントロールに付属のマニュアルを参照してください。 開発プラットフォーム、配布プラットフォーム、および配布するコン トロールの種類によっては、配布先となるコンピュータの WINDOWS システム ディレクトリに、追加の DLL ファイルまたはライセンス ファイルをコピーする必要がある場合もあります。 PowerBuilder ランタイム パッケージャ PowerBuilder ランタイム パッケージャは、アプリケーションが実行時 に 必要な PowerBuilder フ ァイル を Microsoft Windows イン ストー ラ (MSI)パッケージ ファイルにパッケージ化するツールです。Windows インストーラは、最新の Microsoft Windows オペレーティング システ ムとともにインストールされる、インストールおよび環境設定サービ スです。 846 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 ランタイム パッケージャを正常に実行するには、システム上に Microsoft Windows インストーラが必要です。Microsoft では、Windows 2000 上で インストールおよびアップグレードを行うために再配布可能なパッ ケージを提供しています。インストーラは、Windows XP と Windows 2003 で常に使用できます。 最新版 Windows インストーラの詳細および入手方法については、 MSDN Library の Windows Installer のサイト http://msdn.microsoft.com/library/default.asp?url=/library/enus/msi/setup/windows_installer_start_page.asp を参照してください。 ランタイム パッケージャは、Windows システムにインストールされた クライアント アプリケーションで使用するためのものです。ランタイ ム パッケージャは、アプリケーションがデータを PDF 形式でエクス ポートする場合に必要なファイルや、アプリケーションが データウィ ンドウ Web コントロール ActiveX またはプラグインを使用する場合に 必要なファイルをパッケージ化しません。ランタイム パッケージャを 使用する際には、事前に 844 ページの表 41-2 内の該当する節を参照し てください。 ❖ PowerBuilder ランタイム パッケージャを使用するには 1 Windows の[スタート]メニューから[プログラム| Sybase | PowerBuilder 10.0 | PowerBuilder ランタイム パッケージャ]を選 択するか、Shared\PowerBuilder ディレクトリの pbpack100 実行ファ イルを起動します。 2 生成された MSI ファイルの保存場所を選択します。 3 アプリケーションに必要なデータベース インタフェースを選択し ます。 アプリケーション テクニック 847 PowerBuilder ランタイム パッケージャ 選 択 し た デ ー タ ベ ー ス の DLL が パ ッ ケ ー ジ に 追 加 さ れ ま す。 ODBC の場合、pbodb100.ini ファイルも追加されます。JDBC の場 合、pbjdbc12100.jar と pbjvm100.dll ファイルも追加されます。Java Runtime Environment(JRE)は追加されません。詳細については、 868 ページの「JDBC データベース インタフェース」を参照してく ださい。 DataDirect ドライバなど、そのほかの ODBC または OLE DB ファ イルをアプリケーションが必要とする場合がありますが、これら のファイルは追加されません。これらのファイルの配布方法につ いての詳細は、853 ページの「ODBC データベース ドライバとサ ポート ファイル」および 865 ページの「OLE DB データベース プ ロバイダ」を参照してください。 4 アプリケーションが DataWindow XML エクスポートまたはイン ポートを使用する場合、 [XML サポート]チェックボックスをオ ンにします。 ランタイム パッケージャは、PBXerces100.DLL、xerces-c_2_6.dll、 および xerces-depdom_2_6.dll をパッケージに追加します。 5 アプリケーションが、PowerBuilder Document Object Model が提供 する XML サービスを使用する場合や、アプリケーションが EJB ま たは SOAP クライアント(Web サービス)である場合は、それに 該当するチェックボックスをオンにします。 ランタイム パッケージャは、必要な DLL ファイルおよび JAR ファ イルをパッケージに追加します。PowerBuilder エクステンションに 必要なファイル情報については、871 ページの「PowerBuilder エク ステンション」を参照してください。 6 [生成]をクリックします。 ランタイム パッケージャは、選択したコンポーネントに必要な ファイルと、以下の PowerBuilder ランタイム DLL を格納した MSI ファイルを作成します。 libjcc.dll libjlog.dll pbacc100.dll pbdwe100.dll pbdwr100.dll pbdwr100.pbd pbjag100.dll pbjvm100.dll pbrtc100.dll pbshr100.dll 848 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 pbtra100.dll pbvm100.dll MSI ファイルは、あらゆる Windows プラットフォーム上で直接実 行可能な圧縮ファイルです。MSI ファイルは、自己登録 DLL を登 録し、Windows レジストリにインストール先のパスを追加し、シ ステムの PATH 環境変数を設定し、さらに、Windows のコントロー ル パネルの[アプリケーションの追加と削除]ページに情報を追 加します。また、サードパーティのインストール ソフトウェア パッケージの中には MSI ファイルを使用できるものもあります。 PowerBuilder ランタイム ファイル データベースの接続 データベースの接続に必要なファイルについては、851 ページの「デー タベース接続」に個別に一覧表示されています。 主なランタイム ファ イル 表 41-3 は、PowerBuilder の主なランタイム ファイルです。 表 41-3: 主な PowerBuilder ランタイム ファイル 名前 PBVM100.DLL PBSHR100.DLL LIBJCC.DLL LIBJLOG.DLL PBDWE100.DLL Microsoft ファイル 必要とする対象 すべて すべて。PBVM100.DLL は、このファイルへの依存性 を持つ すべて。PBVM100.DLL は、このファイルへの依存性 を持つ すべて。LIBJCC.DLL は、このファイルへの依存性を 持つ データウィンドウおよびデータストア 基本的な PowerBuilder ランタイム ファイルを配布する際に、ユーザの マ シ ン に msvcr71.dll と msvcp71.dll Microsoft Visual C++ ラ ン タ イ ム ファイルが存在しない場合には、これらのファイルも配布する必要が あります。PowerBuilder ランタイム ファイルは、実行時はこれらのファ イルに依存します。 アプリケーション テクニック 849 PowerBuilder ランタイム ファイル Microsoft Windows GDI+ は、スクリーンおよびプリンタ用の拡張グラ フィック機能を実装する Windows XP オペレーティング システムや Windows Server 2003 のサブシステムです。PowerBuilder ランタイム ファイルは、実行時はこれらのファイルに依存します。Windows 2000 プラットフォームに PowerBuilder アプリケーションを配布する場合 は、対象のコンピュータで gdiplus.dll が利用できることを確認する必 要があります。 Microsoft .NET Active Template Library (ATL) モジュール atl71.dll は、Ink コントロールをサポートするために PowerBuilder 10.2 にインクルード されます。アプリケーションが Ink コントロールを使用する場合は、対 象のコンピュータで atl71.dll が利用できることを確認する必要があり ます。 これらの Microsoft ファイルの入手と配布については、最新の PowerBuilder release bulletin のサイト http://sybooks.sybase.com/pb.html を参 照してください。 ほかのランタイム ファイル 表 41-4 に、アプリケーションがさらに必要とする可能性があるランタ イム ファイルを示します。たとえば、PBVM100.DLL はすべての配布 アプリケーションに必要ですが、PBRTC100.DLL は、リッチテキスト コントロールまたはリッチテキスト データウィンドウ オブジェクト を使用するアプリケーションでのみ必要になります。 Java サポート対応の PBJVM100.DLL を使用する配布アプリケーショ ンについての詳細は、869 ページの「Java サポート」を参照してくだ さい。 表 41-4: 追加の PowerBuilder ランタイム ファイル 名前 PBACC100.DLL PBDWR100.DLL PBDWR100.PBD PBXerces100.DLL xerces-c_2_6.dll xerces-depdom_2_6.dll 必要とする対象 アクセシビリティのサポート(第 508 条) Web データウィンドウのサポート PBJVM100.DLL PBRTC100.DLL PBLAB100.INI Java サポート リッチテキストのサポート データウィンドウのラベル提示様式の定義済み フォーマット PBTRA100.DLL PBTRS100.DLL データベース接続のトレース データウィンドウとデータストアの XML サポー ト インストール先パス \Program Files\Sybase\Shared\PowerBuilder 850 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 配布先パス アプリケーションと同じパス、 システム パスのディレクト リ、または App Path レジストリ キー レジストリ エントリ 845 ページの「App Path レジストリ キー」を参照 してください。 データベース接続 データベースにアクセスする実行ファイルまたはコンポーネントを配 布する場合、ユーザは DBMS およびアプリケーションが使用するデー タベースにアクセスする必要があります。 データベース接続ファイルのインストール先 別のコンピュータの中間層コンポーネントを使用してデータベース トランザクションを実行するクライアント アプリケーションでは、 データベース接続ファイルを配布する必要はありません。データベー ス接続ファイルは、データベース サーバと対話するコンピュータに配 布しなければなりません。 以下の作業を行う必要があります。 • 必要であれば、DBMS ランタイム(クライアント)ファイルを、ア プリケーション ディレクトリかシステム パス上のディレクトリ にインストールする スタンドアロンの Adaptive Server Anywhere データベースを使用す るアプリケーションの場合には、ユーザのコンピュータに Adaptive Server Anywhere ランタイム エディション ファイルをインストー ル で き ま す。詳 細 に つ い て は、861 ペ ー ジ の「Adaptive Server Anywhere ファイル」を参照してください。それ以外の場合は、ベ ンダによって明示された指示およびライセンス規約に従ってくだ さい。 • アプリケーションが使用するデータベースに各ユーザがアクセス できるようにしておく アプリケーションがローカル データベースを使用する場合は、 データベースとログ ファイルなどの関連ファイルをユーザのコン ピュータにインストールします。 アプリケーション テクニック 851 データベース接続 アプリケーションがデータベース サーバを使用する場合は、ユー ザのコンピュータからアクセスできるようにセットアップしてお きます。この作業は、データベース管理者が行います。 • ユーザのコンピュータ上でアプリケーションが使用するデータ ベース インタフェースをインストールする • アプリケーションが ODBC インタフェースを使用する場合は、864 ページの「ODBC データ ソースとドライバの環境設定」の説明に 従って、ODBC データベース ドライバとデータ ソースを設定する データベース ドライバとインタフェースの詳細については、以下を参 照してください。 • 次の「ネイティブ データベース ドライバ」 • 853 ページの「ODBC データベース ドライバとサポート ファイル」 • 865 ページの「OLE DB データベース プロバイダ」 • 868 ページの「JDBC データベース インタフェース」 ネイティブ データベース ドライバ 表 41-5 は、PowerBuilder で提供されるネイティブ データベース ドライ バのリストを示します。アプリケーションまたはコンポーネントが、 指定のデータベースを使用する場合、コンピュータ上にそのファイル が必要です。ネイティブ データベース ファイル名の最初の 2 つの文字 は PB であり、次の 3 つの文字でデータベースを識別し、最後の 2 つ の文字で PowerBuilder のバージョンを識別します。 表 41-5: PowerBuilder ネイティブ データベース ドライバ 名前 PBIN9100.DLL PBO84100.DLL PBO90100.DLL PBO10100.DLL PBSYC100.DLL PBSYJ100.DLL 必要とする対象 INFORMIX I-Net 9 Oracle 8.0.x と Oracle8i 8.1.x Oracle9i Oracle 10g Sybase Adaptive Server Enterprise CT-LIB Sybase Adaptive Server Enterprise CT-LIB(EAServer 配布 の場合のみ) インストール先パス \Program Files\Sybase\Shared\PowerBuilder アプリケーションと同じパス、システム パスのディレクト リ、または App Path レジストリ キー 配布先パス 852 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 レジストリ エントリ 845 ページの「App Path レジストリ キー」を参照 してください。 注意 PowerBuilder カスタム クラス ユーザ オブジェクトを EAServer に配布するときは、SYC ではなく SYJ データベース インタフェースを 使用して Adaptive Server Enterprise データベースに接続する必要があり ます。PowerBuilder の開発環境で SYJ を使用することはできませんが、 SYJ DB プロファイル設定 ダイアログボックスを使用して、該当する 接続パラメータを設定することができます。その後、 [プレビュー]タ ブからトランザクション オブジェクトのスクリプトに構文をコピー できます。 ODBC データベース ドライバとサポート ファイル この節では、PowerBuilder アプリケーションまたは InfoMaker アプリ ケーションからのすべての ODBC データベース接続に必要なファイル と、特定のデータベース インタフェースまたは DBMS に必要なファイ ルを一覧します。 PowerBuilder ODBC インタフェース ファ イル アプリケーションが ODBC を使用する場合は、以下の PowerBuilder ODBC インタフェース ファイルが必要です。 表 41-6: PowerBuilder ODBC インタフェース ファイル 名前 PBODB100.DLL PBODB100.INI インストール先パス 説明 PowerBuilder ODBC インタフェース PowerBuilder ODBC 初期設定ファイル \Program Files\Sybase\Shared\PowerBuilder 配布先パス アプリケーションと同じパス、 システム パスのディレクト リ、または App Path レジストリ キー レジストリ エントリ 845 ページの「App Path レジストリ キー」を参照 してください。 INI ファイルと DLL ファイルは、同じディレクトリにあること が必要です。PBODB100 初期設定ファイルを修正した場合には、修正 したバージョンを配布してください。 注意 Microsoft ODBC ファ イル 表 41-7 に、アプリケーションが ODBC を使用する場合に必要な Microsoft ODBC ファイルを一覧します。 アプリケーション テクニック 853 データベース接続 表 41-7: 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 システム ディレクト リにインストールされています。必要であれば、CD の Support ディレ クトリに入っている再配布可能な MDAC_TYP.EXE セットアップ ファ イルを使用して、ユーザのシステムを更新することができます。 注意 PB DataDirect ODBC ドライバとサポート ファイル 指定されたデータベース インタフェースを使用する場合は、表 41-8 の PowerBuilder DataDirect ODBC ファイルが必要です。表には、各データ ベース インタフェースに対して必要なレジストリ エントリを示しま す。文字列値の %SHARED% は、ドライバをインストールしたディレ クトリのパスに置き換えられます。 オプションのヘルプ ファイル ヘルプ ファイルは、ユーザがデータベース管理作業を行う場合のみ、 配布する必要があります。ヘルプ ファイルは HTML 形式であり、 DataDirect ディレクトリの Help サブディレクトリにインストールされ ます。各ドライバのヘルプ ファイル名は、R で始まり、データベース インタフェースの名前を含みます。たとえば、Adaptive Server のヘル プ ファイルには、Rase.html、Rase2.html などの名前が付きます。 854 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 表 41-8: PowerBuilder DataDirect ODBC ファイル 名前 IVPB.LIC PBBAS19*.DLL PBUTL19*.DLL PBTRN19.dll ドライバとレジストリ エントリ すべての PB DataDirect OEM 4.2 ドライバ。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Translators] "OEM to ANSI"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\OEM to ANSI] "Translator"="%SHARED%\\DataDirectODBC\\PBtrn19.dll" "Setup"="%SHARED%\\DataDirectODBC\\PBtrn19.dll" PBBTR19.DLL PBBTR19R.DLL PBBTR19S.DLL PBFLT19.DLL PBFLT19R.DLL PB DataDirect OEM 4.2 Btrieve。レジストリ エントリ : *.UCT PBDB219.DLL PBDB219R.DLL PBDB219S.DLL APPC19IV.DLL BIND19IV.DLL CLRT19IV.DLL COSI19IV.DLL DRDA19IV.DLL LIBUNIC.DLL MEMR19IV.DLL PROT19IV.DLL SOCK19IV.DLL XCPG19IV.DLL XDB2DB2.ERR XDBDRDA.ERR XDBMF.ERR XDBNET.ERR XDBRES.ERR PB DataDirect OEM 4.2 DB2 Wire Protocol。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 Btrieve (*.dta)"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 Btrieve (*.dta)] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBBTR19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBBTR19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="1" "FileExtns"="*.dta" "SQLLevel"="0" "CPTimeout"="60" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 DB2 Wire Protocol"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 DB2 Wire Protocol] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBDB219.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBDB219S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" アプリケーション テクニック 855 データベース接続 名前 PBDBF19.DLL PBDBF19R.DLL PBFLT19.DLL PBFLT19R.DLL ドライバとレジストリ エントリ PB DataDirect OEM 4.2 dBASE。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 dBASEFile (*.dbf)"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 dBASEFile (*.dbf)] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBDBF19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBDBF19.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="1" "FileExtns"="*.dbf" "SQLLevel"="0" "CPTimeout"="60" PBXLWB19.DLL PBXLWB19R.DLL PBFLT19.DLL PBFLT19R.DLL PB DataDirect OEM 4.2 Excel Workbook。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 ExcelWorkbook (*.xls)"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 ExcelWorkbook (*.xls)] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBXLWB19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBXLWB19.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="2" "FileExtns"="*.xls" "SQLLevel"="0" "CPTimeout"="60" 856 PowerBuilder 第 41 章 名前 PBINF19.DLL PBINF19R.DLL PBINF19S.DLL PBINFDTC19.DLL アプリケーションとコンポーネントの配布 ドライバとレジストリ エントリ PB DataDirect OEM 4.2 Informix。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 INFORMIX"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 INFORMIX] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBINF19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBINF19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" PBIFCL19.DLL PBIFCL19R.DLL PBIFCL19S.DLL PB DataDirect OEM 4.2 Informix Wire Protocol。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 INFORMIX Wire Protocol"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 INFORMIX Wire Protocol] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBIFCL19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBIFCL19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" PBOR819.DLL PBOR819R.DLL PBOR819S.DLL PBOR8DTC19.DLL PB DataDirect OEM 4.2 Oracle。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 Oracle"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 Oracle] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBOR819.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBOR819S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" アプリケーション テクニック 857 データベース接続 名前 PBORA19.DLL PBORA19R.DLL PBORA19S.DLL ドライバとレジストリ エントリ PB DataDirect OEM 4.2 Oracle Wire Protocol。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 Oracle Wire Protocol"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 Oracle Wire Protocol] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBORA19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBORA19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" PBIDP19.DLL PBIDP19R.DLL PBIDP19S.DLL PBFLT19.DLL PBFLT19R.DLL 858 PB DataDirect OEM 4.2 Paradox。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 ParadoxFile (*.db)"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 ParadoxFile (*.db)] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBIDP19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBIDP19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="1" "FileExtns"="*.db" "SQLLevel"="0" "CPTimeout"="60" PowerBuilder 第 41 章 名前 PBPRO919.DLL PBPRO919R.DLL PBPRO919S.DLL アプリケーションとコンポーネントの配布 ドライバとレジストリ エントリ PB DataDirect OEM 4.2 Progress 9。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 PROGRESS 9"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 PROGRESS 9] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBPRO919.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBPRO919S.DLL" "APILevel"="1" "ConnectFunctions"="YYN" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="0" "CPTimeout"="60" PBGUP19.DLL PBGUP19R.DLL PBGUP19S.DLL PB DataDirect OEM 4.2 SQLBase。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 SQLBase"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 SQLBase] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBGUP19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBGUP19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" PBSS619.DLL PBSS619R.DLL PBSS619S.DLL PB DataDirect OEM 4.2 SQL Server 6.5。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 SQL Server 6.5"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 SQL Server 6.5] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBSS619.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBSS619S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" アプリケーション テクニック 859 データベース接続 名前 PBMSSS19.DLL PBMSSS19R.DLL PBMSSS19S.DLL DBNETLIB.DLL SQLSRV32.DLL SQLSRV32.RLL SQLUNIRL.DLL ドライバとレジストリ エントリ PBASE19.DLL PBASE19R.DLL PBASE19S.DLL PBASE19.HLP PBASE19.CNT PB DataDirect OEM 4.2 Sybase Adaptive Server Enterprise Wire Protocol。レジストリ エントリ : PB DataDirect OEM 4.2 SQL Server Wire Protocol。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 SQL Server Wire Protocol"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 SQL Server Wire Protocol] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBMSSS19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBMSSS19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="1" "CPTimeout"="60" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 Sybase ASE Wire Protocol" = "Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 Sybase ASE Wire Protocol] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBASE19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBASE19S.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="0" "SQLLevel"="0" "UsageCount"="1" "CPTimeout"="60" 860 PowerBuilder 第 41 章 名前 PBTXT19.DLL PBTXT19R.DLL PBFLT19.DLL PBFLT19R.DLL アプリケーションとコンポーネントの配布 ドライバとレジストリ エントリ PB DataDirect OEM 4.2 Text File。レジストリ エントリ : [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers] "PB DataDirect OEM 4.2 TextFile (*.*)"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\PB DataDirect OEM 4.2 TextFile (*.*)] "UsageCount"="1" "Driver"="%SHARED%\\DataDirectODBC\\PBTXT19.DLL" "Setup"="%SHARED%\\DataDirectODBC\\PBTXT19.DLL" "APILevel"="1" "ConnectFunctions"="YYY" "DriverODBCVer"="3.51" "FileUsage"="1" "FileExtns"="*.*" "SQLLevel"="0" "CPTimeout"="60" インストール先パス \Program Files\Sybase\Shared\PowerBuilder 配布先パス アプリケーションと同じパス、 システム パスのディレクト リ、または App Path レジストリ キー レジストリ エントリ 上記表、845 ページの「App Path レジストリ キー」 および 864 ページの「ODBC データ ソースとドライバの環境設定」を 参照してください。 Adaptive Server Anywhere ファイル Adaptive Server Anywhere データベースを使用する PowerBuilder アプリ ケーションの場合には、Adaptive Server Anywhere の ODBC データベー ス ドライバだけでなく、Adaptive Server Anywhere DBMS も配布する必 要があります。スタンドアロンのデータベースを使用する場合は、ユー ザのコンピュータに Adaptive Server Anywhere デスクトップ ランタイ ム システムを配布することができます。この場合、追加のライセンス 料金はかかりません。ランタイム システムを使うことによって、ユー ザはデータベース内のデータの取り出しや変更を行えますが、データ ベース スキーマは変更できません。また、トランザクション ログ、ス トアド プロシージャ、およびトリガはサポートしていません。 アプリケーション テクニック 861 データベース接続 制約 PowerBuilder には、開発プロセスで使用する Adaptive Server Anywhere が含まれています。ただし、この製品を特許権使用料なしでユーザに 配布することはできません。 データ定義言語(DDL)、トランザクション ログ、ストアド プロシー ジャ、またはトリガがアプリケーションに必要な場合は、サイベース 社におたずねください。 Adaptive Server Anywhere データベースおよびアプリケーションの配布 の詳細については、 『Adaptive Server Anywhere SQL User's Guide』マニュ アルを参照してください。 フル インストール用の、Adaptive Server Anywhere ドライバ、ランタイ ム エンジン、およびサポート ファイルは、インストール ディスクの Support ディレクトリに入っています。表 41-9 に、インストール プロ グラムで[Runtime Server]を選択したときにインストールされるファ イルを示します。また、ヘルプ ファイル、SQL Anywhere 5.0/6.0 互換 性 DLL、および Installshield テンプレートをインストールすることもで きます。 862 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 表 41-9: Adaptive Server Anywhere ファイル 名前 DBODBC9.DLL DBBACKUP.EXE DBCON9.DLL DBISQLC.EXE DBLGEN9.DLL DBLIB9.DLL DBODTR9.DLL DBTOOL9.DLL DBUNLOAD.EXE DBVALID.EXE RTENG9.EXE DBCTRS9.DLL DBSERV9.DLL インストール先パス 説明 ASA ODBC ドライバ ASA バックアップ ユーティリティ 接続 ダイアログボックス。開発者が独自のダイアログ を提供せず、エンド ユーザが独自のデータ ソースを作 成する場合、またはデータベースに接続するときに ユーザ ID とパスワードの入力が必要な場合、あるいは そのほかの目的で接続 ダイアログを表示する必要があ る場合に必要 対話型 SQL ユーティリティ 言語固有の文字列ライブラリ(EN は英語版を示す) インタフェース ライブラリ ODBC トランスレータ。アプリケーションが OEM か ら ANSI 文字セットへの変換を使用する場合に必要 ASA データベース ツール ASA アンロード ユーティリティ ASA 検証ユーティリティ 制限つきのランタイム エンジン パフォーマンス ユーティリティ サーバ ユーティリティ \Program Files\Sybase\SQL Anywhere 9\win32 配布先パス アプリケーションと同じパス、 システム パスのディレクト リ、または App Path レジストリ キー レジストリ エントリ 845 ページの「App Path レジストリ キー」および 次の「ODBC データ ソースとドライバの環境設定」を参照してくださ い。 注意 サポート ファイルは、DBODBC9.DLL と同じディレクトリにイ ンストールしなければなりません。英語版の文字列ライブラリを使用 しない場合は、使用言語固有の文字列ライブラリの該当するバージョ ンを配布しておく必要があります。 アプリケーション テクニック 863 データベース接続 ODBC データ ソース とドライバの環境設定 ODBC.INI ユーザが特定のデータ ソースに接続できるようにするには、 インストール プログラムによって、データ ソースにアクセスするコン ピュータのレジストリにある ODBC.INI キーに、そのデータ ソースの 定義を提供する必要があります。ユーザ DSN の場合は HKEY_CURRENT_USER 、システム DSN の場合は HKEY_LOCAL_MACHINE になります。データ ソース定義では、デー タベース ドライバの名前と保存場所だけでなく、データベース エンジ ンの起動に必要なコマンドも指定します。ODBC Data Sources キーの データ ソースも、ODBC.INI に一覧表示する必要があります。 以下の例では、Adaptive Server Anywhere を使用する MyApp DB という データ ソースの一般的なレジストリ エントリを示します。レジストリ キーは大カッコで囲まれ、後ろに " 名前 "=" 値 " の形式でキーの文字列 値が記述されています。 [HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI\MyApp DB] "Driver"="C:\Program Files\Sybase\SQL Anywhere 9\ win32\dbodbc9.dll" "Start"="c:\program files\sybase\SQL Anywhere 9\win32\ rteng9.exe -c9m" "UID"="dba" "PWD"="sql" "Description"="Database for my application" "DatabaseFile"="C:\Program Files\myapps\myapp.db" "AutoStop"="Yes" [HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI\ ODBC Data Sources] "MyApp DB"="Adaptive Server Anywhere 9.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 キーに追加する必要があります。 864 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 ベンダから提供された ODBC ドライバを使用している場合は、ドライ バのセットアップ プログラムを使用して、ドライバをインストールし てレジストリ エントリを作成することができます。 以下の例は、Adaptive Server Anywhere の一般的なレジストリ エントリ を示します。レジストリ キーは大カッコで囲まれ、後ろに " 名前 "=" 値 " の形式でキーの文字列値が記述されています。 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\ CurrentVersion\App Paths\myapp.exe] "Default"="C:\Program Files\myapps\MYAPP.EXE" "Path"="Program Files\sybase\shared\PowerBuilder; c:\program files\sybase\SQL Anywhere 9\win32\; c:\program files\sybase\shared\DataDirectODBC;" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ ODBC Drivers] "Adaptive Server Anywhere 9.0"="Installed" "PB DataDirect OEM 3.60 32-BIT Sybase"="Installed" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ Adaptive Server Anywhere 9.0] "Driver"="c:\program files\sybase\SQL Anywhere 9\ win32\dbodbc9.dll" "Setup"="c:\program files\sybase\SQL Anywhere 9\ win32\dbodbc9.dll" ODBC ドライバとデータ ソースのレジストリ エントリの内容につい ての詳細は、 『データベースとの接続』マニュアルを参照してください。 OLE DB データベース プロバイダ OLE DB を使用してデータにアクセスするアプリケーションの場合、 各ユーザのコンピュータに Microsoft の Data Access Components ソフト ウェアがインストールされていない場合はインストールしなければな りません。 必要であれば、CD の Support ディレクトリに入っている MDAC_TYP.EXE セットアップ ファイルを使用して、ユーザのシステ ムを更新することができます。MDAC_TYP.EXE を実行すると、 Microsoft OLE DB プロバイダ、SQLOLEDB、および MSDASQL がイ ンストールされます。 アプリケーション テクニック 865 データベース接続 指定された PB DataDirect OLE DB データ プロバイダを使用する場合 は、表 41-10 のファイルが必要です。別のベンダから提供される OLE DB プロバイダを使用するアプリケーションの場合は、ベンダが指定す るファイルのほかに PBOLE100.DLL を配布する必要があります。 オプションのヘルプ ファイル ヘルプ(.HLP および .CNT)ファイルは、ユーザがデータベース管理 作業を行う場合のみ、配布する必要があります。 表 41-10: PowerBuilder DataDirect OLE DB ファイル 名前 PBOLE100.DLL 必要とする対象 すべての OLE DB 接続に必要な PowerBuilder OLE DB インタフェース 401COMUPD.EXE IVODBC.LIC PBADMIN.CNT PBADMIN.EXE PBADMIN.HLP PBADMINR.DLL PBINF09.CNT PBINF09.DLL PBINF09.HLP PBINF09R.DLL PBOR709.CNT PBOR709.DLL PBOR709.HLP PBOR709R.DLL PBOR809.CNT PBOR809.DLL PBOR809.HLP PBOR809R.DLL PBSYB09.CNT PBSYB09.DLL PBSYB09.HLP PBSYB09R.DLL PBXML09.CNT PBXML09.DLL PBXML09.HLP PBXML09R.DLL すべての PB DataDirect OEM 2.70 OLE DB データ プロ バイダに必要なライセンス ファイルとヘルプ ファイ ル、および管理ユーティリティ PB DataDirect OEM 2.70 9.x PB DataDirect OEM 2.70 Oracle 7 PB DataDirect OEM 2.70 Oracle 8 PB DataDirect OEM 2.70 Sybase Adaptive Server Enterprise PB DataDirect OEM 2.70 XML インストール先パス Program Files\Sybase\Shared\DataDirect 866 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 配布先パス アプリケーションと同じパス、 システム パスのディレクト リ、または App Path レジストリ キー レジストリ エントリ PBADMINR.DLL、PBINF90R.DLL、 PBOR709R.DLL、PBOR890R.DLL、PBSYB09R.DLL、および PBXML09R.DLL を共有 DLL として登録します。845 ページの「App Path レジストリ キー」も参照してください。 ADO.NET データベース インタフェース PowerBuilder ADO.NET インタフェースは、OLE DB と Microsoft SQL Server .NET データ プロバイダをサポートしています。ADO.NET を使 用する場合は、PBADO100.DLL、PBDATA100.DLL、および OLE DB データ プロバイダを配布しなければなりません。 PBADO100.DLL ファイルは標準 DLL ファイルであり、他の PowerBuilder DLL と同じ方法で配布することができます。しかし、 PBDATA100.DLL は、.NET アセンブリです。このファイルを配布する ためには、以下の 3 つの方法のうち 1 つを使用します。 • ADO.NET ドライバを呼び出す実行ファイルと同じディレクトリ に、PBDATA100.DLL ファイルを配布する • PBDATA100.DLL のパスを割り当てるために、.NET アプリケー ションの構成ファイルを使用する。そのファイルは、アプリケー ションが読みこむ環境設定と共通言語ランライム(CLR)が読み 込む環境設定を含む。実行ファイルの場合、構成ファイル名は実 行ファイルと同じ名前に、拡張子に .config をつけたものである。 見本の pb100.exe.config ファイルが PowerBuilder 10.0 ディレクトリ にある 構成ファイルの詳細については、.NET Framework 開発者ガイド のサ イト http://www.microsoft.com/Japan/msdn/library/default.asp?url=/library/japan/ msdn/library/ja/cpguide/html/cpconApplicationConfigurationFiles.asp の中 の、アプリケーション構成ファイルに関する資料を参照してくだ さい。 • アプリケーション テクニック グローバル アセンブリ キャッシュ(GAC:Global Assembly Cache ) に PBDATA100.DLL アセンブリを追加する。この方法は、アセン ブリを複数のアプリケーションで共有する場合にのみ使用するこ と。アセンブリの 1 つが GAC を使用している場合、xcopy を使用 してアプリケーションをインストールすることはできません。 867 データベース接続 GAC の 詳 細 に つ い て は、.NET Framework 開発 者ガ イド のサ イト http://www.microsoft.com/Japan/msdn/library/default.asp?url=/library/japan/ msdn/library/ja/cpguide/html/cpconGlobalAssemblyCache.asp. の中の、グ ローバル アセンブリ キャッシュに関する資料を参照してくださ い。 JDBC データベース インタフェース PowerBuilder JDB イ ン タ フ ェ ー ス は、Sun Java Runtime Environment (JRE)バージョン 1.2 以降をサポートしています。 アプリケーションまたはコンポーネントが JDBC 接続を使用する場合 は、使用する Java VM に対応する Java パッケージだけでなく、JDB ド ラ イ バ を 配 布 し な け れ ば な り ま せ ん。Java 仮 想 マ シ ン と、Sybase jConnect® for JDBC などベンダ提供の JDBC 準拠ドライバも、データ ソースにアクセスするコンピュータ上にインストールして設定する必 要があります。 ドライバがロードする Java VM を指定するには、JavaVM DBParm を使 用します。この DBParm については、開発環境と配布環境で同じ設定 を指定してください。詳細については、『データベースとの接続』マ ニュアルを参照してください。 Java VM の詳細については、次の「Java サポート」を参照してください。 表 41-11: PowerBuilder JDB ファイル 名前 PBJDB100.DLL pbjdbc12100.jar 説明 JRE 1.2 以降対応 PowerBuilder JDBC ドライバ(JDB) PowerBuilder JDB ドライバおよび JRE 1.2 以降対応 Java パッケージ インストール先パス \Program Files\Sybase\Shared\PowerBuilder アプリケーションと同じパス、システム パスのディレクト リ、または App Path レジストリ キー 配布先パス CLASSPATH 環境変数には、PowerBuilder pbjdbc12100.jar ファイルを含めておいてください。たとえば、次のよ うになります。 レジストリ エントリ [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control \Session Manager\Environment] "CLASSPATH"="C:\Program Files\sybase\shared\ PowerBuilder\pbjdbc12100.jar;... 868 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 注意 878 ページの「EAServer 上の PowerBuilder コンポーネント」お よび 883 ページの「EAServer 上の Web データウィンドウ」を参照して ください。 Java サポート Java Runtime Environment(JRE)を使用するアプリケーションまたはコ ンポーネントとともに PowerBuilder pbjvm100.dll ファイルを配布し、さ らにターゲット コンピュータに JRE をインストールしておく必要が あります。JRE は、JSP ターゲット、EJB クライアント、JDBC 接続、 および XSL-FO を使用した PDF での保存をする場合に必要になりま す。PowerBuilder とともにインストールされている JRE を、ターゲッ ト コンピュータ上の PowerBuilder ランタイム ファイルと同じディレ クトリにコピーするか、ユーザの PATH システム環境変数で定義され た場所に保存されている既存の JRE を使用します。 Java VM の検索 PowerBuilder アプリケーションで Java VM が必要になると、PowerBuilder ランタイムは、ユーザ コンピュータ上で pbjvm100.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 は、まず pbjvm100.dll がインス トールされている場所を確認します。pbjvm100.dll が、 C:\Sybase\Shared\PowerBuilder にインストールされていると仮定しま す。次に、PowerBuilder はこの検索プロシージャを使って、現在使用 しているパスに jvm.dll の保存場所を追加します。 1 C:\Sybase\Shared\PowerBuilder\ 内でディリクトリ構造 JRE\bin\client(JDK 1.4 の場合)を検索し、見つかったらこれを パスの先頭に追加します。 2 見つからなかった場合、C:\Sybase\Shared\PowerBuilder\ 内でディ リクトリ構造 JDK1.4\JRE\bin\client を検索し、見つかったらこれ をパスの先頭に追加します。 アプリケーション テクニック 869 Java サポート 3 見つからなかった場合、C:\Sybase\Shared\PowerBuilder\ 内でディ リクトリ構造 JRE\bin\classic(JDK 1.2 または 1.3 の場合)を検索 し、見つかったらこれをパスの先頭に追加します。 上記のディレクトリ構造がいずれも見つからなかった場合、PowerBuilder はユーザの PATH 環境変数で定義された場所にある最初の jvm.dll を 使用します。jvm.dll が見つからないと、Java VM は起動されません。 ランタイム Java VM クラスパス ランタイム スタ ティック レジストリ クラスパスの上書き 870 PowerBuilder が Java VM を起動すると、Java VM は内部パスとクラス パス情報を使って、必要な Java クラスが常に使用できる状態にします。 実行時、Java VM は以下のパスを結合して作成されたクラス パスを使 用します。 • システム JAVA_HOME 環境変数 • Java VM の起動時にプログラムによって追加されるクラス パス。 たとえば、EJB クライアント アプリケーションは、CreateJavaVM メソッドにクラス パスを渡すことができます。 • PowerBuilder ランタイム スタティック レジストリ クラスパス。こ れは、PowerBuilder でアプリケーションを配布するときに使用され る、Windows レジストリ内のパスに対応する pbjvm100.dll ファイ ルに組み込まれるパスです。このパスには、Java VM を使用する 機能が実行時に必要とするクラスが含まれます。 • システムの CLASSPATH 環境変数 • 現行ディレクトリ 必要に応じて、スタティック レジストリ内でランタイムの使用のため に定義された JVM 設定およびプロパティを上書きできます。 PowerBuilder は、次のアルゴリズムを使用して設定情報を探します。 1 JVM に対して最初のリクエストが発生すると、PowerBuilder は、 JVM を作成する関数に渡す設定情報およびプロパティのレジスト リ エントリを探します。 2 PowerBuilder が設定情報のレジストリエントリを見つけた場合、ス タティック レジストリのかわりにこのレジストリ エントリを使 用します。レジストリ エントリが見つからない場合、PowerBuilder はスタティック レジストリを使用します。 3 PowerBuilder が JVM に渡すカスタム プロパティのレジストリ エ ントリを見つけた場合、スタティック レジストリのかわりにこの レジストリを使用します。レジストリ エントリが見つからない場 合、PowerBuilder はスタティック レジストリ エントリを使用しま す。 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 デフォルト設定を上書きするには、 HKEY_LOCAL_MACHINE\Software\Sybase\PowerBuilder\10.0\Java キー内に、PBRTConfig という名前の新しいキーを作成した後、 PBJVMconfig および PBJVMprops のどちらか一方または両方のサブ キーを作成したキーに追加します。 スタティック レジストリ エントリを複製するには、PBIDEConfig キー 内に表示される次のサブキーに同じ文字列値を追加します。 サブキー PBJVMconfig PBJVMprops 文字列値名 Count 0 java.compiler 文字列値データ 1 -verbose:jni,class なし 環境設定またはプロパティ エントリのどちらか一方または両方を上 書きできます。エントリを誤って指定すると、PowerBuilder はスタ ティック レジストリのデフォルト設定に戻します。ただし、これらの エントリを正しく設定しないと JVM 内で正しく動作しなくなるので、 エントリを変更する際は注意が必要です。 PowerBuilder エクステンション PowerBuilder 10.0 には、4 つの PowerBuilder エクステンションが備えら れています。アプリケーションがこれらのエクステンションを使用す る場合、表 41-12 に示すファイルを配布する必要があります。 アプリケーション テクニック 871 PDF と XSL-FO のエクスポート 表 41-12: PowerBuilder の組み込みのエクステンションを使用する場合に 必要なファイル エクステンション PowerBuilder Document Object Model EJB クライアント Web サービス用 SOAP クライアント Web サービス用 UDDI プロキシ ファイル pbdom100.pbx PBXerces100.DLL xerces-c_2_6.dll xerces-depdom_2_6.dll pbejbclient100.pbx pbejbclient100.jar EasySoap.DLL ExPat.dll libeay32.dll ssleay32.dll pbsoapclient100.pbx pbuddi100.pbx EJB クライアントに関しては、表に示したファイルに加えて、EJB サーバ の JDK と互換性のある Java Runtime Environment(JRE)をクライアン トで使用できるようにし、CLASSPATH に追加する必要があります。Sun JRE バージョン 1.4 が、PowerBuilder CD の Support ディレクトリに用意 されています。 詳細については、869 ページの「Java サポート」を参照してください。 注意 EJB クライアントを選択した場合、JRE は、ランタイム パッケージャ で作成された MSI ファイルには追加されません。 PDF と XSL-FO のエクスポート PowerBuilder は、データウィンドウのデータと提示様式を 2 つのテク ニックを使って Portable Document Format(PDF)ファイルとして保存 できます。PowerBuilder は PDF ファイルとして保存する場合に、デフォ ルトで distiller を使用します。PowerBuilder では Apache XML Formatting Objects プ ロ セ ッ サ を 使 用 し て、PDF ま た は XSL Formatting Objects (XSL-FO)形式に保存することもできます。 872 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 GNU Ghostscript distiller の使い方 SaveAs メソッドを使って distiller でデータを PDF として保存するに は、まず、次の手順に従って GNU Ghostscript をダウンロードし、コン ピュータにインストールする必要があります。 GNU Ghostscript の使用に際しては、GNU General Public License(GPL) の規定に従う必要があります。GNU Ghostscript をコンピュータにイン ストールする前に、GPL を読んでください。GPL は GNU Project Web server のサイト http://www.gnu.org/licenses/gpl.html から入手できます。 ❖ GNU Ghostscript をインストールするには 1 コンピュータの一時ディレクトリに、Ghostscript Web のサイト http://www.ghostscript.com に あ る サ イ ト の 1 つ か ら 必 要 な GNU Ghostscript のバージョンの自己解凍型実行ファイル(たとえば gs815w32.exe)をダウンロードします。 2 実行ファイルを実行して、Ghostscript をシステムにインストールし ます。 デフォルトのインストール ディレクトリは C:\gs です。別のディ レクトリを選択したり、Ghostscript コンソールと readme ファイル へのショートカットを作成することもできます。 Ghostscript をインストールした後で、Ghostscript の使い方およびアプ リケーションでそれを配布することについて調べるために、Ghostscript インストレーション ディレクトリの doc サブディレクトリにある readme.htm ファイルを読む必要があります。 名前を付けて行を保存に失敗 データウィンドウ ペインタで PDF に保存するには、[ファイル|名前 を付けて行を保存]を選択して、ファイルの種類として「PDF」を選 択します。GNU Ghostscript をインストールしないで、デフォルトのエ クスポート プロパティを使用する場合は、PowerBuilder は名前を付け て行を保存に失敗したことを知らせるポップアップ ウィンドウを表 示します。Ghostscript をインストールし、GNU Ghostscript をインストー ルしたディレクトリ名を変更する場合は、PDF としての行の保存は通 知なく失敗します。 ファイルの場所 distill メソッドを使ってデータウィンドウ オブジェクトを PDF として 保存する場合、PowerBuilder は、 次の場所からインストールされた GNU Ghostscript を探します。 • アプリケーション テクニック Windows レジストリ 873 PDF と XSL-FO のエクスポート • pbdwe100.dll ファイルの相対パス (通常は Sybase\Shared\PowerBuilder) • システムの PATH 環境変数 GNU Ghostscript を Ghostscript 実行ファイルを使ってインストールした 場合は、Windows レジストリにパスが追加されます。 Ghostscript ファイルが pbdwe100.dll ファイルの相対パスにある場合、 Ghostscript は次のディレクトリ構造でインストールされています。 dirname\pbdwe100.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/gnu/7.05/Fonts.htm を参照してください。 Sybase\Shared\PowerBuilder\drivers にインストールされているデフォ ルトの PostScript プリンタ ドライバと関連ファイルも配布する必要が あります。これらのファイルはユーザのコンピュータにコピーまたは インストールできます。次のディレクトリ構造で配置する必要があり ます。 dirname\pbdwe100.dll dirname\drivers PostScript プリンタ プロファイル 各ユーザのコンピュータに、Sybase DataWindow PS という PostScript プ リンタ プロファイルがある必要があります。このプロファイルは、 データウィンドウ ペインタで PDF ファイルにデータウィンドウの行 を保存する際に、自動的に開発コンピュータに追加されます。 ユーザは、プリンタの追加ウィザードを使用して手動でプロファイル を追加することができます。ウィザードで、 [ディスク使用]ボタンを クリックして、Shared\PowerBuilder\drivers ディレクトリあるいは別の PostScript ドライバ ファイルにインストールされた Adist5.inf ファイル をブラウズします。 Apache FO プロセッサの使い方 Apache プロセッサを使用して PDF または XSL-FO 形式で保存するア プリケーションの場合には、アプリケーションとともに fop-0.20.4 ディ レクトリと Java Runtime Environment(JRE)を配布する必要がありま す。 874 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 これらのディレクトリは、PowerBuilder ランタイム ファイルと同じ ディレクトリに配布する必要があります。たとえば、MyApplication と いうディレクトリにアプリケーションと pbvm100.dll とそのほかの PowerBuilder ランタイム ファイルを 配布する場合、Apache プロセッサ と JRE を MyApplication/fop-0.20.4 および MyApplication/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 についての詳細は、869 ページの「Java サポート」を参照してく ださい。 Windows DBCS プラットフォームでは、ターゲット コンピュータの Windows フォント ディレクトリ(C:\WINDOWS\fonts など)に、 DBCS 文字をサポートするファイルも配布する必要があります。フォ ントの設定についての詳細は、Apache Web のサイト http://xml.apache.org/fop/fonts.html を参照してください。 データウィンドウ Web コントロール ActiveX データウィンドウ Web コントロール ActiveX を使用している場合は、 Web サーバに以下のファイルを配布する必要があります。 アプリケーション テクニック 875 プラグインと PowerBuilder ウィンドウ ActiveX コントロール 表 41-13: データウィンドウ Web コントロール ActiveX 用の PowerBuilder ファイル 名前 PSDWC100.CAB PBJDBC12100.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/psdwc100.cab#10,0,0,5031" 追 加 フ ァ イ ル が 必 要 に な る 場 合 も あ り ま す。詳 細 に つ い て は、 PowerBuilder オンライン ブックの「データウィンドウ Web コントロー ルの配布」または『データウィンドウ プログラマーズ ガイド』マニュ アルを参照してください。 プラグインと PowerBuilder ウィンドウ ActiveX コント ロール プラグイン 876 データウィンドウまたはウィンドウ プラグインを使用している場合 は、表 41-14 のファイルをユーザのコンピュータに配布する必要があ ります。 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 表 41-14: ウィンドウおよびデータウィンドウ プラグイン用 PowerBuilder ファイル 名前 NPPBA100.DLL NPPBS100.DLL NPDWE100.DLL インストール先パス 必要とする対象 標準ウィンドウ プラグイン セキュリティ ウィンドウ プラグイン データウィンドウ プラグイン \Program Files\Sybase\PowerBuilder 10.0\Internet Tools\Plugins 配布先パス ブラウザ プラグイン ディレクトリ すべてのプラグインで、プラグインをサポートするブラウザが 必要です。Microsoft Internet Explore 5.5 Service Pack 2 以降のバージョン では、プラグインをサポートしていません。またウィンドウ プラグイ ンでは、ユーザのコンピュータに PowerBuilder ランタイム DLL が必要 です。詳細については、第 33 章「データウィンドウ プラグインの使 い方」および第 32 章「PowerBuilder ウィンドウ プラグインの使い方」 を参照してください。 注意 ウィンドウ ActiveX コ ントロール PowerBuilder ウィンドウ ActiveX を使用している場合は、ユーザのコ ンピュータで表 41-15 のファイルが使用できるようにしなければなり ません。 表 41-15: ウィンドウ ActiveX 用 PowerBuilder ファイル 名前 PBRX100.OCX PBRXS100.OCX インストール先パス 配布先パス 必要とする対象 標準 PowerBuilder ウィンドウ ActiveX セキュリティ PowerBuilder ウィンドウ ActiveX \Program Files\Sybase\Shared\PowerBuilder Windows システム ディレクトリ レジストリ エントリ PowerBuilder ウィンドウ ActiveX コントロールを クライアント コンピュータで使用できるようにするには、これらのコ ントロールをコンピュータにコピーし、REGSVR32 ユーティリティを 使用して登録します。または、Web サーバの HTML ページの Object 要 素に CODEBASE 属性を含めます。詳細については、876 ページの 「CODEBASE 属性について」を参照してください。 アプリケーション テクニック 877 EAServer 上の PowerBuilder コンポーネント 注意 PowerBuilder ウィンドウ ActiveX コントロールには、ActiveX コ ントロールをサポートするブラウザが必要です。また、ユーザ コン ピュータで、PowerBuilder ランタイム DLL、Microsoft のファイル MFC42.DLL、MSVCRT.DLL、URL.DLL、および URLMON.DLL が使 用できる必要があります。Microsoft のファイルは、通常の場合、ター ゲット コンピュータの Windows システム ディレクトリにすでにイン ストールされています。インストールされていない場合は、Microsoft の Web サイト Internet Explorer Components Gallery のサイト http://activex.microsoft.com/controls/vc/mfc42.cab を参照してください。 詳細については、第 34 章「PowerBuilder ウィンドウ ActiveX の使い方」 を参照してください。 EAServer 上の PowerBuilder コンポーネント EAServer で PowerBuilder コンポーネントを実行するには、コンポーネ ントを開発した時の PowerBuilder のバージョンとビルド番号のランタ イム ライブラリが、サーバ上で使用できるようにします。PowerBuilder のメンテナンス リリースをインストールし、EAServer に新しいコン ポーネントまたはアップデートしたコンポーネントを配布するときに は、サーバ上の PowerBuilder VM もアップデートする必要があります。 PowerBuilder で生成されたコンポーネントを実行する EAServer ホスト では、表 41-16 のファイルが必要です。PowerBuilder コンポーネントが 表に一覧表示されている機能またはデータベース インタフェースを 使用しない場合は、サーバにファイルをインストールする必要はあり ません。PowerBuilder VM には、EAServer LIBJCC ファイルとその関連 ファイルも必要です。表の UNIX の列にある ext は、ライブラリ名に 対応するプラットフォーム固有の拡張子を表します。たとえば Solaris では、このファイル名は libpbvm100x.so になります。 表 41-16: EAServer ホストに必要な PowerBuilder ファイル Windows UNIX 説明 878 PBVM100.DLL libpbvm100x.ext* PBSHR100.DLL pbshr100.ext PBDWE100.DLL PBJAG100.DLL libpbdwe100x.ext libpbjag100x.ext、 pbjag100.ext PowerBuilder 仮想マシン(す べての PowerBuilder コン ポーネントに必要) PowerBuilder 仮想マシンに必 要 データストアのサポート EAServer での PowerBuilder のサポート PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 Windows UNIX 説明 PBDWR100.PBD pbdwr100.pbd htmldw.js htmldw.js PBRTC100.DLL PBXerces100.DLLxerce s-c_2_6.dll xerces-depdom_2_6.dll pbdom100.pbx EasySoap.DLL ExPat.dll libeay32.dll ssleay32.dll pbsoapclient100.pbx PBO84100.DLL — Web データウィンドウのサ ポート(PBDWE が必要) Web データウィンドウのサ ポート リッチテキストのサポート PBO90100.DLL PBO10100.DLL PBODB100.INI libxerces100x.ext、 libxerces-c_2_1_0.ext XML サポート libpbdom100x.ext — PBDOM サポート Web サービス用 SOAP クラ イアント libpbo84100x.ext Oracle 8.0.x と Oracle 8i 8.1.x データベース ドライバ Oracle9i データベース ドラ イバ libpbo90100x.ext (Solaris と Linux の み) libpbo10100x.ext (Solaris と Linux の み) pbodb100.ini PBODB100.DLL libpbodb100x.ext PBSYJ100.DLL libpbsyj100x.ext PBJDB100.DLL libjdb100x.ext — libpbwfr100.ext pbjdbc12100.jar pbjdbc12100.jar アプリケーション テクニック Oracle 10g データベース ドラ イバ PowerBuilder ODBC 初期設定 ファイル PowerBuilder ODBC インタ フェース Adaptive Server Enterprise ネ イティブ データベース イン タフェース Sun Java VM JRE 1.1 以降対 応 JDBC データベース ドラ イバ PowerBuilder UNIX 拡張ライ ブラリ PowerBuilder JDBC ドライバ 対応 Java クラス(JRE 1.2 以 降に必要) 879 EAServer 上の PowerBuilder コンポーネント Windows の場合 PowerBuilder VM インストーラを使用できます。このインストーラは、 表 41-16 に記載されているファイルをインストールするために CD の PBVM フォルダに用意されています。PBVM セットアップ プログラム は、PowerBuilder 10.0 用の Web データウィンドウ サーバ コンポーネント (HTMLGenerator100)とリモート デバッグに必要な PBDebugBroker10 コ ンポーネントもインストールします。 EAServer コンポーネントにほかのデータベース ドライバを使用する こともできますが、トランザクション管理およびインスタンス プーリ ングのための EAServer サポートを活用したい場合は、上の表に記載さ れているいずれかのドライバを使用してください。 UNIX の場合 EAServer をインストールしたときに表 41-16 に記載されているファイ ルがインストールされなかった場合、Sybase Downloads EBFs/Updates page のサイト http://downloads.sybase.com/swd/swx からご利用のプラット フォームで必要なファイルが入手できるものもあります。 UNIX プラットフォームで動作する EAServer に配布される PowerBuilder コンポーネントは、Windows API に依存したり、GUI を 使用することはできません。共有ライブラリは、UNIX サーバ上の EAServer lib ディレクトリにインストールされる必要があります。 PowerBuilder JDBC ドライバに必要な Java クラスを、EAServer の html/classes/com/sybase/powerbuilder/jdbc ディレクトリにインストール する必要があります。 UNIX の接続キャッシュ PowerBuilder コンポーネントが接続キャッシュ を使用するためには、表 41-16 に記載のデータベース ドライバが必要 です。PowerBuilder コンポーネントが接続キャッシュを使用するとき は、該当する PowerBuilder ドライバがロードされます。 Informix または DB2 データベースの接続キャッシュを作成するには、 EAServer 付属の DataDirect ODBC ドライバを使用できます。表 41-17 に記載されているファイルを使用して ODBC データ ソースを作成し たのち、ODBC データ ソースへの EAServer 接続キャッシュを作成し ます。 880 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 表 41-17: UNIX 用 PowerBuilder DataDirect ODBC ファイル 名前 PBinf914.ext PBdb214.ext データベース Informix-Client SDK2.x による Informix 7.x、9.x DB2 Universal Database(UDB) PowerBuilder COM サーバ コンポーネントが次の表に一覧表示されている機能を使用する場合 は、PowerBuilder で生成される COM サーバ ファイルに加えて、表 4118 の PowerBuilder ランタイム ファイルを、サーバが実行されるコン ピュータ上にインストールする必要があります。 表 41-18: COM サーバ ホストに必要な PowerBuilder ファイル 名前 PBVM100.DLL PBSHR100.DLL LIBJCC.DLL LIBJLOG.DLL PBDWE100.DLL PBRTC100.DLL PBODB100.INI PBODB100.DLL インストール先パス 説明 PowerBuilder 仮想マシン(すべての PowerBuilder コン ポーネントに必要) PBVM100.DLL に必要 PBVM100.DLL に必要 LIBJCC.DLL に必要 コンポーネントがデータストアを使用する場合に必要 コンポーネントがリッチテキストを使用する場合に必 要 データベース接続に必要な PowerBuilder ODBC 初期設 定ファイル データベース接続に必要な PowerBuilder ODBC インタ フェース \Program Files\Sybase\Shared\PowerBuilder 配布先パス COM サーバと同じディレクトリ、またはシステム パス上 のディレクトリ レジストリ エントリ PowerBuilder COM サーバは自己登録を行います。 つまり、REGSVR32 ユーティリティを使用して、COM サーバを使用す るコンピュータ上でサーバを登録することができます。 注意 PowerBuilder COM サーバの配布の詳細については、634 ページ の「PowerBuilder COM サーバの配布」を参照してください。 アプリケーション テクニック 881 PowerBuilder オートメーション サーバ データベース ドライバ コンポーネントがデータベースに接続する場合は、該当するデータ ベース ドライバも配布しなければなりません。COM コンポーネント ではどのデータベース ドライバでも使用できますが、COM+ によるト ランザクション管理と接続プーリングのサポートを活用したい場合 は、ODBC を使用する必要があります。接続プーリングのみのサポー トを必要とする場合は、任意のスレッド セーフ ODBC ドライバを使用 できます。トランザクションのサポートも必要な場合は、Microsoft の Oracle 対応 ODBC ドライバまたは Microsoft の SQL Server 対応 ODBC ドライバなど、Microsoft Distributed Transaction Coordinator(DTC)をサ ポートするドライバを使用しなければなりません。 データベース ドライバの詳細については、851 ページの「データベー ス接続」を参照してください。 PowerBuilder オートメーション サーバ PowerBuilder オートメーション サーバを使用するには、以下のファイ ルを配布する必要があります。 • オートメーション サーバの実装を含む PBD または DLL • タイプ ライブラリ ファイルの作成を選択した場合は生成された タイプ ライブラリ ファイル。また、名前付きサーバを構築する場 合は、PowerBuilder アプリケーションのタイプ ライブラリ情報を 提供する PBAEN100.TLB ファイル • プロジェクト ペインタで生成され、PBD または DLL とタイプ ラ イブラリ ファイルの配布先ディレクトリを参照するように編集さ れたレジストリ更新ファイル(.REG)のコピー • 881 ページの「PowerBuilder COM サーバ」に記載されているよう な、サーバが必要とする PowerBuilder ランタイム ファイルおよび データベース接続ファイル 上記のファイルを配布したのち、レジストリ更新ファイルを実行して、 ターゲット コンピュータ上にサーバを登録します。オートメーション サーバの使い方についての詳細は、437 ページの「オートメーション サーバを使用するアプリケーションの配布」を参照してください。 882 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 OLE オートメーション オブジェクトのレジストリ情報の作成 OLE インバウンド オートメーションで使用されるユーザ オブジェク トがアプリケーションに含まれる場合、ユーザのレジストリを更新し なければなりません。PowerBuilder オートメーション オブジェクト レ ジストリ ファイル ジェネレータを使うと、重複しないグローバル識別 子(GUID)、登録(REG)ファイル、およびタイプ ライブラリ(TLB) を生成できます。オートメーション サーバ プロジェクト ウィザード は、新規作成 ダイアログボックスの[プロジェクト]ページにありま す。 詳細については、437 ページの「オートメーション サーバを使用する アプリケーションの配布」を参照してください。 EAServer 上の Web データウィンドウ EAServer 上で、ページ サーバとして JSP を使用して、Web データウィ ンドウ サーバ コンポーネントを実行できます。コンポーネントのトラ ンザクション サーバとページ サーバは、同一コンピュータ上でも異な るコンピュータ上でも実行できます。 トランザクション サーバに必要なファイ ル トランザクション サーバには、以下の 2 種類のファイルが必要です。 • データウィンドウ オブジェクトの定義を含む PBL または PBD ファイル これらのファイルは、サーバのパス内のディレクトリにインス トールしておく必要があります。EAServer がサービスとして実行 されている場合は、これらのファイルがシステム パス上に存在す るか、または完全修飾名で指定されなければなりません。 • PowerBuilder ランタイム ファイル(Windows 上の PBVM100.DLL、 PBSHR100.DLL、PBJAG100.DLL、および PBDWE100.DLL を含む) と PBDWR100.PBD。PBDWR100.PBD ファイルには、DataWindow HTMLGenerator100 コンポーネントの実装が含まれる Windows の場合、インストール プログラムで EAserver の標準イン ストールまたはカスタム インストールを選択すると、デフォルト でこれらのファイルがインストールされます。必要なファイルの 詳細については、878 ページの「EAServer 上の PowerBuilder コン ポーネント」を参照してください。 アプリケーション テクニック 883 EAServer 上の Web データウィンドウ さらに、コンポーネントがアクセスするデータベースの接続キャッ シュを作成する必要があります。詳細については、 『データウィンドウ プログラマーズ ガイド』マニュアルを参照してください。 カスタム コンポーネント データウィンドウ コンポーネントのカスタム バージョンを作成し、よ り効率的に再使用できるようにプロパティを構成できます。詳細につ いては、『データウィンドウ プログラマーズ ガイド』マニュアルを参 照してください。 動的ページ サーバに 必要なファイル JSP をページ サーバとして使用し、Java を使って EAServer に接続する には、JSP サーバ コンピュータ上に以下のファイルが必要です。 これらは、アプリケー ション用に作成したファイルです。JSP ターゲットを使用してこれら のファイルを作成した場合は、組み込み配布コントローラを使ってこ れらのファイルをインストールできます。詳細については、 『Web ター ゲットと JSP ターゲットでの作業』マニュアルを参照してください。 HTML ページ、テンプレート、およびスクリプト Java 対応 EAServer クライアント ソフトウェア JSP サーバでは、表 41-19 のファイルが必要です。 表 41-19: JSP サーバに必要な EAServer クライアント ファイル 名前 easclient.jar easj2ee.jar 説明 クライアントに必要な Java クラス J2EE サポートに必要な Java クラス Sun Java 開発キット(JDK) EAServer とともにインストールされた JDK は、どのバージョンも、Sybase\Shared\Sun ディレクトリに保存さ れ て い ま す。PowerBuilder と と も に イ ン ス ト ー ル さ れ た JDK は、 Sybase\Shared\PowerBuilder ディレクトリに保存されています。 JDK 1.2 または 1.3 を使用する場合、JDK の JRE\bin\classic サブディレ クトリが、システムの PATH 環境変数に追加されていることを確認し ます。 JDK 1.4 を使用する場合、JDK の JRE\bin\client サブディレクトリが、 システムの PATH 環境変数に追加されていることを確認します。 884 PowerBuilder 第 41 章 アプリケーションとコンポーネントの配布 COM+ または IIS 上の Web データウィンドウ ASP をページ サーバとして使用すると、COM+ 上で Web データウィ ンドウ サーバ コンポーネントを実行できます。また、Microsoft IIS ア プリケーション サーバ上で Web データウィンドウを実行することも できます。 COM+ または IIS サー バで必要なファイル COM+ または IIS サーバでは、次の 2 種類のファイルが必要です。 データウィンドウ オブジェクトの定義を含む PBL または PBD ファイル • これらのファイルは、システム パス内のディレクトリにインス トールしておく必要があります。 システム パスおよびシステム DSN の使用 COM+ および IIS はどちらもシステム サービスとして実行される ため、必要なファイルはシステム パス上で使用でき、データ ソー スはシステム DSN として定義されていなければなりません。ユー ザ パスおよびユーザ DSN は参照されません。 PowerBuilder ランタイム ファイルと、データウィンドウの HTMLGenerator コンポーネントの実装を含む PBDWR100.DLL • 表 41-20: COM+ または IIS サーバで必要な PowerBuilder ファイル 名前 PBVM100.DLL PBSHR100.DLL LIBJCC.DLL LIBJLOG.DLL PBDWE100.DLL PBODB100.DLL PBODB100.INI PBDWR100.DLL 説明 PowerBuilder 仮想マシン PBVM100.DLL に必要 PBVM100.DLL に必要 LIBJCC.DLL に必要 データウィンドウのサポート PowerBuilder ODBC インタフェース PowerBuilder ODBC インタフェース セットアップ ファイル データウィンドウ HTMLGenerator コンポーネント PowerBuilder が COM+ ま た は IIS サ ー バ コ ン ピュータにインストールされていない場合、これらのファイルは COM+ または IIS サーバのシステム パス上のディレクトリにインス トールしなければなりません。これらのファイルは、PowerBuilder が インストールされているコンピュータの Sybase\Shared\PowerBuilder ディレクトリから取得できます。 インストール先パス アプリケーション テクニック 885 COM+ または IIS 上の Web データウィンドウ 別のコンピュータから PBDWR100.DLL をコピー した場合は、COM+ または IIS サーバにこのファイルを登録しなけれ ばなりません。 レジストリ エントリ 注意 ODBC データ ソースは、システム DSN として定義する必要があ ります。ODBC の環境設定の詳細については、864 ページの「ODBC データ ソースとドライバの環境設定」を参照してください。 COM+ がサーバ コンポーネントのホストになり、IIS とは異なるコン ピュータで実行されている場合、クライアント インストール パッケー ジを作成し、それを IIS サーバにインストールする必要があります。 ASP サーバに必要な ファイル ASP をページ サーバとして使用し、ActiveX で COM+ または IIS コン ポーネントに接続するには、ASP サーバ コンピュータ上に以下のファ イルが必要です。 これらは、アプリケー ション用に作成したファイルです。Web ターゲットを使用してこれら のファイルを作成した場合は、PowerBuilder の配布構成を設定して、こ れらのファイルを ASP に配布できます。詳細については、『Web ター ゲットと JSP ターゲットでの作業』マニュアルを参照してください。 HTML ページ、テンプレート、およびスクリプト 886 PowerBuilder 索引 数字 508 条 778 A AccessibleRole カタログ データ(列挙体)値 781 AccessiWeb アクセシビリティ基準 779 Activate イベント、EAServer 内 506 Activate 関数 353, 355 ActiveX コントロール ActiveX のプロパティ、イベント、関数 360 Object プロパティ 375 アクティブ 362 イベント 363 ウィンドウ ActiveX 735 オートメーション 375 概要 341, 343 組合せイベント リスト 363 動作 361 配布 846 表示形態 361 プログラミング 362 プロパティ 360, 361 プロパティ シート 361 Adaptive Server Anywhere MobiLink 同期 204 ストアド プロシージャ呼び出しでサポートさ れる機能 202 データ ソース 861 Adaptive Server Enterprise データベース インタ フェースのプロパティ(トランザクショ ン オブジェクト) 177 AddColumn 関数 158 AddData 関数 273 AddItem 関数 145, 149, 150, 153 アプリケーション テクニック AddLargePicture 関数 155 AddPicture 関数 146, 151 AddSeries 関数 273 AddSmallPicture 関数 155 AddStatePicture 関数 155, 156 ALIAS FOR キーワード 概要 193 スクリプト記述 194 AncestorReturnValue 変数 33 Any データ型 382 application/datawindow MIME タイプ 732 application/vnd.powerbuilder MIME タイプ 720 application/vnd.powerbuilder-s MIME タイプ 720 AutoCommit プロパティ(トランザクション オブ ジェクト) COMMIT 文と ROLLBACK 文の実行 179 概要 174 データベース インタフェースごとのリスト 177 B bind.object コンポーネント プロパティ bind.thread コンポーネント プロパティ Blob OLE コントロール 359 データウィンドウの同期 523 BMP ファイル リソースとしての配布 826 リソース ファイルでの命名 828 502 539 C CacheName DBParm 518 Cancel 関数 314, 326 ClassName 関数 382 Clicked イベントとグラフ 279 887 索引 CLSID PowerBuilder ウィンドウ ActiveX 749 レジストリ 429 COM サーバ 613 サーバとオートメーション サーバの比較 613 データ型 617 COM オブジェクト インタフェースへのアクセス用メ ソッドの追加 616 COM+ クライアントの構築 643 コンポーネントの構築 609 配布 631 COM+ の ImpersonateClient メソッド 629 COM+ の IsCallerInRole メソッド 628 COM+ の IsSecurityEnabled メソッド 628 COM+ の RevertToSelf メソッド 629 COM/COM+ コンポーネントの検証 619 COM/COM+ コンポーネント(COM コンポーネント を参照) 629 COMMANDPARM 属性 Embed 要素 717, 719 Object 要素 749 COMMIT 文 AutoCommit の設定 179 COM コンポーネント 625 EAServer コンポーネント 514 UseContextObject 512 エラー処理 188 概要 178 接続解除時の自動コミット 179, 185 デフォルト以外のトランザクション オブジェクト 186 COM クライアント 環境設定 643 結果集合 622 構築 643 サーバへの接続 644 トランザクションの制御 646 COM コンポーネント 埋め込み PBD 632 開発プロセス 611 構築 609 888 セキュリティ問題 628 データベース アクセス 620 登録 631 トランザクション サポート 624 プロジェクト ペインタでの構築 629 メモリの割り当て 633 CONNECT 文 USING TransactionObject 句 183 エラー処理 188 概要 178 スクリプト記述 183 デフォルト以外のトランザクション オブジェク ト 186 CORBAUserException オブジェクト 591 CreateInstance 関数 569, 570, 628 CreateInstance メソッド、Web サービス プロキシ 692 CreateJavaVM メソッド 663 CreateObject 関数 442 create メソッド 668 CUR ファイル リソースとしての配布 826 リソース ファイルでの命名 828 C 関数に受け渡す Char 変数 467 D Database プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 DataObject プロパティ(データ パイプライン) 314, 319 dbmlsrv9 204 dbmlsync 概要 207 プロセス 208 DBMS プロパティ(トランザクション オブジェク ト) 概要 174 データベース インタフェースごとのリスト 177 PowerBuilder 索引 DBParm MsgTerse パラメータ 330 DBParm プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 DBPass プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 DDE 概要 337 クライアント イベントと関数 339 クライアント関数 339 サーバ イベントと関数 340 Deactivate イベント、EAServer 内 506 DeleteLargePictures 関数 156 DeleteLargePicture 関数 156 DeletePicture 関数 146 DeleteSmallPictures 関数 156 DeleteStatePictures 関数 156 DeleteStatePicture 関数 156 Disability Discrimination Act 779 DisableCommit メソッド 513 DISCONNECT 文 USING TransactionObject 句 184 エラー処理 188 概要 178 スクリプト記述 184 データベース トランザクションのプール時 189 デフォルト以外のトランザクション オブジェ クト 186 DLL ファイル PBD ファイルとの比較 822 PowerBuilder 配布 836 概要 822 関数の実行 461 作成 833 テスト 835 含まれるリソース 827 例 830 dwprint.ini 552 アプリケーション テクニック E EAServer PowerBuilder DLL 557 PowerBuilder との統合 490 Unicode 接続キャッシュ 520 インスタンス プーリング 505 共有コンポーネント 499 クライアント プル 584 コンポーネントの配布 557 コンポーネント プロパティ 539 接続 563 接続エラー 588 トランザクション サポート 510 非同期リクエスト 584 ログ 550 EAServer 環境変数 PB_FOP_SUPPRESSLOG 556 PB_HEAP_LOGFILE_OVERWRITE 52 PB_HEAP_LOGFILENAME 52 PB_POOL_THRESHOLD 51 PBOnFatalError 514 PBRollbackOnRTError 514 EAServer クライアント 構築 561 配布 593 EAServer コンポーネント インタフェース 530 構築 495 データベース更新 522 デバッグ 548 プロパティ 539 メソッドの呼び出し 568 有効期間 508, 515 EAServer プロキシ オブジェクト 概要 566, 567 破棄 574 EAServer プロファイル、作成 497 EAServer プロファイル ダイアログボックス、概要 498 EJBConnection オブジェクト 654 EJBTransaction オブジェクト 654 EJB クライアント Java コレクション クラス 672 889 索引 構築 651 動的キャスティング 671 戻り値のダウンキャスト 670 例外処理 672 EJB コンポーネント、メソッドの呼び出し 570, 667 EJB プロキシ オブジェクト 概要 652 生成 652 Embed 要素 703, 717, 726, 730 Embed 要素の APPLICATION 属性 710, 717, 719 Embed 要素の HEIGHT 属性 717, 730 Embed 要素の LIBRARY 属性 717, 719 Embed 要素の SRC 属性 717, 730 Embed 要素の WIDTH 属性 717, 730 Embed 要素の WINDOW 属性 717, 719 EnableCommit メソッド 513 ErrorLogging オブジェクト(エラー ロギング サービ スも参照) 474 ExternalException イベント 384 GetFocus イベントによるマイクロヘルプの提供 78 GetFullState 関数 522 GetJavaClasspath メソッド 663 GetJavaVMVersion メソッド 663 GetParent 関数 28, 108 GUID 438, 444 GUID とレジストリ 429 H HKEY_CLASSES_ROOT 431 HotLinkAlarm DDE イベント 339 HTML Embed 要素 717, 730 Object 要素 748 ウィンドウ ActiveX 748 属性 717 文書、ウィンドウ プラグイン 703, 717 文書、データウィンドウ プラグイン 726, 730 F FileEncoding 関数 54 FileLength64 関数 54 FileOpen 関数 54 FileReadEx 関数 55 FileSeek64 関数 54 FileWriteEx 関数 55 FindSeries 関数 274 FOR...NEXT 文(ウィンドウ インスタンスを開く / 閉 じる) 95 FUNCTION 宣言 概要 193 スクリプト記述 194 G GenerateGUID 関数 444 GenerateRegFile 関数 447 GenerateTypeLib 関数 450 GetChanges 関数 522 GetConnectionOption DBParm 890 520 I IAccessible プロパティ 781 ICO ファイル ドラッグ アイコンの指定 163 リソースとしての配布 826 リソース ファイルでの命名 828 imstyle.pbl 800 InfoMaker 様式の作成 800 INFORMIX データベース インタフェース ストアド プロシージャ呼び出しでサポートされ る機能 200 プロパティ(トランザクション オブジェクト) 177 InsertItemFirst 関数 122 InsertItemLast 関数 122 InsertItemSort 関数 122 InsertItem 関数 122, 145, 149, 150, 153 InvokePBFunction 関数 JavaScript 757 VBScript 758 IsInTransaction メソッド 513 PowerBuilder 索引 IsJavaVMLoaded メソッド 663 IsTransactionAborted メソッド 513 データベース インタフェースごとのリスト 177 LUW(論理的な作業単位) 178 J J2EE アーキテクチャ 493 J2EE サーバ 接続 666 Java VM、実行時に起動 869 JavaScript とウィンドウ ActiveX InvokePBFunction 関数 757 PowerScript 関数の呼び出し 755 TriggerPBEvent 関数 759 イベント ハンドラ 753 ユーザ イベントの呼び出し 759 ユーザ定義関数の引数 757 ユーザ定義関数の呼び出し 757 JavaVM オブジェクト 654 Java コレクション クラス、EJB クライアント 672 JDBC データベース インタフェースのプロパティ (トランザクション オブジェクト) 177 JRE、配布に必要 869 JVM、実行時に起動 869 L LibraryList プロパティ 440 Lock プロパティ(トランザクション オブジェク ト) 概要 174 データベース インタフェースごとのリスト 177 LogID プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 LogPass プロパティ(トランザクション オブジェ クト) 概要 174 アプリケーション テクニック M MachineCode プロパティ 440 MailSession オブジェクト 457 MAPI アプリケーションからのアクセス 457 概要 457 MDI_1 コントロール 73 MDI アプリケーション キーボード操作 88 構築 71 シートの使い方 75 ショートカット キー 89 マイクロヘルプの使い方 77 メニューの使い方 74 MDI アプリケーションのキーボード サポート 88 MDI アプリケーションの標準フレーム 73 MDI シート 概要 74 最大化 77 整列 76 閉じる 77 開く 75 マイクロヘルプの使い方 77 メニューの使い方 74 リストを開く 76 MDI フレーム カスタム MDI フレームのサイズ変更 84 シートの整列 76 シートを開く 75 マイクロヘルプの使い方 77 MicroHelpHeight 属性 87 Microsoft Active Accessibility 780 Microsoft Active Accessibility プロパティ 780 Microsoft Excel、OLE 376, 380 Microsoft SQL Server ストアド プロシージャの呼び出し 201 プロパティ(トランザクション オブジェクト) 891 索引 177 Microsoft Windows インストーラ、ランタイム パッ ケージャに対して必要 846 Microsoft Word OLE 367, 378, 381 レター フォーム例 369 MIME タイプ ウィンドウ プラグイン 703 ウィンドウ プラグインの指定 720 データウィンドウ プラグイン 726 データウィンドウ プラグインへの指定 732 MIME タイプの PBD ファイル拡張子 720 MIME タイプの PSR ファイル拡張子 732 MobiLink 同期 dbmlsrv9 204 dbmlsync 207, 208 PowerBuilder オブジェクト 208 アーティクル 207, 230 ウィザード 208 オプション ウィンドウ 215 階層構造 205 概要 203 クライアント 207 サーバ 204 削除の処理 235 サブスクリプション 207, 233 スクリプト 206, 225 スクリプト、デフォルト 223 接続イベント 221 テーブル イベント 223 テクニック 234 統合 204 統合データベース 220 パブリケーション 207, 229 ユーザ 207, 231 リモート 204 リモート データベース 228 リモート マシンで必要なファイル 217 MSAA 780 MSAA プロパティ 780 MsgTerse パラメータ 330 MSI ファイル(Microsoft Windows インストーラ) 846 892 N Netscape プラグイン API PowerBuilder ウィンドウ プラグイン 703 データウィンドウ プラグイン 726 NPDWE100.DLL ファイル 706, 727, 728 NPPBA100.DLL ファイル 705, 706, 728 NPPBS100.DLL ファイル 705, 706, 728 O ObjectAtPointer 関数 280 Object プロパティ 概要 38 ドット表記 29 Object 要素の CODEBASE 属性 749 OCI_9U 接続キャッシュ 520 OCX(ActiveX コントロールを参照) 343 ocx_error イベント 385 ODBCU 接続キャッシュ 520 ODBCU_CONLIB データベース パラメータ 521 ODBC インタフェース インストール 836 環境設定 836 ストアド プロシージャ呼び出しでサポートされ る機能 200 プロパティ(トランザクション オブジェクト) 177 OLE PowerBuilder 例外コード 454 アンビエント プロパティ 361 インプレース アクティブ化 352 インプレース アクティブ化のメニュー 353 埋め込み 350 エラー処理 384 オートメーション 365 オートメーションで使用する言語 389 オフサイト アクティブ化 352 オブジェクト 344 オブジェクトと代入 368 オブジェクトのアクティブ化 355 概要 412 型のない変数 382 PowerBuilder 索引 括弧 377 コンテナ アプリケーション 341 コンパイラのチェック 375 サーバ アプリケーション 341, 344, 394, 412 サーバ コマンドの修飾子 365, 380 サーバのメソッドとプロパティ 375 サーバ メモリの割り当て 379 処理効率 383 ストリーム 405 挿入可能オブジェクト 343 低レベルのアクセス時のポインタ 390 データウィンドウ オブジェクトの関数 391 データウィンドウのカラム 392 データ ファイル 358 名前のついたパラメータ 378 バーブ 355, 393 配布 434, 437 引数の参照渡し 377 ブラウザ 394 プログラム可能なオブジェクト 412 プロパティの変更通知 387 ホット リンク 387 リンク 351 リンク情報の管理 351 リンクと埋め込みの比較 350 レジストリ 429 レター フォーム例 369 OLE DB データベース インタフェースのプロパ ティ(トランザクション オブジェクト) 177 OLEActivate 関数 393 OLEObject オブジェクト エラー イベントの継承 421 概要 365 作成 365 接続 365 接続解除と破棄 367 OLEStorage オブジェクト 398 OLEStream オブジェクト 398 OleTxnObject オブジェクト 646 OLE オートメーション Object プロパティ 390, 392 OLEObject 365 アプリケーション テクニック 構文 375 シナリオ 369 例 369 OLE オブジェクト、ドット表記 29 OLE オブジェクトの埋め込み 358 OLE オブジェクトの挿入 356 OLE オブジェクトの貼り付け 357 OLE オブジェクトのリンク 356, 358 OLE カスタム コントロール(ActiveX コントロー ルも参照) 341 OLE クラス ユーザ オブジェクト 398 OLE 項目のブラウザ 394 OLE コントロール Blob 359 Contents プロパティ 357 ObjectData プロパティ 359 Object プロパティ 375 アクティブ化 355 イベント 359 埋め込み 347, 356 埋め込みデータの保存 358 オートメーション 375 オフサイト アクティブ化とインプレース アク ティブ化の比較 352 オブジェクトのアイコン 347 オブジェクトのアクティブ化 347, 348 オブジェクトの削除 349 オブジェクトの挿入 356 オブジェクトの表示 347 オブジェクトの変更 349, 356 概要 341 空の OLE コントロール 344, 353 サーバ アプリケーション 358 定義 344 動作 346, 349 表示形態 346 プロパティ シート 346 メニュー 353 ユーザ インタラクション 349 リンク 347, 356, 358 リンクの更新 348 リンクの中断 353 OLE ストリーム 893 索引 read/write ポインタ 407 概要 396, 405 長さ 407 開く 405 読み込みと書き込み 407 OLE ストレージ 概要 396 構造 397 効率 399 ストレージの構造の記録管理 410 ファイルの構築 402 保存 400 メンバー 401 例 402 OLE の Open 関数 356 OLE の Save 関数 400 OLE のタイプ ライブラリ 419, 433, 450 OpenSheet 関数 75 Open 関数 96 ORACLE データベース インタフェース プロパティ(トランザクション オブジェクト) 177 ストアド プロシージャの使い方 192, 199 ストアド プロシージャ呼び出しでサポートされる 機能 200 P Parent 代名詞 28, 32 pb.appname コンポーネント プロパティ 539 pb.class コンポーネント プロパティ 539 pb.cookie コンポーネント プロパティ 539 pb.debug コンポーネント プロパティ 539 PB.INI ファイル UserHelpPrefix 169 トランザクション オブジェクト値の読み込み 182 pb.librarylist コンポーネント プロパティ 539 pb.live_edit コンポーネント プロパティ 539 PB_FOP_SUPPRESSLOG 環境変数 556 PB_HEAP_LOGFILE_OVERWRITE 環境変数 52 PB_HEAP_LOGFILENAME 環境変数 52 PB_POOL_THRESHOLD 環境変数 51 894 PBDOM クラス、概要 240 PBD ファイル DLL ファイルとの比較 822 ウィンドウ ActiveX 748 ウィンドウ プラグイン 715 概要 822 作成 833 テスト 835 含まれるリソース 827 例 830 pbejbclient100.pbd 652 pbejbclient100.pbx 652 pbjvm100.dll、保存場所 869 PBOnFatalError 環境変数 514 PBRollbackOnRTError 環境変数 514 PBRXnn.OCX インストール場所 738 解説 737 クライアント ワークステーション 763 PBRXSnn.OCX インストール場所 738 解説 737 登録 738 PBR ファイル 826 ウィンドウ ActiveX 746 ウィンドウ プラグイン 714 PBSOAPClient100.pbd 687 PBSOAPClient100.pbx 687 PBUSR0nn.HPJ ファイル 166 Pcode、実行アプリケーション 820 PipeEnd イベント 314 pipeline システム オブジェクト 314 PipeMeter イベント 314 PipeStart イベント 314 PostEvent 関数 471 Post 関数 470 PowerBuilder 実行時 DLL 836 実行システム 822 パイプライン エラー データウィンドウ 329 PowerBuilder アプリケーション CreateObject 関数 442 GenerateGUID 関数 444 GenerateRegFile 関数 447 PowerBuilder 索引 GenerateTypeLib 関数 450 概要 415, 422, 439 関数 441 名前の変更 417, 427 プロパティ 440 ユーザ オブジェクト 422 例外コード 454 PowerBuilder イベントの発生 471 PowerBuilder ウィンドウ ActiveX 677 PowerBuilder オートメーション サーバ CLSID 429 GUID 438 PowerBuilder アプリケーション 415 Visual Basic クライアント 421, 426 エラー処理 421 オブジェクトのランタイム ライブラリ 418, 423 概要 412 クライアント アプリケーション 413 クライアント コード 420, 424, 428 タイプ ライブラリ 419, 433 名前付きサーバ 417, 427 名前付きサーバの登録 427 配布 434, 437 プログラム可能なオブジェクト 412 プログラム識別子 419, 421, 430 未登録のユーザ オブジェクト 422 ユーザ オブジェクトの登録 414, 417, 419 用途 413 ランタイム オーバーヘッド 413 例外コード 454 レジストリ 429 レジストリ更新ファイルのサンプル 455 PowerBuilder 初期設定ファイル、トランザクショ ン オブジェクト値の読み込み 182 PowerBuilder セキュア ウィンドウ プラグイン 677 PowerBuilder 単位系(PBU)と拡張コントロール プロパティ 343 PowerBuilder の ADO Recordset 623 PowerBuilder 標準ウィンドウ プラグイン 677 PowerBuilder ランタイム パッケージャ 847 PowerScript 関数 アプリケーション テクニック JavaScript での呼び出し 755 VBScript での呼び出し 756 ウィンドウ ActiveX 754 PowerScript ドット表記、ストアド プロシージャ呼 び出しのための使い方 197 Powersoft データベース インタフェース インストール 836 ストアド プロシージャ呼び出しでサポートさ れる機能 199 Powersoft レポート(PSR) 725 PrintCancel 関数 791 PrintClose 関数 791 ProfileString 関数 概要 182, 797 スクリプト記述 182 PropertyChanged イベント 388 PropertyRequestEdit イベント 387 PSR ファイル 作成 729 データウィンドウ プラグイン 725 R REF キーワード 377 RegEdit ユーティリティ、サポートされているバー ブの取得 393 RegistryGet 関数 798 RegistrySet 関数 798 REGSVR32.EXE 739 ReleaseConnectionOption DBParm 520 RemoteHotLinkStart DDE イベント 340 RemoteHotLinkStop DDE イベント 340 RemoteRequest DDE イベント 340 RemoteSend DDE イベント 340 Repair 関数 314, 330 RLE ファイル リソースとしての配布 826 リソース ファイルでの命名 828 ROLLBACK 文 AutoCommit の設定 179 UseContextObject 512 概要 178 デフォルト以外のトランザクション オブジェ クト 186 895 索引 RowsInError プロパティ(データ パイプライン) 314, 324 RowsRead プロパティ(データ パイプライン) 314, 324 RowsWritten プロパティ(データ パイプライン) 314, 324 RPCFUNC キーワード 概要 193 スクリプト記述 194 RTF 283 Run 関数 501 S SaveAs 関数、OLE 358, 400 Secure Sockets Layer プロバイダ サービス 474 Send 関数 470 ServerName プロパティ(トランザクション オブジェ クト) 概要 174 データベース インタフェースごとのリスト 177 SetAbort メソッド 513 SetAutomationLocale 関数 389 SetChanges 関数 522 SetColumn 関数 158 SetComplete メソッド 513 SetFullState 関数 522 SetItem 関数 159 SetMicroHelp 関数 77 SetOptions メソッド、Web サービス プロキシ 692 SetOverLayPicture 関数 156 SetProfileString 関数 797 SetTransPool 関数 189 SOAP 大文字と小文字の区別 690 サーバへの接続 692 例外処理 694 SOAPConnection オブジェクト 687 SoapException オブジェクト 687 Solaris 印刷、設定 552 SQL Server、ストアド プロシージャの呼び出し 201 SQLCA SQLCA からのユーザ オブジェクトの継承 191, 196 896 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 エラー番号の省略 330 PowerBuilder 索引 SQL 文 SQL 文のセミコロンでの終了 181, 183 エラー処理 188 トランザクション オブジェクトの指定 186 トランザクション処理 179 SQL 文の後のエラー処理 188 SQL 文の終止符のセミコロン 181, 183 SSL EAServer との接続 595 コールバック 604 プロバイダ オブジェクト 601 プロバイダ サービス 474 プロパティ 598 SSLCallback オブジェクトの使い方 604 SSLServiceProvider オブジェクト インスタンスの作成 601 使い方 597 Start 関数 314, 322, 501 stateless コンポーネント プロパティ 539 state コンポーネント プロパティ 539 Stop 関数 501 storage コンポーネント プロパティ 539 SUBROUTINE 宣言 概要 193 スクリプト記述 194 Sybase Adaptive Server Enterprise データベース イ ンタフェースのプロパティ(トランザク ション オブジェクト) 182 Sybase DirectConnect データベース インタフェー スのプロパティ(トランザクション オブ ジェクト) 177 Sybase EAServer プロファイル EAServer プロファイル ダイアログボックス 498 Sybase SQL Anywhere、ストアド プロシージャの 呼び出し時にサポートする機能 202 Sybase System 10 と System 11 ストアド プロシージャの呼び出し 201 Syntax プロパティ(データ パイプライン) 314 SystemError イベント、スクリプト作成 592 T TabularResults、PowerBuilder での使い方 アプリケーション テクニック 528 Tag 属性、マイクロヘルプの使い方 78 This 代名詞 27 thread.safe コンポーネント プロパティ 539 thread.safe プロパティ 501 timeout コンポーネント プロパティ 539 TransactionServer コンテキスト オブジェクト COM+ 624, 628 EAServer 511, 536 TriggerEvent 関数 471 TriggerPBEvent 関数 JavaScript 759 VBScript 759 tx_outcome コンポーネント プロパティ 539 tx_timeout コンポーネント プロパティ 539 tx_type コンポーネント プロパティ 539 tx_vote コンポーネント プロパティ 539 type コンポーネント プロパティ 539 U Unicode EAServer 接続キャッシュ 520 URL ウィンドウ プラグイン 720 データウィンドウ プラグイン 732 UseContextObject DBParm 512, 514 UserID プロパティ(トランザクション オブジェク ト) 概要 174 データベース インタフェースごとのリスト 177 USING TransactionObject 句 CONNECT 文 183 DISCONNECT 文 184 概要 186 V VBScript InvokePBFunction 関数 758 PowerScript 関数の呼び出し 756 TriggerPBEvent 関数 759 ウィンドウ ActiveX のイベント ハンドラ 754 897 索引 ユーザ イベントの呼び出し 759 ユーザ定義関数の呼び出し 758 Visual Basic OLE クライアント 421, 426 Voluntary Product Accessibility Template(VPAT を参 照) VPAT 784 W WCAG(Web Content Accessibility Guidelines) 778 Web Content Accessibility Guidelines(WCAG を参照) Web アプリケーションの設計 702 Web サーバ ウィンドウ ActiveX 762 データウィンドウ プラグイン 732 Web サービス PowerScript クライアント 685 概要 678 コンポーネントのエクスポーズ 543 サービスの作成 694 プロキシ オブジェクト 688 メソッドの起動 693 例外処理 694 Web ブラウザ プラグインの互換性 703, 726 プラグインの動作 703, 726 Windows イベント イベント発生 470 処理 472 Windows メッセージ、送信 468 WMF ファイル リソースとしての配布 826 リソース ファイルでの命名 828 Word 97 オートメーション 380 WordBasic ステートメント 378 WordBasic のステートメント(OLE) 378 WSDL、Web サービス プロキシに対する選択 688 ア アーキテクチャ、J2EE アイコン、配布 826 898 493 アクセシビリティ 機能 775 データウィンドウのサポート 782 テスト 784 値、引数の受け渡し 35 EAServer 532 アプリケーション MDI 71 外部ファイルからのトランザクション オブジェ クト値の読み込み 182 実行 835 実行のトレース 835 多言語 767 データベース ストアド プロシージャの呼び出 し 190 データベース トランザクションのプール 189 配布 819 ユーザ オブジェクトにストアド プロシージャ を実行させるスクリプト 197 ローカライズ 767, 774 アプリケーション、クライアント 構築 643 配布 593 アプリケーション、サーバ EAServer コンポーネントの構築 495 アプリケーション環境設定、格納 795 アプリケーション管理 アプリケーション管理を容易にする動的ライブ ラリの使い方 824 アプリケーション管理を容易にするリソースの パッケージ化 826 更新された PowerBuilder ランタイム DLL の提 供 836 アプリケーション サーバ COM/COM+ コンポーネントの構築 629 アプリケーションの実行版 コンパイル オプション 820 テスト 835 トレース 835 パッケージ化モデルの実装 833 パッケージ化モデルの選択 830 パッケージに含まれる要素 821 アプリケーションのテスト PowerBuilder 索引 実行のトレース 835 実行版 835 アプリケーションのパッケージ化 コンパイル オプション 820 実行版の処理 821 テスト 835 モデルの実装 833 モデルの選択 830 アプリケーションのユーザ、コンピュータ環境 設定 836 アプリケーション ペインタ アプリケーション プロパティ シート、変数の 型プロパティ ページを使用 196 デフォルトのグローバル変数型の変更 195 アンビエント プロパティ 361 イ 位置、ウィンドウ 94 イベント DDE 338 イベント発生 470, 471 グラフ コントロール 272 先祖からの戻り値 33 先祖関数の呼び出し 32 データ パイプライン 314 ドラッグ アンド ドロップ 163 引数の受け渡し 35 呼び出し 471 イベント発生 470, 471 イベント ハンドラ PowerBuilder ウィンドウ ActiveX JavaScript 753 VBScript 754 印刷 EAServer コンポーネントのデータストア 550 Solaris 551 UNIX 551 印刷カーソル 789, 791 印刷領域 789 概要 787 関数 787 アプリケーション テクニック 行間隔 793 高度な印刷技法 792 ジョブ 789 測定単位 789 タブ 790 停止 791 描画オブジェクト 793 印刷カーソル 789 印刷領域 789 インスタンス、ウィンドウ 参照変数 93 配列 94 インスタンス プーリング 505 インスタンス変数 アクセス 30 名前の重複 32 インストール後のプラグインの移動 706, 728 インターネット サービス 474 インタフェース コンポーネント プロパティ 539 インタフェース定義言語(IDL:Interface Definition Language) 530 インデックス、ウィンドウ配列 94 ウ ウィザード COM/COM+ コンポーネント 610 EAServer コンポーネント 496 EAServer プロキシ オブジェクト 567 EJB プロキシ オブジェクト 656 ウィンドウ MDI アプリケーション 72, 74, 76 実行中の型の選択 37 データ型として定義 91 データ パイプラインの制御 315 表示 91 ウィンドウ ActiveX CLASSID 値の検索 749 CODEBASE 属性 749 HTML の作成 748 Object 要素 748 Param 構成要素 749 899 索引 PowerScript 関数 754 Web サーバ 762 アプリケーションのアイデア 736 イベント 761 イベント ハンドラ 752 インストール場所 738 ウィンドウの作成 741 外部リソース 744 概要 735 既存アプリケーションの変換 744 クライアント側のスクリプト 752 クライアント ワークステーション ソフトウェア 763 サポートされるブラウザ 736 セキュリティ 737 データベース アクセス 743 テスト 745 動的ライブラリのリソース ファイル 746 登録 738 必須 DLL 740 表示 764 ユーザ定義関数 756 要件 737 ウィンドウ ActiveX の DISPLAYERRORS 属性 749 ウィンドウ ActiveX の LIBLIST 属性 749 ウィンドウ ActiveX の Object 構成要素 748 ウィンドウ ActiveX の Param 構成要素 749 ウィンドウ ActiveX の PBAPPLICATION 属性 749 ウィンドウ ActiveX の PBWINDOW 属性 749 ウィンドウ ActiveX のクライアント側のスクリプト 752 ウィンドウ インスタンスを複数開く 91 ウィンドウ プラグイン HTML 文書 703 アプリケーション設計 709 アプリケーションのアイデア 702 ウィンドウ管理 709 オブジェクト 709 開発 707 外部リソース 711 概要 700 既存アプリケーションの変換 712 クライアント ワークステーション ソフトウェア 900 721 サーバ上のファイル 720 サポートされるブラウザ 701 スクリプト 710 セキュリティ 702 セキュリティ バージョン 701, 706 チャイルド ウィンドウ 712 データベース アクセス 711 テスト 713 動的ライブラリ 714 動的ライブラリのリソース ファイル 714 配布コンポーネント 708 表示 723 標準バージョンの概要 701 ブラウザ / サーバ間対話 703 変数 710 要件 705 ウィンドウ ペインタ、コントロールのドラッグ モードの指定 162 埋め込み SQL でのエラー処理 188 運動障害 777 エ エラー EAServer サーバ ログへの書き込み 550 Windows ログへの書き込み 620 データ パイプライン実行時 311, 329 例外処理 39, 672 ログへの書き込み 474 エラー イベント、スクリプト作成 EAServer クライアント 591 エラー イベントのスクリプト記述 OLE サーバ 384 エラー処理 OLE 384 SQL 文の後 188 エラー ロギング サービス 概要 474 エラー ログ サービス COM+ 620 EAServer 550 PowerBuilder 索引 エリアス、XML メソッド 690 オ オートメーション、OLE 411 オートメーション サーバ PowerBuilder COM サーバとの比較 613 概要 412 オートメーション サーバ ウィザード 419 オートメーションで使用する言語 389 オブジェクト DLL ファイル 822 PBD ファイル 822 PowerBuilder の OLE オートメーション 412 オブジェクトの代名詞 27 関数とイベントの呼び出し 32 共有 499 子孫オブジェクトのインスタンス化 36 子孫オブジェクトの参照 97 実行中の型の選択 36 実行ファイル 822 動的に参照されるオブジェクトの配布 824, 828 名前の重複 31 オブジェクト、プロキシ EJB に対して生成 652 生成 566, 567 オブジェクト指向概念としての代行 22 オブジェクト指向プログラミング、用語 13 オブジェクトの挿入 ダイアログボックス 344 オペレーティング システム、環境設定 836 親オブジェクト 25 カ 外部関数 EAServer コンポーネント 468 宣言 462 使い方 461 データベース ストアド プロシージャ呼び出し のための使い方 193 アプリケーション テクニック 外部ファイル、トランザクション オブジェクト値 の読み込み 182 外部リソース ウィンドウ ActiveX 746 ウィンドウ プラグイン 711 データウィンドウ プラグイン 730 学習障害 777 拡張属性の概要 311 カスタム クラス ユーザ オブジェクト COM/COM+ コンポーネント 610 EAServer コンポーネント 495 オートメーション サーバ 412 典型的な用途 14 カスタム フレーム MDI アプリケーション 73 サイズ変更 84 カッコと OLE オートメーション 377 カプセル化 17, 30 ガベージ コレクション 49 可変長ウィンドウ配列 94 環境変数 PB_FOP_SUPPRESSLOG 556 PB_HEAP_LOGFILE_OVERWRITE 52 PB_HEAP_LOGFILENAME 52 PB_POOL_THRESHOLD 51 PBOnFatalError 514 PBRollbackOnRTError 514 関数 上書き 35 グラフ 272 先祖関数の呼び出し 32 動的 37 引数の受け渡し 35 関数、PowerScript AddColumn 158 AddItem 145, 149, 150, 153 AddLargePicture 155 AddPicture 146, 151 AddSmallPicture 155 AddStatePicture 155, 156 DDE 338 DeleteLargePicture 156 DeleteLargePictures 156 DeletePicture 146 DeleteSmallPicture 156 901 索引 DeleteSmallPictures 156 DeleteStatePicture 156 DeleteStatePictures 156 InsertItem 122, 145, 149, 150, 153 InsertItemFirst 122 InsertItemLast 122 InsertItemSort 122 MAPI 457 SetColumn 158 SetItem 159 SetOverlayPicture 156 データ パイプライン 314 ドラッグ アンド ドロップ 164 ファイル操作 53 ユーティリティ 468 関数、外部 概要 462 宣言 463 データベース ストアド プロシージャ呼び出しのた めの使い方 193 引数の受け渡し 465 関数の多重定義 20 キ キーワード サービス 474 行、テーブル間のパイプライン処理 行間隔、設定 793 共有オブジェクト、概要 586 共有コンポーネント 499 309 ク クライアント アプリケーション COM/COM+ の構築 643 EAServer の構築 561 PowerBuilder.Application の要件 424 PowerBuilder サーバの要件 428 オートメーション 413, 420 同期 207 配布 593 クライアント管理のトランザクション 580 902 クライアント コンピュータ、環境設定 配布 836 クライアント コンピュータの環境設定 ウィンドウ ActiveX 763 ウィンドウ プラグイン 721 データウィンドウ プラグイン 733 クライアント領域 MDI アプリケーション 73 サイズ変更 84 クラス、PBDOM 概要 240 クラス ID(CLSID を参照) 749 グラフ PowerScript 関数 272 ウィンドウ内での系列の作成 273 ウィンドウ内でのデータ ポイントの作成 273 ウィンドウ内でのデータポイントの設定 272 実行中の修正 275 情報取得 278, 280 データの保存 279 データ表示の修正 279 データ プロパティ 277 内部表現 276 プロパティ 276 グラフ関数 データ アクセス 277 データについての情報取得 278, 280 データの保存 279 データ表示の修正 279 グラフでのデータ保存 279 グラフの grAxis サブオブジェクト 276 グラフの grDispAttr サブオブジェクト 276 クリップボードのアプリケーションでの使い方 357 グローバル外部関数 462 グローバル変数 ウィンドウ 91 名前の重複 32 グローバル変数型、デフォルト 195 ケ 継承 PowerBuilder 索引 階層構造 95 サービス オブジェクト 15 先祖オブジェクトの仮想関数 16 継承したオブジェクト間の多相性 19 系列、グラフ ウィンドウ内での作成 273 ウィンドウ内での識別 274 ウィンドウ内でのデータ ポイントの追加 273 結果集合 EAServer での受け渡し 528 PowerBuilder によるストアド プロシージャの 処理 190, 200 トランザクション サーバ環境での受け渡し 621 言語と OLE オートメーション 389 検証、EAServer コンポーネント 533 コ 更新、EAServer コンポーネント内 522 更新ステータス、分散アプリケーション内 522 項目の追加 リストビューへの追加 153 リストボックスへの項目の追加 145, 149, 150 リストボックスへの追加 144, 149 コード セット EAServer Manager での変更 558 コンポーネント プロパティ 539 国際化アプリケーション、設計 767 コロン(スコープ演算子) 32 コンテキスト情報 474 コンテキスト情報サービス 474 コントロール 種類 358 タブ ページ 104 ツリービュー 117 ドラッグ アンド ドロップ 161 ドロップダウン ピクチャ リストボックス 146, 149, 150 ドロップダウン リストボックス 149 ピクチャ リストボックス 144, 145, 146 アプリケーション テクニック マイクロヘルプの使い方 78 リストビュー 152, 154, 155, 156 リストボックス 144 コンパイル オプション 820 スクリプトの記述 53 チェックされない OLE 構文 375 コンポーネント オブジェクト モデル(COM を参 照) 612 コンポーネント管理のトランザクション 580 コンポーネント プロパティの共有 539 コンポーネント プロパティのプール 539 サ サーバ、MobiLink 同期 204 サーバ データベース、環境設定 836 サーバ アプリケーション、OLE 341 サーバ コンピュータ、環境設定 836 サービス オブジェクト 474 再利用可能な動的ライブラリ 824 削除 リストビュー ピクチャ 156 リストボックス ピクチャ 146 サブスクリプション 概要 207 複数サーバとの同期 233 サブルーチン、データベース ストアド プロシー ジャ呼び出しのための使い方 193 参照 EAServer コンポーネントでの引数渡し 531 オブジェクトの動的な参照 824, 828 引数の受け渡し 35, 377 リソースの動的な参照 826 サンプル、コード 5 シ 視覚障害 776 システム例外ハンドラ 589 子孫オブジェクト エンティティの参照 97 903 索引 概要 36 定義 191 実行 アプリケーションの起動 835 グラフへのアクセス 275 データ パイプライン 322 トレース機能 835 ライブラリ リスト 822 実行アプリケーションのトレース 835 実行ファイル 概要 821 作成 833 スタンドアロン 830 テスト 835 含まれるリソース 826 例 830 [ 自動的なデマケーション / 不活性化 ] 設定 513 自動フェイルオーバ コンポーネント プロパティ 539 従属関係 23 ショートカット キー、MDI アプリケーション 89 初期設定ファイル アクセス 795 トランザクション オブジェクト値の読み込み 182 ジョブ、印刷 789 処理効率 概要 30, 383 リソースの配布モデルの影響 824, 826 ス スクリプト OLE オートメーション 390 OLE オブジェクトの操作 374 OLE カラムのアクティブ化 393 グラフの修正 275 同期 206 ブラウザからの OLE 情報 395 リストビュー カラム値の設定 159 リストビュー カラムの追加 158 リストビュー項目の削除 156 904 リストビュー項目の追加 153 リストビュー ピクチャの削除 156 リストビュー ピクチャの追加 155 リストボックス項目の追加 145, 149, 150 リストボックス ピクチャの追加 146, 151 スコープ演算子 32 スタンドアロン実行ファイル 830 ストアド プロシージャ、アプリケーションでの呼 び出し DBMS 機能のサポート 199 ORACLE7 の例 192 ORACLE の例 199 SQLCA に対するデフォルトのグローバル変数 の型の指定 195 アプリケーションのスクリプト記述 197 外部関数としての宣言 193 概要 190 基本的な手順 191 結果集合、PowerBuilder による処理 190, 200 標準クラス ユーザ オブジェクトの定義 192 ユーザ オブジェクトの保存 195 ストアド プロシージャ呼び出しでサポートされる DBMS 機能 199 ストリーム モード 53 セ 静的呼び出し 22 セキュリティ ウィンドウ ActiveX 737 ウィンドウ プラグイン 702 データウィンドウ プラグイン 726 セキュリティ ウィンドウ ActiveX 737 セキュリティ ウィンドウ プラグイン 概要 701 使い方 706 接続 EAServer 563 EJB サーバ 666 OLE オブジェクト 365 トランザクション オブジェクト 183 複数のデータベースの使用 185 PowerBuilder 索引 接続オブジェクト ウィザード 565 接続キャッシュ プロキシの使い方 519 利点 517 宣言 外部関数 462 定数 30 トランザクション オブジェクト 185 先祖オブジェクト ウィンドウ 95 概要 36 関数とイベントの呼び出し 32 先祖スクリプトからの戻り値 33 親 107 削除 102 スクリプトで閉じる 111 スクリプトで開く 111 スクリプト内のコントロール 110 定義 99 独立したユーザ オブジェク 100 表示順序の変更 102 プロパティ シート 104 タブ ページの配列の管理 111 チ 聴覚障害 776 ソ 挿入可能 OLE オブジェクト 343 タ ターゲットとなるコントロールのドラッグ アン ド ドロップ 161 代名詞 27 多相性(ポリモフィズム) 18 タブ コントロール Control プロパティ配列 111 CreateOnDemand プロパティ 113 イベント 114 親 107 概要 99 タブの位置 105 タブ ページの管理 102 タブ ページの種類 100 タブ ラベル 106 定義 99 ドット表記 107 表示形態 104 プロパティ シート 104 タブ ページ イベント 114 埋め込み 100 オブジェクトの参照 111 アプリケーション テクニック ツ 通信エラー、処理 588 ツールバー MDI アプリケーション 74 ツリービュー コントロール 概要 117 例 139 テ 定数 30 データ ウィンドウのグラフとの関連付け 272 ウィンドウのグラフに追加 273 グラフでの保存 279 データ ソース間のパイプライン処理 309 同期 203 データウィンドウ、OLE OLE オブジェクトの関数 391 オートメーション 390, 392 データウィンドウ Web コントロール ActiveX 681 データウィンドウ オブジェクト 概要 283 動的な参照 824, 828 905 索引 ドット表記 29 リソース ファイルへの組み込み 830 データウィンドウ関数 GetChanges 522 GetFullState 522 GetStateStatus 522 SetChanges 522 SetFullState 522 データウィンドウ コントロール データ共有 300 データ パイプライン エラーの処理 316, 322, 329 リッチテキストと関数 286 データウィンドウ式、最適化 38 データウィンドウの同期 522 データウィンドウ プラグイン HTML 文書 726 OLE オブジェクト 730 PSR の作成 729 Web サーバ 732 開発 728 外部リソース 730 概要 725 クライアント ワークステーション ソフトウェア 733 サーバ上のファイル 732 セキュリティ 726 配布コンポーネント 728 ブラウザ / サーバ間の対話 726 要件 727 リッチテキスト提示様式 730 データ型 Any 382 COM/COM+ 617 EAServer 568 XML 691 ウィンドウ 95 ウィンドウの定義 91 データ共有、リッチテキスト エディット コントロー ル 300 データストア オブジェクト EAServer コンポーネントの使い方 516 ツリービューの値の設定 140 標準クラス ユーザ オブジェクト 24 データ ソース 906 Adaptive Server Anywhere 861 配布 861 データ ソース間のデータ転送 309 データ パイプライン PowerBuilder 開発環境での使い方 310 SQLSTATE エラー番号の省略 330 アプリケーションでの使い方 310 エラー行の修復 330 エラー行の処理 329 エラー行の廃棄 332 エラー処理のデータウィンドウ コントロール 316, 322, 329 概要 310 行解析結果の表示 324 更新のコミット 328 実行時の後処理 333 実行時の処理の準備 319 実行の開始 322 実行の監視 324 実行のキャンセル 326 制御用のウィンドウの提供 315 特性の指定 311 パイプライン処理の指定 319 ユーザ オブジェクトのサポート 314, 319, 324, 333 例 309 データ パイプラインの転送先テーブル 311 データ パイプラインの転送元テーブル 311 データ パイプライン ペインタ 対話的な使い方 310 データ パイプラインの定義 310, 311 データ パイプラインへのコミット 311, 328 データベース COM コンポーネントからのアクセス 620 EAServer コンポーネントからのアクセス 516 OLE データの保存 359 アプリケーションでのストアド プロシージャの 呼び出し 190 インタフェースのプロパティ(トランザクショ ン オブジェクト) 177 環境設定 836 接続 183 接続解除 184 PowerBuilder 索引 データ パイプラインの転送先 319, 333 データ パイプラインの転送元 319, 333 データベース間のテーブルの移行 309 トランザクションのプール 189 複数のデータベースへの接続 185 プロファイル、接続プロパティ 174 リッチテキスト 284 データベース インタフェース インストール 836 環境設定 836 プロパティ(トランザクション オブジェク ト) 177 データベースからの接続解除 184 データベース ストアド プロシージャ データ パイプラインの転送元 311 データベース トランザクションのプール 189 データベース内またはデータベース間のテーブ ルの移行 309 テーブル データ パイプラインの転送先 311 データ パイプラインの転送元 311 データベース内またはデータベース間の移行 309 テキスト ファイル 関数 53 読み書き 53 デザイン、ユーザ インタフェース 774 デバッグ 実行のトレース 835 実行ファイル 835 デフォルト以外のトランザクション オブジェク ト SQL 文での指定 186 値の設定 185 概要 185 作成 185 破棄 187 デフォルト以外のトランザクション オブジェク トの作成 185 デフォルト グローバル変数型 195 デフォルトのトランザクション オブジェクト (SQLCA) 174, 180 電子メール システム、アクセス 457 アプリケーション テクニック ト 同期(MobiLink 同期を参照) 同期サーバ 204 統合データベース 204 同時実行コンポーネント プロパティ 501, 539 動的 SQL でのエラー処理 188 動的関数呼び出し 37 動的参照 オブジェクト 824, 828 リソース 826 動的呼び出し 20 動的ライブラリ PowerBuilder ウィンドウ ActiveX 748 PowerBuilder ウィンドウ プラグイン 714 概要 822 独立関係 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 907 索引 デフォルト以外、破棄 187 複数データベース接続 185 リモート プロシージャの呼び出しのテクニック 190 トランザクション オブジェクトのインスタンス化 185 トランザクション オブジェクトのプロパティ 値の設定 181, 185 外部ファイルからの値の読み込み 182 概要 174 記述 174 ストアド プロシージャの呼び出し 197 データベース インタフェースごとのリスト 177 トランザクション コンテキスト サービス 624 トランザクション処理 COM+ のサポート 624 COM クライアントからの制御 646 EAServer 510 SQL 文 179 エラー処理 188 概要 178 データベース トランザクションのプール 189 トランザクション プール 189 ドロップダウン ピクチャ リストボックス コントロー ル 概要 149 項目の追加 149 ピクチャの削除 146 ピクチャの追加 150 例 147 ドロップダウン リストボックス コントロール 概要 149 項目の追加 149 例 147 ナ 内容の種類 名前の修飾 908 703 25 ニ 入力条件則、リッチテキスト 入力フィールド 概要 298 スクリプト 298 テキストへの挿入 284 編集 307 認知障害 777 285 ネ ネットワーク、ユーザ アクセスの設定 836 ハ バイナリ ファイルの読み書き 53 配布 EAServer コンポーネント 557 OLE とレジストリ 434, 437 概要 819 クライアント アプリケーション 593 ランタイム パッケージャ 846 配布 DLL、PowerBuilder 836 パイプライン エラー データウィンドウ 329 パイプライン オブジェクト データ パイプライン ペインタでの定義 311 配布 322 パイプライン処理の指定 319 配列 EAServer コンポーネントでの受け渡し 532 ウィンドウ インスタンス 94 配列の配列 692 パッケージ、COM+ 631 パッケージ化アプリケーションのモデル 概要 830 作成方法 833 テスト 835 パフォーマンス 概要 38 コンパイル時間の短縮 53 変数のスコープ 53 PowerBuilder 索引 パブリケーション 207, 229 パブリック アクセス 30 汎用的スクリプト記述テクニック 108 ヒ 引数 EAServer コンポーネントでの受け渡し 531 OLE 377 受け渡し方法 35 引数の受け渡し EAServer 531 OLE 377 概要 35 ピクチャ リソースとしての配布 826 ピクチャの高さ 145, 150, 154, 155 ピクチャの追加 複数のリストボックスへのピクチャの追加 151 リストビューへの追加 154, 155 リストボックスへの追加 145, 146, 150 ピクチャの幅 145, 150, 154, 155 ピクチャ マスク 145, 150, 154, 155 ピクチャ リストボックス コントロール 概要 144 項目の追加 144, 145 ピクチャの削除 146 例 147 ビジネス ロジック、概要 489 非同期処理 EAServer 584 描画オブジェクト、印刷 793 表記規則 xix 標準クラス データ型の選択 ダイアログボックス 193 フ ファイル DLL 822 PBD 822 PBR 826 アプリケーション テクニック 外部、ファイルからのトランザクション オブ ジェクト値の読み込み 182 実行時 849 実行ファイル 821 リソース 825 リッチテキスト 289 ファイル ポインタ 54 フォーム様式の作成 800 フォント、定義 792 複数データベース、アクセス 185 プライベート アクセス 30 プロキシ オブジェクト Web サービスに対する生成 688 生成 566, 567 プログラム可能なオブジェクト 412 プログラム識別子 421, 430 プロジェクト オブジェクト、作成 834 プロジェクト ペインタ オートメーション オブジェクトの構築 418, 423 配布アプリケーションのパッケージ化における 使い方 834 プロテクト アクセス 30 プロパティ データ パイプライン 314 ドラッグ アンド ドロップ 162 プロパティ、トランザクション オブジェクト 値の設定 181, 185 外部ファイルからの値の読み込み 182 概要 174 記述 174 ストアド プロシージャの呼び出し 197 データベース インタフェースごとのリスト 177 プロパティの変更通知 387 プロファイル、データベース 174 分散アプリケーション アーキテクチャ 489 エラー処理 588 データストア 516 データベース アクセス 516 データベース更新の実行 522 909 索引 ヘ ヘルプ UserHelpFile 169 UserHelpPrefix 169 開発者への提供 167 新規ユーザ ヘルプ ファイル名の指定 169 デフォルトの接頭辞の変更 169 ヘルプ ファイルの名前変更 169 ユーザ定義関数のための作成 168 変数 ウィンドウ型の変数 95 型のない 382 宣言、ウィンドウの型 93 デフォルトのグローバル変数 195 トランザクション オブジェクトのための宣言 185 パフォーマンスへの影響 53 変数のアクセス用メソッド(COM オブジェクト イン タフェースに追加) 616 変数の型プロパティ ページ(アプリケーション ペイ ンタ プロパティ シート) 196 ホ ポインタ、リソースとして配布 826 ポイント アンド クリック、グラフ内 279 ポンド記号、EAServer コンポーネント 559 マ マイクロヘルプの MDI アプリケーションでの使い方 77 マシン コード 820 メ 命名コンポーネント プロパティ 539 メール関連のオブジェクトと構造体 457 メール システム、アクセス 457 メール マージのリッチテキストの例 300 メッセージ オブジェクト 910 概要 472 プロパティ 472 メニュー MDI アプリケーション 73, 74 OLE 353 マージ 353 メニュー項目 マイクロヘルプの使い方 77 メニュー ペインタ マイクロヘルプの使い方 77 メモリの管理 49 ユ ユーザ、MobiLink 207, 231 ユーザ イベント ウィンドウ ActiveX JavaScript での呼び出し 759 VBScript での呼び出し 759 ユーザ インタフェース、国際的な配布のためのデ ザイン 774 ユーザ オブジェクト COM+ コンポーネント 609 Control プロパティ配列 112 EAServer コンポーネント 495 OLE の登録 419 OLE レジストリ 429 PowerBuilder.Application 422 オートメーション サーバ 414, 417 概要 99 構造体としての使い方 24 実行中の型の選択 37 タイプ ライブラリ 419, 433, 450 データ パイプライン処理のサポートのための使 い方 319, 324, 333 データベース ストアド プロシージャ呼び出し のための使い方 192 ユーザ オブジェクトの保存 ダイアログボックス 195 ユーザ オブジェクト ペインタ カスタム トランザクション オブジェクトを定 義する使い方 192 データ パイプライン処理をサポートするユーザ PowerBuilder 索引 オブジェクトの定義 324 ユーザ オブジェクトを構造体として使用する構 造体オブジェクト 24 ユーザ定義関数 上書き 19 状況依存ヘルプの作成 168 多重定義 19 ユーザ定義関数とウィンドウ ActiveX JavaScript での引数 757 JavaScript での呼び出し 757 VBScript での呼び出し 758 ユーザ定義関数の上書き 19, 35 ユーザ定義関数の多重定義 COM ではサポートされない 618 概要 19, 20 ユーザ ヘルプ ボタン 167 ユーティリティ関数 468 ユーロ記号、EAServer コンポーネント 559 ヨ 読み込み専用、引数の受け渡し 35 ラ ライブラリ、動的 822 ライブラリ探索パス、実行アプリケーションで の使用 822 ライブラリ ペインタによるオートメーション オ ブジェクトの構築 418, 423 ライン モード 53 ランタイム パッケージャ 847 リ リストビュー項目 インデックス 152 オーバーレイ ピクチャ インデックス 状態ピクチャ インデックス 152 ピクチャ インデックス 152 ラベル 152 リストビュー コントロール アプリケーション テクニック 152 イメージ リスト 154 概要 152 カラム値の設定 159 カラムの設定 158 カラムの追加 158 項目 152 項目の追加 153 詳細表示 158 ピクチャの削除 156 ピクチャの追加 154, 155 リストボックス コントロール 概要 144 項目の追加 144 例 147 リソース DLL ファイル 824, 827 PBD ファイル 824, 827 ウィンドウ ActiveX 746 ウィンドウ プラグイン 714 概要 825 個別のファイルでの配布 827 実行ファイル 822, 826 テスト 835 動的参照 826 パッケージ化の手順 833 リソース ファイルでの命名 828 例 830 リソース ファイル、作成 828 リソース ファイルでのリソースの探索パス 829 リッチテキスト オブジェクトと書式設定 306 概要 283 作成 284 作成方法 283 選択 301 ツールバー 288 データウィンドウ プラグインの制約 730 データベース 289 データベースへの保存 284 入力条件則 285 入力フィールド 284 日付フィールド 299 911 索引 ページ番号 299 メール マージ例 300 ユーザ操作 305 用途 283 ワード ラップ 288 リッチテキスト エディット コントロール FileExists イベント 292 LoseFocus イベント 291, 302 Modified プロパティとイベント 292 印刷 303 オブジェクト 297, 306 概要 287 書式設定 297 スクロール 300 設定 287 選択 301 挿入ポイント 301 タブ順序 302 ツールバー 288 データ ソース 300 データベースにテキストを保存する例 290 テキストの挿入 289 入力フィールド 298 日付フィールド 299 ファイル 289, 291 ファイルを開く例 293 フォーカス 302 プレビュー 302 ページ番号 299, 303 変更の取り消し 289 編集キー 307 保存 291 保存の例 293 メール マージ例 300 ワード ラップ 288 リッチテキストが使えるワード プロセッサ 284 リッチテキスト 提示様式 516 リッチテキスト提示様式 新しい行 285 スクリプト 286 スクロール 285 入力条件則エラー 285 912 編集キー 307 ユーザ操作 285 リモート ストアド プロシージャ ダイアログボック ス 194 リモート データベース 204 リモート プロシージャの呼び出しのテクニック DBMS 機能のサポート 199 SQLCA に対するデフォルトのグローバル変数 の型の指定 195 アプリケーションのスクリプト記述 197 外部関数としてのストアド プロシージャの宣言 193 概要 191 ストアド プロシージャの結果集合 190, 200 標準クラス ユーザ オブジェクトの定義 192 ユーザ オブジェクトの保存 195 レ 例外、処理 39 EAServer クライアント 588 EJB クライアント 672 Web サービス メソッド 694 レジストリ エントリの作成 433 概要 429 キー 431 クラス情報 394 更新ファイルの作成 447 更新ファイルのサンプル 455 情報の格納 795 ファイルの配置 437 ロ ローカライゼーション 767 ローカル外部関数 463 ログ、EAServer 550 論理的な作業単位 178 PowerBuilder 索引 アプリケーション テクニック 913 索引 914 PowerBuilder
© Copyright 2024 Paperzz