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

Create dateslices in ALV Grid

Former Member
0 Likes
1,698

Hello everyone,

At the moment I'm trying to get some new possibilities for useful helps when user works with ALV-Grid (OO). On of them is the work with dateslices. I know it from the modern coded RE-FX reports in SAP, e.g. REISBE. You can see at the screenshot below how it looks like.

Now I want to insert these dateslice functions in my own-written ALV Grid as well. Now the question: Is this possible and if so, how does it work? When debugging the program in RE-FX it looks like this...

*=======================================================================

FORM dateslice_create.

*=======================================================================

  DATA:

    lt_daterange TYPE re_t_recadaterange,

    ls_daterange TYPE recadaterange,

    lf_dateslices_invalid TYPE recabool.

  CHECK go_view->mf_use_dateslices = abap_true.

  IF go_dateslice IS NOT BOUND.

*   1st pbo call

    CREATE OBJECT go_dateslice

      EXPORTING

        if_no_complete_range = go_view->mf_no_complete_range.

*   set handler

    SET HANDLER:

      lcl_event_handler=>handle_slice_changed    FOR go_dateslice.

  ELSE.

*   further pbo call - only continue if new objects added

    CHECK go_data->mf_dateslices_invalid = abap_true.

    lf_dateslices_invalid = abap_true.

  ENDIF.

  ls_daterange-datefrom = go_view->ms_daterange-datefrom.

  ls_daterange-dateto   = go_view->ms_daterange-dateto.

  CALL METHOD go_data->get_dateslices

    IMPORTING

      et_daterange = lt_daterange.

* remove duplicated time slices, delete initial time

  SORT lt_daterange.

  DELETE ADJACENT DUPLICATES FROM lt_daterange.

  DELETE lt_daterange WHERE dateto IS INITIAL.

* compress date ranges

  CALL METHOD cl_reca_date=>create_date_ranges

    EXPORTING

      it_dates_overlap = lt_daterange

    IMPORTING

      et_dates_cut     = lt_daterange.

* insert selected daterange

  READ TABLE lt_daterange

       WITH KEY datefrom = ls_daterange-datefrom

                dateto   = ls_daterange-dateto

       TRANSPORTING NO FIELDS.

  IF sy-subrc EQ 4.

    IF ( ls_daterange-datefrom IS NOT INITIAL ) OR

       ( ls_daterange-datefrom IS NOT INITIAL ).

      APPEND ls_daterange TO lt_daterange.

    ENDIF.

  ENDIF.

* send slices to dateslice object

  CALL METHOD go_dateslice->set_slices

    EXPORTING

      it_daterange = lt_daterange.

* set current time slice

  IF ( ls_daterange-datefrom IS NOT INITIAL ) AND

     ( ls_daterange-dateto   IS NOT INITIAL ).

    CALL METHOD go_dateslice->set_current_slice

      EXPORTING

        is_current_slice = ls_daterange.

  ELSEIF go_view->mf_use_current_daterange = abap_true.

    go_dateslice->set_at_date( sy-datum ).

  ELSE.

    go_dateslice->set_current_slice_complete( ).

  ENDIF.

* if dateslices are invalid set dateslice for go_data

* since refresh cannot be done by 'slice changed event'

  IF lf_dateslices_invalid = abap_true.

    CALL METHOD go_dateslice->get_current_slice

      IMPORTING

        es_current_slice = ls_daterange.

    CALL METHOD go_data->set_dateslice

      EXPORTING

        id_validfrom = ls_daterange-datefrom

        id_validto   = ls_daterange-dateto.

    gf_list_refresh = abap_true.

  ENDIF.

ENDFORM.                    "do_okcode

...but for me it looks like that it is not that easy to implement it in an own report. Does anyone have experience with dateslisces in ALV Grid?

Kind Regards

Michael

1 ACCEPTED SOLUTION
Read only

Former Member
0 Likes
1,554

This code has been put together just to see whether date slices can be created.

You can use it as a starting point and explore other methods of class.

Idea is to use class cl_reca_date_slices to create internal tables gt_daterange and gt_daterange_string. User will see gt_daterange_string (user-friendly intervals), and once selection is done, you can use index to get logic-friendly date range from gt_daterange.

TYPE-POOLS vrm.

