‎2014 May 15 10:04 AM
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
‎2014 May 15 11:51 AM
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.
‎2014 May 15 10:14 AM
‎2014 May 15 11:51 AM
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.
‎2014 May 15 12:25 PM
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.
‎2014 May 15 12:35 PM
Hello Michal,
Instead of TYPE ANY you should use the root object i.e., TYPE REF TO object.
BR,
Suhas
‎2014 May 15 1:02 PM
Hi Suhas,
that's not possible because of erlier assignment
ASSIGN object->* TO <value>.
BR
‎2014 May 15 1:12 PM
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
‎2014 May 15 2:45 PM
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.