Skip to Content

We are all familiar with the “Patterns” button in the ABAP Editor which helps us to generate templates for function modules,classes and standard SAP Objects.In this blog I would like to talk about creating our own dynamic patterns in the ABAP Editor and calling it via the “Pattern” button.In this blog I will explain how to create a dynamic pattern for the “TYPES” statement in ABAP.

STEPS

1.Creation of pattern
Menu -> Utilities->More Utilities->Edit Pattern->Create Pattern from SE38 Editor

.

image

FUNCTION ztype_editor_exit.

*”—-


“Local Interface:

*”  TABLES

*”      BUFFER TYPE  RSWSOURCET

*”  EXCEPTIONS

*”      CANCELLED

*”—-


  FREE buffer[].

  CALL SCREEN 9900 STARTING AT 1 1 ENDING AT 54 18.

  IF LINES( gt_buffer ) GT 0.

    APPEND LINES OF gt_buffer TO buffer.

  ENDIF.

ENDFUNCTION.

3. Screen 9900

image

Screen 9900 Flow Logic

PROCESS BEFORE OUTPUT.

MODULE STATUS_9900.

PROCESS AFTER INPUT.

MODULE EXIT-PROCESSING AT EXIT-COMMAND.

MODULE USER_COMMAND_9900.

Code in the above modules written in the function pool

FUNCTION-POOL zravi.                        “MESSAGE-ID ..

TYPE-POOLS : vrm.

TYPES :

BEGIN OF t_type,

tabname   TYPE tabname,    “Table name

fieldname TYPE fieldname,  “Fieldname

rollname  TYPE rollname,   “Dataelement

ddtext    TYPE as4text,    “Description

END OF t_type.

DATA :

gv_visible(6)   TYPE c VALUE ‘GLOBAL’, “Visibility

gv_typename(20) TYPE c VALUE ‘T_*’,    “Typename

gv_include(20)  TYPE c ,               “Include type

gv_table        TYPE tabname,          “Table name

gt_type         TYPE STANDARD TABLE OF t_type,

ok_code         TYPE syucomm,

fcode           TYPE syucomm,

gt_values       TYPE TABLE OF vrm_value,

wa_values       TYPE vrm_value,

gv_value        TYPE  vrm_id,

gt_buffer       TYPE  rswsourcet,

gt_collect      TYPE  TABLE OF string,

gv_buffer       TYPE string,

ob_grid  TYPE REF TO cl_gui_alv_grid,

ob_custom_container TYPE REF TO cl_gui_custom_container,

gt_fieldcat TYPE lvc_t_fcat,

gv_layout TYPE lvc_s_layo,

wa_str    TYPE string.

&—-


*&      Module  STATUS_9900  OUTPUT

&—-


  •       text

—-


MODULE status_9900 OUTPUT.

  SET PF-STATUS ‘BASIC1’.

  SET TITLEBAR ‘007’.

  PERFORM zf_visiblity_fill.

  IF ob_custom_container IS INITIAL.

    PERFORM zf_create_and_init_alv.

  ENDIF.

ENDMODULE.                 ” STATUS_9900  OUTPUT

&—-


*&      Module  USER_COMMAND_9900  INPUT

&—-


  •       text

—-


MODULE user_command_9900 INPUT.

  fcode = ok_code.

  CLEAR fcode.

  CASE ok_code.

    WHEN ‘CANC’.

      CLEAR gt_buffer.

      SET SCREEN 0.

      LEAVE SCREEN.

    WHEN ‘CONT’.

      PERFORM zf_add_to_type.