DATA gt_daterange TYPE re_t_recadaterange.

DATA gs_daterange TYPE recadaterange.

DATA gt_daterange_string TYPE  re_t_string.

DATA gs_daterange_string TYPE recastring.

DATA go_slices TYPE REF TO cl_reca_date_slices.

PARAMETERS p_dates TYPE char20 AS LISTBOX VISIBLE LENGTH 20.

AT SELECTION-SCREEN OUTPUT.

  DATA lt_values     TYPE vrm_values.

  DATA ls_value      TYPE vrm_value.

  CREATE OBJECT go_slices.

  PERFORM add_range USING sy-datum '99991231'.

  PERFORM add_range USING sy-datum sy-datum.

  PERFORM add_range USING '19900101' sy-datum.

  PERFORM add_range USING '20130501' '20130531'.

  CALL METHOD go_slices->set_slices

    EXPORTING

      it_daterange = gt_daterange.

  CALL METHOD go_slices->get_slices

    EXPORTING

      if_delete_unlimited_string = abap_true

    IMPORTING

      et_daterange               = gt_daterange

      et_daterange_string        = gt_daterange_string.

  LOOP AT gt_daterange_string INTO gs_daterange_string.

    ls_value-key = sy-tabix.

    ls_value-text = gs_daterange_string.

    APPEND ls_value TO lt_values.

    CLEAR ls_value.

  ENDLOOP.

  CALL FUNCTION 'VRM_SET_VALUES'

    EXPORTING

      id     = 'P_DATES'

      values = lt_values.

*&---------------------------------------------------------------------*

*&      Form  add_range

*&---------------------------------------------------------------------*

FORM add_range USING pv_datefrom TYPE sy-datum

                     pv_dateto   TYPE sy-datum.

  gs_daterange-datefrom = pv_datefrom.

  gs_daterange-dateto = pv_dateto.

  APPEND gs_daterange TO gt_daterange.

  CLEAR gs_daterange.

ENDFORM.                    "add_range

Hello everyone,

At the moment I'm trying to get some new possibilities for useful helps when user works with ALV-Grid (OO). On of them is the work with dateslices. I know it from the modern coded RE-FX reports in SAP, e.g. REISBE. You can see at the screenshot below how it looks like.

Now I want to insert these dateslice functions in my own-written ALV Grid as well. Now the question: Is this possible and if so, how does it work? When debugging the program in RE-FX it looks like this...

*=======================================================================

FORM dateslice_create.

*=======================================================================

  DATA:

    lt_daterange TYPE re_t_recadaterange,

    ls_daterange TYPE recadaterange,

    lf_dateslices_invalid TYPE recabool.

  CHECK go_view->mf_use_dateslices = abap_true.

  IF go_dateslice IS NOT BOUND.

*   1st pbo call

    CREATE OBJECT go_dateslice

      EXPORTING

        if_no_complete_range = go_view->mf_no_complete_range.

*   set handler

    SET HANDLER:

      lcl_event_handler=>handle_slice_changed    FOR go_dateslice.

  ELSE.

*   further pbo call - only continue if new objects added

    CHECK go_data->mf_dateslices_invalid = abap_true.

    lf_dateslices_invalid = abap_true.

  ENDIF.

  ls_daterange-datefrom = go_view->ms_daterange-datefrom.

  ls_daterange-dateto   = go_view->ms_daterange-dateto.

  CALL METHOD go_data->get_dateslices

    IMPORTING

      et_daterange = lt_daterange.

* remove duplicated time slices, delete initial time

  SORT lt_daterange.

  DELETE ADJACENT DUPLICATES FROM lt_daterange.

  DELETE lt_daterange WHERE dateto IS INITIAL.

* compress date ranges

  CALL METHOD cl_reca_date=>create_date_ranges

    EXPORTING

      it_dates_overlap = lt_daterange

    IMPORTING

      et_dates_cut     = lt_daterange.

* insert selected daterange

  READ TABLE lt_daterange

       WITH KEY datefrom = ls_daterange-datefrom

                dateto   = ls_daterange-dateto

       TRANSPORTING NO FIELDS.

  IF sy-subrc EQ 4.

    IF ( ls_daterange-datefrom IS NOT INITIAL ) OR

       ( ls_daterange-datefrom IS NOT INITIAL ).

      APPEND ls_daterange TO lt_daterange.

    ENDIF.

  ENDIF.

