ABAP 中的动态结构与数据引用
动态结构和数据引用已经被很好地记录和编写了十多年,它是 SAP 开发中最灵活(尽管也是最危险的安全)的组件之一。我不会重新设计车轮,而是在动态结构的不同层面上呈现它。
我们将利用动态和数据引用从最简单的结构到更复杂的结构。我会尝试的是向一个刚接触 ABAP 编程的人最好地解释动态编程,因为这是一个巨大的话题,尽早学习它有助于培养良好的框架思维方式。
FIELD-SYMBOLS: <lfs_vkorg> TYPE vkorg.
CONSTANTS: lc_curr_vkorg TYPE objectname VALUE '(SAPMV13H)KOMGH-VKORG'.
... Do something ...
ASSIGN (lc_curr_vkorg) TO <lfs_vkorg>.
IF <lfs_vkorg> IS ASSIGNED.
IF <lfs_vkorg> IS NOT INITIAL.
... Do something ...
ENDIF.
ENDIF.
动态结构
用法:这通常是与动态表同时进行的,但如果不是的话,它给你一个机会从一个名字或一个引用(如另一个变量)中创建一个结构。有多种方法来创建动态结构,但其中一种方法如下:
PARAMETERS: p_tab TYPE tabname.
DATA: lo_structure TYPE REF TO cl_abap_structdescr,
lr_data TYPE REF TO data.
lo_structure ?= cl_abap_structdescr=>describe_by_name( p_name = p_tab ).
CREATE DATA lr_data TYPE HANDLE lo_structure.
ASSIGN lr_data->* TO FIELD-SYMBOL(<lfs_structure>).
IF <lfs_structure> IS ASSIGNED.
" Do something
ENDIF.
另一个例子是一个没有 "参考 "的动态生成的结构。在这个例子中,我正在根据参数 p_cnt
生成一个带有若干标准价格字段的结构。它在运行时生成该结构。这在它可以改变输出的程序中非常有用。
一个常见的用例是根据一个时间范围生成 ALV 输出,如月度值,其中月数是根据用户输出而变化的。
PARAMETERS: p_cnt TYPE i.
TYPES: BEGIN OF ty_material_price,
matnr TYPE matnr,
waers TYPE waers,
END OF ty_material_price.
DATA: go_struc TYPE REF TO cl_abap_structdescr,
go_new_struc TYPE REF TO cl_abap_structdescr,
gr_structure TYPE REF TO data,
go_tabdata TYPE REF TO data,
go_descr TYPE REF TO cl_abap_datadescr,
gv_price TYPE STPRS,
gs_mat_price TYPE ty_material_price.
go_struc ?= cl_abap_structdescr=>describe_by_data( gs_mat_price ).
DATA(components) = go_struc->get_components( ).
DO p_cnt TIMES.
go_descr ?= cl_abap_typedescr=>describe_by_data( gv_price ).
APPEND INITIAL LINE TO components
ASSIGNING FIELD-SYMBOL(<component>).
<component> = VALUE #( name = |STPRS{ sy-index }| type = go_descr ).
ENDDO.
TRY.
DATA(new_struc) = cl_abap_structdescr=>create( p_components = components ). " Structure Type Object
CREATE DATA gr_structure TYPE HANDLE new_struc.
ASSIGN gr_structure->* TO FIELD-SYMBOL(<new_structure>).
IF <new_structure> IS ASSIGNED.
" Do something
ENDIF.
CATCH cx_sy_struct_creation. " Exception when creating a structure description
ENDTRY.
动态内表
ABAP 中的大多数动态用法都是围绕着动态表进行的。有无数的用途,特别是在动态程序中,围绕着动态表的创建。事实上,大多数框架程序在编码中都有一些动态表的概念。
与动态结构类似,有多种方法来创建动态表,但只是为了继续动态结构到动态表的创建,下面是一个如何创建动态表的好例子。
PARAMETERS: p_tab TYPE tabname.
DATA: lo_structure TYPE REF TO cl_abap_structdescr,
lo_table TYPE REF TO cl_abap_tabledescr,
lr_data TYPE REF TO data,
lr_table_data TYPE REF TO data.
FIELD-SYMBOLS: <lfs_table> TYPE STANDARD TABLE.
lo_structure ?= cl_abap_structdescr=>describe_by_name( p_name = p_tab ).
CREATE DATA lr_data TYPE HANDLE lo_structure.
lo_table ?= cl_abap_tabledescr=>create(
p_line_type = lo_structure " Line Type
* p_table_kind = tablekind_std " Table Category (STANDARD, SORTED, HASHED)
* p_unique = abap_false " Uniqueness of the Key
* p_key = " Key table
* p_key_kind = keydefkind_default " Key category
).
CREATE DATA lr_table_data TYPE HANDLE lo_table.
ASSIGN lr_data->* TO FIELD-SYMBOL(<lfs_structure>).
ASSIGN lr_table_data->* TO FIELD-SYMBOL(<lfs_table_data>).
IF <lfs_table_data> IS ASSIGNED.
" Do something
ENDIF.
按照动态结构的例子2,我们也可以用结构来创建一个动态结构的内部表:
PARAMETERS: p_cnt TYPE i.
TYPES: BEGIN OF ty_material_price,
matnr TYPE matnr,
waers TYPE waers,
END OF ty_material_price.
DATA: go_struc TYPE REF TO cl_abap_structdescr,
go_new_struc TYPE REF TO cl_abap_structdescr,
gr_structure TYPE REF TO data,
gr_table TYPE REF TO data,
go_descr TYPE REF TO cl_abap_datadescr,
gv_price TYPE STPRS,
gs_mat_price TYPE ty_material_price.
FIELD-SYMBOLS: <new_table> TYPE STANDARD TABLE.
go_struc ?= cl_abap_structdescr=>describe_by_data( gs_mat_price ).
DATA(components) = go_struc->get_components( ).
DO p_cnt TIMES.
go_descr ?= cl_abap_typedescr=>describe_by_data( gv_price ).
APPEND INITIAL LINE TO components
ASSIGNING FIELD-SYMBOL(<component>).
<component> = VALUE #( name = |STPRS{ sy-index }| type = go_descr ).
ENDDO.
TRY.
DATA(new_struc) = cl_abap_structdescr=>create( p_components = components ). " Structure Type Object
CREATE DATA gr_structure TYPE HANDLE new_struc.
ASSIGN gr_structure->* TO FIELD-SYMBOL(<new_structure>).
IF <new_structure> IS ASSIGNED.
" Do something
ENDIF.
DATA(new_table) = cl_abap_tabledescr=>create( p_line_type = new_struc ).
CREATE DATA gr_table TYPE HANDLE new_table.
ASSIGN gr_table->* TO <new_table>.
IF <new_table> IS ASSIGNED.
" Do something
ENDIF.
CATCH cx_sy_table_creation. " Exception when Creating a Table Type
CATCH cx_sy_struct_creation. " Exception when creating a structure description
ENDTRY.
访问动态结构中的动态字段
如果你不能访问结构中的字段,整个动态表就没有用。来自动态结构和表的字段在设计时是不明确的,只能在运行时生成。
也就是说,你可以使用 ASSIGN COMPONENT
命令或 ASSIGN
命令访问它们。它将尝试在运行时访问该字段或组件。两者都能达到相同的结果。
CREATE DATA gr_structure TYPE HANDLE new_struc.
ASSIGN gr_structure->* TO FIELD-SYMBOL(<new_structure>).
IF <new_structure> IS ASSIGNED.
gv_field = |STPRS{ p_cnt }|.
"Option 1
ASSIGN <new_structure>-(gv_field) TO FIELD-SYMBOL(<stprs2>).
IF <stprs2> IS ASSIGNED.
<stprs2> = 10.
ENDIF.
"Option 2
ASSIGN COMPONENT gv_field OF STRUCTURE <new_structure> TO FIELD-SYMBOL(<stprs>).
IF <stprs> IS ASSIGNED.
<stprs> = 20.
" Do something
BREAK-POINT.
ENDIF.
UNASSIGN <stprs>.
" Do something
ENDIF.
- 点赞
- 收藏
- 关注作者
评论(0)