*End the Type here

      CLEAR gv_buffer.

      CONCATENATE ‘TYPES END OF ‘

                   gv_typename ‘.’

                   INTO gv_buffer

                   SEPARATED BY space.

      SEARCH gt_collect FOR gv_buffer.

      IF sy-subrc NE 0.

        APPEND gv_buffer TO gt_collect.

      ENDIF.

      IF LINES( gt_collect ) GT 0.

        CLEAR gt_buffer.

        APPEND LINES OF gt_collect TO gt_buffer.

      ENDIF.

      FREE gt_collect.

      SET SCREEN 0.

      LEAVE SCREEN.

    WHEN ‘LIST’.

      IF gv_visible = ‘GLOBAL’.

        gv_typename = ‘T_*’.

      ELSE.

        gv_typename = ‘LS_*’.

      ENDIF.

    WHEN ‘GET’.

      PERFORM zf_fieldinfo_get.

      CALL METHOD ob_grid->refresh_table_display.

    WHEN ‘ADD’.

      PERFORM zf_add_to_type.

    WHEN ‘UNDO’.

      CLEAR gv_buffer.

      FREE gt_collect.

  ENDCASE.

ENDMODULE.                 ” USER_COMMAND_9900  INPUT

&—-


*&      Form  zf_visiblity_fill

&—-


FORM zf_visiblity_fill .

  CLEAR : gt_values,wa_values,gv_value.

  wa_values-key = ‘GLOBAL’.

  wa_values-text = ‘GLOBAL’.

  APPEND wa_values TO gt_values.

  wa_values-key = ‘LOCAL’.

  wa_values-text = ‘LOCAL’.

  APPEND wa_values TO gt_values.

  gv_value = ‘GV_VISIBLE’.

  CALL FUNCTION ‘VRM_SET_VALUES’

    EXPORTING

      id              = gv_value

      values          = gt_values[]

    EXCEPTIONS

      id_illegal_name = 1

      OTHERS          = 2.

ENDFORM.                    ” zf_visiblity_fill

&—-


*&      Form  zf_fieldinfo_get

&—-


FORM zf_fieldinfo_get .

  CLEAR gt_type.

  SELECT dd03ltabname dd03lfieldname dd03l~rollname

         dd04t~ddtext FROM ( dd03l AS dd03l INNER JOIN

                             dd04t AS dd04t

                             ON dd03lrollname = dd04trollname )

                   INTO CORRESPONDING FIELDS OF TABLE gt_type

                   WHERE dd03l~tabname = gv_table

                   AND   ddlanguage    = sy-langu.

ENDFORM.                    ” zf_fieldinfo_get

&—-


*&      Form  zf_create_and_init_alv

&—-


FORM zf_create_and_init_alv .

  DATA:lwa_exclude TYPE ui_func,

       lt_exclude TYPE ui_functions.

  CREATE OBJECT ob_custom_container

           EXPORTING container_name = ‘CONTAINER’.

  CREATE OBJECT ob_grid

         EXPORTING i_parent = ob_custom_container.

  • Build fieldcat and set columns edit enabled.

  PERFORM zf_build_fieldcat.

  gv_layout-grid_title = ‘Fields with data elements’.

  gv_layout-cwidth_opt = ‘X’.

*Exclude all functions of alv

  lwa_exclude = cl_gui_alv_grid=>mc_fc_excl_all.

  APPEND lwa_exclude TO lt_exclude.

  CALL METHOD ob_grid->set_table_for_first_display

    EXPORTING

      it_toolbar_excluding = lt_exclude

      is_layout            = gv_layout

    CHANGING

      it_fieldcatalog      = gt_fieldcat

      it_outtab            = gt_type[].

  • Set editable cells to ready for input initially

  CALL METHOD ob_grid->set_ready_for_input

    EXPORTING

      i_ready_for_input = 1.

  • Controls are not integrated into the TAB-Order

  • Call “set_focus” if you want to make sure that ‘the cursor’

  • is active in your control.

  CALL METHOD cl_gui_control=>set_focus

    EXPORTING

      control = ob_grid.

ENDFORM.                    ” zf_create_and_init_alv

&—-


*&      Form  zf_build_fieldcat

&—-


FORM zf_build_fieldcat .

  DATA : ls_fieldcat TYPE lvc_s_fcat,

       lv_pos TYPE i VALUE 1.

