バージョン 4.2.5
 —  プログラミングガイド  —

ダイナミック変数およびラージ変数の使用

このドキュメントでは、次のトピックについて説明します。


全般的な注意事項

通常、次の規則が適用されます。

例外

ダイナミック変数は、SORT ステートメント内では使用できません。 ダイナミック変数を DISPLAYWRITEPRINTREINPUTINPUT の各ステートメント内で使用するには、セッションパラメータ AL または EM のいずれかを使用して変数の長さを定義する必要があります。

ダイナミック変数に割り当てられているストレージの使用長(Natural システム変数 *LENGTH によって示される。「ダイナミック変数の現在の値スペース」を参照)およびサイズは、その変数がターゲットオペランドとして最初にアクセスされるまではゼロです。 割り当て操作またはその他の操作によって、ダイナミック変数はソースオペランドの正確なサイズに初めて割り当てまたは拡張(再割り当て)されます。

以下のステートメントで変更可能なオペランド(ターゲットオペランド)としてダイナミック変数を使用する場合、ダイナミック変数のサイズを拡張できます。

ASSIGN operand1(割り当て内の応答先オペランド)
CALLNAT ダイナミック変数を使用したパラメータ引き渡し」を参照してください(AD=O、または対応するパラメータデータエリア内に BY VALUE が存在する場合を除く)。
COMPRESS operand2。「処理」を参照してください。
EXAMINE DELETE REPLACE 節内の operand1
MOVE operand2(応答先オペランド)。「機能」を参照してください。
PERFORM AD=O、または対応するパラメータデータエリア内に BY VALUE が存在する場合以外)
READ WORK FILE operand1 および operand2。「ラージおよびダイナミック変数の処理」を参照してください。
SEPARATE operand4.
SELECT (SQL) INTO 節内のパラメータ
SEND METHOD operand3AD=O でない場合)

現時点では、ラージ変数の使用には以下の制限があります。

CALL 各パラメータのサイズは 64 KB 未満です(INTERFACE4 オプションを使用した CALL には制限はありません)。

以下のセクションでは、ダイナミック変数の使用について、例を使用してさらに詳しく説明します。

Top of page

ダイナミック変数を使用した割り当て

通常は、ソースオペランドの現在の使用長(Natural システム変数 *LENGTH によって示される)で割り当てが行われます。 応答先オペランドがダイナミック変数の場合、ソースオペランドを切り捨てずに移動できるよう、現在割り当てられているサイズが拡張される場合があります。

例:

