Search code examples
persistenceabap

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. How can I now get those Objects with all of their atributes printed to the user (e.g as ALV)?

Can I call an instance function if i click on it somehow?


Solution

  • 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).

    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 e.G like this:

    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.