*Fieldname

  ls_fieldcat-col_pos   = lv_pos.

  ls_fieldcat-fieldname = ‘FIELDNAME’.

  ls_fieldcat-key        = ‘X’.

  ls_fieldcat-edit       = ‘X’.

  ls_fieldcat-scrtext_m  = ‘Fieldname’.

  ls_fieldcat-colddictxt = ‘M’.

  ls_fieldcat-tipddictxt = ‘M’.

  APPEND ls_fieldcat TO gt_fieldcat.

  CLEAR ls_fieldcat.

*Data Element

  lv_pos = lv_pos + 1.

  ls_fieldcat-col_pos    = lv_pos.

  ls_fieldcat-fieldname  = ‘ROLLNAME’.

  ls_fieldcat-key        = ‘X’.

  ls_fieldcat-edit       = ”.

  ls_fieldcat-scrtext_m  = ‘Data Element’.

  ls_fieldcat-colddictxt = ‘M’.

  ls_fieldcat-tipddictxt = ‘M’.

  APPEND ls_fieldcat TO gt_fieldcat.

  CLEAR ls_fieldcat.

*Description

  lv_pos = lv_pos + 1.

  ls_fieldcat-col_pos    = lv_pos.

  ls_fieldcat-fieldname  = ‘DDTEXT’.

  ls_fieldcat-key        = ‘X’.

  ls_fieldcat-edit       = ”.

  ls_fieldcat-scrtext_m  = ‘Description’.

  ls_fieldcat-colddictxt = ‘M’.

  ls_fieldcat-tipddictxt = ‘M’.

  APPEND ls_fieldcat TO gt_fieldcat.

  CLEAR ls_fieldcat.

ENDFORM.                    ” zf_build_fieldcat

&—-


*&      Form  ZF_ADD_TO_TYPE

&—-


FORM zf_add_to_type .

  DATA : lt_row_table    TYPE lvc_t_row,  ” selected rows

       lwa_row         TYPE lvc_s_row,

       lwa_type        TYPE t_type.

*Call check_changed_data

  CALL METHOD ob_grid->check_changed_data.

  CONCATENATE ‘TYPES BEGIN OF ‘

               gv_typename ‘.’

               INTO gv_buffer

               SEPARATED BY space.

  SEARCH gt_collect FOR gv_buffer.

  IF sy-subrc NE 0.

    APPEND gv_buffer TO gt_collect.

  ENDIF.

  CALL METHOD ob_grid->get_selected_rows

    IMPORTING

      et_index_rows = lt_row_table[].

  IF LINES( lt_row_table ) GT 0.

    LOOP AT lt_row_table INTO lwa_row.

      READ TABLE gt_type INTO lwa_type

               INDEX lwa_row-index.

      IF sy-subrc EQ 0.

*Add data to gt_buffer

        CLEAR gv_buffer.

        CONCATENATE ‘TYPES’ lwa_type-fieldname

                     ‘TYPE’ lwa_type-rollname

                     ‘.’ INTO gv_buffer

                     SEPARATED BY space.

        SEARCH gt_collect FOR gv_buffer.

        IF sy-subrc NE 0.

          APPEND gv_buffer TO gt_collect.

        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDIF.

*Check if user has inputted an include type

  IF NOT gv_include IS INITIAL.

    CLEAR gv_buffer.

    CONCATENATE ‘INCLUDE TYPE’

                 gv_include ‘.’

                 INTO gv_buffer

                 SEPARATED BY space.

    SEARCH gt_collect FOR gv_buffer.

    IF sy-subrc NE 0.

      APPEND gv_buffer TO gt_collect.

    ENDIF.

  ENDIF.

ENDFORM.                    ” ZF_ADD_TO_TYPE

&—-


*&      Module  EXIT-PROCESSING  INPUT

&—-


  •       text

—-


MODULE exit-processing INPUT.

  fcode = ok_code.

  CLEAR fcode.

  CASE ok_code.

    WHEN ‘CANCEL’ OR ‘EXIT’ OR ‘CANCEL’.

      REFRESH gt_buffer.

      SET SCREEN 0.

      LEAVE SCREEN.

  ENDCASE.

