O maravilhoso mundo do Application Log
Uma boa parte dos reports, interfaces ou jobs, têm de produzir algum tipo de relatório. É normal ver isso feito recorrendo ao comando WRITE. Ora nos dias que correm, usar o comando WRITE para isto é como recorrer a um par de pedras para acender uma fogueira. Afinal, porque não usar o Application Log que é muito mais simples e prático e standard e é só vantagens?
O Application Log é um sistema standard do SAP para guardar logs aplicacionais e é usado por várias transacções standard. Ao utilizá-lo podemos simplificar e uniformizar os logs dos nossos programas. Vamos aprender aqui como é simples usá-lo nos nossos desenvolvimentos.
Como usar?
Durante a execução de um programa, vamos acumulando mensagens no log. No final podemos optar por apresentar as mensagens no ecrã e/ou gravá-las na base de dados para posterior consulta na SLG1. Há casos em que não faz sentido guardar para a posterioridade; outros há, como os jobs, em que não faz sentido apresentá-los no ecrã. Nota: caso o objectivo seja só apresentar o log no ecrã, não é necessário definir um objecto/sub-objecto.
Mas como usar??
Funciona assim:
-
Configurar o objecto e sub-objecto (na SLG0);
-
Inicializar log (definindo os seus objecto e sub-objecto);
-
Adicionar-lhe mensagens até que a voz nos doa;
-
Gravando-o na base de dados (para mais tarde recordar na SLG1);
-
Apresentar o log no ecrã.
Segue-se uma descrição detalhada de cada passo. No final do artigo deixo-vos o código de um grupo de funções Z feito por um amigo meu que simplifica ainda mais a utilização do Application Log.
0. Configurar na SLG0
A transacção SLG0 permite fazer a manutenção dos objectos e sub-objectos , os dois identificadores que servem para identificar os logs. Trolha que contém 2 interfaces e um job diário. Então na SLG0 pode definir-se o objecto ZTROLHA e debaixo destes um sub-objecto para cada um dos programas específicos: INTER1, INTER2, JOB1. O objecto tem de começar por Z ou Y; já os sub-objectos começam pelo que bem se entender.
1. Inicializar
A partir daqui vamos usar módulos de funções do grupo de funções SBAL. A função para inicializar o log é a BAL_LOG_CREATE. No entanto, esta inicialização só é necessária caso se deseje vir a guardar o log na base de dados. Se o objectivo for apenas apresentá-lo no ecrã este passo pode ser ignorado.
DATA: wa_log TYPE bal_s_log.
wa_log-object = object.
wa_log-subobject = subobject.
wa_log-alprog = sy-repid.
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = wa_log
IMPORTING
e_log_handle = log_handle
EXCEPTIONS
log_header_inconsistent = 1
OTHERS = 2.
2. Amealhar
A função BAL_LOG_MSG_ADD serve para adicionar mensagens ao log.
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = log_handle
i_s_msg = msg
EXCEPTIONS
log_not_found = 1
msg_inconsistent = 2
log_is_full = 3
OTHERS = 4.
3. Gravar
CALL FUNCTION 'BAL_DB_SAVE'
EXPORTING
i_t_log_handle = it_log_handle[]
EXCEPTIONS
log_not_found = 1
save_not_allowed = 2
numbering_error = 3
OTHERS = 4.
4. Apresentar no ecrã
CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
EXPORTING
* i_s_display_profile = display_profile
i_t_log_handle = it_log_handle[]
i_amodal = space
EXCEPTIONS
profile_inconsistent = 1
internal_error = 2
no_data_available = 3
no_authority = 4
OTHERS = 5.
Pronto. Simples, não?
Mas para ficar ainda mais simples, aqui fica um grupo de funções Z feito pelo meu amigo letão Reinis Dzenis que pode ser usado em vez do standard:
FUNCTION-POOL z_application_log. "MESSAGE-ID ..
CONSTANTS: object_zall TYPE balobj_d VALUE 'ZALL'.
* Global log handle
DATA: it_log_handle TYPE bal_t_logh,
log_handle TYPE balloghndl.
FUNCTION z_appl_log_initialize .
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" EXCEPTIONS
*" INIT_ERROR
*"--------------------------------------------------
DATA: wa_log TYPE bal_s_log.
* Initialize current log object
CLEAR: log_handle.
* Log object
IF object IS NOT INITIAL.
wa_log-object = object.
ELSE.
wa_log-object = object_zall.
ENDIF.
* Log subobject
wa_log-subobject = subobject.
* External ID
wa_log-extnumber = extnumber.
* Report
wa_log-alprog = repid.
* Initialize log
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = wa_log
IMPORTING
e_log_handle = log_handle
EXCEPTIONS
log_header_inconsistent = 1
OTHERS = 2.
IF sy-subrc <> 0.
RAISE init_error.
ENDIF.
* Collect log handles in table
INSERT log_handle INTO TABLE it_log_handle.
ENDFUNCTION.
FUNCTION z_appl_log_write.
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(MSG) TYPE BAL_S_MSG OPTIONAL
*" REFERENCE(MSG_TAB) TYPE BAL_T_MSG OPTIONAL
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID OPTIONAL
*" EXCEPTIONS
*" INIT_ERROR
*" WRITE_ERROR
*"--------------------------------------------------
FIELD-SYMBOLS: LIKE LINE OF msg_tab.
* Initialize log if needed
IF log_handle IS INITIAL.
CALL FUNCTION 'Z_APPL_LOG_INITIALIZE'
EXPORTING
object = object
subobject = subobject
extnumber = extnumber
repid = repid
EXCEPTIONS
init_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
RAISE init_error.
ENDIF.
ENDIF.
* Write passed message to log (if there is some...)
IF msg IS NOT INITIAL.
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = log_handle
i_s_msg = msg
EXCEPTIONS
log_not_found = 1
msg_inconsistent = 2
log_is_full = 3
OTHERS = 4.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDIF.
* Write passed table of messages to log (if there are some...)
LOOP AT msg_tab ASSIGNING .
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = log_handle
i_s_msg =
EXCEPTIONS
log_not_found = 1
msg_inconsistent = 2
log_is_full = 3
OTHERS = 4.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDLOOP.
ENDFUNCTION.
FUNCTION z_appl_log_write_msg_syst.
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" EXCEPTIONS
*" NO_SYST_MESSAGE
*" WRITE_ERROR
*"--------------------------------------------------
DATA: msg_type TYPE msgty,
msg_id TYPE msgid,
msg_no TYPE msgno.
* Check if SYST contains valid message
IF sy-msgty IS INITIAL OR
sy-msgid IS INITIAL.
RAISE no_syst_message.
ENDIF.
* Write Message to Log
CALL FUNCTION 'Z_APPL_LOG_WRITE_MSG'
EXPORTING
msg_type = sy-msgty
msg_id = sy-msgid
msg_no = sy-msgno
msg_v1 = sy-msgv1
msg_v2 = sy-msgv2
msg_v3 = sy-msgv3
msg_v4 = sy-msgv4
object = object
subobject = subobject
extnumber = extnumber
repid = repid
EXCEPTIONS
write_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDFUNCTION.
FUNCTION z_appl_log_from_bapiret.
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(BAPIRET2) TYPE BAPIRET2_T
*" CHANGING
*" REFERENCE(BAL_MSG_TAB) TYPE BAL_T_MSG
*"--------------------------------------------------
DATA: bal_msg LIKE LINE OF bal_msg_tab.
FIELD-SYMBOLS: LIKE LINE OF bapiret2.
LOOP AT bapiret2 ASSIGNING .
CLEAR: bal_msg.
* Save message via message class and no
IF -id IS NOT INITIAL.
bal_msg-msgty = -type.
bal_msg-msgid = -id.
bal_msg-msgno = -number.
bal_msg-msgv1 = -message_v1.
bal_msg-msgv2 = -message_v2.
bal_msg-msgv3 = -message_v3.
bal_msg-msgv4 = -message_v4.
INSERT bal_msg INTO TABLE bal_msg_tab.
* Save message as text
ELSEIF -message IS NOT INITIAL.
bal_msg-msgty = -type.
bal_msg-msgid = 'ZAPPLOG'.
bal_msg-msgno = '000'.
bal_msg-msgv1(50) = -message(50).
bal_msg-msgv2(50) = -message+50(50).
bal_msg-msgv3(50) = -message+100(50).
bal_msg-msgv4(50) = -message+150(50).
INSERT bal_msg INTO TABLE bal_msg_tab.
ENDIF.
ENDLOOP.
ENDFUNCTION.
FUNCTION z_appl_log_write_bapiret.
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(BAPIRET2) TYPE BAPIRET2_T
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" EXCEPTIONS
*" BAPIRET_INITIAL
*" WRITE_ERROR
*"--------------------------------------------------
DATA: bal_msg_tab TYPE bal_t_msg.
* See if valid BAPIRET was passed
IF bapiret2[] IS INITIAL.
RAISE bapiret_initial.
ENDIF.
* Create Application Log Message from BAPIRET
CALL FUNCTION 'Z_APPL_LOG_FROM_BAPIRET'
EXPORTING
bapiret2 = bapiret2[]
CHANGING
bal_msg_tab = bal_msg_tab[].
* Write Application Log Message
CALL FUNCTION 'Z_APPL_LOG_WRITE'
EXPORTING
msg_tab = bal_msg_tab[]
object = object
subobject = subobject
extnumber = extnumber
repid = repid
EXCEPTIONS
init_error = 1
write_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDFUNCTION.
FUNCTION z_appl_log_write_text.
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(MSG_TXT) TYPE CHAR200
*" REFERENCE(MSG_TYPE) TYPE MSGTY DEFAULT 'I'
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" EXCEPTIONS
*" WRITE_ERROR
*"--------------------------------------------------
DATA: msg TYPE bal_s_msg.
msg-msgty = msg_type.
msg-msgid = 'ZAPPLOG'.
msg-msgno = '000'.
msg-msgv1(50) = msg_txt(50).
msg-msgv2(50) = msg_txt+50(50).
msg-msgv3(50) = msg_txt+100(50).
msg-msgv4(50) = msg_txt+150(50).
CALL FUNCTION 'Z_APPL_LOG_WRITE'
EXPORTING
msg = msg
object = object
subobject = subobject
extnumber = extnumber
repid = repid
EXCEPTIONS
init_error = 1
write_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDFUNCTION.
FUNCTION Z_APPL_LOG_READ_FROM_DB .
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(EXTERNALID) TYPE BALNREXT
*" EXPORTING
*" REFERENCE(MSG_TAB) TYPE BAL_T_MSG
*"--------------------------------------------------
DATA: ls_bal_s_lfil TYPE bal_s_lfil,
ls_bal_s_extn TYPE bal_s_extn,
lt_msg_handle TYPE bal_t_msgh,
ls_msg_handle LIKE LINE OF lt_msg_handle,
ls_msg TYPE bal_s_msg,
l_line TYPE string,
lt_log_header TYPE balhdr_t.
* Configure filter with external id
ls_bal_s_extn-sign = 'I'.
ls_bal_s_extn-option = 'EQ'.
ls_bal_s_extn-low = externalid.
APPEND ls_bal_s_extn TO ls_bal_s_lfil-extnumber.
* The log is still in memory so we use
* this function to get message headers
CALL FUNCTION 'BAL_GLB_SEARCH_MSG'
EXPORTING
i_s_log_filter = ls_bal_s_lfil
IMPORTING
e_t_msg_handle = lt_msg_handle
EXCEPTIONS
msg_not_found = 1
OTHERS = 2.
IF sy-subrc NE 0.
CALL FUNCTION 'BAL_DB_SEARCH'
EXPORTING
i_s_log_filter = ls_bal_s_lfil
IMPORTING
e_t_log_header = lt_log_header
EXCEPTIONS
log_not_found = 1
no_filter_criteria = 2
OTHERS = 3.
CALL FUNCTION 'BAL_DB_LOAD'
EXPORTING
i_t_log_header = lt_log_header
IMPORTING
e_t_msg_handle = lt_msg_handle
EXCEPTIONS
no_logs_specified = 1
log_not_found = 2
log_already_loaded = 3
OTHERS = 4.
ENDIF.
* Get messages and write them to the log file
refresh msg_tab.
LOOP AT lt_msg_handle INTO ls_msg_handle.
CLEAR ls_msg.
CALL FUNCTION 'BAL_LOG_MSG_READ'
EXPORTING
i_s_msg_handle = ls_msg_handle
IMPORTING
e_s_msg = ls_msg
* E_EXISTS_ON_DB =
* E_TXT_MSGTY =
* E_TXT_MSGID =
* E_TXT_DETLEVEL =
* E_TXT_PROBCLASS =
* E_TXT_MSG =
* E_WARNING_TEXT_NOT_FOUND =
EXCEPTIONS
log_not_found = 1
msg_not_found = 2
OTHERS = 3.
append ls_msg to msg_tab.
ENDLOOP.
ENDFUNCTION.
FUNCTION z_appl_log_db_save .
*"--------------------------------------------------
*"*"Local interface:
*" EXCEPTIONS
*" LOG_NOT_INITIALIZED
*" DB_SAVE_ERROR
*"--------------------------------------------------
* See if log has been initialized
IF it_log_handle[] IS INITIAL.
RAISE log_not_initialized.
ENDIF.
* Try to save log to DB
CALL FUNCTION 'BAL_DB_SAVE'
EXPORTING
i_t_log_handle = it_log_handle[]
EXCEPTIONS
log_not_found = 1
save_not_allowed = 2
numbering_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
RAISE db_save_error.
ENDIF.
ENDFUNCTION.
FUNCTION z_appl_log_display.
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(MODE) TYPE NUM1 DEFAULT '0'
*" EXCEPTIONS
*" LOG_NOT_INITIALIZED
*" DISPLAY_ERROR
*"--------------------------------------------------
DATA: display_profile TYPE bal_s_prof.
* See if log has been initialized
IF it_log_handle[] IS INITIAL.
RAISE log_not_initialized.
ENDIF.
CASE mode.
WHEN '0'.
CALL FUNCTION 'BAL_DSP_PROFILE_STANDARD_GET'
IMPORTING
e_s_display_profile = display_profile.
WHEN '1'.
CALL FUNCTION 'BAL_DSP_PROFILE_NO_TREE_GET'
IMPORTING
e_s_display_profile = display_profile.
WHEN '2'.
CALL FUNCTION 'BAL_DSP_PROFILE_POPUP_GET'
IMPORTING
e_s_display_profile = display_profile.
WHEN '3'.
CALL FUNCTION 'BAL_DSP_PROFILE_SINGLE_LOG_GET'
IMPORTING
e_s_display_profile = display_profile.
WHEN OTHERS.
CALL FUNCTION 'BAL_DSP_PROFILE_STANDARD_GET'
IMPORTING
e_s_display_profile = display_profile.
ENDCASE.
* Display log
CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
EXPORTING
i_s_display_profile = display_profile
i_t_log_handle = it_log_handle[]
i_amodal = space
EXCEPTIONS
profile_inconsistent = 1
internal_error = 2
no_data_available = 3
no_authority = 4
OTHERS = 5.
IF sy-subrc <> 0.
RAISE display_error.
ENDIF.
ENDFUNCTION.
FUNCTION z_appl_log_clear.
*"--------------------------------------------------
*"*"Local interface:
*"--------------------------------------------------
FIELD-SYMBOLS: LIKE LINE OF it_log_handle.
* Remove all created logs
LOOP AT it_log_handle ASSIGNING .
CALL FUNCTION 'BAL_LOG_REFRESH'
EXPORTING
i_log_handle =
EXCEPTIONS
log_not_found = 1
OTHERS = 2.
ENDLOOP.
REFRESH: it_log_handle[].
CLEAR: log_handle.
ENDFUNCTION.
FUNCTION z_appl_log_get_handle.
*"--------------------------------------------------
*"*"Local interface:
*" EXPORTING
*" REFERENCE(E_LOG_HANDLE) TYPE BALLOGHNDL
*" REFERENCE(ET_LOG_HANDLE) TYPE BAL_T_LOGH
*" EXCEPTIONS
*" NO_HANDLE
*"--------------------------------------------------
* See if log is initialized
IF it_log_handle[] IS INITIAL AND log_handle IS INITIAL.
RAISE no_handle.
ENDIF.
e_log_handle = log_handle.
et_log_handle[] = it_log_handle[].
ENDFUNCTION.
FUNCTION z_appl_log_write_param.
*"--------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(PARAMETER)
*" REFERENCE(MSG_TYPE) TYPE MSGTY DEFAULT 'I'
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" EXCEPTIONS
*" WRITE_ERROR
*"--------------------------------------------------
DATA: msg_txt TYPE char200,
tmp TYPE string.
DATA: fieldname TYPE fieldname,
ddtext TYPE ddtext.
* Spell fieldname
CALL FUNCTION 'Z_SPELL_FIELDNAME'
EXPORTING
field = parameter
IMPORTING
ddtext = ddtext
fieldname = fieldname.
IF parameter IS INITIAL.
CONCATENATE: 'SELECTION:' ddtext 'is empty'
INTO msg_txt SEPARATED BY space.
ELSE.
WRITE: parameter TO msg_txt.
SHIFT msg_txt LEFT DELETING LEADING space.
CONCATENATE: 'SELECTION:' ddtext 'is equal to' msg_txt
INTO msg_txt SEPARATED BY space.
ENDIF.
* Write to log...
CALL FUNCTION 'Z_APPL_LOG_WRITE_TEXT'
EXPORTING
msg_txt = msg_txt
msg_type = msg_type
object = object
subobject = subobject
extnumber = extnumber
repid = repid
EXCEPTIONS
write_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDFUNCTION.
Paldies Reinis!
O Abapinho saúda-vos.
Actualização: aqui fica o código dos módulos de função em falta:
FUNCTION z_appl_log_initialize .
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" REFERENCE(UNAME) TYPE SY-UNAME DEFAULT SY-UNAME
*" EXCEPTIONS
*" INIT_ERROR
*"----------------------------------------------------------------------
DATA: wa_log TYPE bal_s_log.
* Initialize current log object
CLEAR: log_handle.
* Log object
IF object IS NOT INITIAL.
wa_log-object = object.
ELSE.
wa_log-object = object_zall.
ENDIF.
* Log subobject
wa_log-subobject = subobject.
* External ID
wa_log-extnumber = extnumber.
* Report
wa_log-alprog = repid.
* User name
wa_log-aluser = uname.
* Initialize log
CALL FUNCTION 'BAL_LOG_CREATE'
EXPORTING
i_s_log = wa_log
IMPORTING
e_log_handle = log_handle
EXCEPTIONS
log_header_inconsistent = 1
OTHERS = 2.
IF sy-subrc <> 0.
RAISE init_error.
ENDIF.
* Collect log handles in table
INSERT log_handle INTO TABLE it_log_handle.
ENDFUNCTION.
FUNCTION z_appl_log_write.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(MSG) TYPE BAL_S_MSG OPTIONAL
*" REFERENCE(MSG_TAB) TYPE BAL_T_MSG OPTIONAL
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" REFERENCE(UNAME) TYPE SY-UNAME DEFAULT SY-UNAME
*" EXCEPTIONS
*" INIT_ERROR
*" WRITE_ERROR
*"----------------------------------------------------------------------
FIELD-SYMBOLS: <msg> LIKE LINE OF msg_tab.
* Initialize log if needed
IF log_handle IS INITIAL.
CALL FUNCTION 'Z_APPL_LOG_INITIALIZE'
EXPORTING
object = object
subobject = subobject
extnumber = extnumber
repid = repid
uname = uname
EXCEPTIONS
init_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
RAISE init_error.
ENDIF.
ENDIF.
* Write passed message to log (if there is some...)
IF msg IS NOT INITIAL.
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = log_handle
i_s_msg = msg
EXCEPTIONS
log_not_found = 1
msg_inconsistent = 2
log_is_full = 3
OTHERS = 4.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDIF.
* Write passed table of messages to log (if there are some...)
LOOP AT msg_tab ASSIGNING <msg>.
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
i_log_handle = log_handle
i_s_msg = <msg>
EXCEPTIONS
log_not_found = 1
msg_inconsistent = 2
log_is_full = 3
OTHERS = 4.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDLOOP.
ENDFUNCTION.
FUNCTION z_appl_log_write_msg.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(MSG_TYPE) DEFAULT 'I'
*" REFERENCE(MSG_ID)
*" REFERENCE(MSG_NO)
*" REFERENCE(MSG_V1) OPTIONAL
*" REFERENCE(MSG_V2) OPTIONAL
*" REFERENCE(MSG_V3) OPTIONAL
*" REFERENCE(MSG_V4) OPTIONAL
*" REFERENCE(OBJECT) TYPE BALOBJ_D OPTIONAL
*" REFERENCE(SUBOBJECT) TYPE BALSUBOBJ OPTIONAL
*" REFERENCE(EXTNUMBER) TYPE BALNREXT OPTIONAL
*" REFERENCE(REPID) TYPE SY-REPID DEFAULT SY-CPROG
*" REFERENCE(UNAME) TYPE SY-UNAME DEFAULT SY-UNAME
*" EXCEPTIONS
*" WRITE_ERROR
*"----------------------------------------------------------------------
DATA: msg TYPE bal_s_msg.
msg-msgty = msg_type.
msg-msgid = msg_id.
msg-msgno = msg_no.
WRITE: msg_v1 TO msg-msgv1.
SHIFT msg-msgv1 RIGHT DELETING TRAILING space.
SHIFT msg-msgv1 LEFT DELETING LEADING space.
WRITE: msg_v2 TO msg-msgv2.
SHIFT msg-msgv2 RIGHT DELETING TRAILING space.
SHIFT msg-msgv2 LEFT DELETING LEADING space.
WRITE: msg_v3 TO msg-msgv3.
SHIFT msg-msgv3 RIGHT DELETING TRAILING space.
SHIFT msg-msgv3 LEFT DELETING LEADING space.
WRITE: msg_v4 TO msg-msgv4.
SHIFT msg-msgv4 RIGHT DELETING TRAILING space.
SHIFT msg-msgv4 LEFT DELETING LEADING space.
CALL FUNCTION 'Z_APPL_LOG_WRITE'
EXPORTING
msg = msg
object = object
subobject = subobject
extnumber = extnumber
repid = repid
uname = uname
EXCEPTIONS
init_error = 1
write_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
RAISE write_error.
ENDIF.
ENDFUNCTION.
FUNCTION Z_SPELL_FIELDNAME .
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(FIELD)
*" EXPORTING
*" REFERENCE(DDTEXT) TYPE DDTEXT
*" REFERENCE(FIELDNAME) TYPE FIELDNAME
*"----------------------------------------------------------------------
DATA: type_ref TYPE REF TO cl_abap_typedescr.
DATA: langu LIKE sy-langu.
* Get current data element decription
type_ref ?= cl_abap_typedescr=>describe_by_data( field ).
fieldname = type_ref->get_relative_name( ).
DO 2 TIMES.
CASE sy-index.
WHEN 1.
langu = sy-langu.
WHEN 2.
langu = 'E'.
ENDCASE.
SELECT SINGLE dd04t~ddtext FROM dd04t
INTO ddtext
WHERE dd04t~rollname = fieldname AND
dd04t~ddlanguage = langu AND
as4local = 'A'.
IF sy-subrc = 0 OR langu = 'E'.
EXIT.
ENDIF.
ENDDO.
IF ddtext IS INITIAL.
ddtext = fieldname.
ENDIF.
ENDFUNCTION.