将ABAP 740语法转换为700 - VALUE & LOOP AT ...分组依据

  • 本文关键字:AT LOOP VALUE ABAP 语法 转换 abap
  • 更新时间 :
  • 英文 :


我在网上找到了一个我想使用的树救世主演示程序,但由于它使用 740 语法,我必须先转换它。这也是了解有关新语法的更多信息的好机会。

我已经做了几乎所有的事情,但是在VALUE上遇到了麻烦。阅读这个维基条目,除其他外,对我无济于事。

740 中的原始代码:

" Treenodes einfügen
LOOP AT it_spfli ASSIGNING FIELD-SYMBOL(<c>) GROUP BY <c>-carrid.
DATA(it_cp) = VALUE ty_it_spfli( FOR <cp> IN GROUP <c> ( <cp> ) ).
DATA(o_parent) = o_tree->get_nodes( )->add_node( related_node   = ''
relationship   = cl_gui_column_tree=>relat_last_child
collapsed_icon = CONV #( icon_closed_folder )
expanded_icon  = CONV #( icon_open_folder )
row_style      = if_salv_c_tree_style=>intensified
text           = CONV #( <c>-carrid ) ).
IF lines( it_cp ) > 1.
o_parent->get_item( 'CARRID' )->set_type( if_salv_c_item_type=>button ).
o_parent->get_item( 'CARRID' )->set_value( 'all' ).
ENDIF.
LOOP AT GROUP <c> ASSIGNING FIELD-SYMBOL(<f>).
DATA(o_carrid) = o_tree->get_nodes( )->add_node( related_node = o_parent->get_key( )
relationship = cl_gui_column_tree=>relat_last_child
data_row     = <f>
row_style    = if_salv_c_tree_style=>intensified
text         = CONV #( <f>-connid ) ).
o_carrid->get_item( 'CARRID' )->set_type( if_salv_c_item_type=>checkbox ).
o_carrid->get_item( 'CARRID' )->set_editable( abap_true ).
ENDLOOP.
ENDLOOP.

700 中的新代码,除了带有VALUE行:

" new variables added to convert code to 700
DATA: o_nodes  TYPE REF TO cl_salv_nodes,
o_parent TYPE REF TO cl_salv_node,
o_carrid TYPE REF TO cl_salv_node,
o_item   TYPE REF TO cl_salv_item,
o_key    TYPE lvc_nkey.
DATA: h_collapsed_icon TYPE salv_de_tree_image VALUE 'icon_closed_folder',
h_expanded_icon TYPE salv_de_tree_image VALUE 'icon_open_folder',
h_text_carrid TYPE lvc_value.
DATA: it_cp TYPE STANDARD TABLE OF ty_it_spfli.    
SORT it_spfli BY carrid.
" Treenodes einfügen
LOOP AT it_spfli ASSIGNING <c>.
AT NEW carrid.
it_cp = value TY_IT_SPFLI( for <CP> in GROUP <c> ( <CP> ) ).  <--- Here
o_nodes = o_tree->get_nodes( ).
h_text_carrid = <c>-carrid.
o_parent = o_nodes->add_node( related_node   = ''
relationship   = cl_gui_column_tree=>relat_last_child
collapsed_icon = h_collapsed_icon
expanded_icon  = h_expanded_icon
row_style      = if_salv_c_tree_style=>intensified
text           = h_text_carrid ).
IF LINES( it_cp ) > 1.
o_item = o_parent->get_item( 'CARRID' ).
o_item->set_type( if_salv_c_item_type=>button ).
o_item->set_value( 'all' ).
ENDIF.
ENDAT.
o_key = o_parent->get_key( ).
o_carrid = o_nodes->add_node( related_node = o_key
relationship = cl_gui_column_tree=>relat_last_child
data_row     = <c>
row_style    = if_salv_c_tree_style=>intensified
text         = h_text_carrid ).
o_item = o_parent->get_item( 'CARRID' ).
o_item->set_type( if_salv_c_item_type=>checkbox ).
o_item->set_editable( abap_true ).
ENDLOOP.

我现在的问题是:

  1. 我是否使用AT NEW正确转换了LOOP AT ... GROUP BY
  2. 如何用VALUE转换行?

提前感谢您的帮助。

您无法按照自己的方式进行转换。CARRID 原始代码分组的外部循环与 AT NEW 并不完全相同,因为它生成了一个临时组表,然后您可以在任何地方使用。如果没有它,您应该提前生成组。

我没有验证代码,但为了模拟 GROUP BY,然后使转换的其余部分变得容易而不必重写太多,我会从原始的每个 CARRID 创建一个嵌套表:

DATA: BEGIN OF ls_spfli_carrid_group,
carrid  TYPE carrid,
flights TYPE ty_it_spfli,
END OF ls_spfli_carrid_group,
lt_spfli_carrid_group LIKE STANDARD TABLE OF ls_spfli_carrid_group.
SORT it_spfli BY carrid.
LOOP AT it_spfli INTO ls_spfli.
AT NEW carrid.
it_spfli
ls_spfli_carrid_group-carrid = ls_spfli-carrid.
REFRESH ls_spfli_carrid_group-flights.
APPEND ls_spfli_carrid_group TO lt_spfli_carrid_group.
ENDAT.
APPEND ls_spfli TO ls_spfli_carrid_group-flights.
ENDLOOP.
LOOP AT lt_spfli_carrid_group INTO ls_spfli_carrid_group.
it_cp = ls_spfli_carrid_group-flights.
...
LOOP AT ls_spfli_carrid_group-flights INTO ls_flight. "Should be like the LOOP AT GROUP
ENDLOOP.
ENDLOOP.

事实上,你问的是"FOR ...分组":

TYPES: ty_it_spfli TYPE STANDARD TABLE OF spfli WITH DEFAULT KEY.
DATA it_spfli TYPE ty_it_spfli.
LOOP AT it_spfli ASSIGNING FIELD-SYMBOL(<c>) GROUP BY <c>-carrid.
DATA(it_cp) = VALUE ty_it_spfli( FOR <cp> IN GROUP <c> ( <cp> ) ).
...
ENDLOOP.

首先,带有"GROUP BY"的外部循环迭代 CARRID 组件的不同值。例如,内部表it_spfli可能有 100 行,但只有 10 个不同的 CARRID 值,因此它将迭代 10 次。

内部的"值构造"FOR <cp> IN GROUP <c><c>行的"组">"成员">处做一个循环,其中"成员"是对应于当前组的it_spfli行(那些对应于当前组的CARRID值的行(,并且在每次迭代时,行( <cp> )被附加到变量it_cp

这一行:

DATA(it_cp) = VALUE ty_it_spfli( FOR <cp> IN GROUP <c> ( <cp> ) ).

相当于下面的语法和LOOP AT GROUP,也只从 7.40 开始有效,但对你来说应该更清楚,你可以在 7.0 中更直观地转换它:

DATA(it_cp) = VALUE ty_it_spfli( ). " initialization (empty internal table)
LOOP AT GROUP <c> ASSIGNING FIELD-SYMBOL(<cp>).
INSERT <cp> INTO TABLE it_cp.
ENDLOOP.

谢谢桑德拉和拉蒂奥的帮助。

现在我明白了应该发生什么,我有以下两个解决方案(其中一个是来自 RaTiO 的解决方案(。

(应该发生的情况:VALUE 命令应该用循环表的那些行填充另一个 itab,其中包含当前的 CARRID。然后,根据行数,您可以查看节点是否有子节点,因此需要成为扩展按钮。

因此,我想到的解决方案是填写 LOOP 中表的副本,并删除那些不包含当前 CARRID 的条目。

DATA: it_copy_spfli TYPE ty_it_spfli.
...
SORT it_spfli BY carrid.
LOOP AT it_spfli ASSIGNING <c>.
AT NEW carrid.
REFRESH it_copy_spfli.
it_copy_spfli = it_spfli.
DELETE it_copy_spfli WHERE carrid <> <c>-carrid.
...
IF LINES( it_copy_spfli ) > 1.
...
ENDIF.
ENDAT.
...
ENDLOOP.

然后是RaTiO的解决方案,创建一个嵌套表来循环。

DATA: it_copy_spfli TYPE ty_it_spfli.
DATA: BEGIN OF ls_spfli_carrid_group,
carrid  TYPE s_carr_id,
flights TYPE ty_it_spfli,
END OF ls_spfli_carrid_group.
DATA: ls_spfli  TYPE spfli,
ls_flight TYPE spfli,
lt_spfli_carrid_group LIKE STANDARD TABLE OF ls_spfli_carrid_group.
SORT it_spfli BY carrid.
LOOP AT it_spfli INTO ls_spfli.
APPEND ls_spfli TO ls_spfli_carrid_group-flights.
AT END OF carrid.
ls_spfli_carrid_group-carrid = ls_spfli-carrid.
APPEND ls_spfli_carrid_group TO lt_spfli_carrid_group.
REFRESH ls_spfli_carrid_group-flights.
ENDAT.
ENDLOOP.
LOOP AT lt_spfli_carrid_group INTO ls_spfli_carrid_group.
REFRESH it_copy_spfli.
it_copy_spfli = ls_spfli_carrid_group-flights.
...
h_text_carrid = ls_spfli_carrid_group-carrid.
...
IF LINES( it_copy_spfli ) > 1.
...
ENDIF.
LOOP AT ls_spfli_carrid_group-flights INTO ls_flight.
...
o_carrid = o_nodes->add_node( ...
data_row     = ls_flight
... ).
...
ENDLOOP.
ENDLOOP.

然后我改编它以使用字段符号代替。

DATA: it_copy_spfli TYPE ty_it_spfli.
TYPES: BEGIN OF ty_spfli_carrid_group,
carrid  TYPE s_carr_id,
flights TYPE ty_it_spfli,
END OF ty_spfli_carrid_group.
DATA: lt_spfli_carrid_group TYPE STANDARD TABLE OF ty_spfli_carrid_group.
FIELD-SYMBOLS: <spfli>  TYPE spfli,
<flight> TYPE spfli,
<spfli_carrid_group> TYPE ty_spfli_carrid_group.
SORT it_spfli BY carrid.
LOOP AT it_spfli ASSIGNING <spfli>.
AT NEW carrid.
APPEND INITIAL LINE TO lt_spfli_carrid_group ASSIGNING <spfli_carrid_group>.
ENDAT.
APPEND <spfli> TO <spfli_carrid_group>-flights.
AT END OF carrid.
<spfli_carrid_group>-carrid = <spfli>-carrid.
ENDAT.
ENDLOOP.
LOOP AT lt_spfli_carrid_group ASSIGNING <spfli_carrid_group>.
...
LOOP AT <spfli_carrid_group>-flights ASSIGNING <flight>.
...
ENDLOOP.
ENDLOOP.

所有解决方案都按预期工作。比较运行时,最后一个是最快的,但它们非常非常接近。所以我决定使用我的,因为它只有几行,而 RaTiO 需要另一个 LOOP。

再次感谢=(

相关内容

  • 没有找到相关文章

最新更新