Skip to Content

See the UPDATES section below for change log 

1. Intro

In this months  I hadn’t so much time to be active in the community, but one blog in the ABAP category caught my attention.

The blog Calling a function module (abap code)  (Calling a function module (abap code)) focuses on a task of the ABAP programming that is very time-consuming; the declaration of the variables used in the call statement.

I always performed this task using an approach based on the “where used list” of the function module, in order to copy the ABAP code containing the declaration of variables.

I absolutely agree, as ABAPer,  with the feelings of Raúl Vides Mosquera Pumaricra  and in my opinion, the ABAP tool contained in his blog is very useful but… the classical icing on the cake is still missing.

2.1 Install the components

2.1.1 Create the Function Group ZSDN_FUNC: SDN: Function Module Pattern (with DATA)

2.1.2 Edit the top include LZSDN_FUNCTOP and paste the following code

function-pool zsdn_func.                    "MESSAGE-ID ..
*&---------------------------------------------------------------------*
*& Function  ZSDN_FUNC
*& Author: Andrea Olivieri
*&         Techedge SpA
*& Version: 1.0  - 2010/11/02
*& Title   SDN: Start Function Module Pattern (with DATA)
*& Supported releases: SAP ECC 6.0
*& Original Source Code By: Raul Vides Mosquera Pumaricra@BizPartner
*& See SDN Blog: http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/21817
*&---------------------------------------------------------------------*
constants: c_tip_import type c value 'I',
          c_tip_export type c value 'E',
          c_tip_tables type c value 'T'.
types: begin of ty_codigo,
        linea type string,
      end of ty_codigo.
types ty_tfdir      type standard table of tfdir.
types ty_tftit      type standard table of tftit.
types ty_funct      type standard table of funct.
types ty_enlfdir    type standard table of enlfdir.
types ty_trdir      type standard table of trdir.
types ty_fupararef  type standard table of sfupararef.
types ty_abaptxt255 type standard table of abaptxt255.
types ty_line(72)   type c.
types ty_line_tab   type standard table of ty_line.
types swbse_max_line(255) type c.
types swbse_max_line_tab  type table of swbse_max_line.
types:  begin of ty_variable,
         tipo_var      type c,
         identificador type string, "char30,
"char25,
         pertenece_a   type char30,
         tipo_dato     type rs38l_typ,
         tipo_tabla    type c,
         instancia     type char15,
         valor         type char30,
         cod_mod       type numc5,
         in_out        type c,
         traspaso      type c, "Ref o Value
         optional      type c,
         param_origina type char30,
       end of ty_variable.
types:  begin of ty_parametro_cant,
         parameter type char30,
         cant      type i,
       end of ty_parametro_cant.
types:  begin of ty_modulos,
         cod_mod       type numc5,
         tipo_mod      type c, "Form o Metodo
         identificador type char30,
         pertenece_a   type char30,
         metodo_event  type char30,
         clase_event   type char30,
       end of ty_modulos.
data it_codigo type standard table of ty_codigo.
* Parameters
data it_import     type standard table of rsimp.       "Importing
data it_change     type standard table of rscha.       "Changing
data it_export     type standard table of rsexp.       "Exporting
data it_tables     type standard table of rstbl.       "Tables
data it_except     type standard table of rsexc.       "Exception
data it_param_docu type standard table of rsfdo.
data it_variables  type standard table of ty_variable.
data it_parametro_cant type standard table of ty_parametro_cant.
data it_ptfdir     type ty_tfdir.
data it_ptftit     type ty_tftit.
data it_pfunct     type ty_funct.
data it_penlfdir   type ty_enlfdir.
data it_ptrdir     type ty_trdir.
data it_pfupararef type ty_fupararef.
data it_uincl      type ty_abaptxt255.
data w_offset      type i.
data w_max_offset  type i.

2.1.3 Create the Function module Z_SDN_PATTERN_FUNC_START – Start Function Module Pattern

function z_sdn_pattern_func_start.
*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*"  TABLES
*"      BUFFER TYPE  RSWSOURCET
*"----------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& Function  Z_SDN_PATTERN_FUNC_START
*& Author: Andrea Olivieri
*&         Techedge SpA
*& Version: 1.0  - 2010/11/02
*& Title   SDN: Editor Exit for Calling Function Module
*& Supported releases: SAP ECC 6.0
*& Original Source Code By: Raul Vides Mosquera Pumaricra@BizPartner
*& See SDN Blog: http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/21817
*&---------------------------------------------------------------------*
  data w_funcname    type rs38l_fnam.
  data it_lines      type ty_line_tab.
  data wa_lines      like line of it_lines.
  data pattern_func type rs38l_fnam .
  data rep               type swbse_max_line_tab.
*--------------------------------------------------------------------*
  refresh: it_import, it_change, it_export,
           it_tables, it_except, it_param_docu, it_parametro_cant,
it_codigo, it_variables.
  clear:  it_ptfdir,
          it_ptftit,
          it_pfunct     ,
          it_penlfdir   ,
          it_ptrdir     ,
          it_pfupararef ,
          it_uincl      .
  clear: w_offset, w_max_offset.
  perform get_function_name changing w_funcname.
  perform fu_import_interface_ext(sapms38l)
                             tables it_import
                                    it_change
                                    it_export
                                    it_tables
                                    it_except
                                    it_param_docu
                              using w_funcname.
  refresh: it_ptfdir,   it_ptftit, it_pfunct,
           it_penlfdir, it_ptrdir, it_pfupararef,
           it_uincl.
  perform func_get_object using w_funcname
                       changing it_ptfdir
                                it_ptftit
                                it_pfunct
                                it_penlfdir
                                it_ptrdir
                                it_pfupararef
                                it_uincl.
  refresh it_parametro_cant.
  clear: w_offset, w_max_offset.
  perform get_max_longitud_fm_param    using c_tip_tables
                                    changing w_offset.
  w_max_offset = w_offset.
  clear w_offset.
  perform get_max_longitud_fm_param    using c_tip_export
                                    changing w_offset.
  if w_offset gt w_max_offset.
    w_max_offset = w_offset.
  endif.
  clear w_offset.
  perform get_max_longitud_fm_param    using c_tip_import
                                    changing w_offset.
  if w_offset gt w_max_offset.
    w_max_offset = w_offset.
  endif.
  perform generar_variables using 'I'.
  perform generar_variables using 'E'.
  perform generar_variables using 'T'.
  perform evitar_parametros_repetidos.
  perform codigo_declaracion_variable changing buffer[].
  perform generar_llamado_fm    using w_funcname
                             changing rep.
  field-symbols <fs_rep> like line of rep.
  data wa_buffer type string.
  loop at rep assigning <fs_rep>.
    wa_buffer = <fs_rep>.
    append wa_buffer to buffer.
  endloop.
endfunction.
*&-------------------------------------------------------------------
*&      Form  get_max_longitud_fm_param
*&-------------------------------------------------------------------
*       Obtiene la máxima longitud de los nombres de los parámetros.
*--------------------------------------------------------------------
*  -->  w_tipo_param        Tipo de parámetro
*  <--  w_length_o          Longitud máxima
*--------------------------------------------------------------------
form get_max_longitud_fm_param    using value(w_tipo_param) type c
                              changing value(w_length_o)   type i.
  data w_length    type i.
  data w_campo     type char30.
  data w_itab_name type char30.
  data wa_parametro_cant like line of it_parametro_cant.
  field-symbols <fs_fm_parameters>  type any table.
  field-symbols <fs>                type any.
  clear: w_itab_name, w_length_o.
  perform get_nombre_parametro using w_tipo_param
                            changing w_itab_name.
  assign (w_itab_name) to <fs_fm_parameters>.
  loop at <fs_fm_parameters> assigning <fs>.
    w_campo = '<fs>-parameter'.
    assign (w_campo) to <fs>.
    w_length = strlen( <fs> ).
    clear wa_parametro_cant.
    wa_parametro_cant-parameter = <fs>.
    wa_parametro_cant-cant      = 1.
    collect wa_parametro_cant into it_parametro_cant.
    check w_length > w_length_o.
    w_length_o = w_length.
  endloop.
  unassign: <fs_fm_parameters>, <fs>.
endform.                    " get_max_longitud_fm_param
*&---------------------------------------------------------------------
*&      Form  get_nombre_parametro
*&---------------------------------------------------------------------
*       Obtiene en nombre del parámetro
*----------------------------------------------------------------------
*  -->  w_tipo_param        (I)mport, (E)xport (T)ables
*  <--  w_itab_name         Nombre de tabla interna
*----------------------------------------------------------------------
form get_nombre_parametro using value(w_tipo_param) type c
                      changing value(w_itab_name)  type char30.
  case w_tipo_param.
    when c_tip_import. "Import
      w_itab_name = 'it_import'.
    when c_tip_export. "Export
      w_itab_name = 'it_export'.
    when c_tip_tables. "Tables
      w_itab_name = 'it_tables'.
  endcase.
endform.                    " get_nombre_parametro
*&---------------------------------------------------------------------
*&      Form  get_patron_para_declaracion
*&---------------------------------------------------------------------
*       text
*----------------------------------------------------------------------
*  -->  wa_fs_fm
*  -->  w_tipo_param        text
*  <--  w_var               text
*  <--  w_tipo_dato
*  <--  w_tipo_s
*----------------------------------------------------------------------
form get_patron_para_declaracion using value(wa_fs_fm)     type any
                                      value(w_tipo_param) type c
                             changing value(w_var)        type string
                                      value(w_tipo_dato)  type string
                                      value(w_tipo_s)     type char10.
  data w_campo type char30.
  field-symbols <fs> type any.
  if w_tipo_param eq 'T'.
    w_campo = 'wa_fs_fm-dbstruct'.
  else.
    w_campo = 'wa_fs_fm-dbfield'.
  endif.
  assign (w_campo) to <fs>.
  clear: w_var, w_tipo_dato. ", w_campo.
  case w_tipo_param.
    when c_tip_import. "Import
      w_var       = 'v_[NOMBRE]'.
      w_tipo_dato = '[TIPO]'.
      if <fs> is not initial.
        w_campo     = '<fs_fm>-dbfield'.
      elseif <fs> is initial.
        w_campo     = '<fs_fm>-typ'.
      endif.
    when c_tip_export. "Export
      w_var       = 'v_[NOMBRE]'.
      w_tipo_dato = '[TIPO]'.
      if <fs> is not initial.
        w_campo     = '<fs_fm>-dbfield'.
      elseif <fs> is initial.
        w_campo     = '<fs_fm>-typ'.
      endif.
    when c_tip_tables. "Tables
      w_var       = 'it_[NOMBRE]'.
      w_tipo_dato = 'STANDARD TABLE OF [TIPO]'.
      w_campo     = '<fs_fm>-dbstruct'.
  endcase.
  check <fs> is assigned.
  find '-' in <fs>. "Indica la referencia a un campo de una estructura
*el dic.datos
  if sy-subrc eq 0.
    w_tipo_s = 'LIKE'.
  else.
    w_tipo_s = 'TYPE'.
  endif.
  unassign <fs>.
endform.                    " get_patron_para_declaracion
*&---------------------------------------------------------------------*
*&      Form  GENERAR_LLAMADO_FM
*&---------------------------------------------------------------------*
*       Genera el código de llamado de la FM.
*       Nota: tomado del método standard METH_ED_GENERATE_CALL
*       de la clase CL_FB_FUNCTION_UTILITY.
*----------------------------------------------------------------------*
*  -->  funcname        Nombre de la función
*  <--  rep             Código
*----------------------------------------------------------------------*
form generar_llamado_fm    using value(funcname)  type rs38l_fnam
                       changing value(rep)       type
swbse_max_line_tab.
  data: begin of func,
            fu1  type c value '''',
            name type rs38l-name,
            fu2  type c value '''',
        end of func.
  data: begin of ip,
         ip1 type c value 'I',
         num(2),
        end of ip.
  data: begin of ep,
         ep1 type c value 'E',
         num(2),
        end of ep.
  data: begin of tp,
         tp1 type c value  'T',
         num(2),
        end of tp.
  data: incl           type rs38l-include,
        length         type i,
        lengt2         type i,
        max            type p,
        l_com_line     type i,
        l_lines        type i,
        mit_try_endtry type c,
        l_obli         type c.
  data  w_lengt_aux    type i.
  constants: type_ins type i value 2,
             parm_ins type i value 4.
  data: num type i.
  field-symbols <f> type any.
  field-symbols <fs_variables> like line of it_variables.
* E. Crasovan:  Work-area's  wg. OO definiert
  data w_enlfdir     type enlfdir.
  data w_p_if_import type rsimp.
  data w_p_if_export type rsexp.
  data w_p_if_change type rscha.
  data w_p_if_tables type rstbl.
  data w_p_if_except type rsexc.
  data w_rep         type swbse_max_line.
  data l_rseumod     type rseumod.
  data l_fbpattern   type fbpattern.
  field-symbols <fs_import> like line of it_import.  "I-RMP
  field-symbols <fs_change> like line of it_change.  "I-RMP
  field-symbols <fs_export> like line of it_export.  "I-RMP
  field-symbols <fs_tables> like line of it_tables.  "I-RMP
  field-symbols <fs_except> like line of it_except.  "I-RMP
*
  call function 'RS_WORKBENCH_CUSTOMIZING'
    exporting
      choice          = 'EW'
      suppress_dialog = 'X'
    importing
      setting         = l_rseumod.
* E. Crasovan: exten3 sagt aus ob der FB mit Exceptionklassen arbeitet
  clear l_fbpattern.
  move-corresponding l_rseumod to l_fbpattern.
  mit_try_endtry = l_fbpattern-with_try_endtry.
  select single exten3 from enlfdir into w_enlfdir-exten3
  where funcname = funcname.
