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

Dynamic SORT with multiple components

Mathias_24
Explorer
0 Likes
3,882

Hi all,

I want to sort an internal table in this way:

SORT itab BY (component).

This is not difficult if "component" contains the name of ONE column of itab. But - and here is my problem - how can I sort with multiple components?

Like this:

SORT itab BY (comp_1) (comp_2) ... (comp_N).

The number of components (N) shall be flexible. It is not possible to concatenate the components into one string-variable. This causes an error ITAB_ILLEGAL_COMPONENT.

Brillant would be a solution which also contains the sort-direction (ASCENDING or DESCENDING for each component like this:

SORT itab BY (comp_1) (dir_1)

(comp_2) (dir_2)

...

(comp_N) (dir_N).

Is there a way to do so?

Thanks for all hints!

Mathias

7 REPLIES 7
Read only

Former Member
0 Likes
1,724

You can do this for example:

SORT PERSON DESCENDING BY AGE ASCENDING NAME AS TEXT.

Gianluca

Read only

Former Member
0 Likes
1,724

Hi Matahias ...

From ABAP help...

SORT itab.

Extras:

1. ... BY f1 f2 ... fn

2. ... ASCENDING

3. ... DESCENDING

4. ... AS TEXT

5. ... STABLE

The syntax check performed in an ABAP Objects context is stricter than in other ABAP areas. See Field symbols not allowed as sort criterion.

Effect

The entries in the internal table are sorted in ascending order using the key from the table definition (DATA, TYPES).

Addition 1

... BY f1 f2 ... fn

Effect

Uses the sort key defined by the sub-fields f1, f2, ..., fn of the table itab instead of the table key. The fields can be of any type; even number fields and tables are allowed.

You can also specify the sort fields dynamically in the form (name). If name is blank at run time, the sort field is ignored. If itab is a table with a header line, you can also use a field symbol pointing to the header line of itab as a dynamic sort criterion. A field symbol that is not assigned is ignored. If a field symbol is assigned, but does not point to the header line of the internal table, a runtime error occurs.

If the line type of the internal table contains object reference variables as components, or the entire line type is a reference variable, you can use the attributes of the object to which a reference is pointing in a line as sort criteria (see Attributes of Objects as the Key of an Internal Table

You can address the entire line of an internal table as the key using the pseudocomponent TABLE_LINE. This is particularly relevant for tables with a non-structured line type when you want to address the whole line as the key of the table (see also Pseudocomponent TABLE_LINE With Internal Tables).

If you use one of the additions 2 to 5 before BY, it applies to all fields of the sort key by default. You can also specify these additions after each individual sort field f1, f2, ..., fn. For each key field, this defines an individual sort rule which overrides the default.

Cheers

Preetham

Read only

ssimsekler
Product and Topic Expert
Product and Topic Expert
1,724

Hi Mathias

If it does not give an error for null field holders, you can try something such:

DATA lv_f1_asc(30) TYPE c .
DATA lv_f1_des(30) TYPE c .
DATA lv_f2_asc(30) TYPE c .
DATA lv_f3_des(30) TYPE c .
...
DATA lv_fn_asc(30) TYPE c .
DATA lv_fn_des(30) TYPE c .

*--The logic to determine directions for each field
*--For fields to be sorted ascending fill the relevant 
*--lv_fx_asc value and reset the lv_fx_des to space; and for descending do vice versa.
*-- e.g.
IF <i><some_condition></i> . "sort itab by field1 ascending"
  lv_f1_asc = 'FIELD1' .
  CLEAR lv_f1_des .
ELSE . "sort itab by field2 descending"
  lv_f1_des = 'FIELD1' .
  CLEAR lv_f1_asc .
ENDIF .

*--Same procedure for other (n-1) fields


SORT itab BY (lv_f1_asc) ASCENDING
             (lv_f1_des) DESCENDING
             (lv_f2_asc) ASCENDING
             (lv_f2_des) DESCENDING
             ...
             (lv_fn_asc) ASCENDING
             (lv_fn_des) DESCENDING .

OR alternatively, you can go with <b>generic programming</b>.

Hope this may help.

*--Serdar <a href="https://www.sdn.sap.com:443http://www.sdn.sap.comhttp://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.sdn.businesscard.sdnbusinesscard?u=qbk%2bsag%2bjiw%3d">[ BC ]</a>

Read only

0 Likes
1,724

Thanks for all, guys!

Serdar, yes I think it will be possible to do like you wrote. It seems that it is not possible to do it without defining N variables.

I try to explain my problem a bit more detailed.

I have a table which should be sorted. I need it in a BSP-Application to display it in a HTMLB-tablewiew-tag. I have created the possibility of multiselect columns by clicking header of them and when e.g. 3 of them are selected I can click a sorting button (as you know from ALV-Grid).

All is ready, I have a internal table which contains the info which columns are selected and the sort buttons are there, too. Only the dynamic sort statement is missing. In the example it should be like this:

SORT itab BY (field1) (field2) (field3).

If the user selects only 1 column it should be

SORT itab BY (field1).

And with 5 it should be

SORT itab BY (field1) (field2) (field3) (field4) (field5).

If you know how do this with generic programing, let me please know. I think that I can use your first proposal as well.

Best thanks,

Mathias

Read only

ssimsekler
Product and Topic Expert
Product and Topic Expert
0 Likes
1,724

Hi Mathias

Here is an example I write here. I cannot test it on a development environment. It may lack somethings, nevertheless I believe it has the logic you require.

REPORT dynamic_sort_example .

DATA gt_data TYPE ... . "Internal table to be sorted"

DATA: BEGIN OF gt_itab OCCURS 1 ,
        line(80) TYPE c ,
END OF gt_itab .

DATA gv_name(30) TYPE c .
DATA gv_err(120) TYPE c .

DATA: BEGIN OF gt_sort_data OCCURS 0 ,
        field(30) TYPE c ,
        direction(1) TYPE c ,
      END OF gt_sort_data .

START-OF-SELECTION .

gt_itab-line = 'REPORT generated_sql .' .
APPEND gt_itab .
gt_itab-line = 'FORM sort_itab CHANGING et_table .' .
APPEND gt_itab .

*--Here generate the SORT statement.
*--e.g.

gt_itab-line =  'SORT et_table BY' .
APPEND gt_itab .

LOOP AT gt_sort_data .
  IF gt_sort_data-direction = 'A' .
    CONCATENATE gt_sort_data-field 'ASCENDING'
                INTO gt_itab-line 
                SEPARATED BY space .
  ELSEIF gt_sort_data-direction = 'D' .
    CONCATENATE gt_sort_data-field 'DESCENDING'
                INTO gt_itab-line 
                SEPARATED BY space .
  ELSE .
    CONTINUE .
  ENDIF .
  
  APPEND gt_itab .
ENDLOOP .            

gt_itab-line = '.' .
APPEND gt_itab .

gt_itab-line = 'ENDFORM.' .
APPEND gt_itab .

GENERATE SUBROUTINE POOL gt_itab NAME gv_name MESSAGE gv_err .

...

WRITE:/ gv_err .

...

PERFORM sort_itab IN PROGRAM (gv_name) CHANGING gt_data
                  IF FOUND .

Regards

*--Serdar <a href="https://www.sdn.sap.com:443http://www.sdn.sap.comhttp://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.sdn.businesscard.sdnbusinesscard?u=qbk%2bsag%2bjiw%3d">[ BC ]</a>

Read only

0 Likes
1,724

thank you very much .

actually i got a requrirment Dynamic field wise table control data sorting in module pool.

i tried in many wasy finally i triedLIKE BELO.

First i got the field name by

GET CURSORE FIELD followed by (Dynamic Cursore Field Name).

i then splitted at '-' into table name, Dynamic Field Name

and then finally passed this Dynamic Field name at SORT Statement.

SORT <TABLE> by (Dynamic Field Name) ASCENDING.

Read only

0 Likes
1,724

Or you can take a look at function:

C140_TABLE_DYNAMIC_SORT

Bye

sambarza