簡體   English   中英

返回 abap 中持久化類的所有屬性的列表

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

我在自定義表上獲得了一個持久類。 現在使用 GET_PERSISTENT_BY_QUERY 我可以獲得對象列表。 我現在怎樣才能獲得那些打印給用戶的所有屬性的對象(例如作為 ALV)?

如果我以某種方式單擊它,我可以調用實例函數嗎?

這是一個動態解決方案,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.

一種(我認為不好)方法是定義一個名為 list 的實例屬性。 然后,生成的 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.

... 代表我想要在列表中的每個屬性。

此解決方案的缺點:

  • 在每次調用有非常多的邏輯做
  • 未使用該屬性

另一種(我認為不好)方法是定義一個名為 list 的實例屬性。 然后,在初始化時,列表准備就緒。

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 上,也在這個列表中它被改變了

此解決方案的缺點:

  • 一切都是多余的,
  • 每個二傳手都必須改變

另一種方法是定義一個名為 list 的實例屬性。 然后,生成的 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 上的列表。

最大的缺點是生成器會覆蓋所有內容。 (沒有任何警告。)

根據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.

現在有了這個助手類,我不必重新編碼它總是我想要一個對象列表。

在程序中,調用是這樣的 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:我想編輯答案,但沒有被接受。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM