可変長の文字形式、図形形式および UCS-2 形式

可変長文字フィールドには、宣言された最大長と、プログラムの実行時に変化する 現在の長さがあります。 この長さは、文字形式の場合は 1 バイト単位で、図形形式および UCS-2 形式の場合は 2 バイト単位で測定されます。可変長文字フィールドに割り振られる記憶域は、宣言された 最大長より 2 バイト長くなります。 左端の 2 バイトは、現在の長さを示す文字数、図形文字数、または UCS-2 文字数が入っている符号なし整数フィールドです。実際の文字データは可変長フィールドの 3 番目のバイトから開始します。 図 81 は可変長文字フィールドの記憶方法を 示しています。

図 81. 可変長形式の 文字フィールド

図 82 は、 可変長図形フィールドの保管方法を示しています。UCS-2 フィールドも同様に保管 されます。

図 82. 可変長形式の図形フィールド
注:
現在の長さまで (現在の長さを含む) のデータのみが有効になります。

可変長文字データフィールドを定義するには、定義仕様書に、A (文字)、G (図形)、また は C (UCS-2) と、キーワード VARYING を指定します。 また、パラメーターが可変長文字フィールドである場合には、 定義仕様書の LIKE キーワードを使用して定義することもできます。

外部可変長フィールドを参照するには、入力仕様 または出力仕様で、*VAR データ属性を 使用します。

可変長フィールドは、デフォルトで、ゼロの現在の長さを持つように 初期化されます。

可変長フィールドの使用例については、以下の項を参照してください。

可変長の文字形式、図形形式、および UCS-2 形式に関する規則

可変長フィールドを定義する場合、次の規則が適用されます。

以下に示すのは、可変長文字フィールドの定義例です。

図 83. 可変長文字および UCS-2 フィールドの定義
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... *
DName+++++++++++ETDsFrom+++To/L+++IDc.Functions++++++++++++++++++++++++++++
 * Standalone fields:
D var5            S              5A   VARYING
D var10           S             10A   VARYING INZ('0123456789')
D max_len_a       S          32767A   VARYING
 * Prerun-time array:
D arr1            S            100A   VARYING FROMFILE(dataf)
 * Data structure subfields:
D ds1             DS
 *   Subfield defined with length notation:
D   sf1_5                        5A   VARYING
D   sf2_10                      10A   VARYING INZ('0123456789')
 *   Subfield defined using positional notation: A(5)VAR
D   sf4_5               101    107A   VARYING
 *   Subfields showing internal representation of varying:
D   sf7_25                     100A   VARYING
D   sf7_len                      5I 0 OVERLAY(sf7_25:1)
D   sf7_data                   100A   OVERLAY(sf7_25:3)
 * Procedure prototype
D Replace         PR         32765A   VARYING
D   String                   32765A   CONST VARYING OPTIONS(*VARSIZE)
D   FromStr                  32765A   CONST VARYING OPTIONS(*VARSIZE)
D   ToStr                    32765A   CONST VARYING OPTIONS(*VARSIZE)
D   StartPos                     5U 0 VALUE
D   Replaced                     5U 0 OPTIONS(*OMIT)

以下に示すのは、可変長図形フィールドおよび UCS-2 フィールドの定義例です。

図 84. 可変長図形フィールドおよび UCS-2 フィールドの定義
* .. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+...
DName+++++++++++ETDsFrom+++To/L+++IDc.Functions++++++++++++++++
 *-------------------------------------------------------------
 * Graphic fields
 *-------------------------------------------------------------
 * Standalone fields:
D GRA20           S             20G   VARYING
D MAX_LEN_G       S          16383G   VARYING
 * Prerun-time array:
D ARR1            S            100G   VARYING FROMFILE(DATAF)
 * Data structure subfields:
D DS1             DS
 *   Subfield defined with length notation:
D   SF3_20                      20G   VARYING
 *   Subfield defined using positional notation: G(10)VAR
D   SF6_10               11     32G   VARYING
 *-------------------------------------------------------------
 *   UCS-2 fields
 *-------------------------------------------------------------
D MAX_LEN_C       S          16383C   VARYING
D FLD1            S              5C   INZ(%UCS2('ABCDE')) VARYING
D FLD2            S              2C   INZ(U'01230123') VARYING
D FLD3            S              2C   INZ(*HIVAL) VARYING
D DS_C            DS
D   SF3_20_C                    20C   VARYING
 *   Subfield defined using positional notation: C(10)VAR