#MYDYNTEXT1 := OPERAND
MOVE OPERAND TO #MYDYNTEXT1
/* #MYDYNTEXT1 IS AUTOMATICALLY EXTENDED UNTIL THE SOURCE OPERAND CAN BE COPIED 

MOVE ALL、およびダイナミックターゲットオペランドを使用した MOVE ALL UNTIL は、以下のように定義されています。

例:

#MYDYNTEXT1 := 'ABCDEFGHIJKLMNO'          /* *LENGTH(#MYDYNTEXT1) = 15
MOVE ALL 'AB' TO #MYDYNTEXT1              /* CONTENT OF #MYDYNTEXT1 = 'ABABABABABABABA';  
                                          /* *LENGTH IS STILL 15
MOVE ALL 'CD' TO #MYDYNTEXT1 UNTIL 6      /* CONTENT OF #MYDYNTEXT1 = 'CDCDCD';
                                          /* *LENGTH = 6
MOVE ALL 'EF' TO #MYDYNTEXT1 UNTIL 10     /* CONTENT OF #MYDYNTEXT1 = 'EFEFEFEFEF'; 
                                          /* *LENGTH = 10

ターゲットオペランドがダイナミック変数の場合、MOVE JUSTIFIED はコンパイル時に拒否されます。

MOVE SUBSTR および MOVE TO SUBSTR は実行できます。 ダイナミック変数の使用長(*LENGTH)を超えるサブストリングを参照すると、MOVE SUBSTR はランタイムエラーになります。 *LENGTH + 1 を超えるサブストリングの位置を参照すると、ダイナミック変数の内容に未定義のギャップが生じるため、MOVE TO SUBSTR はランタイムエラーになります。 ターゲットオペランドを MOVE TO SUBSTR で拡張する必要がある場合(第 2 オペランドが *LENGTH+1 に設定されている場合など)、第 3 オペランドは必須です。

有効な構文:

#OP2 := *LENGTH(#MYDYNTEXT1)
MOVE SUBSTR (#MYDYNTEXT1, #OP2) TO OPERAND                /* MOVE LAST CHARACTER TO OPERAND
#OP2 := *LENGTH(#MYDYNTEXT1) + 1
MOVE OPERAND TO SUBSTR(#MYDYNTEXT1, #OP2, #lEN_OPERAND)   /* CONCATENATE OPERAND TO #MYDYNTEXT1          

無効な構文:

#OP2 := *LENGTH(#MYDYNTEXT1) + 1
MOVE SUBSTR (#MYDYNTEXT1, #OP2, 10) TO OPERAND            /* LEADS TO RUNTIME ERROR; UNDEFINED SUB-STRING  
#OP2 := *LENGTH(#MYDYNTEXT1 + 10) 
MOVE OPERAND TO SUBSTR(#MYDYNTEXT1, #OP2, #EN_OPERAND)    /* LEADS TO RUNTIME ERROR; UNDEFINED GAP
#OP2 := *LENGTH(#MYDYNTEXT1) + 1
MOVE OPERAND TO SUBSTR(#MYDYNTEXT1, #OP2)                 /* LEADS TO RUNTIME ERROR; UNDEFINED LENGTH

割り当ての互換性

例:

#MYDYNTEXT1   := #MYSTATICVAR1
#MYSTATICVAR1 := #MYDYNTEXT2   

ソースオペランドがスタティック変数の場合、ダイナミックな応答先オペランドの使用長(*LENGTH(#MYDYNTEXT1))はスタティック変数のフォーマット長に設定され、末尾の空白(フォーマット A および U)またはバイナリゼロ(フォーマット B)を含め、この長さでソースオペランドがコピーされます。

応答先オペランドがスタティックでソースオペランドがダイナミックの場合、ダイナミック変数は現在の使用長でコピーされます。 この長さがスタティック変数のフォーマット長より短い場合、残りの部分は空白(英数字フィールドおよび Unicode フィールドの場合)またはバイナリゼロ(バイナリフィールドの場合)で埋められます。 そうでない場合、値は切り捨てられます。 ダイナミック変数の現在の使用長が 0 の場合、スタティックのターゲットオペランドは空白(英数字フィールドおよび Unicode フィールドの場合)またはバイナリゼロ(バイナリフィールドの場合)で埋められます。

Top of page

ダイナミック変数の初期化

ダイナミック変数は、RESET ステートメントを使用して、最大で現在の使用長(= *LENGTH)まで、空白(英数字フィールドおよび Unicode フィールドの場合)またはゼロ(バイナリフィールドの場合)で初期化できます。 *LENGTH は変更できません。

例:

DEFINE DATA LOCAL
1 #MYDYNTEXT1   (A)  DYNAMIC
END-DEFINE
#MYDYNTEXT1 := 'SHORT TEXT'
WRITE *LENGTH(#MYDYNTEXT1)          /* USED LENGTH = 10
RESET #MYDYNTEXT1                   /* USED LENGTH = 10, VALUE = 10 BLANKS  

ダイナミック変数を特定のサイズと値で初期化するには、MOVE ALL UNTIL ステートメントを使用します。

例:

MOVE ALL 'Y' TO #MYDYNTEXT1 UNTIL 15          /* #MYDYNTEXT1 CONTAINS 15 'Y'S, USED LENGTH = 15 

Top of page

ダイナミック英数字変数での文字列操作

変更可能なオペランドがダイナミック変数の場合、切り捨てまたはエラーメッセージを発生させずに操作できるよう、現在割り当てられているサイズが拡張される場合があります。 これは、ダイナミック変数の連結(COMPRESS)および分割(SEPARATE)で有効です。

例:

** Example 'DYNAMX01': Dynamic variables (with COMPRESS and SEPARATE)   
************************************************************************
DEFINE DATA LOCAL                                                       
1 #MYDYNTEXT1 (A)   DYNAMIC                                             
1 #TEXT       (A20)                                                     
1 #DYN1       (A)   DYNAMIC                                             
1 #DYN2       (A)   DYNAMIC                                             
1 #DYN3       (A)   DYNAMIC                                             
END-DEFINE                                                              
*                                                                       
MOVE ' HELLO WORLD ' TO #MYDYNTEXT1                                     
WRITE #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1)           
/*  dynamic variable with leading and trailing blanks                   
*                                                                       
MOVE ' HELLO WORLD ' TO #TEXT                                           
*                                                                       
MOVE #TEXT TO #MYDYNTEXT1                                               
WRITE #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1)           
/*  dynamic variable with whole variable length of #TEXT
*                                                              
COMPRESS #TEXT INTO #MYDYNTEXT1                                
WRITE #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1)  
/*  dynamic variable with leading blanks of #TEXT              
*                                                              
*                                                              
#MYDYNTEXT1 := 'HERE COMES THE SUN'                            
SEPARATE #MYDYNTEXT1 INTO #DYN1 #DYN2 #DYN3 IGNORE             
*                                                              
WRITE / #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1)
WRITE #DYN1 (AL=25) 'with length' *LENGTH (#DYN1)              
WRITE #DYN2 (AL=25) 'with length' *LENGTH (#DYN2)              
WRITE #DYN3 (AL=25) 'with length' *LENGTH (#DYN3)              
/*  #DYN1, #DYN2, #DYN3 are automatically extended or reduced  
*                                                              
EXAMINE #MYDYNTEXT1 FOR 'SUN' REPLACE 'MOON'                   
WRITE / #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1)
/*  #MYDYNTEXT1 is automatically extended or reduced           
*
END

注意:
非ダイナミック変数の場合、エラーメッセージが返されます。

Top of page

ダイナミック変数を使用した論理条件の基準(LCC)

ダイナミック変数を使用して読み取り専用の操作(比較など)を行う場合、通常は現在の使用長を使用して実行されます。 読み取り操作(変更なし)で使用される場合、ダイナミック変数はスタティック変数と同様に処理されます。

例:

IF  #MYDYNTEXT1  =  #MYDYNTEXT2  OR  #MYDYNTEXT1 =  "**"  THEN ...
IF  #MYDYNTEXT1  <  #MYDYNTEXT2  OR  #MYDYNTEXT1 <  "**"  THEN ...  
IF  #MYDYNTEXT1  >  #MYDYNTEXT2  OR  #MYDYNTEXT1 >  "**"  THEN ...

英数字変数および Unicode 変数の末尾の空白またはバイナリ変数の先頭のバイナリゼロは、スタティック変数とダイナミック変数で同様に処理されます。 例えば、AA および空白が続く AA を値として持つ英数字変数は同一とみなされ、H'00003031' および H'3031' という値を持つバイナリ変数は同一とみなされます。 値が完全に同じ場合にのみ比較結果を TRUE とする場合は、ダイナミック変数の使用長も比較する必要があります。 一方の変数ともう一方の変数の値が完全に同じであれば、その使用長もまた同じです。

例:

#MYDYNTEXT1  :=  'HELLO'                                     /* USED LENGTH IS 5
#MYDYNTEXT2  :=  'HELLO     '                                /* USED LENGTH IS 10  
IF   #MYDYNTEXT1  =  #MYDYNTEXT2   THEN  ...                 /* TRUE
IF   #MYDYNTEXT1  =  #MYDYNTEXT2 AND     
     *LENGTH(#MYDYNTEXT1) = *LENGTH(#MYDYNTEXT2)  THEN  ...  /* FALSE

2 つのダイナミック変数は、どちらか短い方の使用長に達するまで 1 ポジションずつ比較されます(英数字変数の場合は左から右、バイナリ変数の場合は右から左)。 最初に値が異なったポジションで、1 番目の変数と 2 番目の変数のどちらがより大きいか、小さいか、または同じかが判断されます。 変数の短い方の使用長まで値が同じで、長い方の残りの値がダイナミック英数字変数の場合は空白のみ、ダイナミックバイナリ変数の場合はバイナリゼロのみの場合、それらの変数は同じとみなされます。 2 つのダイナミック Unicode 変数を比較する場合、両方の値の末尾の空白を削除してから、ICU 照合アルゴリズムを使用して 2 つの値が比較されます。 『Unicode とコードページのサポート』ドキュメントの「論理条件の基準」も参照してください。

例:

#MYDYNTEXT1  :=  'HELLO1'                    /* USED LENGTH IS 6
#MYDYNTEXT2  :=  'HELLO2'                    /* USED LENGTH IS 10  
IF #MYDYNTEXT1  <  #MYDYNTEXT2 THEN  ...     /* TRUE
#MYDYNTEXT2  :=  'HALLO'
IF #MYDYNTEXT1  >  #MYDYNTEXT2 THEN  ...     /* TRUE

比較の互換性

ダイナミック変数とスタティック変数の比較は、ダイナミック変数間の比較と同じです。 スタティック変数のフォーマット長が使用長として使用されます。

例:

#MYSTATTEXT1 :=  'HELLO'                      /* FORMAT LENGTH OF MYSTATTEXT1 IS A20  
#MYDYNTEXT1  :=  'HELLO'                      /* USED LENGTH IS 5
IF  #MYSTATTEXT1  =  #MYDYNTEXT1  THEN  ...   /* TRUE
IF  #MYSTATTEXT1  >  #MYDYNTEXT1  THEN  ...   /* FALSE

Top of page

ダイナミックコントロールフィールドの AT/IF-BREAK

ブレイクコントロールフィールドの元の値との比較は、左から右に向かって 1 ポジションずつ実行されます。 ダイナミック変数の元の値と新しい値で長さが異なる場合、比較するために長さが短い方の値の右側に空白(ダイナミック英数字変数またはダイナミック Unicode 変数の場合)またはバイナリゼロ(バイナリ値の場合)が追加されます。

英数字または Unicode のブレイクコントロールフィールドの場合、比較において末尾の空白は意味を持ちません。つまり、末尾の空白は値の変更を意味しないため、ブレイクは発生しません。

バイナリのブレイクコントロールフィールドの場合、比較において末尾のバイナリゼロは意味を持ちません。つまり、末尾のバイナリゼロは値の変更を意味しないため、ブレイクは発生しません。

Top of page

ダイナミック変数を使用したパラメータ引き渡し

ダイナミック変数は、呼び出されたプログラムオブジェクト(CALLNATPERFORM)へのパラメータとして渡すことができます。 ダイナミック変数の値スペースは連続しているので、参照渡しが可能です。 値渡しを使用すると、呼び出し元の変数定義がソースオペランドとして割り当てられ、パラメータ定義が応答先オペランドとして割り当てられます。 また、値渡しの結果では、逆方向にデータが移動します。

参照渡しを使用する場合、変数定義およびパラメータ定義は DYNAMIC である必要があります。 そのうちの 1 つだけが DYNAMIC の場合、ランタイムエラーが発生します。 値渡し(結果)の場合、すべての組み合わせを使用できます。 以下の表に、有効な組み合わせを示します。

参照渡し

呼び出し元 パラメータ
スタティック ダイナミック
スタティック ×
ダイナミック ×

ダイナミック変数 A または B のフォーマットは一致する必要があります。

値渡し(結果)

呼び出し元 パラメータ
スタティック ダイナミック
スタティック
ダイナミック

注意:
スタティック/ダイナミック定義またはダイナミック/スタティック定義を使用する場合、割り当てのデータ転送規則によって値が切り捨てられることがあります。

例 1:

** Example 'DYNAMX02': Dynamic variables (as parameters)                
************************************************************************
DEFINE DATA LOCAL                                                       
1 #MYTEXT (A) DYNAMIC                                                   
END-DEFINE                                                              
*                                                                       
#MYTEXT := '123456'      /* extended to 6 bytes, *LENGTH(#MYTEXT) = 6   
*                                                                       
CALLNAT 'DYNAMX03' USING #MYTEXT                                        
*                                                                       
WRITE *LENGTH(#MYTEXT)          /* *LENGTH(#MYTEXT) = 8                 
*                                                                       
END                                                                  

サブプログラム DYNAMX03

** Example 'DYNAMX03': Dynamic variables (as parameters)                
************************************************************************
DEFINE DATA PARAMETER                                                   
1 #MYPARM (A) DYNAMIC  BY VALUE RESULT                                  
END-DEFINE                                                              
*                                                                       
WRITE *LENGTH(#MYPARM)                  /* *LENGTH(#MYPARM) = 6         
#MYPARM := '1234567'                    /* *LENGTH(#MYPARM) = 7         
#MYPARM := '12345678'                   /* *LENGTH(#MYPARM) = 8         
EXPAND DYNAMIC VARIABLE #MYPARM TO 10   /* 10 bytes are allocated       
*                                                                       
WRITE *LENGTH(#MYPARM)                  /* *LENGTH(#MYPARM) = 8         
*                                                                       
/* content of #MYPARM is moved back to #MYTEXT                          
/* used length of #MYTEXT = 8                                           
*                                                                       
END                                                                    

例 2:

** Example 'DYNAMX04': Dynamic variables (as parameters)                
************************************************************************
DEFINE DATA LOCAL                                                       
1 #MYTEXT (A) DYNAMIC                                                   
END-DEFINE                                                              
*                                                                       
#MYTEXT := '123456'      /* extended to 6 bytes, *LENGTH(#MYTEXT) = 6   
*                                                                       
CALLNAT 'DYNAMX05' USING #MYTEXT                                        
*                                                                       
WRITE *LENGTH(#MYTEXT)          /* *LENGTH(#MYTEXT) = 8                 
                                /* at least 10 bytes are                
                                /* allocated (extended in DYNAMX05)     
*                                                                       
END                                                               

サブプログラム DYNAMX05

** Example 'DYNAMX05': Dynamic variables (as parameters)                
************************************************************************
DEFINE DATA PARAMETER                                                   
1 #MYPARM (A) DYNAMIC                                                   
END-DEFINE                                                              
*                                                                       
WRITE *LENGTH(#MYPARM)                  /* *LENGTH(#MYPARM) = 6         
#MYPARM := '1234567'                    /* *LENGTH(#MYPARM) = 7         
#MYPARM := '12345678'                   /* *LENGTH(#MYPARM) = 8         
EXPAND DYNAMIC VARIABLE #MYPARM TO 10   /* 10 bytes are allocated       
*                                                                       
WRITE *LENGTH(#MYPARM)                  /* *LENGTH(#MYPARM) = 8         
*                                                                       
END                                                                    

3GL プログラムに対する CALL

CALL ステートメントで INTERFACE4 オプションを使用すると、ダイナミック変数およびラージ変数を有効に使用できます。 このオプションを使用すると、異なるパラメータ構造を使用した 3GL プログラムとのインターフェイスになります。

ダイナミックパラメータを使用して 3GL プログラムを呼び出す前に、必要なバッファサイズを必ず割り当てるようにしてください。 これは、EXPAND ステートメントを使用すると明示的に実行できます。

バッファを初期化する必要がある場合、MOVE ALL UNTIL ステートメントを使用することにより、ダイナミック変数を初期値および必要なサイズに設定できます。 Natural には、3GL プログラムでダイナミックパラメータに関する情報を取得し、パラメータデータを返すときに長さを変更できるようにする、一連のファンクションが用意されています。

例:

MOVE ALL ' ' TO  #MYDYNTEXT1 UNTIL 10000
  /* a buffer of length 10000 is allocated
  /* #MYDYNTEXT1 is initialized with blanks
  /* and *LENGTH(#MYDYNTEXT1) = 10000
CALL INTERFACE4  'MYPROG'  USING  #MYDYNTEXT1
WRITE *LENGTH(#MYDYNTEXT1)
  /* *LENGTH(#MYDYNTEXT1) may have changed in the 3GL program

詳細については、『ステートメント』ドキュメントに記載されている、CALL ステートメントの説明を参照してください。

Top of page

ラージ変数およびダイナミック変数によるワークファイルへのアクセス

253 以下の長さの固定長の変数と 253 を超える長さのラージ変数の扱いは同じです。

ダイナミック変数は、WRITE WORK FILE ステートメントの実行時に、その実際の長さ(つまり、この変数に対するシステム変数 *LENGTH の値)でデータが書き込まれます。 同じ WRITE WORK FILE ステートメントであっても実行するたびに長さが異なるため、キーワード VARIABLE を指定する必要があります。

タイプ FORMATTED のワークファイルを読み込む場合、ダイナミック変数には、READ WORK FILE ステートメントの実行時に、その実際の長さ(つまり、この変数に対するシステム変数 *LENGTH の値)でデータが読み込まれます。 ダイナミック変数が現在のレコードの残りのデータより長い場合、空白(英数字フィールドおよび Unicode フィールドの場合)またはバイナリゼロ(バイナリフィールドの場合)が埋め込まれます。

タイプ UNFORMATTED のワークファイルを読み込む場合、ダイナミック変数にはワークファイルの残りが読み込まれます。 サイズは適切に調整され、この変数に対するシステム変数 *LENGTH の値に反映されます。

Top of page

ダイナミック変数の使用によるパフォーマンスへの影響

ダイナミック変数を少量ずつ複数回にわたって拡張する場合(バイト単位など)、必要なストレージの(おおよその)上限がわかっているときは、拡張を繰り返すのではなく EXPAND ステートメントを使用します。 これにより、必要なストレージを調整するための余分なオーバーヘッドを回避できます。

ダイナミック変数が不要になった場合、特に *LENGTH の値が大きい変数の場合は、REDUCE ステートメントまたは RESIZE ステートメントを使用します。 これにより、Natural でストレージを解放または再利用できます。 したがって、全体的なパフォーマンスが向上します。

ダイナミック変数に割り当てられているメモリの量は、REDUCE DYNAMIC VARIABLE ステートメントを使用すると減らすことができます。 変数に特定の長さを(再)割り当てするには、EXPAND ステートメントを使用できます (変数を初期化する場合は、MOVE ALL UNTIL ステートメントを使用します)。

例:

** Example 'DYNAMX06': Dynamic variables (allocated memory)             
************************************************************************
DEFINE DATA LOCAL                                                       
1 #MYDYNTEXT1  (A)  DYNAMIC                                             
1 #LEN         (I4)                                                     
END-DEFINE                                                              
*                                                                       
#MYDYNTEXT1 := 'a'     /* used length is 1, value is 'a'                
                       /* allocated size is still 1                     
WRITE *LENGTH(#MYDYNTEXT1)                                              
*                                                                       
EXPAND DYNAMIC VARIABLE  #MYDYNTEXT1 TO 100                             
                       /* used length is still 1, value is 'a'          
                       /* allocated size is 100                         
*                                                                       
CALLNAT 'DYNAMX05' USING #MYDYNTEXT1                                    
WRITE *LENGTH(#MYDYNTEXT1)                                              
                       /* used length and allocated size                
                       /* may have changed in the subprogram            
*                                                                       
#LEN := *LENGTH(#MYDYNTEXT1)                                            
REDUCE DYNAMIC VARIABLE  #MYDYNTEXT1  TO  #LEN                          
                       /* if allocated size is greater than used length,
                       /* the unused memory is released                 
*                                                                       
REDUCE DYNAMIC VARIABLE  #MYDYNTEXT1  TO  0                             
WRITE *LENGTH(#MYDYNTEXT1)                                              
                       /* free allocated memory for dynamic variable    
END

ルール:

Top of page

ダイナミック変数の出力

ダイナミック変数は、以下のような出力ステートメント内で使用できます。

ステートメント 注意点
DISPLAY これらのステートメントでは、セッションパラメータの AL(出力に対する英数字長)またはEM(編集マスク)を使用して、ダイナミック変数の入出力フォーマットを設定する必要があります。
WRITE
INPUT
REINPUT --
PRINT PRINT ステートメントの出力はフォーマットが指定されていないため、AL および EM パラメータを使用して、PRINT ステートメント内のダイナミック変数の出力フォーマットを設定する必要はありません。 したがって、これらのパラメータは無視されます。

Top of page

ダイナミック X-array

ダイナミック X-array の割り当てでは、最初にオカレンス数を指定し、後でそのオカレンス数を拡張できます。

例:

DEFINE DATA LOCAL
1 #X-ARRAY(A/1:*)  DYNAMIC
END-DEFINE
*
EXPAND  ARRAY   #X-ARRAY TO (1:10)  /* Current boundaries (1:10) 
#X-ARRAY(*) := 'ABC'
EXPAND  ARRAY   #X-ARRAY TO (1:20)  /* Current boundaries (1:20)
#X-ARRAY(11:20) := 'DEF'

Top of page