メニューボタン
IBMi海外記事2013.02.20

他の対話型ジョブの画面を表示させる方法

カーステン・フレンズバーグ 著

ここでご紹介するAPIの使用例を通じてプログラミングに対する2つの興味深い課題についてご紹介します。1つ目の課題は、他のジョブ中でプロセスを遂行するプログラムを実行することに関連しています。2つ目の課題は、表示ファイルやパネル・グループを介することなく5250データ・ストリームを表示装置に直接通信させる処理をすることについてです。後者については動的画面マネージャ(DSM: Dynamic Screen Manager) APIがこの要件を処理するための堅牢でわかりやすい方法を提供しています。従来の方法では、5250データ・ストリームをDDSキーワードUSRDFNなどといった表示ファイル・レコード形式に手で記述していました。しかしDSM APIはこの処理を簡素化し、表示装置に対する通信をより意識せずに済むようにしてくれました。

この興味深い試みに携わったきっかけは自分の会社のサービス・デスクからの要求から出てきたものでした。そのサービス・デスクの担当者は、リモートの対話型ジョブの画面を簡単に覗き見して支援を必要としているユーザーをサポートしてガイドできる機能が欲しいと言ってきました。ヨーロッパ中のユーザーがエラーメッセージやメニューのオプションをさまざまな言語で電話で読み上げるより、ユーザーの肩越しにすばやく見る方がずっと効率的でしかも誤りが少ないはずです。対話型のジョブをユーザー・プロフィール名で検索するのも、ネットワーク上で問題となっているリモート端末を識別するよりもずっと速くできることがわかっています。この課題を頭に置いて、私は手元にあるオプションを調査することから始めてDisplay Job Screen (DSPJOBSCN)コマンドを作成しました。

QWCJBITP API

他のジョブの中でプログラムを実行させるには、精巧ではあるけれども複雑で少しだけわかりにくい方法を使用していました。1つの方法は対象とするジョブ中でメッセージ・キューのbreak処理プログラムを使用する方法で、もう1つの方法はStart Service Job (STRSRVJOB)コマンドとTrace Job (TRCJOB)プログラムの出口プログラム機能との間の協調動作を伴う方法です。1つ目の方法を使用するときはユーザー・プログラムをシステム状態に継ぎ当てるか、または、対象とするジョブを実行しているユーザーの協力を求めるかのいずれかが必要でした。あなたが舞台裏でプログラムを実行しているということを対象とするジョブのユーザーに知られることのないように後者の方法を実行することができます。IBMはリリース5.4からTRCJOBコマンドの出口プログラム(EXITPGM)パラメータを無効にしました。そしてリリース6.1では、新しいオブジェクト完全性執行スキーマがオブジェクトをシステム状態に継ぎ当てるオプションを取り去りました。

しかしリリース5.4では他のジョブ中でプログラムを実行するための、システムによってコントロールされるアクセスを提供する別の概念が導入されました。Call Job Interrupt Programは以下のシステム・コンポーネントに基づいています。

  • Call Job Interrupt Program (QWCJBITP) APIを使用すると、割り込むジョブと呼び出す出口プログラムを指定できます。
  • 登録機能のQIBM_QWC_JOBITPPGM 出口点では、QWCJBITP APIを呼び出す前にこの出口点に対して指定された出口プログラムを追加する必要があります。
  • Allow Jobs to be Interrupted (QALWJOBITP)というシステム値は3つの割り込み可能な状態のうちの1つを定義できます。 デフォルト値である0 (ゼロ)を指定するとジョブの割り込みを一切認めません。値を1とするとジョブの割り込みが可能になりますがすべての新しいジョブはデフォルトで割り込み不可となります。値を2としてもジョブの割り込みが可能になりますが、すべての新しいジョブはデフォルトで割り込み可能となります。
  • システム値QALWJOBITPの値を1に設定してChange Job Interrupt Status (QWCCJITP)を使用すると、ジョブの初期割り込み不可ステータスをジョブ自身の中で割り込み可能に変えることができます。ジョブのユーザーの協力があればこの障害物は対話型ジョブの中で簡単に取り除くことができますが、バッチ・ジョブはその手の届かないところにあります。