* Die ganze Logik hier ist eigentlich die Form ed_generate_call_new
*
  clear length.
  loop at it_import assigning <fs_import>.
    lengt2 = strlen( <fs_import>-parameter ).
    if lengt2 gt length.
      length = lengt2.
    endif.
  endloop.
  loop at it_change assigning <fs_change>.
    lengt2 = strlen( w_p_if_change-parameter ).
    if lengt2 gt length.
      length = lengt2.
    endif.
  endloop.
  loop at it_export assigning <fs_export>.
    lengt2 = strlen( <fs_export>-parameter ).
    if lengt2 gt length.
      length = lengt2.
    endif.
  endloop.
  loop at it_tables assigning <fs_tables>.
    lengt2 = strlen( <fs_tables>-parameter ).
    if lengt2 gt length.
      length = lengt2.
    endif.
  endloop.
  loop at it_except assigning <fs_except>.
    lengt2 = strlen( <fs_except>-exception ).
    if lengt2 gt length.
      length = lengt2.
    endif.
  endloop.
  if length lt 7.
    length = 7.
  endif.
  lengt2 = length + 13.
  length = length + 11.
* E. Crasovan
* Wenn mit Exceptionklassen gearbeitet wird, soll der Aufruf des FB's
*n einem
* TRY ... ENDTRY Block eingeschlossen werden.
  clear: w_rep.
*
* Achtung, hier wird entschieden ob TRY...CATCH...ENTRY verwendet wird
*der nicht!!!
* Sollte TRY...ENTRY doch erscheinen, dann mit_try_endry auf NICHT
*INITIAL setzen.
  if not w_enlfdir-exten3 is initial.
    if not mit_try_endtry is initial.
      w_rep = 'TRY.'.
      append w_rep to rep.
      clear w_rep.
    endif.
  endif.
  w_rep = 'CALL FUNCTION'.
  func-name = funcname.
  condense func no-gaps.
  w_rep+20 = func.
  condense w_rep.
  append w_rep to rep. clear w_rep.
*
  clear: l_com_line.
  l_obli = 'X'.
  loop at it_import assigning <fs_import>.
    unpack sy-tabix to ep-num.
    if sy-tabix = 1.
      w_rep+type_ins = 'EXPORTING'.
      append w_rep to rep. clear w_rep.
      describe table rep lines l_com_line.
    endif.
    w_rep+parm_ins = <fs_import>-parameter.
    w_lengt_aux = 255 - length.              "I-RMP
*    ASSIGN w_rep+length(1) TO <f>.          "D-RMP
    assign w_rep+length(w_lengt_aux) to <f>. "I-RMP
    <f> = '='.
*   Inicio RMP
    read table it_variables assigning <fs_variables>
      with key tipo_var      = 'V'
               param_origina = <fs_import>-parameter
               in_out        = 'I'.
    if sy-subrc eq 0.
      concatenate '=' <fs_variables>-identificador
             into <f> separated by space.
    endif.
*   Fin    RMP
    if not <fs_import>-default is initial or
       not <fs_import>-optional is initial.
      assign w_rep(1) to <f>.
*      <f> = '"'. "D-RMP
      <f> = '*'. "I-RMP
      if not <fs_import>-default is initial.
        if <fs_import>-default = 'SPACE'.
          assign w_rep+lengt2(3) to <f>.
*          <f> = ''' '''. "D-RMP
        else.
          assign w_rep+lengt2(28) to <f>.
          <f> = <fs_import>-default.
        endif.
      else.
        if l_fbpattern-formal_eq_actual <> space.
          assign w_rep+lengt2(length) to <f>.
          <f> = <fs_import>-parameter.
        endif.
      endif.
      if l_obli = 'X'.
        clear l_obli.
      endif.
    else.
      if l_fbpattern-formal_eq_actual <> space.
        assign w_rep+lengt2(length) to <f>.
        <f> = <fs_import>-parameter.
      endif.
      l_obli = '1'.
    endif.
    append w_rep to rep. clear w_rep.
  endloop.
  if l_obli is initial.
    read table rep index l_com_line into w_rep.
    assign w_rep(1) to <f>.
*      <f> = '"'. "D-RMP
    <f> = '*'. "I-RMP
    modify rep from w_rep index l_com_line.
    clear w_rep.
  endif.
  loop at it_export assigning <fs_export>.
    if sy-tabix = 1.
      w_rep+type_ins = 'IMPORTING'.
      assign w_rep(1) to <f>.
*      <f> = '"'. "D-RMP
      <f> = '*'. "I-RMP
      append w_rep to rep. clear w_rep.
    endif.
    w_rep+parm_ins = <fs_export>-parameter.
    w_lengt_aux = 255 - length.              "I-RMP
*    ASSIGN w_rep+length(1) TO <f>.          "D-RMP
    assign w_rep+length(w_lengt_aux) to <f>. "I-RMP
    <f> = '='.
*   Inicio RMP
    read table it_variables assigning <fs_variables>
      with key tipo_var      = 'V'
               param_origina = <fs_export>-parameter
               in_out        = 'E'.
    if sy-subrc eq 0.
      concatenate '=' <fs_variables>-identificador
             into <f> separated by space.
    endif.