D   SF_110_C             11     32C   VARYING

可変長フィールドの使用

可変長フィールドの長さの部分は、文字で測定されたフィールドの現在の長さを 表します。 文字フィールドの場合には、この長さはバイト単位での現在の長さも表します。 2 バイト・フィールド (図形および UCS-2) の場合、これは、2 バイト単位での フィールドの長さを表します。 たとえば、現在の長さが 3 である UCS-2 フィールドの長さは、3 個の 2 バイト文字 で、6 バイトということになります。

次のセクションでは、可変長フィールドを最大限活用する方法 と、異なる命令コードを使用するときに現在の長さを変更する方法について説明 します。

フィールドの長さの設定方法

可変長フィールドが INZ を使用して初期化されるとき、初期長は 初期化値の長さに設定されます。 たとえば、長さ 10 の文字フィールドが値 'ABC' に初期化される と、初期長は 3 に設定されます。

EVAL 命令では、可変長ターゲットの長さが変更されます。 たとえば、長さ 10 の文字フィールドに値 'XY' が割り当てられる と、長さは 2 に設定されます。

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++++
D fld                      10A        VARYING
 * It does not matter what length 'fld' has before the
 * EVAL; after the EVAL, the length will be 2.
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq...
C                   EVAL      fld = 'XY'

DSPLY 命令では、可変長結果フィールドの長さが、ユーザーによって入力された 値の長さに変更されます。 たとえば、結果フィールドが長さ 10 の文字フィールドであり、ユーザーに よって入力された値が '12345' である場合、このフィールドの長さは、DSPLY 命令 によって 5 に設定されます。

CLEAR 命令では、可変長フィールドの長さが 0 に変更されます。

PARM 命令では、結果フィールドの長さが、演算項目 2 (指定されている場合) の中の フィールドの長さに設定されます。

固定形式命令の MOVE、MOVEL、CAT、SUBST および XLATE は、可変長結果フィールド の長さを変更しません。 たとえば、値 'XYZ' が、MOVE を使用して、現在の長さが 2 である長さ 10 の 可変長文字フィールドに移動された場合、このフィールドの長さ は変更されず、データが切り捨てられます。

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++++
D fld                      10A        VARYING
      * Assume fld has a length of 2 before the MOVEL.
      * After the first MOVEL, it will have a value of 'XY'
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq...
C                   MOVEL     'XYZ'      fld
      * After the second MOVEL, it will have the value '1Y'
C                   MOVEL     '1'        fld
注:
MOVE と MOVEL について推奨される使用法は、EVAL とは対照的 に、一時的に長さを固定したいフィールドの値を変更する場合です。 たとえば、報告書を作成する場合に、その列のサイズが毎日異なって いて、ただし、プログラムの所定の実行時にはそれを固定する必要がある、という場合などです。

フィールドがファイル (入力仕様書) から読み取られるとき、可変長フィールドの 長さは入力データの長さに設定されます。

出力仕様書の「後で消去」機能は、可変長フィールドの長さを 0 に設定します。

可変長フィールドの長さは、EVAL 命令の左側の %LEN 組み込み関数を使用して、ユーザー自身で設定することができます。

フィールドの長さの使用法

可変長フィールドがその値に使用されるとき、その現在の長さが使用されます。 次の例では、「結果」は長さが 7 の固定長フィールドと想定されています。

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++++
D fld                      10A        VARYING
 * For the following EVAL operation
 *    Value of 'fld'    Length of 'fld'   'result'
 *    --------------    ---------------   -----------
 *    'ABC'             3                 'ABCxxx '
 *    'A'               1                 'Axxx   '
 *    ''                0                 'xxx    '
 *    'ABCDEFGHIJ'      10                'ABCDEFG'
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq...
C                   EVAL      result = fld + 'xxx'
 * For the following MOVE operation, assume 'result'
 * has the value '.......' before the MOVE.
 *    Value of 'fld'    Length of 'fld'   'result'
 *    --------------    ---------------   -----------
 *    'ABC'             3                 '....ABC'
 *    'A'               1                 '......A'
 *    ''                0                 '.......'
 *    'ABCDEFGHIJ'      10                'DEFGHIJ'
C                   MOVE      fld           result
可変長フィールドを使用する理由

一時変数に可変長フィールドを使用すると、ストリング命令のパフォーマンスが 向上するとともに、ユーザーのコードを読みやすくします。これ は、フィールドの現在の長さを %SUBST の別の変数内に保管したり、余分のブランク を %TRIM を使用して無視する必要がないためです。

