バイト列と文字列の処理(連結、分割、検索、置換、圧縮、変換、オフセット)

19.2 バイト列と文字列の処理(連結、分割、検索、置換、圧縮、変換、オフセット)

2. バイト列と文字列の処理(連結、分割、検索、置換、圧縮、変換、オフセット)

バイト列と文字列の処理について紹介していきます。
ここでいうバイト列と文字列は、以下のデータ型を持つデータオブジェクトに格納された値のことを指します。

以前は、文字列とバイト列を区別して処理を行うことができませんでしたが、現在は明示的に区別して処理を行うことができる命令文も存在します。
  文字列やバイト列の処理を行うには、次のような命令を使用します。

① CONCATENATE命令(連結)
② SPLIT命令(分割)
③ SHIFT命令(文字列シフト)
④ FIND命令(検索)
⑤ REPLACE命令(置換)
⑥ CONDENSE命令(圧縮)
⑦ TRANSLATE命令(変換)
⑧ OVERLAY命令(上書き)
⑨ RETURN命令

CONCATENATE命令(連結)

CONCATENATE命令は、文字列を連結する命令です。
<文字列1>~<文字列n>の文字列を結合して、<結合結果>に格納します。

オプションは、主に1つです。

[オプション]
SEPARATED BY<区切文字>
SEPARATED BYオプションのく区切文字>には、「文字列が格納されている変数」と「文字列そのもの」を指定することができます。
また、このオプションで指定した文字列を<文字列1>…<文字列n>の間に配置することもできます。

サンプルコード

CONCATENATE命令(連結)

REPORT ZTEST_PROGRAM_CONCATENAME_1.
DATA:
  WK_TEXT1(3)       TYPE C VALUE 'ABC',
  WK_TEXT2(3)       TYPE C VALUE 'DEF',
  WK_TEXT3(3)       TYPE C VALUE 'GH',
  WK_RESULT1(20)  TYPE C,
  WK_RESULT2(20)  TYPE C.

CONSTANTS:
  CN_MARK TYPE C VALUE '_'.

CONCATENATE WK_TEXT1 WK_TEXT2 WK_TEXT3 INTO WK_RESULT1.
CONCATENATE WK_TEXT1 WK_TEXT2 WK_TEXT3 INTO WK_RESULT2
  SEPARATED BY CN_MARK.

WRITE:  WK_RESULT1,
        /  WK_RESULT2. 

結果

SPLIT命令(分割)

SPLIT命令は、文字列を分割する命令です。
く分割対象>の文字列からく区切文字>を検索し、区切文字前後部分をく変数1>…<変数n>または、内部テーブルに格納します。
格納項目数が不足した場合は、残りの文字列が区切文字を含んだまま最後の項目に格納されます。

サンプルコード

SPLIT命令(分割)

REPORT ZTEST_PROGRAM_SPLIT_1.
DATA:
  WK_TEXT(20)    TYPE C,
  WK_TEXT1(10)  TYPE C,
  WK_TEXT2(10)  TYPE C,
  WK_TEXT3(10)  TYPE C.

CONSTANTS:
  CN_MARK TYPE C VALUE  '/'.

WK_TEXT = 'ABC/DEF/GHI/JKL'.

SPLIT WK_TEXT AT CN_MARK INTO WK_TEXT1 WK_TEXT2 WK_TEXT3.

WRITE:  WK_TEXT1,
        /  WK_TEXT2,
        /  WK_TEXT3. 

結果

SHIFT命令(文字列シフト)

SHIFT命令を使用すると、文字ごとに項目内容が移動する文字列シフトができます。
また、オプション①では、主に2つのオプション(BY n PLACES,mode)が使用できます。

[オプション①]

BY n PLACES

文字列が n 個分移動します。省略すると、n は1として解釈されます。n が 0または負の値の場合、文字列は変更されません。 n が文字列の長さを超えると、文字列は空白で埋め込まれます。

[mode]

LEFT、RIGHT または CIRCULAR を指定します。
「LEFT」は、位置が n 個分左に移動さえ、右端に移動した分の空白が追加されます。
「RIGHT」は、位置が n 個分右に移動され、左端に移動した分の空白が追加されます。
「CIRCULAR」は、文字列を周期的に移動します。右側の n 個分の文字が左に移動され、左側の n 個の文字が右に移動されます。
なお、modeオプションを指定しない場合には、LEFTが設定されます。

サンプルコード

SHIFT命令(文字列シフト)

REPORT ZTEST_PROGRAM_SHIFT_1.
DATA:
  WK_TEXT(10) TYPE C VALUE '1234567890',
  WK_TEXT1(10) TYPE C,
  WK_TEXT2(10) TYPE C,
  WK_TEXT3(10) TYPE C,
  WK_TEXT4(10) TYPE C.

WK_TEXT1 = WK_TEXT.
WK_TEXT2 = WK_TEXT.
WK_TEXT3 = WK_TEXT.
WK_TEXT4 = WK_TEXT.

SHIFT WK_TEXT1.
SHIFT WK_TEXT2 BY 3 PLACES LEFT.
SHIFT WK_TEXT3 BY 3 PLACES RIGHT.
SHIFT WK_TEXT4 BY 3 PLACES CIRCULAR.

WRITE: WK_TEXT,
        / WK_TEXT1,
        / WK_TEXT2,
        / WK_TEXT3,
        / WK_TEXT4. 

結果

FIND命令(検索)

FIND命令は、文字列を検索する命令です。文字列の中から対象の文字列を検索します。
見つかった場合は、システム変数 SY-SUBRCに 0 が自動で設定されます。

REPORT ZTEST_PROGRAM_FIND_1.
DATA:
  WK_TEXT1(7) TYPE C VALUE 'ABC-DEF',
  WK_TEXT2(6) TYPE C VALUE 'ABCDEF'.

CONSTANTS:
  CN_MARK TYPE C VALUE '-'.

FIND CN_MARK IN WK_TEXT1.
WRITE SY-SUBRC.
FIND CN_MARK IN WK_TEXT2.
WRITE / SY-SUBRC. 

結果

REPLACE命令(置換)

REPLACE命令は、文字列を置換する命令です。く文字列>からく置換対象>を検索し、<置換文字列>に変換します。

サンプルコード

REPLACE命令(置換)

REPORT ZTEST_PROGRAM_REPLACE_1.
DATA:
  WK_TEXT1(11)  TYPE C VALUE 'ABC/DEF/GH/',
  WK_TEXT2(11)  TYPE C VALUE 'ABC/DEF/GH/'.

CONSTANTS:
  CN_TARGET TYPE C VALUE '/',
  CN_NEW  TYPE C  VALUE '  '.

REPLACE FIRST OCCURRENCE   OF CN_TARGET IN WK_TEXT1 WITH CN_NEW.
REPLACE ALL    OCCURRENCES OF CN_TARGET IN WK_TEXT2 WITH CN_NEW.

WRITE: WK_TEXT1,
        / WK_TEXT2.

結果

CONDENSE命令(圧縮)

CONDENSE命令を使用すると、<文字列>の先頭と末尾の空白が削除され、文字列が圧縮されます。
また、その他の箇所で空白が連続している場合は、 1つの空白に置換されます。
主なオプションは、NO-GAPSオプションです。

[オプション]

NO-GAPS

NO-GAPSオプションを指定すると、すべての空白が削除されます。
なお、CONDENSE命令はバイト型データ(x型およびxstring型)をサポートしていません。

サンプルコード

CONDENSE命令(圧縮)

REPORT ZTEST_PROGRAM_CONDENSE_1.
DATA:
  WK_TEXT1(11) TYPE C VALUE ' A B  A P',
  WK_TEXT2(11) TYPE C VALUE '  A B  A P'.

CONDENSE WK_TEXT1.
CONDENSE  WK_TEXT2 NO-GAPS.

WRITE:    WK_TEXT1,
        /    WK_TEXT2. 

結果

TRANSLATE命令(変換)

TRANSLATE命令を使用すると、文 字列が大文字(UPPER CASE)、または小文字(LOWER
CASE)に変換されます。
なお、TRANSLATE命令は、バイト型データ(x型およびxstring型)をサポートしていません。

サンプルコード

TRANSLATE命令(変換)

REPORT ZTEST_PROGRAM_TRANSLATE_1.
  DATA:
     WK_TEXT_U(10) TYPE C VALUE 'TrAinInG',
     WK_TEXT_L(10) TYPE C VALUE 'TrAinInG'.

  TRANSLATE WK_TEXT_U TO UPPER CASE.
  TRANSLATE WK_TEXT_L TO LOWER CASE.

  WRITE: / WK_TEXT_U,
            /  WK_TEXT_L. 

結果

OVERLAY命令(上書き)

OVERLAY命令は、<上書き文字列>で<文字列>を上書きします。
オプションは、主にONL<文字列>です。

[オプション]

ONLY命令<文字列>