*   Fin    RMP
    if l_fbpattern-formal_eq_actual <> space.
      assign w_rep+lengt2(length) to <f>.
      <f> = <fs_export>-parameter.
    endif.
    assign w_rep(1) to <f>.
*      <f> = '"'. "D-RMP
    <f> = '*'. "I-RMP
    append w_rep to rep. clear w_rep.
  endloop.
*
  clear: l_com_line.
  l_obli = 'X'.
  loop at it_tables assigning <fs_tables>.
    if sy-tabix = 1.
      w_rep+type_ins = 'TABLES'.
      append w_rep to rep. clear w_rep.
      describe table rep lines l_com_line.
    endif.
    w_rep+parm_ins = <fs_tables>-parameter.
*    ASSIGN w_rep+length(1) TO <f>.          "D-RMP
    assign w_rep+length(w_lengt_aux) to <f>. "I-RMP
    <f> = '='.
*   Inicio RMP
    read table it_variables assigning <fs_variables>
      with key tipo_var      = 'V'
               param_origina = <fs_tables>-parameter
               in_out        = 'T'.
    if sy-subrc eq 0.
      concatenate '=' <fs_variables>-identificador
             into <f> separated by space.
    endif.
*   Fin    RMP
    if l_fbpattern-formal_eq_actual <> space.
      assign w_rep+lengt2(length) to <f>.
      <f> = <fs_tables>-parameter.
    endif.
    if not <fs_tables>-optional is initial.
*      w_rep(1) = '"'.   "D-RMP
      w_rep(1) = '*'.   "I-RMP
      if l_obli = 'X'.
        clear l_obli.
      endif.
    else.
      l_obli = '1'.
    endif.
    append w_rep to rep. clear w_rep.
  endloop.
  if l_obli is initial.
    read table rep index l_com_line into w_rep.
    assign w_rep(1) to <f>.
*      <f> = '"'. "D-RMP
    <f> = '*'. "I-RMP
    modify rep from w_rep index l_com_line.
    clear w_rep.
  endif.
*
  clear: l_com_line.
  l_obli = 'X'.
  loop at it_change assigning <fs_change>.
    unpack sy-tabix to ep-num.
    if sy-tabix = 1.
      w_rep+type_ins = 'CHANGING'.
      append w_rep to rep. clear w_rep.
      describe table rep lines l_com_line.
    endif.
    w_rep+parm_ins = <fs_change>-parameter.
    assign w_rep+length(1) to <f>.
    <f> = '='.
    if not <fs_change>-default is initial or
       not <fs_change>-optional is initial.
      assign w_rep(1) to <f>.
*      <f> = '"'. "D-RMP
      <f> = '*'. "I-RMP
      if not <fs_change>-default is initial.
        if <fs_change>-default = 'SPACE'.
          assign w_rep+lengt2(3) to <f>.
          <f> = ''' '''.
        else.
          assign w_rep+lengt2(28) to <f>.
          <f> = <fs_change>-default.
        endif.
      else.
        if l_fbpattern-formal_eq_actual <> space.
          assign w_rep+lengt2(length) to <f>.
          <f> = <fs_change>-parameter.
        endif.
      endif.
      if l_obli = 'X'.
        clear l_obli.
      endif.
    else.
      if l_fbpattern-formal_eq_actual <> space.
        assign w_rep+lengt2(length) to <f>.
        <f> = <fs_change>-parameter.
      endif.
      l_obli = '1'.
    endif.
    append w_rep to rep. clear w_rep.
  endloop.
  if l_obli is initial.
    read table rep index l_com_line into w_rep.
    assign w_rep(1) to <f>.
*      <f> = '"'. "D-RMP
    <f> = '*'. "I-RMP
    modify rep from w_rep index l_com_line.
    clear w_rep.
  endif.
*
* E. Crasovan
* Wenn mit Exceptionklassen gearbeitet wird, soll der Aufruf des FB's
*in einem
* TRY ... ENDTRY Block eingeschlossen werden.
*
*
  if not w_enlfdir-exten3 is initial.
    clear w_rep.
    w_rep+10 = '.'.
    append w_rep to rep.
*
    if not mit_try_endtry is initial.
      describe table it_except lines l_lines.
      if not l_lines is initial.
        loop at it_except assigning <fs_except>.
          concatenate 'CATCH*' <fs_except>-exception '.' into w_rep.
          w_rep+5(1) = space.
          append w_rep to rep.
          clear w_rep.
        endloop.
      endif.
*
      w_rep = 'ENDTRY.'.
      append w_rep to rep.
      clear w_rep.
    endif.
  else.
* dieser Teil kommt aus ed_generate_call_new
    describe table it_except lines l_lines.
    if not l_lines is initial.
