ABAP CONCATENATEについて

ABAPのCONCATENATEとは?基礎から理解する文字列結合

ABAPにおけるCONCATENATEは、文字列を結合するための基本的かつ強力なステートメントです。その特徴は、明確な構文と柔軟な使用方法にあります。

CONCATENATEステートメントの基本構文と動作原理

基本構文

* 基本的な2つの文字列の結合
CONCATENATE string1 string2 INTO result.

* 区切り文字を使用した結合
CONCATENATE string1 string2 INTO result SEPARATED BY space.

* 複数の文字列を一度に結合
CONCATENATE string1 string2 string3 string4 INTO result.

CONCATENATEステートメントの処理イメージ

動作原理

CONCATENATEステートメントの内部動作を理解することは、効率的な実装のために重要です:

  1. メモリ割り当て
    • 結果格納用の新しいメモリ領域を確保
    • 入力文字列の長さに基づいて適切なサイズを計算
  2. 文字列処理
    • 入力文字列を順次読み取り
    • バッファメモリに一時的に保存
    • 必要に応じて文字コード変換を実行
  3. 結果生成
    • バッファの内容を結果変数にコピー
    • 不要なメモリの解放

主要な特徴

特徴説明メリット
明示的な構文処理内容が明確に表現されるコードの可読性が高い
バッファ管理効率的なメモリ使用パフォーマンスが安定
文字コード対応自動的な文字コード変換互換性の問題が少ない
エラーハンドリング明確なエラーメッセージデバッグが容易

基本的な使用例

DATA: lv_first_name TYPE string VALUE 'John',
      lv_last_name  TYPE string VALUE 'Doe',
      lv_full_name  TYPE string.

* 単純な結合
CONCATENATE lv_first_name lv_last_name INTO lv_full_name.
* 結果: 'JohnDoe'

* スペースを含めた結合
CONCATENATE lv_first_name lv_last_name INTO lv_full_name SEPARATED BY space.
* 結果: 'John Doe'

* 複数文字列の結合
DATA: lv_title     TYPE string VALUE 'Mr.',
      lv_separator TYPE string VALUE ' '.
CONCATENATE lv_title lv_first_name lv_last_name INTO lv_full_name SEPARATED BY separator.
* 結果: 'Mr. John Doe'

パフォーマンスに関する注意点

  1. 文字列長の考慮
    • 結果文字列の最大長を事前に把握
    • 適切なデータ型の選択が重要
  2. メモリ管理
    • 大きな文字列を扱う場合は注意
    • 必要に応じてガベージコレクションを考慮
  3. 実行頻度
    • ループ内での使用は慎重に
    • 必要に応じて一時変数を活用

このような基本的な理解を踏まえた上で、実際のプロジェクトでは状況に応じた適切な実装方法を選択することが重要です。

データ型の選択と互換性

文字列結合における適切なデータ型の選択は、処理の正確性とパフォーマンスに直接影響を与えます。

データ型特徴適用場面
STRING可変長、メモリ効率が良い長さが不定な文字列処理
CHAR固定長、パディング有りレガシーシステムとの互換性維持
TEXT大容量テキスト向け長大なテキスト処理
* データ型による結合の違い
DATA: lv_string TYPE string,
      lv_char10 TYPE c LENGTH 10,
      lv_char20 TYPE c LENGTH 20.

* STRINGの場合(動的長)
lv_string = 'ABAP'. 
CONCATENATE lv_string 'Programming' INTO lv_string.
* 結果: 'ABAPProgramming'(余分なスペースなし)

* CHARの場合(固定長)
lv_char10 = 'ABAP'.
CONCATENATE lv_char10 'Code' INTO lv_char20.
* 結果: 'ABAP     Code     '(パディングあり)

CONCATENATEの実装パターンを徹底解説

基本的な2つの文字列を結合するパターン

直接結合パターン

最もシンプルな実装パターンから解説します:

* 1. 基本的な直接結合
DATA: lv_first  TYPE string VALUE 'Hello',
      lv_second TYPE string VALUE 'World',
      lv_result TYPE string.

CONCATENATE lv_first lv_second INTO lv_result.
* 結果: 'HelloWorld'

* 2. スペース区切りの結合
CONCATENATE lv_first lv_second INTO lv_result SEPARATED BY space.
* 結果: 'Hello World'

* 3. 変数への直接代入
DATA: lv_name   TYPE string VALUE 'John',
      lv_suffix TYPE string VALUE 'san'.

CONCATENATE lv_name lv_suffix INTO lv_name.
* 結果: lv_nameが'Johnsan'に更新される

条件付き結合パターン

実務でよく使用される条件付きの結合パターン:

* 1. IF文を使用した条件付き結合
DATA: lv_title  TYPE string VALUE 'Mr.',
      lv_name   TYPE string VALUE 'Smith',
      lv_result TYPE string.

IF sy-langu = 'J'. "日本語環境の場合
  CONCATENATE lv_name lv_title INTO lv_result SEPARATED BY space.
ELSE.
  CONCATENATE lv_title lv_name INTO lv_result SEPARATED BY space.
ENDIF.

* 2. 空文字チェック付き結合
DATA: lv_optional TYPE string.

IF lv_optional IS NOT INITIAL.
  CONCATENATE lv_name lv_optional INTO lv_result SEPARATED BY space.
ELSE.
  lv_result = lv_name.
ENDIF.

複数文字列を一度に結合するパターン

基本的な複数結合

* 1. 3つ以上の文字列を一度に結合
DATA: lv_prefix TYPE string VALUE 'Dear',
      lv_title  TYPE string VALUE 'Mr.',
      lv_name   TYPE string VALUE 'Smith',
      lv_result TYPE string.

