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:我想编辑答案,但没有被接受。