*      w_rep = '"'.      "D-RMP
      w_rep = '*'.      "I-RMP
      w_rep+type_ins = 'EXCEPTIONS'.
      append w_rep to rep. clear w_rep.
      loop at it_except assigning <fs_except>.
        move sy-tabix to num.
        assign w_rep(1) to <f>.
*        <f> = '"'.       "D-RMP
        <f> = '*'.       "I-RMP
        w_rep+parm_ins = <fs_except>-exception.
        assign w_rep+length(1) to <f>.
        <f> = '='.
        assign w_rep+lengt2(2) to <f>.
        <f> = num.
        append w_rep to rep. clear w_rep.
      endloop.
      if l_fbpattern-exc_wo_others = space.
        num = num + 1.
*      w_rep = '"'.      "D-RMP
        w_rep = '*'.      "I-RMP
        w_rep+parm_ins = 'OTHERS'.
        assign w_rep+length(1) to <f>.
        <f> = '='.
        assign w_rep+lengt2(2) to <f>.
* Wegen zu starken Moserns der Anwendung wieder ausgebaut
*  if num = 1.
**   Keine Exception vorhanden, wegen des SLIN auf 0 abbilden.
*    num = 0.
*  endif.
        <f> = num.
        append w_rep to rep. clear w_rep.
      endif.
    endif.
    clear w_rep.
    w_rep+10 = '.'.
    append w_rep to rep.
*EC's
  endif.
endform.                    " GENERAR_LLAMADO_FM
*&---------------------------------------------------------------------*
*&      Form  GENERAR_VARIABLES
*&---------------------------------------------------------------------*
*       Genera las variables en base a los parámetros de la función
*----------------------------------------------------------------------*
*  -->  w_tipo_param       (I)mport, (E)xport (T)ables
*----------------------------------------------------------------------*
form generar_variables using value(w_tipo_param) type c.
  data w_itab_name  type char30.
  data w_var        type string.
  data w_tipo_dato  type string.
  data w_tipo_ref   type rs38l_typ.
  data w_campo      type char30.
  data w_tipo_s     type char10.
  data wa_variables like line of it_variables.
  field-symbols <fs_fm_parameters> type any table.
  field-symbols <fs>               type any.
  field-symbols <fs_fm>            type any.
  field-symbols <fs_pfupararef>    like line of it_pfupararef.
  clear w_itab_name.
  perform get_nombre_parametro using w_tipo_param
                            changing w_itab_name.
  assign (w_itab_name) to <fs_fm_parameters>.
  check <fs_fm_parameters> is assigned.
  loop at <fs_fm_parameters> assigning <fs_fm>.
    clear wa_variables.
    w_campo = '<fs_fm>-parameter'.
    assign (w_campo) to <fs>.
    perform get_patron_para_declaracion using <fs_fm>
                                              w_tipo_param
                                     changing w_var
                                              w_tipo_dato
                                              w_tipo_s.
    replace '[NOMBRE]' in w_var with <fs>.
    wa_variables-param_origina = <fs>.
    wa_variables-tipo_var      = 'V'.
    wa_variables-identificador = w_var.
    wa_variables-instancia     = w_tipo_s.
    read table it_pfupararef assigning <fs_pfupararef>
      with key parameter = <fs>
               paramtype = w_tipo_param.
    if sy-subrc eq 0.
      w_tipo_ref = <fs_pfupararef>-structure.
    endif.
    replace '[TIPO]'   in w_tipo_dato with w_tipo_ref.
    wa_variables-tipo_dato     = w_tipo_dato.
    wa_variables-in_out        = w_tipo_param.
    append wa_variables to it_variables.
  endloop.
endform.                    " GENERAR_VARIABLES
*&---------------------------------------------------------------------*
*&      Form  CODIGO_DECLARACION_VARIABLE
*&---------------------------------------------------------------------*
*       Genera el código acerca de la declaración de variables.
*----------------------------------------------------------------------*
form codigo_declaracion_variable changing buffer type  rswsourcet.
  data: wa_buffer type string.
  data w_line      type swbse_max_line.
  data w_line_aux  type swbse_max_line.
  field-symbols <fs_variables> like line of it_variables.
  loop at it_variables assigning <fs_variables>.
    w_line  = 'DATA [VAR]%[TYPE] [TIP_DATO].'.
    replace '[VAR]'      in w_line with <fs_variables>-identificador.
    if not <fs_variables>-tipo_dato is initial.
      replace '[TIP_DATO]' in w_line with <fs_variables>-tipo_dato.
    else.
      replace '[TIP_DATO]' in w_line with 'CHAR30'.
    endif.
    replace '[TYPE]'     in w_line with <fs_variables>-instancia.
    w_offset = w_max_offset + 9.
    split w_line at '%' into w_line w_line_aux.
    w_line+w_offset = w_line_aux.
    wa_buffer = w_line.
    append wa_buffer to buffer.
  endloop.
