Call a function module in the ABAP Editor: Stop Crying – Start Laughing.
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
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
Specify the function module name
Here we are…STOP CRYING, START LAUGHING.
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
Raul is very good friend of mine, as we worked together on BizPartner when I was still living in Lima.
Love to see how the community works together -:)
Greetings,
Blag.
you're right, SCN was founded for this and I love it. 😉
Cheers,
Andrea
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 🙂
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?
halo Andrea,_EDITOR_EXIT' buffer is having values
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
certainly I'll follow your advice... and Ivan is a master of the code exchange.
Regards,
Andrea
You take the great work of Raul and give us a great tool!
See you on codexchange 😉
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
i'm starting to code a custom pattern in my dev system 🙂
keep in touch 4 codexchange.
Regards,
Andrea
it's the same for me.
Are you going to create the project?
We need a good name.. 😉
Andrea
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
Thank you for your comment.
I find your ideas very interesting, why don't try to help us joining the project FMDROID?
Andrea
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
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
are you aware of the fmdroid project on SAP Code Exchange where the work on this functionality is continued?
Best regards
Gregor
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/
Is the project still located anywhere now that Code Exchange is gone?