Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


【Delphi/400】ファイルのメンバー作成/削除の手順

前回はIBM i の物理(論理)ファイルのデフォルト以外のメンバーを利用する手法を紹介しましたが、
今回はそのメンバーをDelphi/400から作成・削除する方法をご紹介します。

 


概要・使用目的

ワークファイルをジョブごとに分けて使いたい場合には、主に以下の3つの方法があります。

  • ①:ワークファイルをQTEMPにコピーまたはコンパイルして使用する。
  • ②:ワークファイル内の第1キーをジョブ番号とし、ジョブごとに一意になるようにする。
  • ③:ワークファイル内にメンバーを追加し、ジョブごとに割り当てて独立したメンバーを使用する。

今回はこのうちについてご紹介していきます。

IBM i(AS/400・iSeries)の物理ファイルや論理ファイルにおける
『メンバー』とは、同じファイル内の論理的な区分です。
複数のメンバーを活用することで、データの組織化と管理の効率化を図ることができます。

例えば各ソースファイル(QDDSSRCなど)も複数のメンバーを使用しており、
それぞれのソースは各メンバー内に記述されています。

 

ワークファイルを使用する場合は上記①のQTEMPに作成するパターンが一般的ですが、
③のメンバーを使用する場合にはQTEMPと比較して以下のメリット・デメリットがあります。

  • <メリット>
    • 他のジョブからでもメンバーを指定すれば(エミュレータのRUNQRY等)参照できるため、
      トラブル発生時にワークファイルの内容確認が容易。
    • IntraWebなどでネイティブ接続とそれ以外(FireDAC等)でジョブが分かれる場合でも、
      メンバーを指定することでワークファイルを共用できる。
       
  • <デメリット>
    • 今回紹介するようなメンバー追加・削除の一手間が必要。
    • 使用後はジョブ終了時に自動で解放されないため、
      手動で除去しておかないとIBM i のディスク容量が徐々に圧迫される。
       

今回はワークファイルでメンバー処理を行うことを想定し、
Delphi/400からメンバー追加・削除を行う際の手順を紹介します。

 


前提条件

今回は、下図のようにメンバーを複数使用する想定です。
メンバー名は「M」+ジョブ番号の合計7桁としています。
(他のジョブと重複しない、かつ先頭数字は不可なので「M」をつける)

メンバーを複数使用するためには、DDSのコンパイル(CRTPF)時に
メンバーの最大数(MAXMBRS)のパラメータを「*NOMAX」に設定しておきます。
このメンバーの最大数は、既にコンパイルされたファイルでも
物理ファイル変更(CHGPF)から再設定可能ですが、
SQL(CREATE TABLE)で生成されたファイルはメンバーの複数使用ができません

物理ファイルのメンバー追加にはADDPFMコマンドを、
メンバー削除にはRMVMコマンドを使用します。
事前にエミュレータでコマンドを発行してみて、メンバーの追加や削除ができるかご検証ください。

/*メンバー追加のコマンド*/
ADDPFM     FILE(ライブラリー名/ファイル名) MBR(メンバー名) TEXT('テキスト(省略可)')

/*メンバー除去のコマンド*/
RMVM       FILE(ライブラリー名/ファイル名) MBR(メンバー名)

 

エミュレータでコマンドを発行してみた際にエラーが出た場合、それぞれの意味は以下の通りです。

  • <追加時・削除時>
    CPF7312:ライブラリー~~~にファイル~~~が見つからない。
    • ライブラリー名やファイル名に誤りがないかご確認ください。
    • ライブラリー名を省略した場合は*LIBLが使用されるため、ライブラリーリストに存在するかご確認ください。
  • <追加時>
    CPF5812:メンバー~~~はライブラリー~~~のファイル~~~に既に存在している。
    • この名前のメンバーは既に存在するため、他のメンバー名を指定してください。
    • 同名で再作成したい場合は、既存のメンバーを削除またはリネームして下さい。
  • <削除時>
    CPF5815:メンバー~~~がライブラリー~~~のファイル~~~に見つからない。
    • この名前のメンバーが存在しません。既に削除済みのメンバーをもう一度削除しようとした際などに発生します。
  • <削除時>
    CPF7310:メンバー~~~は~~~のファイル~~~から除去されませんでした。
    • 何らかの理由でメンバー削除に失敗しました。当該メンバーが他のジョブから使用中の場合などに発生します。

 


