このトピックでは、ABAPでUniCodeのシステムからSJISコードで固定長ファイル出力の方法を取り上げて説明します。
ABAPで文字コードの関係でSJISコードで固定長ファイルを出力するには少し工夫する必要があります。 タブ区切りやカンマ区切りのファイル出力にするほうがだんぜん楽ですが、ふるい既存システムへの連携で固定長ファイルにしなければならない場面がしばしばあります。
固定長ファイル出力の基本は、項目を固定バイト長に出力させることです。
以下の構造体をファイルに出力することを例とします。
TYPES: BEGIN OF typ_row, col1 TYPE C LENGTH 10, col2 TYPE C LENGTH 12, END OF typ_row.
Unicodeシステムのため、co1に定義されたLENGTH=10はバイト数ではなく文字数ですので、SJISで出力されるバイト数は可変になります。 一番少ないのは、すべて半角文字の場合であり、出力バイト数が10×1半角文字1バイト=10バイトになります。 一番多いのは、すべて全角文字の場合であり、出力バイト数が10×1全角文字2バイト=20バイトになります。 col1の固定長出力は以下の2パターンに分けることができます。
上記の課題を対応するポイントは以下になります。
固定バイト数で文字列を出力するサブルーチンのサンプルコードです。
*&---------------------------------------------------------------------* *& Form F_OUTPUT_FIXED_BYTES *&---------------------------------------------------------------------* * 固定バイト数で文字列出力 *----------------------------------------------------------------------* * -->U_LEN : 出力バイト長 * -->U_FIELD : 入力値 * -->C_STR : 出力文字列 *----------------------------------------------------------------------* FORM f_output_fixed_bytes USING u_len TYPE i u_field CHANGING c_str. DATA: l_len TYPE i, "length l_cnt TYPE i, l_rc TYPE abap_list_repl_rc. CLEAR: c_str, l_cnt. * byte数取得 CALL METHOD cl_abap_list_utilities=>dynamic_output_length EXPORTING field = u_field RECEIVING len = l_cnt. * データ長が出力バイト長を超えた場合、出力バイト長で文字列をカット IF l_cnt > u_len. TRY. CALL METHOD cl_abap_list_utilities=>read_from_display_layout EXPORTING display_data = u_field display_offset = 0 display_length = u_len IMPORTING field = c_str rc = l_rc. CATCH cx_parameter_invalid_range . ENDTRY. * byte数再取得 (カット箇所に全角文字が跨っているケースを考慮) CALL METHOD cl_abap_list_utilities=>dynamic_output_length EXPORTING field = c_str RECEIVING len = l_cnt. * バイト数が足りない場合は、後ろにスペースを埋める WHILE l_cnt < u_len. CONCATENATE c_str ' ' INTO c_str RESPECTING BLANKS. l_cnt = l_cnt + 1. ENDWHILE. ENDIF. ENDFORM.