データウィンドウが表示されるまで(前編)
こんにちは、サポート部の Yama-chan です。いつも「初心者の憂鬱」シリーズを読んでいただき、ありがとうございます。
はじめに
PowerBuilder の機能を紹介するブログをいくつか書きましたが、いつも「まず、やってみよう」をモットーに簡単な説明とシンプルな操作がメインで、そして機能がうまく動作しているところまで紹介する内容がほとんどでした。機能や仕組みなどの説明も詳しく書きませんでした。書けなかったのは実は自分もちゃんと理解できていなかったからなのかもしれません。
ブログを書いていく中で今回は少し踏み込んだ形で、アプリケーションの起動からデータウィンドウが表示されるまでに内部でどんなイベントを使用して動作させているのか、そしてそれぞれのイベントでどのような処理を書くのかなどについて解説したいと思います。エラー処理に関しても今までは触れていませんでしたが、そのあたりも説明したいと思います。
それでは早速はじめましょう。
すべては Open から始まる
PowerBuilder でのアプリケーションはイベント駆動型になっています。メニュー選択、ボタンクリックなどユーザーの操作により発生するイベントのほか、アプリケーションが実行された時にもイベントが発生します。また処理の結果によりいろんなイベントも発生します。イベント内で PowerScript 言語を使用して処理を書くことでアプリケーションが動作します。そして、アプリケーションが実行されるとき、一番最初に発生するイベントが Application オブジェクトの Open イベントです。では、この Open イベントで何を書けばよいのか、考えてみましょう。
この Open イベントはアプリケーションを実行した時に一度しか発生しません。つまりこのイベントはアプリケーションの始まりで、どのウィンドウを表示するのかもこの Open イベントに書かなければ、アプリケーションを実行しても、画面には何も表示されません。
Open ( w_main )
GUI を表示するアプリケーションであれば、必ず上記のような PowerScript が Open イベントに書かれていると思います。この例では w_main というウィンドウを開いています。これはアプリケーションで一番最初に表示するウィンドウになります。今までのブログで紹介したデモアプリでもよく見かけたと思います。
さらに、一番最初にこの Open イベントが発生するので、ここでアプリケーションを実行するための準備を行いましょう。必要な準備処理を記述し、それから、最初に表示するウィンドウを開きます。準備処理として、一番多いのはやはりデータベースとの接続ではないでしょうか。それでは、データベースとの接続処理を見ていきましょう。
データベースとの接続処理
PowerBuilder アプリケーションからデータベースに接続するには、トランザクションオブジェクトのプロパティとして、必要な接続パラメーターをアプリケーションのスクリプトに指定しなければなりません。たとえば、アプリケーションの Open イベントのスクリプトに接続パラメーターを指定します。
いざやろうとすると、データベースと接続するには何をどのように書いたらいいのか分からない方も多いと思います。特に初心者ビルダーさんはだいたいここでつまずきます。私もそうでした。
でも、心配は不要です。
まず DB プロファイルを開いて、プレビュータブを見てみましょう。DB プロファイルは DB ペインタから「ODB ODBC」「PB Demo DB V2017R3」を選択後、右クリックしてプロパティをクリックすると表示されます。なお今回は PowerBuilder インストール時にデモ用のアプリケーションも同時にインストールしているため自動的に設定されています。
プロファイルプレビュー画面
なんと、デフォルトですでに DB 接続構文が選択されています。しかも「コピー」ボタンまで用意されているではないか!そうです。 PowerBuilder は、親切に接続方法をコピペでできるようになっています。また、正しく接続できるか検証するための「接続のテスト」ボタンも用意されています。念のために一度「接続のテスト」ボタンを押して、データベースサーバーと正常に接続できることを確認してから、コピーするようにしましょう。「接続のテスト」ボタンを押して、問題がなければ、「接続に成功」と表示されるはずです。つぎに「コピー」ボタンを押して接続構文をコピーしましょう。
つぎに Application オブジェクトの Open イベントを開いてみましょう。はじめは空でスクリプトは何も記述されていません。早速コピーした接続構文を貼り付けましょう。下記のようになります。
// Profile PB Demo DB V2017R3 SQLCA.DBMS = "ODBC" SQLCA.AutoCommit = False SQLCA.DBParm = "ConnectString='DSN=PB Demo DB V2017R3;UID=dba;PWD=******'"
パスワードはダミーとなっているので実際のパスワードを入力してあげましょう。
上記のスクリプトは接続構文を用意しただけですので、接続するには以下のスクリプトが必要となります。
CONNECT USING SQLCA ;
SQLCA は標準で用意されているグローバルトランザクションオブジェクトです。接続するデータベースが一つの場合はこの SQLCA を利用します。なお、USING SQLCA は省略可能ですので、SQLCA のみを利用する場合は省略して構文をシンプルに記述できます。
注意してほしいのは接続したら、かならず切断処理を忘れずに入れることです。この時点で、Application オブジェクトの Close イベントに、DISCONNECT を書くようにしましょう。
DISCONNECT;
デモアプリを作成するときは DB 接続の確認ができているのでここまで十分なのですが、今回は DB との接続でエラーが発生したかどうかのチェック処理を入れます。エラーが発生した場合はエラー内容を表示し、正常に接続できた場合は最初のウィンドウ: w_main を開くようにします。
// データベースに接続します。 CONNECT USING SQLCA ; // 接続が成功したかどうかをテストします。 IF SQLCA.SQLCode <> 0 THEN MessageBox ("接続失敗", "データベースへの接続ができません。" + SQLCA.SQLErrText ) RETURN ELSE Open ( w_main ) END IF
またスクリプトを先に書いてしまいましたが、トランザクションオブジェクト SQLCA のプロパティ SQLCode を確認することでデータベースとの接続結果が分かります。 SQLCode が 0 ではないときはデータベースとの接続がエラーとなり、正常に接続できていません。その場合、エラーメッセージを表示し、アプリケーションを終了するようにしています。 0 が返ってきた場合は正常に接続できたことになり、Open 関数で最初のウィンドウ w_main を開くようにしています。なお、データベースから返された詳細なエラー情報はプロパティ SQLErrText で確認できます。この情報は接続しているデータベースの種類によって、内容が違いますので、ご注意ください。
INI ファイルによるアプリケーションの初期設定
上記の説明で DB 接続設定はコピペでもできると紹介しました。入門としてコピペを利用して、初心者でもすぐに開発に取り掛かれますが、実際の開発現場ではやはりハードコーディングになってしまい実用性に欠けます。このトピックスでは INI ファイルから DB 接続設定情報を読み込んで使用する方法をご紹介します。 INI ファイルは設定ファイルとも言います。アプリケーションを実行する際必要な設定値が保存されているものです。「セッション」と「パラメーター」で構成されています。
では、早速 myapp.ini というファイルを用意し、内容は以下のように設定します。なお、このサンプルでは INI ファイルはアプリケーションターゲット( pbt ) ファイルがある場所に格納しています。
; セッション名 [DataBase] ; パラメーターに設定する値 DBMS=ODBC AutoCommit=False Database=PB Demo DB V2017R3 LogID=dba LogPassword=***
これはデモアプリで私がよく使用している SQL Anywhere と接続するために必要な設定です。接続先のデータベースサーバーの種類によって、設定する内容が違いますので、詳細は使用するデータベースに合わせてマニュアルをご参照ください。
ProfileString 関数を使用して、INI ファイルから設定情報を読み込みます。パラメーターとしては INI ファイル名、セッション名、キー名、そして取得できなかったときのデフォルト値を指定します。以下のサンプルスクリプトをご参照ください。
String ls_database, ls_logid, ls_logpass, ls_autocommit SQLCA.DBMS = ProfileString ("myapp.ini", "DataBase", "DBMS", "") ls_database = ProfileString ( "myapp.ini", "Database", "Database", "") ls_logid = ProfileString ( "myapp.ini", "Database", "LogID", "") ls_logpass = ProfileString ( "myapp.ini", "Database", "LogPassword", "") SQLCA.DBParm="ConnectString='DSN=" + ls_database + ";UID=" + ls_logid + ";PWD=" + ls_logpass + "'" ls_autocommit = Upper ( ProfileString ("myapp.ini", "Database", "Autocommit","")) IF ls_autocommit = "TRUE" THEN SQLCA.Autocommit = TRUE ELSE SQLCA.Autocommit = FALSE END IF
SQLCA の Autocommit は Boolean 型になっているので、文字列で読み込んだ情報をそのまま DB 接続設定のプロパティに設定できません。上記の例では、文字列を判定して、’TRUE’ であれば、Autocommit に TRUE を設定し、それ以外の場合は FALSE に設定しています。注目してほしいのは読み込んだ文字列情報に対して Upper 関数を使用して、大文字に変換していることです。これは INI ファイルを作成する時に大文字と小文字が混じっていても、すべて大文字に変換して判定できるようにするためです。一つのテクニックとして覚えておいて損はないでしょう。
ウィンドウも Open イベントから
ウィンドウの表示も同じく、一番最初のイベントが Open です。そうです。すべてが Open から始まります。ウィンドウの Open イベントで何を書けばよいのでしょうか?
ウィンドウの Open イベントではウィンドウ上に配置されているコントロールの初期設定、またはデータウィンドウに表示させるデータをデータベースから取得する機能が主な処理となります。もちろん実際のアプリに応じてウィンドウを表示させるための事前処理をこのイベントで行います。
今回のテーマはデータウィンドウが表示されるまでになっているので、データウィンドウの表示に必要な処理をメインに紹介しながら、スクリプトを書いていきます。
トランザクションオブジェクトは前節で紹介した標準のグローバルトランザクションオブジェクト SQLCA を使用します。たとえば、顧客情報のテーブルを単純に表示するデータウィンドウ dw_customer があるとしてつぎの処理を見てみましょう。ウィンドウの Open イベントでウィンドウ内のデータウィンドウ dw_customer にデータを読み込んでいます。
long ll_rows dw_customer.SetTransObject(SQLCA) ll_rows = dw_customer.Retrieve() IF ll_rows = -1 THEN MessageBox("エラー", & "データベースからデータの読み込みに失敗しました!") END IF
今まで紹介したサンプルアプリと違って、エラー処理を追加しました。バグの元になりますから、何か関数を呼び出したら、必ず戻り値を確認するように習慣を付けた方がよろしいかと思います。
Retrieve ()の戻り値としては以下のとおりです。
1 以上 | 検索されたデータの件数となります。 |
0 | 検索されたデータの件数が 0 件となります。 |
– 1 | エラーが発生したことを意味します。この時に DBError イベントが発生します。 |
戻り値の情報はマニュアルに記載されているので、スクリプトを書いているときは常にオンラインヘルプを開いておくとよいでしょう。
まとめ
以上、Application オブジェクト と ウィンドウオブジェクトの Open イベントでのデータベース接続処理およびエラー処理について説明してきました。初めて先輩ビルダーが DB 接続構文をコピペしてコーディングしているところを見たときは衝撃的でした。これはそのために用意されたものだったんだ!と感動しました。そのおかげでデータベースから必要とするデータを取り出してデータウィンドウに表示するといった簡単なデモ用のアプリケーションなら 5 分でできます。もちろん、PowerBuilder の開発スピードが高いからできることだと思います。
前編ではすべては Open から始まることと、Open でのデータベース接続処理について説明しましたが、後編ではデータウィンドウが表示されるまでの他のイベントを確認しながら、解説していきます。
以上、Yama-chan でした。