Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

sort table of objects by object attribute

Former Member
0 Likes
1,983

Hi all,

I would like to write method for sorting table of objects. Sorting will be according selected attribute of object.

My problem is that when I have dynamic data, I'm not able to access attributes of object. Here is example in code. Problematic lines are commented.
If you have any idea how to solve it, I will be very happy.

CLASS lcl_reflection DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.

    CLASS-METHODS: sort_object_table_by_field IMPORTING field_name   TYPE char72

                                                        direction    TYPE c DEFAULT 'A'

                                              CHANGING  object_table TYPE table.

ENDCLASS.                    "lcl_reflection DEFINITION

CLASS lcl_reflection IMPLEMENTATION.

  METHOD sort_object_table_by_field.

    DATA: obj_type_desc   TYPE REF TO cl_abap_refdescr,

          cls_type_desc   TYPE REF TO cl_abap_classdescr,

          tab_type_desc   TYPE REF TO cl_abap_tabledescr,

          elm_type_desc   TYPE REF TO cl_abap_elemdescr,

          struc_type_desc TYPE REF TO cl_abap_structdescr,

          line            TYPE REF TO data,

          tab             TYPE REF TO data,

          object          TYPE REF TO data,

          lt_component TYPE cl_abap_structdescr=>component_table,

          ls_component LIKE LINE OF lt_component.

    FIELD-SYMBOLS: <object> TYPE any,

                   <tab>    TYPE table,

                   <line>   TYPE any,

                   <value>  TYPE any.

    READ TABLE object_table INDEX 1 ASSIGNING <object>.

    cls_type_desc ?= cl_abap_classdescr=>describe_by_object_ref( <object> ).

    elm_type_desc ?= cls_type_desc->get_attribute_type( field_name ).

    obj_type_desc ?= cl_abap_refdescr=>create( cls_type_desc ).

    UNASSIGN <object>.

    ls_component-name = 'key'.

    ls_component-type = elm_type_desc.

    APPEND ls_component TO lt_component.

    ls_component-name = 'object'.

    ls_component-type ?= obj_type_desc.

    APPEND ls_component TO lt_component.

    struc_type_desc ?= cl_abap_structdescr=>create( lt_component ).

    tab_type_desc ?= cl_abap_tabledescr=>create( p_line_type  = struc_type_desc

                                                 p_table_kind = cl_abap_tabledescr=>tablekind_std

                                                 p_unique     = abap_false ).

    REFRESH lt_component.

    CLEAR ls_component.

    CREATE DATA line TYPE HANDLE struc_type_desc.

    CREATE DATA tab TYPE HANDLE tab_type_desc.

    CREATE DATA object TYPE HANDLE obj_type_desc.

    ASSIGN tab->* TO <tab>.

    ASSIGN line->* TO <line>.

    ASSIGN object->* TO <object>.

    LOOP AT object_table REFERENCE INTO object.

      APPEND INITIAL LINE TO <tab> REFERENCE INTO line.

      ASSIGN object->* TO <value>.

      ASSIGN line->* TO <line>.

*      <line>-key = <value>->(field_name).

*      <line>-object = object.

    ENDLOOP.

*    SORT <tab> BY key.

*    LOOP AT <tab> REFERENCE INTO line.

*      APPEND INITIAL LINE TO object_table REFERENCE INTO object.

*      object = line-object.

*    ENDLOOP.

  ENDMETHOD.                    "sort_object_table_by_field

ENDCLASS.                    "lcl_reflection IMPLEMENTATION

1 ACCEPTED SOLUTION
Read only

kesavadas_thekkillath
Active Contributor
0 Likes
1,451

Can you try it this way. I have used the 7.4 syntax of declaration, please change it accordingly.

    LOOP AT object_table REFERENCE INTO object.
      APPEND INITIAL LINE TO <tab> REFERENCE INTO line.
      ASSIGN object->* TO <value>.
      ASSIGN line->* TO <line>.
      ASSIGN COMPONENT 'KEY' OF STRUCTURE <line> TO FIELD-SYMBOL(<fs_l>).
      ASSIGN COMPONENT 'OBJECT' OF STRUCTURE <line> TO FIELD-SYMBOL(<fs_o>).
      ASSIGN <value>->(field_name) TO FIELD-SYMBOL(<fs_v>).
      <fs_l> = <fs_v>.
      <fs_o> = object.
    ENDLOOP.

    DATA:sort_f1 TYPE fieldname.

    sort_f1 = 'KEY'.
    SORT <tab> BY (sort_f1).
    LOOP AT <tab> REFERENCE INTO line.
      APPEND INITIAL LINE TO object_table REFERENCE INTO object.
      ASSIGN line->* TO <line>.
      ASSIGN COMPONENT 'OBJECT' OF STRUCTURE <line> TO  <fs_o>.
      object = <fs_o>.
    ENDLOOP.

7 REPLIES 7
Read only

gaurab_banerji
Active Participant
0 Likes
1,451

Not sure about ->..

*      <line>-key = <value>->(field_name).

Read only

kesavadas_thekkillath
Active Contributor
0 Likes
1,452

