2017-01-20 120 views
1

有一個任務可以用宏來填充深層結構,其中結構組件的名稱是相似的,並且可以通過帶有索引的簡單循環來構造。 例如,結構根1級,級別2 - 3級,級別4用循環將參數傳遞給宏

我想用下面的嵌套宏

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-Sheet 1中-level2- levelsy-指數級別4沒有找到

所示,但是數字文字作品奇妙。

這裏應該使用什麼語法?

ADDITION:這是我在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.S.是的,我知道宏是不可破壞的,不安全的,完全不應該使用,但我對這個特殊問題感興趣,而不是最佳實踐建議。

+0

PS:我沒有看到你在'fill'宏中使用第5個參數(level4)...... – Marius

回答

0

使用動態編程,改變你的fill宏:

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. 

這將工作,但您可能希望ASSIGN後檢查sy-subrc,因爲該參數是不變的(僅在運行時知道)和因此在編譯時不會像其他參數那樣拾取錯誤。

您還可以爲您的DO循環的上限添加編譯時驗證,因爲您因此知道最大值sy-index。要做到這一點,你可以在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. 

第二種方法是添加一個case語句。只有在知道該部分總是有一定數量的字段的情況下才能使用(當然,應該始終至少有一個字段......)。所以,如果你知道你的束縛環DO的底部,那麼你可以編寫以下爲優化:

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

    WHEN OTHERS. 
     " dynamic set 
    ENDCASE. 

由於動態集較慢,優化緊湊循環始終是一個好主意。

+1

好,它的作品!我修正了你的代碼片段,因爲* sy-index *是* fill *宏的第三個參數,而不是第一個。另外,'CONDENSE'應該應用於* l_field *,因爲如果不在循環計數器之前修剪前導額外空間,'ASSIGN'會進入短暫轉儲。 – Suncatcher

+0

謝謝,錯過了!我不得不盲目打字,因爲我沒有你引用的源結構類型。還解決了在原始帖子中檢測到的參數問題。 – Marius

1

系統正在執行documentation中所述的操作。不幸的是,在這種情況下,英文翻譯缺乏一些細節,而不是德國的原文,更重要的是,恕我直言。宏的使用不是某種調用,而是在編譯前發生的文本替換。參數被替換,未被評估 - 他們不能被評估,因爲在大多數情況下,只有在運行時才能知道編譯時的值。要做你想做的事情,你將不得不使用動態訪問技術,如ASSIGN COMPONENT ... OF ...

+0

也許可以進行一些內嵌轉換或其他的東西?需要單線宏的任務,如果我們使用動態方法,應該被數十行重寫:) – 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