endform.                    " CODIGO_DECLARACION_VARIABLE
*&---------------------------------------------------------------------*
*&      Form  EVITAR_PARAMETROS_REPETIDOS
*&---------------------------------------------------------------------*
*       Evita los parámetros repetidos.
*----------------------------------------------------------------------*
form evitar_parametros_repetidos .
  data w_i type n.
  field-symbols <fs_parametro_cant> like line of it_parametro_cant.
  field-symbols <fs_variables>      like line of it_variables.
  w_i = 1.
  loop at it_parametro_cant assigning <fs_parametro_cant>
    where cant ge 2.
    w_i = w_i + 1.
    read table it_variables assigning <fs_variables>
    with key tipo_var      = 'V'
                   param_origina = <fs_parametro_cant>-parameter
                   in_out        = 'E'.
    if sy-subrc eq 0.
      concatenate <fs_variables>-identificador '_' w_i
             into <fs_variables>-identificador.
    endif.
    read table it_variables assigning <fs_variables>
    with key tipo_var      = 'V'
                   param_origina = <fs_parametro_cant>-parameter
                   in_out        = 'T'.
    if sy-subrc eq 0.
      concatenate <fs_variables>-identificador '_' w_i
             into <fs_variables>-identificador.
    endif.
  endloop.
endform.                    " EVITAR_PARAMETROS_REPETIDOS
*&---------------------------------------------------------------------*
*&      Form  FUNC_GET_OBJECT
*&---------------------------------------------------------------------*
*       FM: FUNC_GET_OBJECT
*----------------------------------------------------------------------*
*  -->  w_funcname        Nombre del módulo de función
*  <--  it_ptfdir
*  <--  it_ptftit
*  <--  it_pfunct
*  <--  it_penlfdir
*  <--  it_ptrdir
*  <--  it_pfupararef
*  <--  it_uincl
*----------------------------------------------------------------------*
form func_get_object using    value(w_funcname)    type rs38l_fnam
                    changing value(it_ptfdir)     type ty_tfdir
                             value(it_ptftit)     type ty_tftit
                             value(it_pfunct)     type ty_funct
                             value(it_penlfdir)   type ty_enlfdir
                             value(it_ptrdir)     type ty_trdir
                             value(it_pfupararef) type ty_fupararef
                             value(it_uincl)      type ty_abaptxt255.
  refresh: it_ptfdir,   it_ptftit, it_pfunct,
           it_penlfdir, it_ptrdir, it_pfupararef,
           it_uincl.
  check w_funcname is not initial.
  call function 'FUNC_GET_OBJECT'
    exporting
      funcname           = w_funcname
    tables
      ptfdir             = it_ptfdir
      ptftit             = it_ptftit
      pfunct             = it_pfunct
      penlfdir           = it_penlfdir
      ptrdir             = it_ptrdir
      pfupararef         = it_pfupararef
      uincl              = it_uincl
    exceptions
      function_not_exist = 1
      version_not_found  = 2
      others             = 3.
endform.                    " FUNC_GET_OBJECT
*&---------------------------------------------------------------------*
*&      Form  get_function_name
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->VALUE(W_FUNCNAME)  text
*----------------------------------------------------------------------*
form get_function_name  changing value(w_funcname)    type rs38l_fnam.
  data: begin of fields occurs 1.
          include structure sval.
  data: end of fields,
        returncode(1)       type c,
        popup_title(30)     type c.
*--------------------------------------------------------------------*
  popup_title       = 'Gimme the function ;-)'(100).
  clear fields.
  fields-tabname    = 'RS38L'.
  fields-fieldname  = 'NAME'.
  fields-field_obl  = 'X'.             "Muß-Feld
  append fields.
  call function 'POPUP_GET_VALUES_USER_HELP'
    exporting
      popup_title    = popup_title
      programname    = 'SAPLZSDN_FUNC'
      f4_programname = 'SAPLZSDN_FUNC'
      f4_formname    = 'HELP_REQUEST'
    importing
      returncode     = returncode
    tables
      fields         = fields.
  check returncode <> 'A'.
  read table fields index 1.
  w_funcname =  fields-value.
endform.                    "get_function_name
*&---------------------------------------------------------------------*
*&      Form  HELP_REQUEST
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->TABNAME    text
*      -->FIELDNAME  text
*      -->DISPLAY    text
*      -->RETURNCODE text
*      -->VALUE      text
*----------------------------------------------------------------------*
form help_request using      tabname fieldname display
                  changing   returncode value.
  data: field like dynpread-fieldname.
  field = 'SVALD-VALUE'.
  call function 'RS_HELP_HANDLING'
    exporting
      dynpfield                 = field
      dynpname                  = sy-dynnr
      object                    = 'FB'
      progname                  = 'SAPLSPO4'
      suppress_selection_screen = 'X'.