Can you try it this way. I have used the 7.4 syntax of declaration, please change it accordingly.

    LOOP AT object_table REFERENCE INTO object.
      APPEND INITIAL LINE TO <tab> REFERENCE INTO line.
      ASSIGN object->* TO <value>.
      ASSIGN line->* TO <line>.
      ASSIGN COMPONENT 'KEY' OF STRUCTURE <line> TO FIELD-SYMBOL(<fs_l>).
      ASSIGN COMPONENT 'OBJECT' OF STRUCTURE <line> TO FIELD-SYMBOL(<fs_o>).
      ASSIGN <value>->(field_name) TO FIELD-SYMBOL(<fs_v>).
      <fs_l> = <fs_v>.
      <fs_o> = object.
    ENDLOOP.

    DATA:sort_f1 TYPE fieldname.

    sort_f1 = 'KEY'.
    SORT <tab> BY (sort_f1).
    LOOP AT <tab> REFERENCE INTO line.
      APPEND INITIAL LINE TO object_table REFERENCE INTO object.
      ASSIGN line->* TO <line>.
      ASSIGN COMPONENT 'OBJECT' OF STRUCTURE <line> TO  <fs_o>.
      object = <fs_o>.
    ENDLOOP.

Read only

0 Likes
1,451

Thanks Kesavadas, your construction ASSIGN COMPONENT was helpfull, but problem with assigning persists.

ASSIGN <value>->(field_name) TO <fs_v>.

I need something simillar to "ASSIGN COMPONENT" for object, because workbench said <value> is not reference variable.

Read only

0 Likes
1,451

Hello Michal,

Instead of TYPE ANY you should use the root object i.e., TYPE REF TO object.

BR,

Suhas

Read only

0 Likes
1,451

Hi Suhas,
that's not possible because of erlier assignment

ASSIGN object->* TO <value>.


BR

Read only

0 Likes
1,451

I meant the root class (ABAP Keyword Documentation), my bad!


ASSIGN object->* TO <value>.

This is a classic case of ambiguous variable name I think you should consider not naming your variables as SAP keywords for the sake of the general masses

Cheersy cheers,

Suhas

Read only

0 Likes
1,451

Ok guys, it's solved. It was little bit more complicated then I expected. Thanks for you help.

METHOD sort_object_table_by_field.

    TYPES: t_object TYPE REF TO object.

    DATA: obj_type_desc   TYPE REF TO cl_abap_refdescr,

          cls_type_desc   TYPE REF TO cl_abap_classdescr,

          tab_type_desc   TYPE REF TO cl_abap_tabledescr,

          elm_type_desc   TYPE REF TO cl_abap_elemdescr,

          struc_type_desc TYPE REF TO cl_abap_structdescr,

          r_line          TYPE REF TO data,

          r_tab           TYPE REF TO data,

          r_object        TYPE REF TO data,

          r_obj           TYPE REF TO data,

          lt_component TYPE cl_abap_structdescr=>component_table,

          ls_component LIKE LINE OF lt_component.

    FIELD-SYMBOLS: <object>    TYPE any,

                   <obj>       TYPE REF TO object,

                   <tab>       TYPE table,

                   <line>      TYPE any,

                   <key>       TYPE any,

                   <fs_key>    TYPE any,

                   <fs_object> TYPE any.

    READ TABLE object_table INDEX 1 ASSIGNING <object>.

    cls_type_desc ?= cl_abap_classdescr=>describe_by_object_ref( <object> ).

    elm_type_desc ?= cls_type_desc->get_attribute_type( field_name ).

    obj_type_desc ?= cl_abap_refdescr=>create( cls_type_desc ).

    UNASSIGN <object>.

    ls_component-name = 'key'.

    ls_component-type = elm_type_desc.

    APPEND ls_component TO lt_component.

    ls_component-name = 'object'.

    ls_component-type ?= obj_type_desc.

    APPEND ls_component TO lt_component.

    struc_type_desc ?= cl_abap_structdescr=>create( lt_component ).

    tab_type_desc ?= cl_abap_tabledescr=>create( p_line_type  = struc_type_desc

                                                 p_table_kind = cl_abap_tabledescr=>tablekind_std

                                                 p_unique     = abap_false ).

    REFRESH lt_component.

    CLEAR ls_component.

    CREATE DATA r_line TYPE HANDLE struc_type_desc.

    CREATE DATA r_tab TYPE HANDLE tab_type_desc.

    CREATE DATA r_object TYPE HANDLE obj_type_desc.

    CREATE DATA r_obj TYPE REF TO object.

    ASSIGN r_tab->* TO <tab>.

    LOOP AT object_table REFERENCE INTO r_object.

      APPEND INITIAL LINE TO <tab> REFERENCE INTO r_line.

      ASSIGN r_object->* TO <object>.

      ASSIGN r_obj->* TO <obj>.

      MOVE <object> TO <obj>.

      ASSIGN <obj>->(field_name) TO <key>.

      ASSIGN r_line->* TO <line>.

      ASSIGN COMPONENT 'KEY' OF STRUCTURE <line> TO <fs_key>.

      ASSIGN COMPONENT 'OBJECT' OF STRUCTURE <line> TO <fs_object>.

      <fs_object> = <object>.

      <fs_key> = <key>.

    ENDLOOP.

    DATA: sort_field TYPE fieldname.

    sort_field = 'KEY'.

    SORT <tab> BY (sort_field).

    REFRESH object_table.

    LOOP AT <tab> REFERENCE INTO r_line.

      APPEND INITIAL LINE TO object_table REFERENCE INTO r_object.

      ASSIGN r_line->* TO <line>.

      ASSIGN r_object->* TO <object>.

      ASSIGN COMPONENT 'OBJECT' OF STRUCTURE <line> TO <fs_object>.

      <object> = <fs_object>.

    ENDLOOP.

  ENDMETHOD.