ONLY<文字列>オプションを使用すると、<文字列>内で上書きする対象を限定することができます。
なお、OVERLAY命令はバイト型データ(x型およびxstring型)をサポートしていません。

サンプルコード

OVERLAY命令(上書き)

REPORT ZTEST_PROGRAM_OVERLAY_1.
 DATA:
   WK_CHAR(6) TYPE C VALUE 'S R N',
   WK_TEXT(6)  TYPE C,
   WK_OVER(6) TYPE C VALUE 'spring',
   WK_STR(2)  TYPE C VALUE 'SR'.

 WK_TEXT = WK_CHAR.
 OVERLAY WK_TEXT WITH WK_OVER.
 WRITE / WK_TEXT.

  WK_TEXT = WK_CHAR.
 OVERLAY WK_TEXT WITH WK_OVER ONLY WK_STR.
 WRITE / WK_TEXT. 

結果

※OVERLAY WK_TEXT WITH WK_OVER.の場合
WK_TEXTの中に入っている文字列に対して、空白の箇所にWK_OVERの文字列で上書きをしています。
※OVERLAY WK_TEXT WITH WK_OVER ONLY WK_STR.の場合
オプションを使用したこちらは、WK_STRに入っている内容と一致する箇所をWK_TEXTから探して、WK_OVERの中にある文字列で上書きしております。

オフセット

文字列のうち、何文字目から何文字目までを取得したいという場合はオフセットを使用します。
オフセットは、ABAP特有の用語ではありません。必要なデータ位置を基準となる位置からの差で表した値のことを、IT業界では一般的にオフセットと呼んでいます。

ABAPでは、オフセットを「指定開始位置を指す用語」や、「指定開始位置から指定の長さ分のデ一タを取得すること」という意味で使っています。

上記の場合は、変数WK_1の1桁目から2桁分つまり ‘AB’がWK_2に代入されます。「0(2)」の 0 が先頭から何バイトを飛ばすことになるので、開始位置は1,、括弧内の2が長さということになります。

上記の例を含め、オフセット代入には様々なバリエーションがあります。

代入先の開始位置と長さを指定する場合は、次の通りです。

サンプルコード

オフセット

REPORT ZTEST_PROGRAM_OFFSET_1.
DATA:
  WK_TEXT1(8) TYPE C VALUE 'ABCDEFGH',
  WK_TEXT2(1) TYPE C,
  WK_NUM1(2)  TYPE C VALUE '89',
  WK_NUM2(5)  TYPE C VALUE '12345',
  WK_CHAR1(8)  TYPE C VALUE 'ABCDEFGH',
  WK_CHAR2(5)  TYPE C VALUE '12345'.

WK_TEXT2 = WK_TEXT1+0(1).

WRITE:/ WK_TEXT2.

WK_NUM2+1(2) = WK_NUM1.

WRITE:/ WK_NUM2.

WK_CHAR2+3(1) = WK_CHAR1+2(1).

WRITE:/ WK_CHAR2. 

結果

長さの取得

文字列やバイト列の長さを求めるには、関数のSTRLENやXSTRLENを使用します。

サンプルコード

長さの取得

REPORT ZTEST_PROGRAM_LENGTH_1.
DATA:
  WK_TEXT1(10) TYPE C VALUE 'ABC',
  WK_TEXT2(10) TYPE C VALUE '   DE',
  WK_TEXT3(10) TYPE C,
  WK_STRLEN1   TYPE I ,
  WK_STRLEN2   TYPE I ,
  WK_STRLEN3   TYPE I .

WK_STRLEN1 = STRLEN( WK_TEXT1 ).
WK_STRLEN2 = STRLEN( WK_TEXT2 ).
WK_STRLEN3 = STRLEN( WK_TEXT3 ).

WRITE:    WK_STRLEN1,
        /    WK_STRLEN2,
        /    WK_STRLEN3. 

結果

RETURN命令

RETURN命令を使用すると、その処理ブロックを途中で終了させることが出来ます。「EXIT」と処理内容が似ていますが、違いは「ループ処理以外でも使用できる」所にあります。
その為、IF文と組み合わせれば、条件が満たされた時に処理を終了させることが出来ます。

以下のタイプの処理ブロックで利用可能になります。

  • ダイアログモジュール
  • イベントブロック
  • プロシージャ(メソッド、サブルーチン、汎用モジュール)

上記の例の場合、リターンコードが0(※正常終了ではない)の場合、エラーメッセージを出力して、処理を終了させるという流れになります。


NEXT>> 19.3 練習問題(条件分岐)