This website is not affiliated with, sponsored by, or approved by SAP AG.

0019 - Editor Patterns

Moderators: Snowy, thx4allthefish, Rich, ilya

0019 - Editor Patterns

Postby Rich » Thu Mar 26, 2009 12:02 pm

Source Code Patterns.

In the ABAP editor there is the functionality to insert code into your program using what is called a pattern. You use this functionality each time you insert a function call for example. This menu option is reached via the menu path SE38->Edit->Pattern:

Image

By entering a function module name, or selecting one of the other options SAP will automatically enter the correct code into your program enabling you to just "fill in the blanks".

One of the things that I do when I get to a new site is to enter my own program header and procedure headers as a pattern using the Pattern Editor (SE38->Utilities->More Utilities->Edit Pattern. You provide a pattern name (such as 'Header'), enter the text using SE38, save it and then use it. By selecting the 'Other Pattern' radio button in the pattern selection window shown above and entering your pattern name in the relevant field, the lines of text you have defined will be entered into your source code at the current cursor location.

This works well for static patterns, Ie patterns that do not have any variable text in them. However, Rob Dielemans (Rob) has sent in some code that allows you to define a dynamic pattern, again a header which automatically fills in various fields.

This has been tested in 4.6c, but not on any other versions although the pattern editor has been around since 3.1 so you might be lucky.....

Whilst this has been written to produce a program header, SAP when inserting a pattern looks for a function module that contains the name of your pattern followed by the string '_editor_exit'. This is then called allowing you to do whatever processing you require before returning any results back to the editor where they are dumped into your source code.

To implement this, create your pattern in the pattern editor as described above. The pattern should contain only one line of text:

Code: Select all
*$&$MUSTER


The next thing to do is to create the function module that is called. Create a new function group first (because I can see this becoming extremely useful.....) and then insert a new function module into the group. This function module should have a single table parameter of structure 'ABAPSOURCE'.

Anything that you place in this table will be copied back to your own source.

Taking Robs example function, he is inserting the user name, department and a few other bits and bobs into the header:

Code: Select all
FUNCTION ZIPS_MODEL_HEADER_EDITOR_EXIT.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  TABLES
*"      BUFFER STRUCTURE  ABAPSOURCE
*"----------------------------------------------------------------------

* <DATA>
  DATA: l_commentline1 LIKE LINE OF buffer,
  l_commentline2 LIKE LINE OF buffer,
  l_commentline3 LIKE LINE OF buffer,
  l_firstname LIKE adrp-name_first,
  l_lastname LIKE adrp-name_last,
  l_function LIKE adcp-function,
  l_department LIKE adcp-department,
  l_datum(10).

* <TABLES>
  TABLES: usr21, "Assign user name address key
  adrp, "Persons (central address administration)
  adcp. "Person/Address assignment (central address administration)

*additional:, although using the comment charater '"', the system
* converts it to '*'
  CONCATENATE '"##############################'
  '#########################################' INTO l_commentline1.

  CONCATENATE '"------------------------------------'
  '-----------------------------------' INTO l_commentline2.
  CONCATENATE '"=================================='
  '=====================================' INTO l_commentline3.

  buffer = l_commentline1.
  APPEND buffer.

  buffer = '* Report : '.
  APPEND buffer.

  buffer = '* Version : 1.00'.
  APPEND buffer.

* initialize first and last name, if not found in database
  l_firstname = 'first name'.
  l_lastname = 'last name'.

* retrieval of first and last name in database
  SELECT SINGLE * FROM usr21 WHERE bname = sy-uname.
  IF sy-subrc = 0.

    SELECT SINGLE * FROM adrp WHERE persnumber = usr21-persnumber.
    IF sy-subrc = 0.
      l_firstname = adrp-name_first.
      l_lastname = adrp-name_last.

* retrtieval of function and department of user
      SELECT SINGLE * FROM adcp WHERE persnumber = usr21-persnumber.
      IF sy-subrc = 0.
        l_function = adcp-function.
        l_department = adcp-department.

      ENDIF.
    ENDIF.
  ENDIF.

  CONCATENATE '* Author :' sy-uname' -' l_firstname l_lastname INTO
  buffer SEPARATED BY space.
  APPEND buffer.

  CONCATENATE '* Function :' l_function
  ' Department :' l_department
  INTO buffer SEPARATED BY space.
  APPEND buffer.

  WRITE sy-datum DD/MM/YYYY TO l_datum.
  CONCATENATE '* Date : ' l_datum INTO buffer SEPARATED BY space.
  APPEND buffer.

  buffer = l_commentline2.
  APPEND buffer.

  buffer = '* Title : '.
  APPEND buffer.

  buffer = '* Purpose : '.
  APPEND buffer.

  buffer = '* Details : '.
  APPEND buffer.

  buffer = l_commentline3.
  APPEND buffer.

  buffer = '* Change History'.
  APPEND buffer.

  buffer = l_commentline2.
  APPEND buffer.

  buffer = '* Correction on version : 1.00'.
  APPEND buffer.

  buffer = '* New version : 1.01'.
  APPEND buffer.

  buffer = '* Author :'.
  APPEND buffer.

  buffer = '* Date :'.
  APPEND buffer.

  buffer = '* Reason :'.
  APPEND buffer.

  buffer = '* Change :'.
  APPEND buffer.

  buffer = l_commentline1.
  APPEND buffer.

ENDFUNCTION.


Activate the function and away you go!

Entering the pattern name 'ZIPS_MODEL_HEADER' into the pattern name field produces the following output in the ABAP Editor:

Code: Select all
*#######################################################################
* Report :
* Version : 1.00
* Author : BCUSER  - Richard Harper
* Function : ABAP Programmer  Department : My Office
* Date : 18.06.2004
*-----------------------------------------------------------------------
* Title :
* Purpose :
* Details :
*=======================================================================
* Change History
*-----------------------------------------------------------------------
* Correction on version : 1.00
* New version : 1.01
* Author :
* Date :
* Reason :
* Change :
*#######################################################################


Neat huh ??

Thanks Rob!

Further to this, Mattg has also been doing some research into editor patterns and has come up with the following:

If the pattern contains *$&$EXIT at the start of line 1, then a standard user exit is called.

The userexit enhancement is SEUED001, the component to change is EXIT_SAPLLOCAL_EDT1_001.

Now this allows you to add the code from before. This is the UE code;

Code: Select all
CASE KEYWORD.
  WHEN  'MATTG_HEADER'.
    PERFORM MATTG_HEADER  TABLES BUFFER.

  WHEN  'MATTG_HISTORY'.
    CALL FUNCTION 'ZZMATT_HISTORY_EDITOR_EXIT'
         TABLES
              BUFFER = BUFFER.

ENDCASE.


Just the change the function call to a perform, as above, BUFFER has type ABAPSOURCE.

If you want to get the Transport Request information for the object you are editing try the following code;

Code: Select all
  TABLES: E07T.      "WBO and Transport: Short Texts for Requests/Tasks

  DATA:  WA_BUFFER      TYPE ABAPSOURCE,
         ORDERNUM       LIKE E070-TRKORR,
         L_PROGFIELD    LIKE BDCDATA-FNAM.

  FIELD-SYMBOLS: <TRDIR>    LIKE TRDIR,
                 <TRKEY>    LIKE TRKEY.



* Additional:, although using the comment character '"', the system
* converts it to '*'
  CONCATENATE '"------------------------------------'
              '----------------------------------*'
              INTO L_COMMENTLINE2.

  PERFORM GET_DEVELOPER_NAME   USING SY-UNAME
                            CHANGING L_FIRSTNAME
                                     L_LASTNAME
                                     L_FUNCTION
                                     L_DEPARTMENT.

  WRITE SY-DATUM DD/MM/YYYY TO L_DATUM.
  CONCATENATE '* Date:' L_DATUM
              'Author:' SY-UNAME '-' L_FIRSTNAME L_LASTNAME
              INTO WA_BUFFER SEPARATED BY SPACE.
  IF  WA_BUFFER+71(1)  =  SPACE.
    WA_BUFFER+71(1)  =  '*'.
  ENDIF.
  APPEND WA_BUFFER  TO  BUFFER.


  L_PROGFIELD  =  '(SAPLS38E)TRDIR'.
  ASSIGN (L_PROGFIELD) TO <TRDIR>.
  IF SY-SUBRC EQ 0.
    CALL FUNCTION 'RS_CORR_INSERT'
         EXPORTING
              OBJECT                   = <TRDIR>-NAME
              OBJECT_CLASS             = 'ABAP'
*             MODE                     = ' '
*             GLOBAL_LOCK              = ' '
*             DEVCLASS                 = ' '
*             KORRNUM                  = ' '
*             AUTHOR                   = ' '
*             MASTER_LANGUAGE          = ' '
*             GENFLAG                  = ' '
*             PROGRAM                  = ' '
*             OBJECT_CLASS_SUPPORTS_MA = ' '
*             EXTEND                   = ' '
         IMPORTING
*             DEVCLASS                 =
*             KORRNUM                  =             "Task number
              ORDERNUM                 = ORDERNUM    "Request number
*             NEW_CORR_ENTRY           =
*             AUTHOR                   =
*             TRANSPORT_KEY            =
*             NEW_EXTEND               =
         EXCEPTIONS
              CANCELLED                = 1
              PERMISSION_FAILURE       = 2
              UNKNOWN_OBJECTCLASS      = 3
              OTHERS                   = 4
              .
    IF SY-SUBRC  =  0.
      IF  NOT ORDERNUM  IS INITIAL.
        SELECT SINGLE * FROM E07T
               WHERE TRKORR  =  ORDERNUM.
        IF  SY-SUBRC  <>  0.
          CLEAR E07T.
        ENDIF.
        CONCATENATE '*'  ORDERNUM  E07T-AS4TEXT
                    INTO WA_BUFFER SEPARATED BY SPACE.

      ELSE.
        L_PROGFIELD  =  '(SAPLS38E)TRANSPORT_KEY'.
        ASSIGN (L_PROGFIELD) TO <TRKEY>.
        CONCATENATE '* Development class;'  <TRKEY>-DEVCLASS
                    'WYTK9&$&$'  INTO WA_BUFFER SEPARATED BY SPACE.
      ENDIF.

    ELSE.
*     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*             WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
      L_PROGFIELD  =  '(SAPLS38E)TRANSPORT_KEY'.
      ASSIGN (L_PROGFIELD) TO <TRKEY>.
      CONCATENATE '* Development class;'  <TRKEY>-DEVCLASS
                  'WYTK9&$&$'  INTO WA_BUFFER SEPARATED BY SPACE.
    ENDIF.
  ELSE.
    L_PROGFIELD  =  '(SAPLS38E)TRANSPORT_KEY'.
    ASSIGN (L_PROGFIELD) TO <TRKEY>.
    CONCATENATE '* Development class;'  <TRKEY>-DEVCLASS
                'WYTK9&$&$'  INTO WA_BUFFER SEPARATED BY SPACE.
  ENDIF.

  IF  WA_BUFFER+71(1)  =  SPACE.
    WA_BUFFER+71(1)  =  '*'.
  ENDIF.
  APPEND WA_BUFFER  TO BUFFER.


*  L_PROGFIELD  =  '(SAPLS38E)KORRNUM'.
*  ASSIGN (L_PROGFIELD) TO <KORRNUM>.

  WA_BUFFER = '* Description: '.
  WA_BUFFER+71(1)  =  '*'.
  APPEND WA_BUFFER  TO  BUFFER.

  CLEAR WA_BUFFER.
  WA_BUFFER+00(1)  =  '*'.
  WA_BUFFER+71(1)  =  '*'.
  APPEND WA_BUFFER  TO  BUFFER.
  APPEND WA_BUFFER  TO  BUFFER.

  APPEND L_COMMENTLINE2  TO  BUFFER.



The FORM GET_DEVELOPER_NAME is just the code from your existing example.

This is on a 4.6B system (patch level 7), so should be usable by most people.

4.7 Enterprise

This functionality is still available in 4.7, the modifications required to the function module have been sent in by jpb2001. The only change required is that the table BUFFER must be of type RSWSOURCET instead of ABAPSOURCE to cope with the extra line size allowed in Enterprise.
Regards

Rich

Image
Abap KC:http://www.richard-harper.me.uk/Kb
SFMDR:http://www.se37.com
Rich
 
Posts: 7112
Joined: Thu Oct 31, 2002 4:47 pm
Location: Liverpool

Return to ABAPers

Who is online

Users browsing this forum: No registered users and 3 guests





loading...


This website is not affiliated with, sponsored by, or approved by SAP AG.