2013-03-02

ABAP: Loop AT 〜 [INTO | ASSIGN]

どもです。

久々のSAPネタ。
忘れないうちに書いときます。

Loop AT <内部テーブル> INTO <構造体>.

  AT NEW .

  ENDAT.

ENDLOOP.

とした場合、 に書けるのは、<構造体>内の項目になります。
しかも、この書き方の場合、 <構造体>がこんな
 ITEM001     TYPE    C LENGTH 10
 ITEM002     TYPE    C LENGTH 10
 ITEM003     TYPE    C LENGTH 10
内容だとして、ITEM001 だとすると、
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つ。
  1. INTOの場合、指定した項目(先の例で言えばITEM001)以降の項目の参照ができませんでしたが、ASSIGNの場合、全ての項目の参照が出来ます。
  2. 任意の複数項目を一つのキーとして使用することができる。
と言う事になります。

例えば、こんなの。

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 内で
「全項目へのアクセスができる」
って所が個人的には
すげーーーーー!Σ(・ω・;|||
って単純に思っちゃたんです。(^^;

まあ、覚えておいて…どっかで使うこと…あるかな????


では〜。

0 件のコメント:

SSH Keyを作成してGitHubなどに接続してみる - Qiita

大事なことなので。 SSH Keyを作成してGitHubなどに接続してみる - Qiita : GitHubやGitLab上のリポジトリへgitコマンドでファイルをpushする時に、上手く接続出来なかったのでSSH Keyの作成からやり直してみました。これはその作業ログなので自分...