CONCATENATE lv_prefix lv_title lv_name INTO lv_result SEPARATED BY space.
* 結果: 'Dear Mr. Smith'

* 2. 配列要素の連続結合
DATA: lt_parts TYPE TABLE OF string,
      lv_part  TYPE string.

APPEND 'Hello' TO lt_parts.
APPEND 'Beautiful' TO lt_parts.
APPEND 'World' TO lt_parts.

CLEAR lv_result.
LOOP AT lt_parts INTO lv_part.
  IF sy-tabix = 1.
    lv_result = lv_part.
    CONTINUE.
  ENDIF.
  CONCATENATE lv_result lv_part INTO lv_result SEPARATED BY space.
ENDLOOP.
* 結果: 'Hello Beautiful World'

高度な複数結合パターン

* 1. 動的な区切り文字を使用した複数結合
DATA: lv_separator TYPE string VALUE ', ',
      lv_last_sep  TYPE string VALUE ' and '.

DATA: lt_items TYPE TABLE OF string.
APPEND 'Apple' TO lt_items.
APPEND 'Banana' TO lt_items.
APPEND 'Orange' TO lt_items.

DATA: lv_current TYPE string,
      lv_final   TYPE string.

LOOP AT lt_items INTO lv_current.
  CASE sy-tabix.
    WHEN 1.
      lv_final = lv_current.
    WHEN lines( lt_items ).
      CONCATENATE lv_final lv_current INTO lv_final SEPARATED BY lv_last_sep.
    WHEN OTHERS.
      CONCATENATE lv_final lv_current INTO lv_final SEPARATED BY lv_separator.
  ENDCASE.
ENDLOOP.
* 結果: 'Apple, Banana and Orange'

* 2. 条件付きセパレータを使用した結合
TYPES: BEGIN OF ty_address,
         street  TYPE string,
         city    TYPE string,
         state   TYPE string,
         country TYPE string,
       END OF ty_address.

DATA: ls_address TYPE ty_address,
      lv_address TYPE string.

ls_address-street  = '123 Main St'.
ls_address-city    = 'Springfield'.
ls_address-state   = 'IL'.
ls_address-country = 'USA'.

CONCATENATE ls_address-street 
            ls_address-city 
            ls_address-state 
            ls_address-country 
       INTO lv_address 
       SEPARATED BY ', '.
* 結果: '123 Main St, Springfield, IL, USA'

一般的なエラーパターンと解決方法

1. メモリ不足エラー

エラー症状

* SYSTEM_FAILURE MEMORY_ALLOCATION_ERROR
DATA: lv_huge_string TYPE string.
DO 1000000 TIMES.
  CONCATENATE lv_huge_string 'some text' INTO lv_huge_string.
ENDDO.

解決方法

* 1. バッファを使用した効率的な実装
DATA: lv_result TYPE string,
      lv_buffer TYPE string.

" サイズを事前計算
DATA(lv_total_size) = 1000000 * strlen( 'some text' ).
CREATE DATA lv_buffer TYPE string LENGTH lv_total_size.

" 一度の操作で結合
DO 1000000 TIMES.
  CONCATENATE lv_buffer 'some text' INTO lv_buffer.
ENDDO.
lv_result = lv_buffer.

2. 文字コード変換エラー

エラー症状

* CHARACTER_CONVERSION_ERROR
DATA: lv_utf8_text  TYPE string VALUE '漢字',
      lv_ascii_text TYPE c LENGTH 10.

CONCATENATE lv_ascii_text lv_utf8_text INTO lv_ascii_text.

解決方法

* 1. 適切な文字コード変換の実装
CLASS lcl_text_converter DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      safe_concatenate
        IMPORTING
          iv_text1        TYPE any
          iv_text2        TYPE any
        RETURNING
          VALUE(rv_result) TYPE string.
ENDCLASS.

CLASS lcl_text_converter IMPLEMENTATION.
  METHOD safe_concatenate.
    DATA: lv_text1_conv TYPE string,
          lv_text2_conv TYPE string.

    " 文字コード変換 CONV命令で直接型を指定できる
    TRY.
        lv_text1_conv = CONV string( iv_text1 ).
        lv_text2_conv = CONV string( iv_text2 ).

        CONCATENATE lv_text1_conv lv_text2_conv INTO rv_result.
    CATCH cx_sy_conversion_error INTO DATA(lx_conv_error).
        " エラーハンドリング
        rv_result = 'Conversion Error: ' && lx_conv_error->get_text( ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

3. 長さ超過エラー

エラー症状

* STRING_OVERFLOW
DATA: lv_char10 TYPE c LENGTH 10,
      lv_text   TYPE string VALUE 'This is a long text'.

CONCATENATE lv_char10 lv_text INTO lv_char10.

解決方法

* 1. 安全な文字列長処理
CLASS lcl_string_handler DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      safe_truncate_concatenate
        IMPORTING
          iv_text1        TYPE any
          iv_text2        TYPE any
          iv_max_length   TYPE i
        RETURNING
          VALUE(rv_result) TYPE string.
ENDCLASS.

CLASS lcl_string_handler IMPLEMENTATION.
  METHOD safe_truncate_concatenate.
    DATA: lv_temp TYPE string.

    " 結合前に長さをチェック
    CONCATENATE iv_text1 iv_text2 INTO lv_temp.

    IF strlen( lv_temp ) > iv_max_length.
      rv_result = lv_temp(iv_max_length).
    ELSE.
      rv_result = lv_temp.
    ENDIF.
  ENDMETHOD.
ENDCLASS.