Custom input helps

Calendar week as an example for value helps and FOR expressions

The example

Data element KWEEK refers to a factory calendar week in the format YYYYMM. Sadly, there is no standard search help available.

Data element 'KWEEK' in the ABAP Dictionary
Data element KWEEK in the ABAP Dictionary

There are alternatives in search helps RSCALWEEK and /BI0/OCALWEEK.

Popup for search help '/BI0/OCALWEEK'
Popup for search help /BI0/OCALWEEK
Popup for search help 'RSCALWEEK'
Popup for search help RSCALWEEK

However, these are not user-friendly, partly because the input starts way in the past. So let’s help our end-users easily select a week with a custom implementation.

The approach

Data type: value list columns

To provide end-users with a list of possibilities, we first need to determine the relevant fields to display and their respective data types. In our example, we opt for the year, week number, and calendar week (the concatenation of the two beforementioned fields).

"data type for value help entries
TYPES:
  BEGIN OF week_calendar_value_help,
    year          TYPE ajahr,
    week          TYPE weekn,
    calendar_week TYPE kweek,
  END OF week_calendar_value_help,
  t_week_calendar_value_help TYPE STANDARD TABLE OF
    week_calendar_value_help WITH DEFAULT KEY.
Parameters in the custom search help for factory calendar week
Parameters in the custom search help for factory calendar week

Preparing the values

Let’s assume the end-user should be able to select a calendar week for the current year, up to two years in the past, and up to two years in the future. This requirement is an ideal use-case for the FOR expression, which we can use in a nested way to fill all week values (52 for the number of weeks in a year) for every relevant year.

This is a simplified representation since some years have 53 weeks. See the demo program below for the full code that takes this into account.
CONSTANTS weeks_in_a_year TYPE i VALUE 52.

CONSTANTS value_help_years_in_past TYPE i VALUE 2.
CONSTANTS value_help_years_in_future TYPE i VALUE 2.

"prepare value help table containing calendar week numbers
"going x amount of years in the past and future
DATA(calendar_weeks) = VALUE t_week_calendar_value_help(
  LET current_year = sy-datum(4) IN
  FOR year = CONV int2( current_year - value_help_years_in_past )
    UNTIL year > current_year + value_help_years_in_future
  FOR weeknumber = 1 UNTIL weeknumber > weeks_in_a_year
    LET week = |{ CONV char2( weeknumber ) ALPHA = IN }|
      IN ( year = year
           week = weeknumber
           calendar_week = |{ year }{ week }| ) ).