出口プログラムを実行する直前に、システムは対象とするジョブの初期スレッドのユーザー・プロフィールをQWCJBITP APIの呼び出し側のユーザー・プロフィールと入れ替えるという点に注意してください。出口プログラムの実行が(通常の終了条件またはエラーによって)完了すると、対象とするジョブの初期スレッドのユーザー・プロフィールが、出口プログラムを呼び出す前の実際のユーザー・プロフィールに入れ替えて戻されます。つまり、出口プログラムは対象とするジョブの中で、QWCJBITP APIを呼び出したユーザー・プロフィールの権限と特権で実行されるということを意味しています。

図1のQWCJBITP APIのパラメータの一覧を見てみましょう。入力変数はQWCJBITP APIが実行する出口プログラムを見つけるために必要な情報、割り込む対象ジョブ、最大で2,000バイトまでのプログラム・データを伝達するためのデータ構造を定義していて、このデータ構造は出口プログラムに対する主要な入力パラメータとして提供されます。入力フォーマット名は入力変数のフォーマットを識別し(図2)、現在のところJITP0100というフォーマットだけが利用可能になっています。

QWCJBITP APIが割り込んだジョブ中で呼び出すプログラムをプログラム名とライブラリで識別します。呼び出しが正常に完了するためには指定されたプログラムはQIBM_QWC_JOBITPPGM出口点とともに登録されていなければなりません。対象ジョブ名、ユーザー、数字で割り込むジョブを識別し、それに続いて出口プログラムを呼び出します。プログラム・データは出口プログラム対してその最初のパラメータとしてサブミットされます。プログラム・データの長さは最大で2,000バイトです。出口プログラムの2番目のパラメータは4バイトの整数で、プログラム・データの実際の長さを保持しています。

DSM API

この時点で、前提条件として他のジョブ中でプログラムを実行させておかなければなりません。ここで対話型ジョブの現在の画面を取り出す方法を見つける必要があります。ここがDSM APIを使うと便利な場面です。DSM APIは画面を動的に作成して操作するための画面入出力関数群を提供しています。通常はDDSで表示ファイルやパネル・グループ、あるいはユーザー・インタフェース・マネージャ(UIM)をそれぞれコーディングすることで画面を定義します。DSMでは一連のDSM APIを呼び出すことで画面の表示を指定し制御することが、その場でできます。DSMのインタフェースは束縛可能なので、ILEプログラムだけにアクセスが可能です。DSM APIは以下の3つの関数グループに分かれています。

  • 低レベルのサービスは5250データ・ストリーム・コマンドに対する直接的なインタフェースを提供します。これらのAPIを使用して画面の状態を問い合わせて操作します。つまり、入力コマンドとコマンド・バッファを作成、問い合わせ、操作して画面と対話します。そしてフィールドを定義しデータを画面に書き出します。
  • ウィンドウ・サービスを使用するとウィンドウの作成、削除、移動、サイズの変更と、1つのセッション中で複数のウィンドウの操作を管理できます。
  • セッション・サービスは汎用のスクロール・インタフェースを提供し、セッションの作成、問い合わせ、操作とセッションに対する入出力操作が実行できます。

一般的に、DSM APIはその機能を直接操作モードあるいは間接操作モードのいずれかで実行します。直接操作モードでは、DSM APIは生成された5250データ・ストリームを表示装置に直接通信します。間接操作モードでは、リクエストされた画面操作のグループを蓄積しておくコマンド・バッファを使用し、蓄積された操作は1つの入出力操作で画面に対して書き出すことができます。
リモートの現在の画面、対話型ジョブを取り出してその画面を現在のジョブ中に表示するためのステップは以下のとおりです。

  1. 通信データ・キューが存在するかどうかを調べ、必要があればキューを1つ作成する。
  2. QWCJBITP APIの JITP0100パラメータ・データ構造を初期化する。
  3. APIプログラム・データ構造を初期化する。
  4. データ・キューputエントリとreplyエントリに対するユニークなキーを作成する。
  5. データ・キュー・エントリをユーティリティ・データ・キューに移動し、応答を待つ。
  6. QWCJBITP APIを呼び出してJITP0100パラメータ・データ構造を渡す。

    この時点で対象とするジョブがコントロールを掌握します。

  7. プログラム・データ構造情報に基づいたキーでデータ・キュー・エントリを取得する。
  8. 現在の画面イメージとその他の画面情報を取得する。
  9. 戻ってきたデータ構造を取得した画面情報で更新する。
  10. データ・キュー・エントリを応答キーとともにユーティリティ・データ・キューに移動し終了する。

    ここで現在のジョブがコントロールを取り戻します。

  11. 応答キーでデータ・キュー・エントリを取得し、戻ってきたデータを処理する。
  12. 現在の画面をクリアする。
  13. 取り出した画面とカーソル位置を回復する。
  14. ファンクション・キーが押されるのを待つ。F3キーが押されればプログラムを終了し、F5キーが押されれば上記ステップ2~14を繰り返す。

