简体   繁体   English

返回 abap 中持久化类的所有属性的列表

[英]Return a list of all atributes of a persistent class in abap

I got a persistent class on a custom table.我在自定义表上获得了一个持久类。 Now with GET_PERSISTENT_BY_QUERY I can get a list of objects.现在使用 GET_PERSISTENT_BY_QUERY 我可以获得对象列表。 How can I now get those Objects with all of their atributes printed to the user (eg as ALV)?我现在怎样才能获得那些打印给用户的所有属性的对象(例如作为 ALV)?

Can I call an instance function if i click on it somehow?如果我以某种方式单击它,我可以调用实例函数吗?

Here is a dynamic solution, query_data is the result returned from the call to get_persistent_by_query( ).这是一个动态解决方案,query_data 是调用 get_persistent_by_query() 返回的结果。 In the end the data will be stored in structured table <table>, you can use this to display in your ALV.最终数据将存储在结构化表<table>中,您可以使用它在您的ALV中显示。 Note that there is little control over the order of the field.请注意,对字段的顺序几乎没有控制。 For real use you'd have to add some error handling as well.对于实际使用,您还必须添加一些错误处理。

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.

One (i do not think good) way is to define a instance atribute called list.一种(我认为不好)方法是定义一个名为 list 的实例属性。 Then, the generated getter can be overwritten as following, which is addresed from anywhere.然后,生成的 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.

The ... stands for each attribute I want in the List. ... 代表我想要在列表中的每个属性。

The CONS to this solution:此解决方案的缺点:

  • on every call there is very much logic to do在每次调用有非常多的逻辑做
  • the attribute is not used未使用该属性

An other (I do not think good) way is to define a instance atribute called list.另一种(我认为不好)方法是定义一个名为 list 的实例属性。 Then, on the initialize, the list gets prepared.然后,在初始化时,列表准备就绪。

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.

The ... stands for each attribute I want in the List. ... 代表我想要在列表中的每个属性。

Then, on every setter, also in this list it gets changed然后,在每个 setter 上,也在这个列表中它被改变了

The CONS to this solution:此解决方案的缺点:

  • Everything is redundant,一切都是多余的,
  • each setter has to get changed每个二传手都必须改变

One more way is to define a instance atribute called list.另一种方法是定义一个名为 list 的实例属性。 Then, the generated getter can be overwritten as following, which is addresed from anywhere.然后,生成的 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.

The ... stands for each attribute I want in the List. ... 代表我想要在列表中的每个属性。

Additionaly to that, I need to CLEAR the list on every setter.除此之外,我需要CLEAR每个 setter 上的列表。

The big con to that is that the generator overwrites everything.最大的缺点是生成器会覆盖所有内容。 (Without any warning.) (没有任何警告。)

Based on the answer of gert beukema I have written a helper class (with major improvements like accepting more than public simple atributes without failing) .根据gert beukema的回答,我编写了一个辅助类(有重大改进,例如接受比公共简单属性更多的属性而不会失败)

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.

Now with that helperclass I do not have to recode it always I want a list out of a Object.现在有了这个助手类,我不必重新编码它总是我想要一个对象列表。

In a programm the call is eG like this:在程序中,调用是这样的 eG:

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: I wanted to edit the answer, but it was not accepted. Ps:我想编辑答案,但没有被接受。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM