2017-01-20 18 views
1

深い構造体にマクロを埋め込むタスクがあります。構造体の名前が似ていて、インデックス付きの単純なループで構築できます。 は例えば、構造体は、ルート・レベル1・レベル2-LEVEL3-LEVEL4私は、次のネストされたマクロループを使用してマクロにパラメータを渡す

DEFINE iterate_menges. 
do &4 times. 
    fill &1 &2 sy-index level4. 
enddo. 
END-OF-DEFINITION. 

DEFINE fill. 
cs_root-sheet&1-&2-level&3-&4 = 'some_value'. 
END-OF-DEFINITION. 

でそれを埋めるたい

である。しかし、この概念は機能せず、sy-indexがテキストのように扱われています。エラー

成分cs_root-シート1-level2- levelsyインデックス-LEVEL4

が見つからない場合は素晴らしく、しかし数値リテラル作品を示しています。

ここではどのような構文を使用する必要がありますか?

追加:ここはSCNで見つかったスニペットの例です。完全に動作します。なぜそうですか?

DEFINE ADD_MAPPING. 
p_c = &1. 
CONDENSE p_c. 
CONCATENATE 'p_old' p_c INTO p_c. 
ASSIGN (p_c) TO <fs>. 
WRITE <fs>. 
END-OF-DEFINITION. 

DO 14 TIMES. 
ADD_MAPPING sy-index. 
ENDDO. 

P.はい、私はマクロがundebuggable、危険であり、完全に使用すべきではないことを知っていますが、私はこの特定の問題に興味があり、ベストプラクティスアドバイスではありません。

+0

PS: 'fill'マクロで5番目のパラメータ(level4)を使用していません... – Marius

答えて

0

、あなたのfillマクロに変更します。そのパラメータは不変であるので、あなたがASSIGNsy-subrcをチェックしたいかもしれませんが、

DATA l_field TYPE string. 
    FIELD-SYMBOLS <l_value> TYPE any. 
    DEFINE fill. 
    l_field = &3. 
    CONDENSE l_field. 
    CONCATENATE 'cs_root-sheet&1-&2-level' l_field '-&4' INTO l_field. 
    ASSIGN (l_field) TO <l_value>. 
    IF sy-subrc = 0. 
     <l_value> = 'some_value'. 
    ELSE. 
     " TODO: error handling? 
    ENDIF. 
    END-OF-DEFINITION. 

これは動作しますが(実行時にのみ知られている)と、したがって、他のパラメータのようにコンパイル時にエラーを受け取ることはありません。

最大値がsy-indexであることがわかっているので、DOループの上限のコンパイル時検証を追加することもできます。これを行うには、iterate_mengesマクロで非実行の参照を追加することができます。

DEFINE iterate_menges. 
    IF 1 = 0. " compile-time boundary validation test 
     cs_root-sheet&1-&2-level&4-level4 = ''. 
    ENDIF. 
    DO &4 TIMES. 
    fill &1 &2 sy-index level4. 
    ENDDO. 
    END-OF-DEFINITION. 

第2の方法はcase文を追加することです。これは、その部分に常に一定量のフィールドがあることがわかっている場合にのみ使用できます(必ず少なくとも1つは存在するはずです...)。だから、あなたはあなたのDOループの拘束下を知っていれば、あなたが最適化として、以下をコーディングすることができます

CASE &3. 
    WHEN 1. " set 1 
    WHEN 2. " set 2 
    WHEN 3. " set 3 
    " ... 

    WHEN OTHERS. 
     " dynamic set 
    ENDCASE. 

ダイナミックセットが遅いので、タイトなループを最適化することは常に良い考えです。

+1

いいです、それは動作します! * sy-index *は第1引数ではなく、* fill *マクロの3番目のパラメータであるため、あなたのスニペットを少し修正しました。また、ループカウンタの前に余分なスペースをトリミングしない場合は、 'ASSIGN'がショートダンプになるので、' CONDENSE'を* l_field *に適用する必要があります。 – Suncatcher

+0

ありがとう、それを逃した!あなたが参照したソース構造体型がないので、私はいくつかのブラインド型入力をしなければなりませんでした。また、私は元の投稿で検出されたパラメータの問題を回避しました。 – Marius

1

システムは、documentationに記載されているとおりです。残念なことに、この場合、英語の翻訳には、ドイツ語の元のテキストよりもいくつかの細部が欠けています。マクロの使用方法はであり、何らかの種類のと呼びます。テキストの置換がコンパイル前に発生します。パラメータは置き換えられ、評価されません。と評価されません。ほとんどの場合、値はコンパイル時には知られていないため、実行時にのみ認識されます。あなたがしたいことをするには、ASSIGN COMPONENT ... OF ...

+0

インライン変換を行うことができますか?私たちが動的なアプローチを使用する場合、1行のマクロを必要とするタスクは、何十行も書き直す必要があります。 – Suncatcher

+0

ところで、私の質問に加えてマクロを説明するにはどうしたらいいですか? – Suncatcher

+0

SDNのこのコードスニペットは、そこにネストされたマクロがないので動作しますか? – Jagger

-2

のような動的アクセステクニックを使用する必要があります。マクロはコンパイル時にしか分からないため、実行できません。それらはABAPのモジュール化の手段の一部ではありません。

Brainfuckの独自のバージョンを作成することもできます。次の例を見てください。

REPORT zzz. 

TYPES: BEGIN OF t1, 
     sheet1 TYPE c, 
     sheet2 TYPE c, 
     END OF t1. 

DATA: 
    cs_root TYPE t1. 

DEFINE test. 
    cs_root-sheet&1 = 'costam'. 
END-OF-DEFINITION. 

DEFINE brainfuck. 
    &4=>&1&3 &2. 
END-OF-DEFINITION. 

START-OF-SELECTION. 
    brainfuck IF_SYSTEM_UUID_STATIC~CREATE_UUID_X16) (CL_SYSTEM_UUID. 
    test sy-index. 

他の回答の下であなたのコメントを回答してください。解決策はこのように見えるかもしれません。

ダイナミックプログラミングを使用して
REPORT zzz. 

TYPES: BEGIN OF t4, 
    level4 TYPE c, 
    END OF t4. 

TYPES: BEGIN OF t3, 
    level1 TYPE t4, 
    level2 TYPE t4, 
    END OF t3. 

TYPES: BEGIN OF t2, 
    level1 TYPE t3, 
    level2 TYPE t3, 
    END OF t2. 

TYPES: BEGIN OF t1, 
    sheet1 TYPE t2, 
    sheet2 TYPE t2, 
    END OF t1. 

CLASS lcl_test DEFINITION FINAL. 
    PUBLIC SECTION. 
    CLASS-METHODS: 
     test 
     IMPORTING 
      i_1 TYPE i 
      i_2 TYPE i 
      i_3 TYPE i 
     CHANGING 
      cs_root TYPE t1. 
ENDCLASS. 

CLASS lcl_test IMPLEMENTATION. 
    METHOD test. 
    ASSIGN COMPONENT |sheet{ i_1 }| OF STRUCTURE cs_root TO FIELD-SYMBOL(<fs_sheet>). 
    IF sy-subrc = 0. 
     ASSIGN COMPONENT |level{ i_2 }| OF STRUCTURE <fs_sheet> TO FIELD-SYMBOL(<fs_level1>). 
     IF sy-subrc = 0. 
     ASSIGN COMPONENT |level{ i_3 }| OF STRUCTURE <fs_level1> TO FIELD-SYMBOL(<fs_level2>). 
     IF sy-subrc = 0. 
      ASSIGN COMPONENT 'level4' OF STRUCTURE <fs_level2> TO FIELD-SYMBOL(<fs_level3>). 
      IF sy-subrc = 0. 
      <fs_level3> = 'some_value'. 
      ENDIF. 
     ENDIF. 
     ENDIF. 
    ENDIF. 
    ENDMETHOD. 
ENDCLASS. 

DEFINE test. 
    lcl_test=>test(
    EXPORTING 
     i_1 = &1 
     i_2 = &2 
     i_3 = &3 
    CHANGING 
     cs_root = &4 
). 
END-OF-DEFINITION. 

DATA: gs_root TYPE t1. 

START-OF-SELECTION. 
    DO 14 TIMES. 
    test 1 2 sy-index gs_root. 
    ENDDO. 
+0

ダウンボートの理由についてのコメントはありますか? – Jagger

関連する問題