* send slices to dateslice object

  CALL METHOD go_dateslice->set_slices

    EXPORTING

      it_daterange = lt_daterange.

* set current time slice

  IF ( ls_daterange-datefrom IS NOT INITIAL ) AND

     ( ls_daterange-dateto   IS NOT INITIAL ).

    CALL METHOD go_dateslice->set_current_slice

      EXPORTING

        is_current_slice = ls_daterange.

  ELSEIF go_view->mf_use_current_daterange = abap_true.

    go_dateslice->set_at_date( sy-datum ).

  ELSE.

    go_dateslice->set_current_slice_complete( ).

  ENDIF.

* if dateslices are invalid set dateslice for go_data

* since refresh cannot be done by 'slice changed event'

  IF lf_dateslices_invalid = abap_true.

    CALL METHOD go_dateslice->get_current_slice

      IMPORTING

        es_current_slice = ls_daterange.

    CALL METHOD go_data->set_dateslice

      EXPORTING

        id_validfrom = ls_daterange-datefrom

        id_validto   = ls_daterange-dateto.

    gf_list_refresh = abap_true.

  ENDIF.

ENDFORM.                    "do_okcode

...but for me it looks like that it is not that easy to implement it in an own report. Does anyone have experience with dateslisces in ALV Grid?

Kind Regards

Michael

10 REPLIES 10
Read only

Former Member
0 Likes
1,555

This code has been put together just to see whether date slices can be created.

You can use it as a starting point and explore other methods of class.

Idea is to use class cl_reca_date_slices to create internal tables gt_daterange and gt_daterange_string. User will see gt_daterange_string (user-friendly intervals), and once selection is done, you can use index to get logic-friendly date range from gt_daterange.

TYPE-POOLS vrm.

DATA gt_daterange TYPE re_t_recadaterange.

DATA gs_daterange TYPE recadaterange.

DATA gt_daterange_string TYPE  re_t_string.

DATA gs_daterange_string TYPE recastring.

DATA go_slices TYPE REF TO cl_reca_date_slices.

PARAMETERS p_dates TYPE char20 AS LISTBOX VISIBLE LENGTH 20.

AT SELECTION-SCREEN OUTPUT.

  DATA lt_values     TYPE vrm_values.

  DATA ls_value      TYPE vrm_value.

  CREATE OBJECT go_slices.

  PERFORM add_range USING sy-datum '99991231'.

  PERFORM add_range USING sy-datum sy-datum.

  PERFORM add_range USING '19900101' sy-datum.

  PERFORM add_range USING '20130501' '20130531'.

  CALL METHOD go_slices->set_slices

    EXPORTING

      it_daterange = gt_daterange.

  CALL METHOD go_slices->get_slices

    EXPORTING

      if_delete_unlimited_string = abap_true

    IMPORTING

      et_daterange               = gt_daterange

      et_daterange_string        = gt_daterange_string.

  LOOP AT gt_daterange_string INTO gs_daterange_string.

    ls_value-key = sy-tabix.

    ls_value-text = gs_daterange_string.

    APPEND ls_value TO lt_values.

    CLEAR ls_value.

  ENDLOOP.

  CALL FUNCTION 'VRM_SET_VALUES'

    EXPORTING

      id     = 'P_DATES'

      values = lt_values.

*&---------------------------------------------------------------------*

*&      Form  add_range

*&---------------------------------------------------------------------*

FORM add_range USING pv_datefrom TYPE sy-datum

                     pv_dateto   TYPE sy-datum.

  gs_daterange-datefrom = pv_datefrom.

  gs_daterange-dateto = pv_dateto.

  APPEND gs_daterange TO gt_daterange.

  CLEAR gs_daterange.

ENDFORM.                    "add_range

Read only

0 Likes
1,554

Dear Manish,

thanks a lot I can try using this snippet and also looking for cl_reca_date_slices.

But how do I get the slices to the Grid then, so that I can just switch between actual slices and all slices and so on?

Regards

Michael

Read only

0 Likes
1,554

Case 1: Use method CL_GUI_ALV_GRID->SET_DROP_DOWN_TABLE if you want dateslice dropdown to appear in a column of ALV grid output.