ENDMODULE.                 ” EXIT-PROCESSING  INPUT

3. Test Program calling the pattern

Create a program in SE38.Click on the

Pattern

button and select the

Other pattern

radio button.Enter the pattern created by you in the input box and press ENTER.

The following popup screen will be displayed.

image

The following features are possible in this application.

1.You can include another type within your type by inputting the “Include Type” name.

2.Entering the table name and clicking on the “LIST” button will populate the fieldnames of the table along with their data elements.

3.You can edit the fieldnames as per your requirements.Clicking the ‘ADD” button below the ALV grid will add the fields to the type.The “UNDO” button will clear the fields added to the type.

4.Clicking the “CONTINUE” arrow will insert the generated type within your program.

5.Clicking the “CANCEL” cross will exit the popup box and clear the selection.

A sample test program is as shown below .

You can transport your created pattern by clicking on the “Transport” option in the pattern editor

To report this post you need to login first.

10 Comments

You must be Logged on to comment or reply to a post.

  1. Matthew Gifford
    The idea of having your own Patterns has been around some time. There are tips for this at SAPsuperUsers.com (~http://sapsuperusers.com/forums/forumdisplay.php?f=677)Rich’s Tuly Idiot ABAP Knowledge Corner, and at SearchSAP.TechTarget.com.

    If you use *$&$EXIT instead of *$&$MUSTER you can access the SAP user exit instead of creating your own function module. The userexit enhancement is SEUED001, the component to change is EXIT_SAPLLOCAL_EDT1_001. In the include I have a case statement to process different Patterns. Thus:
    CASE KEYWORD.
       WHEN  ‘MATTG_HEADER’.
         PERFORM MATTG_HEADER  TABLES BUFFER.

       WHEN  ‘MATTG_HISTORY’.
         CALL FUNCTION ‘ZZMATT_HISTORY_EDITOR_EXIT’
              TABLES
                   BUFFER = BUFFER.

    ENDCASE.
    The function is the same as would be called by using *$&$MUSTER. The perform is code in another part of the user exit.

    My choice of patterns for HISTORY is a set of comments that show who made a set of code changes, thus info on who made the change when, and with some complexity the transport request number and text.
    The HEADER pattern also shows the HISTORY and some other relevant info.

    The DB table to look at to see the SAP patterns is TSE05.

    Upto 6.20 the pattern width was 72 characters, the same width in TSE05. After this the dynamic pattern is of type string, so can be of greater length.

    MattG

    (0) 
  2. Thomas Jung
    You guys aren’t the only ones who dislike having to create large types statements for data dictionary types. 🙂

    If you attended SDN Days in Las Vegas or Amsterdam then you got a chance to see that this functionality is coming with a future version of the ABAP editor. 

    (0) 
    1. Ravi Shankar Rajan Post author
      Hi Thomas
      Thanks for your comments.It is great to know that this functionality is coming in the futute version of the ABAP Editor.I am really looking forward to it.
      (0) 
  3. Stefanie Silvetta
    I also use this dynamic patterns with the
    *$&$EXIT – Method.

    Since I dont want to change the User-Exit everytime I create a new Pattern, my Exit looks like this:
    ************************************************
    data functionname like RS38L-NAME.
    data i_return like sy-subrc.
    .
    *–> Here is my specific table
    select single Functionmodule from ZDTSOCODEPATTERN into functionname
    where pattern = Keyword.
    * No entry found – no FM to call
    if sy-subrc ne 0.
    exit.
    endif.
    * Function does exist ?
    CALL FUNCTION ‘FUNCTION_EXISTS’
    EXPORTING
    FUNCNAME = functionname
    EXCEPTIONS
    FUNCTION_NOT_EXIST = 1
    OTHERS = 2
    .
    IF SY-SUBRC <> 0.
    exit.
    ENDIF.

    CALL FUNCTION functionname
    TABLES
    BUFFER = buffer
    *************************************************
    So all I have to do is to write a new FM and add an entry in my specific table.

    (0) 

Leave a Reply