TCall400を使ったメンバー追加・削除方法

メンバー追加・削除のためのCLを作成して
Delphi/400からTCall400を使って呼び出す場合、以下のように記述します。
ロジックは一例です。実際の要件にあわせて調整してください。)

今回のCLでは追加・削除を同じCLで実施し、パラメータで呼び分けるようにしています。
また追加時も既存メンバーが存在すれば削除することで、上書きを可能にしています。

なお対象ファイルのライブラリーは、ライブラリーリストに存在する前提となります。
(存在しない状態でこのCLをキックするとMSGWになります。)

 
<CLソース>
※プログラム名は任意。以降の文章では「YSCMBR」としています。

/********************************************************************/
/* NAME       : ファイルメンバー追加/削除                           */
/********************************************************************/
             PGM        PARM(&P@PMOD  &P@FLNM  &P@MBNM  &P@ERRC  )

 /*CL変数定義*/
       /*パラメーター*/
             /*プログラムモード 0:作成 1:削除     */
             DCL        VAR(&P@PMOD) TYPE(*CHAR) LEN(1)
             /*ワークファイル名        (文字10桁)*/
             DCL        VAR(&P@FLNM) TYPE(*CHAR) LEN(10)
             /*メンバー名           (文字10桁)*/
             DCL        VAR(&P@MBNM) TYPE(*CHAR) LEN(10)
             /*エラーフラグ            (文字1桁)*/
             DCL        VAR(&P@ERRC) TYPE(*CHAR) LEN(1)

       /*メンバーが既に存在すれば除去*/
             CHKOBJ     OBJ(&P@FLNM) OBJTYPE(*FILE) MBR(&P@MBNM)
             MONMSG     MSGID(CPF9815) EXEC(GOTO CMDLBL(#ST1000))
             RMVM       FILE(&P@FLNM) MBR(&P@MBNM) /*除去実施*/
             MONMSG     MSGID(CPF7310) EXEC(GOTO CMDLBL(#PGMERR))

 #ST1000:
             IF COND(&P@PMOD = '0') THEN(DO)
      /*メンバーを追加*/
             ADDPFM     FILE(&P@FLNM) MBR(&P@MBNM) /*追加実施*/
             MONMSG     MSGID(CPF9999) EXEC(GOTO CMDLBL(#PGMERR))
             ENDDO

/*正常終了*/
             RETURN
/*エラー終了*/
 #PGMERR:
             CHGVAR     VAR(&P@ERRC) VALUE('1')

             ENDPGM

 

 
<Delphi/400 呼び出しソース>

以下のソース中でジョブ番号の取得を行っている関数『GetMyJobNo』は、
デフォルトでは存在しません。以下のTipsをもとに作成してみて下さい。

Delphi/400 プログラム実行中のジョブ情報取得方法

{*******************************************************************************
 目的: メンバー追加/削除処理 TCall400のExecute
 引数:
 戻値:
*******************************************************************************}
procedure TForm2.Button1Click(Sender: TObject);
var
  i: Integer;
  sJOBN: String;
begin

  // ジョブ番号(6桁)を取得し、先頭に「M」をつける
  sJOBN := 'M' + GetMyJobNo;

  with Call4001 do
  begin
    LibraryName := 'TESTLIB';  // CLのライブラリー名、*LIBLも可
    ProgramName := 'YSCMBR';   // CLのプログラム名、任意

    // パラメータの追加(ここは設計画面で実施してもよい)
    ClearParams;              // 初期化
    AddParam('A',  1, 0);     // プログラムモード 0:作成 1:削除
    AddParam('A', 10, 0);     // ワークファイル名
    AddParam('A', 10, 0);     // メンバー名
    AddParam('A',  1, 0);     // エラーコード(戻り値)

    // パラメータ値を指定して実行
    Value[0] := '0';          // プログラムモード 0:作成 1:削除
    Value[1] := 'FILENAME';   // ワークファイル名(※実際の値を指定)
    Value[2] := sJOBN;        // メンバー名(M+ジョブ番号)
    Value[3] := '0';          // エラーコード(戻り値)
    Execute;

    if (Value[3] <> '0') then
    begin
      // 処理失敗時のメッセージ(一例)
      ShowMessage('処理に失敗しました。');
    end;
  end;
end;

 

 


ネイティブ接続不使用時のメンバー追加・削除方法

前回の記事(OVRDBF)の時と同様に、
IntraWebで構築している場合やTAS400を全く使用していない場合など、
ネイティブ接続を不使用のときにはTAS400TCall400コンポーネントが使えません。

このような場合は、クエリーコンポーネント(TFDQueryやTSQLQuery)を使って
SQL単独で実行可能です。

Delphi/400では、クエリーのSQL文にCALLコマンドを指定してExecSQLすると、
そのコマンドを実行することができます。
(TAS400のRemoteCmdと同様、戻り値を受け取ることはできません。)

CALLコマンドの指定方法は、以下の2通りがあります。
以下1.2.いずれかのコマンドをクエリーのSQLプロパティにセットしてExecSQLします。

1.メンバー処理を行うCLを呼び出す
LibName・CLNameは、それぞれCALLするCLのライブラリ名とプログラム名です。
このコマンドは上記で例示したソースのCLを呼び出すイメージとなっています。
また、パラメータとして処理成否を渡していますが受け取ることはできません。

2.コマンド実行 (QCMDEXC) APIを使ってコマンドを直接発行する
CL使用時とは異なり、処理失敗時のエラーが実行中のDelphi/400アプリケーションに直接返されます。
(既に存在するメンバーをADDPFM、逆に存在しないメンバーをRMVMしようとした場合など)
コマンドを直接発行する前に、メンバーの存在チェックを行っておくと安全です。詳細は後述します。

1.メンバー処理を行うCLを呼び出す例
メンバー追加例:CALL PGM(TESTLIB/YSCMBR) PARM(('0') ('FILENAME') ('MEMBNAME') ('0'))
メンバー削除例:CALL PGM(TESTLIB/YSCMBR) PARM(('1') ('FILENAME') ('MEMBNAME') ('0'))

2.コマンド実行 (QCMDEXC) APIを使ってコマンドを直接発行する例
メンバー追加例:CALL QCMDEXC('ADDPFM  FILE(FILENAME) MBR(MEMBNAME)')
メンバー削除例:CALL QCMDEXC('RMVM  FILE(FILENAME) MBR(MEMBNAME)')

 

2.においては、コマンドを直接発行する前に、メンバーの存在チェックを行っておくと安全です。
メンバーの一覧を出力してくれるSYSPARTITIONSTATビューを使って、
対象のファイルやメンバーの存在チェックができます。【※V7R1以降で確認】
(詳細:SYSPARTITIONSTAT – IBM Documentation )

クエリーを使って以下のようなSQLを発行して、一致するメンバー名があればレコードが抽出されます。
(※WHERE句はそれぞれライブラリ名、ファイル名、メンバー名。
  ライブラリは「*LIBL」を指定できないため、直接指定または全ライブラリを対象とします。)

SELECT DISTINCT SYS_DNAME, SYS_TNAME, SYS_MNAME
FROM QSYS2/SYSPARTITIONSTAT
WHERE SYS_DNAME = 'TESTLIB'
  AND SYS_TNAME = 'FILENAME'
  AND SYS_MNAME = 'MEMBNAME'