Case 2: In case you want the content of ALV grid to be filtered according the chosen dateslice, change alv table content in PAI based on chose dateslice, and do ALV refresh using CL_GUI_ALV_GRID->REFRESH_TABLE_DISPLAY. Method APPLY_FILTER can also be looked at.

Read only

0 Likes
1,554

Hm okay for me it would be case 2. But I'm not quite sure how it works.

How do I get the dateslices showed in the ALV grid like in the screenshot?

Normally I just have the Grid content that is shown in the ALV container. But how to put the element for choosing timeslices in the grid?

Read only

0 Likes
1,554

Please search  for working example of "dropdown list in alv".

Method SET_DROP_DOWN_TABLE would be used to set gt_daterange_string as list of values to be shown as dropdown. The field of internal table needs to be of compatible type.

Read only

0 Likes
1,554

Ok, now I had a look how it worked in SAP standard with the dropwdown box as own dynpro element above the grid. Now that's clear.

And a simple example of building my timeslices worked as well. But now I do not know how to link them with my internal table from the grid?

I got an easy example for timeslices which means

(1) All dates

(2) until sy-datum - 1

(3) from sy-datum on

my timeslice table looks fine.

But now I got my 'valid from' and 'valid to' fields in my internal table from the grid. How do I link them with these three time slices? e.g. saying when user takes time slice (2), only show the relevant table entries and so on. Do I have to work with filter methods of alv grid then?

Read only

0 Likes
1,554

Once user selects a slice, set that as current slice in object.

Loop through internal table, and check whether date range is in current slice.

Based on result, you can keep or delete record.

If going for ALV filter, you need to add hidden column to internal table which would store calculated slice. The filter would then be applied to this hidden column.

Code to check date range against selected slice would be something like this:

* assume user selected 2nd slice

CALL METHOD go_slices->set_current_slice

  EXPORTING

    id_tabix = 2.

* for every record in internal table, check date range

CALL METHOD go_slices->is_entry_in_current_slice

  EXPORTING

    id_datefrom = ls_record-datefrom

    id_dateto   = ls_record-dateto

  RECEIVING

    rf_valid    = lv_result.

IF lv_result EQ abap_true.

  "record is in current slice

ELSE.

  "record is not in current slice

ENDIF.

Read only

0 Likes
1,554

Hm is there any other way for keeping or deleting a record?

I'm just thinking about how to get it back when deleting them from my internal table. Of course I can work with local table as copy of the global and refresh only the local after changing it. This would help in this case of the report on what I'm working at the moment.

But for implementing it in other grids, e.g. grids with editing function I think I would get some problems with indexes when updating the internal table in database in using a filtered time slice.

Read only

0 Likes
1,554

Ok now my dateslice grid works pretty good. Now its up to some extra goodies 🙂

Is it possible in any easy way to build my dateslices in the dropdown menu some kind of individual like it works in SAP standard?

For example, I got my grid with the table fields 'valid from' and 'valid to'. I want to build by dateslices in reference to all possible combinations of these both fields. This means:

grid row 1 - 00.00.0000 until 30.06.2013

grid row 2 - 01.07.2013 until 31.12.2013

grid row 3 - 01.01.2014 until 31.12.9999

Now I want the dateslices

(1) ALL

(2) until 30.06.2013

(3) 01.07.2014 until 31.12.2013

(4) from 01.01.2014

Is there any easy way with some special method? Or do I have to loop my whole grid table? If so whats the best way to create the slices then?

Regards

Michael

Read only

0 Likes
1,554

Yes, you have to loop through whole grid table to fill gt_daterange. Once this is filled, there can be some useful methods to manipulate the daterange table.

The code you found while debugging has some clues.

  • I think SORT and DELETE ADJACENT can be used to remove duplicate entries.
  • A method call is done in your snippet to compress date ranges. This can be helpful.
  • Code can also be written to remove a daterange when a superset date range exists.
  • Best bet would be debug the standard further and see which methods are being used.

* compress date ranges

  CALL METHOD cl_reca_date=>create_date_ranges

    EXPORTING

      it_dates_overlap = gt_daterange

    IMPORTING

      et_dates_cut     = gt_daterange.