DSM APIは上記の画面入出力関数をすべて遂行します。通常、画面入出力操作は同じジョブの中で発生しますので、入出力バッファはすべてジョブの内部で保存されて1つのDSM APIが返してきて次のDSM APIに渡されるバッファ・ハンドルを介してのみ参照可能です。ただしこの場合、実際の画面バッファ・データを取り出す必要があります。バッファ・ハンドルは同じジョブ内でのみ有効です。バッファ・データにアクセスできないのであれば、DSPJOBSCNコマンドを実行しているジョブにそれを戻すことができません。

この障害物を乗り越えるために、私は入出力操作をDSMが直接サポートしていない場合や今回の場合のように目の前の目的に適したサポートがない状況のために提供されている2つのDSM APIを使っています。QsnPutlnpCmdとQsnPutOutCmdの2つのDSM APIを使用すると、適切な5250データ・ストリーム・コマンドを直接使用して入出力操作を遂行することができます。今回の状況で使用する5250コマンドはSAVE SCREENとRESTORE SCREENになります。 SAVE SCREENコマンドにはRESTORE SCREENコマンドと戻ってきたコマンド・バッファのエスケープ・シーケンスが暗示的に含まれています。したがってこのコマンド・バッファをQsnPutOutCmd APIに対して直接与えることで取り出した画面を回復することができます。

CBX2561ソースとCBX2562ソースを調べるかまたはプログラムの実行中にソース・デバッグ・セッションを実行することで、画面ダイアログがどのように展開されるのかを詳細にみることができます。CBX2562プログラムをデバッグするには、対象とするジョブ中でこのプログラムに対してデバッグ・セッションを起動し、次に別のセッションから対象とするジョブに対してDSPJOBSCNコマンドを実行します。以前の記事で紹介したWork with Jobs (WRKJOBS)コマンドを更新してリスト・オプション15=ジョブ画面の表示を追加しておきました。このオプションは関連するジョブを探してDSPJOBSCNコマンドを発行するのを少しだけ容易にしてくれます。

このリストをさらに絞り込むには特定のあるいは汎用のジョブやユーザー名を明記します。システム値QALWJOBITPが1に設定されていてジョブがデフォルトで割り込み不可になっている場合は、そのジョブ中で以下のChange Job Interrupt Status Attribute (CHGJOBITPS)コマンドを実行することでジョブの割り込みステータスを割り込み可能に変えることができます。

fig021

システム値QALWJOBITPが2に設定されている場合はすべてのジョブがデフォルトで割り込み可能になっています。この場合はCHGJOBITPSコマンドを使用して特定のジョブ中でジョブの割り込みを禁止することができます。ルーティング・エントリを使用するとジョブのデフォルトの割り込みステータス属性をシステム値QALWJOBITPがサポートしているよりもより細かなレベルでグローバルにコントロールすることができます。

図3にDSPJOBSCNコマンド・プロンプトを示します。このコマンドは現在の画面をリストするジョブの有効名と、ジョブの割り込みプロセスがタイムアウトになるまでの秒数を定義する2番目のコマンド・パラメータを受け取ります。

図4はシステムのメイン・メニューを対象とするジョブの現在のジョブ画面として取り出した例を示しています。ファクション・キーのテキストF3=ExitとF5=Refreshはジョブ画面表示コマンドをキャンセルするか、または現在の画面を更新するかをそれぞれ反映しています。ファンクション・キー・テキストの表示のオン、オフを切り替えるにはF2キーを使います。対象とするジョブ画面のカーソル位置も取り出されて、表示された画面コピー上に追加されています。

あわせて読みたい記事

PAGE TOP