Let’s deconstruct the code snippet above. To start, we construct our value help table using the VALUE operator. Inside, we define a helper variable for the current year using a LET expression. Afterwards we start a first conditional iteration using the FOR operator: we specify we want to iterate from two years in the past (year = CONV int2( current_year - value_help_years_in_past) until two years in the future (UNTIL year > current_year + value_help_years_in_future). Inside this main iteration, we iterate a second time over the week numbers in a year (52), once again using the FOR operator. In this inner iteration, we fill our table value.

Implementing a custom search help

Creating the search help

To create a custom search help:

  1. Open either the ABAP Development Tools in Eclipse or transactions SE80 (Repository Browser) or SE11 (ABAP Dictionary) in the SAP GUI.
  2. Follow the steps as described in Creating Elementary Search Helps on the SAP Help Portal.
  3. Define the parameters calendar week (KWEEK), year (AJAHR), and week (WEEKN) as shown in the screenshot below.
  4. Save the new search help.
    Create and activate the search help exit (see below).
  5. Finally, assign the exit and activate the search help.
The custom search help in the ABAP Dictionary
The custom search help in the ABAP Dictionary

Creating the search help exit

To get started quickly, copy the demo function module F4IF_SHLP_EXIT_EXAMPLE. There is no need to change the interface.

Copying the demo search help exit in transaction SE37
Copying the demo search help exit in transaction SE37

As described above, the code in our search help exit below uses a nested FOR expression to provide a week calendar value list to the end user. Here the user can choose any week up to two years in the past or future.

Check out the example search help exit.

This is a simplified representation since some years have 53 weeks. See the demo program below for the full code that takes this into account.
FUNCTION zca_kweek_sh_exit.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  TABLES
*"      SHLP_TAB TYPE  SHLP_DESCR_TAB_T
*"      RECORD_TAB STRUCTURE  SEAHLPRES
*"  CHANGING
*"     VALUE(SHLP) TYPE  SHLP_DESCR_T
*"     VALUE(CALLCONTROL) LIKE  DDSHF4CTRL STRUCTURE  DDSHF4CTRL
*"----------------------------------------------------------------------

  IF callcontrol-step = 'DISP'.
    TYPES:
      BEGIN OF week_calendar_value_help,
        year          TYPE ajahr,
        week          TYPE weekn,
        calendar_week TYPE kweek,
      END OF week_calendar_value_help,
      t_week_calendar_value_help TYPE STANDARD TABLE OF
        week_calendar_value_help WITH DEFAULT KEY.

    "handle 'F4'/value help request for the week calendar parameter
    CONSTANTS weeks_in_a_year TYPE i VALUE 52.

    CONSTANTS value_help_years_in_past TYPE i VALUE 2.
    CONSTANTS value_help_years_in_future TYPE i VALUE 2.

    "prepare value help table containing calendar week numbers
    "going x amount of years in the past and future
    DATA(calendar_weeks) = VALUE t_week_calendar_value_help(
      LET current_year = sy-datum(4) IN
      FOR year = CONV int2( current_year - value_help_years_in_past )
        UNTIL year > current_year + value_help_years_in_future
      FOR weeknumber = 1 UNTIL weeknumber > weeks_in_a_year
        LET week = |{ CONV char2( weeknumber ) ALPHA = IN }|
          IN ( year = year
               week = weeknumber
               calendar_week = |{ year }{ week }| ) ).


    LOOP AT calendar_weeks ASSIGNING FIELD-SYMBOL(<calender_week>).
      LOOP AT shlp_tab[ 1 ]-fielddescr ASSIGNING FIELD-SYMBOL(<fielddescr>).
        ASSIGN COMPONENT <fielddescr>-fieldname 
          OF STRUCTURE <calender_week> TO FIELD-SYMBOL(<value>).
        CALL FUNCTION 'F4UT_PARAMETER_RESULTS_PUT'
          EXPORTING
            parameter         = <fielddescr>-fieldname
            value             = <value>
            fieldname         = CONV dfies-lfieldname( <fielddescr>-fieldname )
          TABLES
            shlp_tab          = shlp_tab
            record_tab        = record_tab
            source_tab        = calendar_weeks
          CHANGING
            shlp              = shlp
            callcontrol       = callcontrol
          EXCEPTIONS
            parameter_unknown = 1
            OTHERS            = 2.

      ENDLOOP.
    ENDLOOP.
  ENDIF.
ENDFUNCTION.

Generating a value list at runtime

A second option is to handle a value request for a selection screen without creating a custom search help but generating a value list at runtime.

The benefits of using search helps

Note that before using this approach, one should reconsider whether a custom search help would not be the better option. Search helps can be attached to a data element or a field of a structure. The F4 help is then automatically available for all users of the data element or structure.

Implementation

Self-programmed value lists are achieved via function module F4IF_INT_TABLE_VALUE_REQUEST.

The SAP Help Portal clearly describes how the function can be used.

This function module displays a value list that you created in an ABAP program. The self-programmed value list is passed to the function module as the table parameter VALUE_TAB. If you specify the import parameters DYNPPROG, DYNPNR, and DYNPROFIELD, the user's selection is returned to the corresponding field on the screen. If you specify the table parameter RETURN_TAB, the selection is returned into the table instead.

Demo program

The demo program below uses the function module described above in conjunction with a nested FOR expression (see ‘Preparing the values’) to provide a value list to the end-user. Here the user can choose any week up to two years in the past or future.

In addition, this implementation takes into account the fact that some years contain 53 weeks instead of 52. The number of weeks in a year is determined using a helper method that calls FM DATE_GET_WEEK. The year 2026 is used as an example.

A value list generated at runtime
A value list generated at runtime
Check out the demo program.

*&---------------------------------------------------------------------*
*& Report ZKWEEKDEMO
*&---------------------------------------------------------------------*
*& Demo program for custom value help for factory calendar week (KWEEK)
*&
*& https://www.laurix.com/post/abap/search-help/calendar-week/
*&---------------------------------------------------------------------*
REPORT zkweekdemo.

"data type for value help entries
TYPES:
  BEGIN OF week_calendar_value_help,
    year          TYPE ajahr,
    week          TYPE weekn,
    calendar_week TYPE kweek,
  END OF week_calendar_value_help,
  t_week_calendar_value_help TYPE STANDARD TABLE OF
    week_calendar_value_help WITH DEFAULT KEY.

"Helper class for determining the number of weeks in a given year
CLASS lcl_week_number_helper DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS get_weeks_in_year
      IMPORTING
        iv_year                   TYPE ajahr
      RETURNING
        VALUE(rv_amount_of_weeks) TYPE i.
ENDCLASS.

CLASS lcl_week_number_helper IMPLEMENTATION.
  METHOD get_weeks_in_year.
    DATA lv_max_calendar_week TYPE kweek.
    DATA(lv_last_day_of_year) = CONV dats( |{ iv_year }1231| ).

    WHILE lv_max_calendar_week(4) NE iv_year AND sy-subrc = 0.
      CALL FUNCTION 'DATE_GET_WEEK'
        EXPORTING
          date = lv_last_day_of_year
        IMPORTING
          week = lv_max_calendar_week.

      "try again with an earlier date
      "if the week returned is in the wrong/next year
      lv_last_day_of_year -= 1.
    ENDWHILE.

    rv_amount_of_weeks = CONV #( lv_max_calendar_week+4 ).
  ENDMETHOD.
ENDCLASS.

PARAMETERS pa_kweek TYPE kweek.

"handle 'F4'/value help request for the week calendar parameter
AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_kweek.
  "2026 is an example of a year with 53 ISO calendar weeks
  CONSTANTS start_year TYPE i VALUE 2026.
  CONSTANTS value_help_years_in_past TYPE i VALUE 2.
  CONSTANTS value_help_years_in_future TYPE i VALUE 2.

  "prepare value help table containing calendar week numbers
  "going x amount of years in the past and future
  DATA(calendar_weeks) = VALUE t_week_calendar_value_help(
    FOR current_year = start_year - value_help_years_in_past
      UNTIL current_year > start_year + value_help_years_in_future

      FOR weeknumber = 1
        "determine number of weeks in each year
        "since some years have 53 weeks
        UNTIL weeknumber > lcl_week_number_helper=>get_weeks_in_year( CONV #( current_year ) )

        LET week = |{ CONV char2( weeknumber ) ALPHA = IN }|
         IN ( year = current_year
              week = weeknumber
              calendar_week = |{ current_year }{ week }| ) ).

  CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
    EXPORTING
      retfield        = 'CALENDAR_WEEK'
      dynpprog        = sy-repid
      dynpnr          = sy-dynnr
      dynprofield     = 'PA_KWEEK'
      value_org       = 'S'
    TABLES
      value_tab       = calendar_weeks
    EXCEPTIONS
      parameter_error = 1
      no_values_found = 2
      OTHERS          = 3.

Further reading

Conclusion

This post shows how to offer value lists when standard SAP does not suffice through a concrete example. Next to generating a list of values at runtime and creating a custom search help with the corresponding search help exit, we saw an interesting application of the ‘FOR’ expression.

Discussion

Discuss this post on Community
Laurens Deprost
Laurens Deprost
SAP Consultant

Related