サブプロシージャーが、長さの異なるストリング・データを処理することを示している 場合、プロトタイプ・プロシージャーのパラメーターおよび戻り値 に可変長フィールドを使用すると、ユーザーの呼び出しとプロシージャーの、 パフォーマンスと読みやすさの両方を向上させることができます。 サブプロシージャーの中で長さパラメーターを渡したり、CEEDOD を 使用して、パラメーターの実際の長さを知る必要はなくなります。

CVTOPT(*VARCHAR) および CVTOPT(*VARGRAPHIC)

ILE RPG コンパイラーは、外部記述ファイルまたはデータ構造からの可変長の文字フィールド、図形フィールド、または UCS-2 フィールドを、固定長の文字フィールドとして内部的に定義することができます。 可変長の文字フィールド、図形フィールド、および UCS-2 フィールドの固定長形式への変換は不要ですが、可変長フィールドがサポートされる前に作成されたプログラムをサポートするために、CVTOPT がこの言語に残されています。

可変長フィールドを変換するには、CVTOPT 制御仕様書 キーワードまたはコマンド・パラメーターで、*VARCHAR (可変長文字フィールド) または *VARGRAPHIC (可変長図形フィールドまたは UCS-2 フィールド) を指定します。*VARCHAR または *VARGRAPHIC を指定しないか、あるいは *NOVARCHAR または *NOVARGRAPHIC を指定した場合、可変長フィールドは固定長文字に変換されないので、ILE RPG プログラム内で可変長として使用することができます。

*VARCHAR または *VARGRAPHIC を指定 した場合には、次の条件が適用されます。

図 86. 可変長文字フィールドの変換
*..1....+....2....+....3....+....4....+....5....+....6....+....7....+..
A*
A*   File MASTER contains a variable-length field
A*
AAN01N02N03T.Name++++++Rlen++TDpBLinPosFunctions+++++++++++++++++++++
A*
A          R REC
A            FLDVAR       100          VARLEN
*..1....+....2....+....3....+....4....+....5....+....6....+....7....+.. *
 *
 *   Specify the CVTOPT(*VARCHAR) keyword on a control
 *   specification or compile the ILE RPG program with
 *   CVTOPT(*VARCHAR) on the command.
 *
HKeywords++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 *
H CVTOPT(*VARCHAR)
 *
 *   Externally described file name is MASTER.
 *
FFilename++IPEASFRlen+LKlen+AIDevice+.Keywords++++++++++++++++++++++++++++
 *
FMASTER    UF   E             DISK
 *
 *   FLDVAR is a variable-length field defined in DDS with
 *   a DDS length of 100.  Notice that the RPG field length
 *   is 102.
 *
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++
 *
D            DS
D FLDVAR                  1    102
D   FLDLEN                       5U 0 OVERLAY(FLDVAR:1)
D   FLDCHR                     100    OVERLAY(FLDVAR:3)
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq..
 *
 * A character value is moved to the field FLDCHR.
 * After the CHECKR operation, FLDLEN has a value of 5.
C                   READ      MASTER                                 LR
C                   MOVEL     'SALES'       FLDCHR
C     ' '           CHECKR    FLDCHR        FLDLEN
C  NLR              UPDATE    REC

変換済み可変長図形フィールドを使用したい場合には、2 バイトの符号なし 整数フィールドをコーディングして、長さを保留し、長さ N の図形サブフィールドを コーディングしてフィールドのデータ部分を保留することができます。

図 87. 可変長図形フィールドの変換
 *
 *   Specify the CVTOPT(*VARGRAPHIC) keyword on a control
 *   specification or compile the ILE RPG program with
 *   CVTOPT(*VARGRAPHIC) on the command.
 *
 *   The variable-length graphic field VGRAPH is declared in the
 *   DDS as length 3.  This means the maximum length of the field
 *   is 3 double bytes, or 6 bytes.  The total length of the field,
 *   counting the length portion, is 8 bytes.
 *
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++
 *
D            DS
DVGRAPH                          8
D  VLEN                          4U 0 OVERLAY(VGRAPH:1)
D  VDATA                         3G   OVERLAY(VGRAPH:3)
 *
 *   Assume GRPH is a fixed-length graphic field of length 2
 *   double bytes.  Copy GRPH into VGRAPH and set the length of
 *   VGRAPH to 2.
 *
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq..
C*
C                   MOVEL     GRPH          VDATA
C                   Z-ADD     2             VLEN