endform.                    "HELP_REQUEST

2.1.4 Create the Function module Z_FUNC_W_PARAMS_EDITOR_EXIT – SDN: Editor Exit for Calling Function Module

function z_func_w_params_editor_exit.
*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*"  TABLES
*"      BUFFER TYPE  RSWSOURCET
*"----------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& Function  Z_FUNC_W_PARAMS_EDITOR_EXIT
*& Author: Andrea Olivieri
*&         Techedge SpA
*& Version: 1.0  - 2010/11/02
*& Title   SDN: Start Function Module Pattern (with DATA)
*& Supported releases: SAP ECC 6.0
*&---------------------------------------------------------------------*
  call function 'Z_SDN_PATTERN_FUNC_START'
    tables
      buffer = buffer.
  endfunction.

2.1.5 Activate all the inactive objects.

2.2 Create a custom Pattern

Create a pattern in SE38 named Z_FUNC_W_PARAMS; from the ABAP editor menu choose: Utilities > More Utilities > Edit Pattern > Create Pattern

image

in the pattern editor type the magic word *$&$MUSTER and save it.

3. Pattern Call

Now  we can call the pattern  Z_FUNC_W_PARAMS directly from the ABAP editor using the function: Pattern> Other Patterns

image

Specify the function module name

image

Here we are…STOP CRYING, START LAUGHING.

Call.Pattern.Result.2.png

UPDATES

9-Nov-2010 FMDroid CodeExchange project born

1-Feb-2011 Latest release available to https://cw.sdn.sap.com/cw/groups/fmdroid?view=documents



To report this post you need to login first.

25 Comments

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

      1. Kesavadas Thekkillath
        Thanks to Andrea and Raul.

        I was wondering that how this would react to the import and export parameters which are of reference type.

        For ex: when we give functions like GUI_UPLOAD it just declares it like

        DATA it_DATA_TAB TYPE STANDARD TABLE OF.

        And for functions like CONVERT_TO_LOCAL_CURRENCY, it determines the Importing variables as character 30. I have to check it how it does 🙂

        But really i have to say … Its great 🙂 .. Thanks a ton 🙂

        (0) 
        1. Andrea Olivieri Post author
          Hi Keshav,
          thanks for the comment.

          Yes, the abap program by Raul is very powerful, and when the parameters are of reference type, it reacts in a smarty way.

          Andrea

          p.s.
          Why don’t you join us in codexchange?

          (0) 
  1. Gregor Wolf
    Hi Andrea,

    great that you make the next step for Raúl’s project. What do you think about creating it as a SAP Code Exchange project? Your colleague Ivan can help you there.

    Best regards
    Gregor

    (0) 
  2. Roel van den Berge
    Hi Andrea,

    I just tried it with FM CRM_ORDER_MAINTAIN and it works like a charm! This will save developers a lot of repetitive work! Will point some colleagues to this blog! 🙂

    Thanks for your contribution!

    Cheers, Roel

    (0) 
            1. Hart Liu
              Thank you very much Andrea and Raúl for sharing this great tool! It does save a lot of codings.

              We usually utilize the “call pattern” within a program which may have quite a few variables already defined. Using this tool in a separate session or via “call pattern”, it may generate some unwanted codes that need further “clean-up”. I think the following could be some potential enhancements that can be added to this tool to reduce “clean-up” efforts:

              1. Add one step to allow the user entering an existing variable name for each parameter so that no new variable will be generated for that/those parameters and existing variable(s) will be used instead.

              2. Any way to automatically search the embedding program and “suggest” variables that have been defined with the same data type?

              3. Similar to #2, any way to validate the entered variable names (after #1) against the corresponding parameters to make sure that they are of the same data type?

              #1 might be easier to implement, but #2/3 might be asking too much…

              Best regards,
              Hart

              (0) 
  3. Vinod Kumar
    Hi,
    Very useful developement. One suggestion, can’t we use the Class “CL_FB_FUNCTION_UTILITY”, method “METH_GET_INTERFACE” to get this information without much coding?

    Regards
    Vinod

    (0) 
    1. Andrea Olivieri Post author
      Hello Vinod,
      thanks for the suggestion.

      I will forward this information to Raul.

      Wouldn’t be better if you join the FMDroid project on Code Exchange?  😉

      Regards,
      Andrea

      (0) 
  4. Josh Stanton

    This is a nice custom pattern, congrats.

    However, I know a nice free tool that does more than this. It’s called Hovitaga Advanced Pattern… just google it. It is an enhancement of the standard pattern functionality… a popup window appears where you can customize your FM or OO method call and it can automatically declare your variables. Cool stuff. I like it very much.

    Here is a blog post about it:

    http://www.tricktresor.de/blog/hovitaga-advanced-pattern-enhancement/

    (0) 

Leave a Reply