Return abap中持久化class的所有属性列表
Return a list of all atributes of a persistent class in abap
我在自定义 table 上得到了持久的 class。现在使用 GET_PERSISTENT_BY_QUERY 我可以获得对象列表。我现在如何才能将这些对象及其所有属性打印给用户(例如作为 ALV)?
如果我以某种方式单击它,我可以调用实例函数吗?
一种(我认为不太好)方法是定义一个名为列表的实例属性。然后,生成的getter可以覆盖如下,从任何地方寻址。
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
result = WA.
" GET_LIST
endmethod.
... 代表列表中我想要的每个属性。
此解决方案的缺点:
- 每次调用都有非常很多逻辑要做
- 未使用该属性
另一种(我认为不太好)方法是定义一个名为列表的实例属性。然后,在初始化时,列表准备就绪。
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
LIST = WA.
endmethod.
... 代表列表中我想要的每个属性。
然后,在每个 setter 上,它也会在此列表中发生变化
此解决方案的缺点:
- 一切都是多余的,
- 每个 setter 都必须更换
这里是动态解,query_data是调用get_persistent_by_query( )返回的结果。最后数据会存储在结构化的table
中,你可以用它来显示在你的ALV中。请注意,几乎无法控制字段的顺序。对于实际使用,您还必须添加一些错误处理。
DATA: pers_obj_desc TYPE REF TO cl_abap_classdescr,
pers_query_data TYPE REF TO data,
field_cat TYPE lvc_t_fcat.
FIELD-SYMBOLS: <table> TYPE STANDARD TABLE.
LOOP AT query_data ASSIGNING FIELD-SYMBOL(<pers_data>).
AT FIRST.
pers_obj_desc ?= cl_abap_typedescr=>describe_by_object_ref( p_object_ref = <pers_data> ).
LOOP AT pers_obj_desc->attributes ASSIGNING FIELD-SYMBOL(<attr_desc>).
APPEND INITIAL LINE TO field_cat ASSIGNING FIELD-SYMBOL(<field_cat>).
<field_cat>-fieldname = <attr_desc>-name.
<field_cat>-intlen = <attr_desc>-length.
<field_cat>-datatype = <attr_desc>-type_kind.
ENDLOOP.
cl_alv_table_create=>create_dynamic_table(
EXPORTING
it_fieldcatalog = field_cat
IMPORTING
ep_table = pers_query_data
).
ASSIGN pers_query_data->* TO <table>.
ENDAT. " first
APPEND INITIAL LINE TO <table> ASSIGNING FIELD-SYMBOL(<line>).
LOOP AT pers_obj_desc->attributes ASSIGNING <attr_desc>.
ASSIGN COMPONENT <attr_desc>-name OF STRUCTURE <line> TO FIELD-SYMBOL(<field>).
data(getter) = 'GET_' && <attr_desc>-name.
CALL METHOD <pers_data>->(getter) RECEIVING result = <field>.
ENDLOOP.
ENDLOOP.
另一种方法是定义一个名为列表的实例属性。然后,生成的 getter 可以覆盖如下,从任何地方寻址。
if me->list is initial.
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
me->list = WA.
endif.
result = me->list
" GET_LIST
endmethod.
... 代表列表中我想要的每个属性。
除此之外,我需要 CLEAR
每个 setter 上的列表。
最大的缺点是生成器会覆盖所有内容。 (没有任何警告。)
根据 的回答,我编写了一个帮助程序 class (主要改进包括接受超过 public 个简单属性而不会失败).
class ZCL_PS_OBJECT_TO_STRUCTURE_HLP definition
public
create private .
public section.
class-methods REFTAB_TO_STRUCTURE_LIST
importing
!IT_REFRENCE_TABLE type OSREFTAB
returning
value(RR_OBJECT_ATTRIBUTES_TABLE) type ref to DATA .
class-methods CREATE_FIELDCAT
importing
!IR_OBJ_DESC type ref to CL_ABAP_CLASSDESCR
returning
value(RO_FIELD_CAT) type LVC_T_FCAT .
protected section.
private section.
ENDCLASS.
CLASS ZCL_PS_OBJECT_TO_STRUCTURE_HLP IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_PS_OBJECT_TO_STRUCTURE_HLP=>CREATE_FIELDCAT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IR_OBJ_DESC TYPE REF TO CL_ABAP_CLASSDESCR
* | [<-()] RO_FIELD_CAT TYPE LVC_T_FCAT
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD CREATE_FIELDCAT.
LOOP AT IR_obj_desc->attributes ASSIGNING FIELD-SYMBOL(<fs_attr_desc>).
APPEND INITIAL LINE TO ro_field_cat ASSIGNING FIELD-SYMBOL(<fs_field_cat>).
<fs_field_cat>-fieldname = <fs_attr_desc>-name.
<fs_field_cat>-intlen = <fs_attr_desc>-length.
<fs_field_cat>-datatype = <fs_attr_desc>-type_kind.
<fs_field_cat>-outputlen = calculate a good outputlength (double when hex)
ENDLOOP.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_PS_OBJECT_TO_STRUCTURE_HLP=>REFTAB_TO_STRUCTURE_LIST
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_REFRENCE_TABLE TYPE OSREFTAB
* | [<-()] RR_OBJECT_ATTRIBUTES_TABLE TYPE REF TO DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD reftab_to_structure_list.
DATA: lr_obj_desc TYPE REF TO cl_abap_classdescr,
lr_query_data TYPE REF TO data,
lt_fieldcat TYPE lvc_t_fcat.
FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE.
LOOP AT it_refrence_table ASSIGNING FIELD-SYMBOL(<fs_object>).
AT FIRST.
lr_obj_desc ?= cl_abap_typedescr=>describe_by_object_ref( p_object_ref = <fs_object> ).
lt_fieldcat = create_fieldcat( ir_obj_desc = lr_obj_desc ).
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
* i_style_table =
it_fieldcatalog = lt_fieldcat
* i_length_in_byte =
IMPORTING
ep_table = rr_object_attributes_table
* ep_table = lr_query_data
* e_style_fname =
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2.
* IF sy-subrc <> 0.
* do some errorhandling here
* ENDIF.
ASSIGN rr_object_attributes_table->* TO <fs_table>.
* ASSIGN lr_query_data->* TO <fs_table>.
ENDAT. "first
APPEND INITIAL LINE TO <fs_table> ASSIGNING FIELD-SYMBOL(<fs_line>).
LOOP AT lr_obj_desc->attributes ASSIGNING FIELD-SYMBOL(<fs_attr_desc>).
ASSIGN COMPONENT <fs_attr_desc>-name OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_attr_value>).
DATA(getter) = 'GET_' && <fs_attr_desc>-name.
TRY .
CALL METHOD <fs_object>->(getter) RECEIVING result = <fs_attr_value>.
CATCH cx_sy_dyn_call_illegal_method. "get_method is protected or private
CLEAR <fs_attr_value>.
CATCH cx_sy_dyn_call_illegal_type.
"what to do with a list?
ENDTRY.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
现在有了那个助手class我不需要总是重新编码我想要一个对象列表。
在程序中调用是这样的:
DATA: lt_query_data TYPE osreftab,
lt_query_table TYPE REF TO data.
FIELD-SYMBOLS <fs_table>.
lt_query_data = zca_ps_user=>agent->if_os_ca_persistency~get_persistent_by_query(
i_query = cl_os_system=>get_query_manager( )->create_query( )
).
CALL METHOD zcl_ps_object_to_structure_hlp=>reftab_to_structure_list
EXPORTING
it_refrence_table = lt_query_data
RECEIVING
rr_object_attributes_table = lt_query_table.
IF lt_query_table IS INITIAL.
LEAVE.
ENDIF.
ASSIGN lt_query_table->* TO <fs_table>.
*Create a ALV
DATA: lr_alv TYPE REF TO cl_salv_table .
cl_salv_table=>factory( IMPORTING r_salv_table = lr_alv
CHANGING t_table = <fs_table> )
.
lr_alv->display( ).
Ps:我想编辑答案,但没有被接受。
我在自定义 table 上得到了持久的 class。现在使用 GET_PERSISTENT_BY_QUERY 我可以获得对象列表。我现在如何才能将这些对象及其所有属性打印给用户(例如作为 ALV)?
如果我以某种方式单击它,我可以调用实例函数吗?
一种(我认为不太好)方法是定义一个名为列表的实例属性。然后,生成的getter可以覆盖如下,从任何地方寻址。
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
result = WA.
" GET_LIST
endmethod.
... 代表列表中我想要的每个属性。
此解决方案的缺点:
- 每次调用都有非常很多逻辑要做
- 未使用该属性
另一种(我认为不太好)方法是定义一个名为列表的实例属性。然后,在初始化时,列表准备就绪。
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
LIST = WA.
endmethod.
... 代表列表中我想要的每个属性。
然后,在每个 setter 上,它也会在此列表中发生变化
此解决方案的缺点:
- 一切都是多余的,
- 每个 setter 都必须更换
这里是动态解,query_data是调用get_persistent_by_query( )返回的结果。最后数据会存储在结构化的table