久々のSAPネタ。
忘れないうちに書いときます。
Loop AT <内部テーブル> INTO <構造体>.
AT NEW.
ENDAT.
ENDLOOP.
とした場合、
しかも、この書き方の場合、 <構造体>がこんな
ITEM001 TYPE C LENGTH 10
ITEM002 TYPE C LENGTH 10
ITEM003 TYPE C LENGTH 10
内容だとして、
AT NEW でブレイクすると AT NEW 〜 ENDAT 内で参照できるのは、ITEM001だけで
ITEM002以降については文字項目の場合 '*' が詰められて参照できません。
これが最初分からなくって、随分ハマりましたし、恐らくABAPでAT NEW とか「使いにくい」って感じてる人はこれが原因じゃないかと思います。
ところが。
LOOP AT 〜 にはもうひとつの記法が有るのはご存知だと思います。
そう!
LOOP AT <内部テーブル> ASSIGN <フィールドシンボル>.
この書き方の場合、先程のAT NEW の書き方がチョット違ってきます。
LOOP AT <内部テーブル> ASSIGN <フィールドシンボル>.
AT NEW <フィールドシンボル>.
ENDAT.
ENDLOOP.
INTO では、AT NEW に書けるのは<構造体>内の1項目でしたが、
ASSIGN の場合は、<フィールドシンボル> そのものを書きます。
じゃあこれでどうなるかって言うと、<フィールドシンボル> の参照元の内部テーブルの構造全体がキーとして認識されます。
「…え?じゃあ…どうなるの?」
極端なことをいえば、<内部テーブル>内の全レコードがAT NEWの対象になります。
つまり、”必ずAT NEW”を通ります。
それじゃあ、NEWの意味が無いんですが、重要な点が2つ。
- INTOの場合、指定した項目(先の例で言えばITEM001)以降の項目の参照ができませんでしたが、ASSIGNの場合、全ての項目の参照が出来ます。
- 任意の複数項目を一つのキーとして使用することができる。
例えば、こんなの。
TYPES:
BEGIN OF TYP001, " 内部テーブル構造体1
ITEM001 TYPE C LENGTH 10,
ITEM002 TYPE C LENGTH 10,
ITEM003 TYPE C LENGTH 10,
ITEM004 TYPE C LENGTH 10,
END OF TYP001.
TYPES:
BEGIN OF TYP00A, " ブレイクキー構造体
ITEM001 TYPE C LENGTH 10,
ITEM002 TYPE C LENGTH 10,
END OF TYP00A.
TYPES:
BEGIN OF TYP002, " 内部テーブル構造体2
ITEM00A TYPE TYP00A, " ブレイクキー項目
ITEM003 TYPE C LENGTH 10,
ITEM004 TYPE C LENGTH 10,
END OF TYP002.
DATA:
TB001 TYPE STANDARD TABLE TYP001, " 内部テーブル1
TB002 TYPE STANDARD TABLE TYP002, " 内部テーブル2(キー構造有り)
KEY TYPE TYP00A. " キー退避項目
FIELD-SYMBOLS:
TYPE TYP002. " フィールドシンボル
* 既に TB001 にはデータが入っていてSORTまでされているとします
* ブレイクキー項目の有る内部テーブルにコピー
TB002[] = TB001[].
LOOP AT TB002 ASSIGN.
AT NEW.
IF-ITEM00A <> KEY.
*** ここにブレイク時の処理を記述(今回はWRITEします)
WRITE: /1(10)-ITEM00A-ITEM001,
13(10)-ITEM00A-ITEM002.
KEY =-ITEM00A. " KEY項目の更新(これをしないとブレイクしない)
ELSE.
NEW-LINE. " ブレイクしない場合、ただ改行だけ
ENDIF.
ENDAT.
WRITE: 26(10)-ITEM003, " 非キー項目はそのままWRITE
39(10)-ITEM004.
ENDLOOP.
これを実行するとこんな感じに出力される(はず)。
aaaaa aaaaa xxxxx yyyyy
xxxxx yyy00
xxxxx yyy01
aaaaa bbbbb xxxxx yyyyy
x00xx yyyyy
abbbb bbbbb xxxxx yyyyy
キー部分がブレイクした時だけ出力されて、非キー項目はレコード毎に出力されます。
ちょっと面倒な感じもあるし、比較項目を2つ用意してLOOPさせながらIFで比較するって言う旧来のやり方と殆ど変わらない気もするんですが、 フィールドシンボルの場合AT NEW 内で
「全項目へのアクセスができる」
って所が個人的には
すげーーーーー!Σ(・ω・;|||
って単純に思っちゃたんです。(^^;
まあ、覚えておいて…どっかで使うこと…あるかな????
では〜。