СБИС Сапёр - Вызов из программ печати — различия между версиями
Строка 60: | Строка 60: | ||
ev_prog_name = lv_cur_prog | ev_prog_name = lv_cur_prog | ||
ev_form_name = lv_cur_form. | ev_form_name = lv_cur_form. | ||
+ | " exception проходит через прогр печати без текста! | ||
FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core. | FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core. | ||
ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>. | ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>. | ||
Строка 83: | Строка 84: | ||
Т.о. в зависимости от флага lv_not_print мы либо печатаем, либо выходим из программы с правильным кодом возврата. | Т.о. в зависимости от флага lv_not_print мы либо печатаем, либо выходим из программы с правильным кодом возврата. | ||
− | ==Вызов из подпрограммы | + | ==Вызов из подпрограммы== |
Особенности вызова из подпрограмм заключается в том, что дополнительно необходимо прервать несколько подпрограмм. Для этого признак делается глобальным и проверяется после выхода из подпрограмм непосредственно перед печатью. | Особенности вызова из подпрограмм заключается в том, что дополнительно необходимо прервать несколько подпрограмм. Для этого признак делается глобальным и проверяется после выхода из подпрограмм непосредственно перед печатью. | ||
Строка 116: | Строка 117: | ||
ENDTRY. | ENDTRY. | ||
ENDFORM. | ENDFORM. | ||
+ | </source> | ||
+ | |||
+ | |||
+ | ==Вызов из BADI== | ||
+ | <source> | ||
+ | METHOD j_3r_torg12_badi_interface~doc_details. | ||
+ | |||
+ | ** I_VBDKL TYPE VBDKL | ||
+ | ** T_VBDPL TYPE EHS_VBDPL_T | ||
+ | ** EDITABLE TYPE XFELD | ||
+ | ** HDOC TYPE J_3RV_HT12 | ||
+ | ** ITEMS TYPE J_3RV_TT12 | ||
+ | |||
+ | ************************************************************** | ||
+ | * TENSOR SBIS EDO * | ||
+ | ************************************************************** | ||
+ | DATA lv_prog_and_field TYPE char255. | ||
+ | TRY. | ||
+ | *" получить NAST | ||
+ | "имя программы берем из инишки сверху | ||
+ | FIELD-SYMBOLS: <lfs_prog_name> TYPE char40. | ||
+ | ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GV_PROG_NAME') TO <lfs_prog_name>. | ||
+ | IF <lfs_prog_name> IS ASSIGNED. | ||
+ | |||
+ | lv_prog_and_field = `(` && <lfs_prog_name> && `)` && 'NAST'. | ||
+ | FIELD-SYMBOLS: <lfs_nast> TYPE nast. | ||
+ | * ASSIGN ('(J_3RV_DELIV_PDF)NAST') TO <lfs_nast>. | ||
+ | ASSIGN (lv_prog_and_field) TO <lfs_nast>. | ||
+ | IF <lfs_nast> IS ASSIGNED. | ||
+ | *" MAPPING | ||
+ | DATA cx_root TYPE REF TO cx_root. | ||
+ | DATA cl_mapping TYPE REF TO /sbis/cl_mapping. | ||
+ | CREATE OBJECT cl_mapping. | ||
+ | CALL METHOD cl_mapping->calc_doc | ||
+ | EXPORTING | ||
+ | is_nast = <lfs_nast> | ||
+ | IMPORTING | ||
+ | ev_not_print = gv_not_print. | ||
+ | ELSE. | ||
+ | "нет такой переменной - исключение! | ||
+ | RAISE EXCEPTION TYPE /sbis/cx_core | ||
+ | EXPORTING | ||
+ | textid = /sbis/cx_core=>/sbis/cx_core | ||
+ | lv_error_msg_ext = `Variable not assigned: '` | ||
+ | && lv_prog_and_field && `'` | ||
+ | lv_error_msg_detail = ''. | ||
+ | ENDIF. " IF <lfs_nast> IS ASSIGNED. | ||
+ | |||
+ | *" EXIT FROM PRINT PROGRAM | ||
+ | IF NOT gv_not_print IS INITIAL. | ||
+ | lv_prog_and_field = `(` && <lfs_prog_name> && `)` && 'VBDKL'. | ||
+ | FIELD-SYMBOLS: <lfs_vbdkl> TYPE vbdkl. | ||
+ | "ASSIGN ('(J_3RV_DELIV_PDF)VBDKL') TO <lfs_vbdkl>. | ||
+ | ASSIGN (lv_prog_and_field) TO <lfs_vbdkl>. | ||
+ | IF <lfs_vbdkl> IS ASSIGNED. | ||
+ | CLEAR <lfs_vbdkl>-vbeln. " хитрый способ выйти из прогр J_3RV_DELIV_PDF | ||
+ | ELSE. | ||
+ | "если в логике программы что-то поменялось - исключение! | ||
+ | RAISE EXCEPTION TYPE /sbis/cx_core | ||
+ | EXPORTING | ||
+ | textid = /sbis/cx_core=>/sbis/cx_core | ||
+ | lv_error_msg_ext = `Variable not assigned: '` | ||
+ | && lv_prog_and_field && `'` | ||
+ | lv_error_msg_detail = ''. | ||
+ | ENDIF. " IF <lfs_vbdkl> IS ASSIGNED. | ||
+ | ENDIF. | ||
+ | ENDIF. " IF <lfs_prog_name> IS ASSIGNED. | ||
+ | |||
+ | CATCH /sbis/cx_core INTO cx_core. | ||
+ | DATA lv_cur_prog TYPE char255. | ||
+ | DATA lv_cur_form TYPE char255. | ||
+ | CALL METHOD /sbis/cl_core=>get_current_progname | ||
+ | IMPORTING | ||
+ | ev_prog_name = lv_cur_prog | ||
+ | ev_form_name = lv_cur_form. | ||
+ | " exception проходит через прогр печати без текста! | ||
+ | " а без exception нельзя - прогр печати печатает дальше. | ||
+ | " Передадим только текст через assign!!! а уже потом exception без текста. | ||
+ | FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core. | ||
+ | ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>. | ||
+ | IF <fs_exc> IS ASSIGNED. | ||
+ | <fs_exc>-error_msg_ext = cx_core->lv_error_msg_ext. | ||
+ | <fs_exc>-error_msg_detail = cx_core->lv_error_msg_detail | ||
+ | && ` <= ` && lv_cur_prog && `->` && lv_cur_form. | ||
+ | ENDIF. | ||
+ | RAISE EXCEPTION TYPE /sbis/cx_core | ||
+ | EXPORTING | ||
+ | textid = cx_core->textid | ||
+ | lv_error_msg_ext = cx_core->lv_error_msg_ext | ||
+ | lv_error_msg_detail = cx_core->lv_error_msg_detail | ||
+ | && ` <= ` && lv_cur_prog && `->` && lv_cur_form. | ||
+ | ENDTRY. | ||
+ | ENDMETHOD. | ||
</source> | </source> | ||
Версия 08:23, 9 октября 2017
Содержание
Общая концепция
Алгоритм формирования электронного документа следующий:
- программа печати рассчитывает данные необходимые для печати.
- перед вызовом формуляра управление передается в SBIS SAPPER. SAPPER проверяет кто инициатор вызова программы печати.
- Если это не SAPPER, то он возвращает управление программе печати (все как обычно).
- Если это SAPPER, то он по настройкам маппинга из таблицы /SBIS/SETTINGS получает данные из подготовленных программой печати. На основе этих данных формирует XML файл. По окончании возвращает флаг, сигнализирующий о необходимости прервать программу печати.
Стандартные программы печати
Сначала запускается подпрограмма ENTRY. Это оболочка для подпрограммы PROCESSING, передает код возврата, в ней изменения не понадобятся:
FORM entry USING return_code us_screen. "#EC CALLED
CLEAR retcode.
xscreen = us_screen.
PERFORM processing USING us_screen.
IF retcode NE 0.
return_code = 1.
ELSE.
return_code = 0.
ENDIF.
CLEAR status.
ENDFORM.
Вызов непосредственно печати обычно находится в теле подпрограммы PROCESSING.
FORM processing USING proc_screen.
PERFORM get_data.
PERFORM print_form.
ENDFORM.
Поэтому до вызова печати (PRINT_FORM) необходимо вставить СБИС-код формирования электронных документов.
Получаем следующее:
FORM processing USING proc_screen.
PERFORM get_data.
* "TENSOR SBIS EDO
TRY.
DATA lv_not_print TYPE c VALUE ''.
DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
CREATE OBJECT cl_mapping.
CALL METHOD cl_mapping->calc_doc
EXPORTING
is_nast = nast
IMPORTING
ev_not_print = lv_not_print.
IF lv_not_print = 'X'.
EXIT.
ENDIF.
DATA cx_core TYPE REF TO /sbis/cx_core.
CATCH /sbis/cx_core INTO cx_core.
DATA lv_cur_prog TYPE char255.
DATA lv_cur_form TYPE char255.
CALL METHOD /sbis/cl_core=>get_current_progname
IMPORTING
ev_prog_name = lv_cur_prog
ev_form_name = lv_cur_form.
" exception проходит через прогр печати без текста!
FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core.
ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>.
IF <fs_exc> IS ASSIGNED.
<fs_exc>-error_msg_ext = cx_core->lv_error_msg_ext.
<fs_exc>-error_msg_detail = cx_core->lv_error_msg_detail
&& ` <= ` && lv_cur_prog && `->` && lv_cur_form.
ENDIF.
RAISE EXCEPTION TYPE /sbis/cx_core
EXPORTING
textid = cx_core->textid
lv_error_msg_ext = cx_core->lv_error_msg_ext
lv_error_msg_detail = cx_core->lv_error_msg_detail
&& ` <= ` && lv_cur_prog && `->` && lv_cur_form.
ENDTRY.
PERFORM print_form.
ENDFORM.
Т.о. в зависимости от флага lv_not_print мы либо печатаем, либо выходим из программы с правильным кодом возврата.
Вызов из подпрограммы
Особенности вызова из подпрограмм заключается в том, что дополнительно необходимо прервать несколько подпрограмм. Для этого признак делается глобальным и проверяется после выхода из подпрограмм непосредственно перед печатью.
Пример кода:
DATA gv_not_print TYPE c . " TENSOR SBIS EDO
FORM processing USING proc_screen.
PERFORM checks.
PERFORM init_data.
PERFORM get_data.
PERFORM sbis_edi. " TENSOR SBIS EDO
CHECK gv_not_print IS INITIAL. " TENSOR SBIS EDO
PERFORM print.
ENDFORM.
FORM sbis_edi .
* TENSOR SBIS EDO
TRY.
DATA cx_root TYPE REF TO cx_root.
DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
CREATE OBJECT cl_mapping.
CALL METHOD cl_mapping->calc_doc
EXPORTING
is_nast = nast
IMPORTING
ev_not_print = gv_not_print.
CATCH cx_root INTO cx_root.
* your code...
ENDTRY.
ENDFORM.
Вызов из BADI
METHOD j_3r_torg12_badi_interface~doc_details.
** I_VBDKL TYPE VBDKL
** T_VBDPL TYPE EHS_VBDPL_T
** EDITABLE TYPE XFELD
** HDOC TYPE J_3RV_HT12
** ITEMS TYPE J_3RV_TT12
**************************************************************
* TENSOR SBIS EDO *
**************************************************************
DATA lv_prog_and_field TYPE char255.
TRY.
*" получить NAST
"имя программы берем из инишки сверху
FIELD-SYMBOLS: <lfs_prog_name> TYPE char40.
ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GV_PROG_NAME') TO <lfs_prog_name>.
IF <lfs_prog_name> IS ASSIGNED.
lv_prog_and_field = `(` && <lfs_prog_name> && `)` && 'NAST'.
FIELD-SYMBOLS: <lfs_nast> TYPE nast.
* ASSIGN ('(J_3RV_DELIV_PDF)NAST') TO <lfs_nast>.
ASSIGN (lv_prog_and_field) TO <lfs_nast>.
IF <lfs_nast> IS ASSIGNED.
*" MAPPING
DATA cx_root TYPE REF TO cx_root.
DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
CREATE OBJECT cl_mapping.
CALL METHOD cl_mapping->calc_doc
EXPORTING
is_nast = <lfs_nast>
IMPORTING
ev_not_print = gv_not_print.
ELSE.
"нет такой переменной - исключение!
RAISE EXCEPTION TYPE /sbis/cx_core
EXPORTING
textid = /sbis/cx_core=>/sbis/cx_core
lv_error_msg_ext = `Variable not assigned: '`
&& lv_prog_and_field && `'`
lv_error_msg_detail = ''.
ENDIF. " IF <lfs_nast> IS ASSIGNED.
*" EXIT FROM PRINT PROGRAM
IF NOT gv_not_print IS INITIAL.
lv_prog_and_field = `(` && <lfs_prog_name> && `)` && 'VBDKL'.
FIELD-SYMBOLS: <lfs_vbdkl> TYPE vbdkl.
"ASSIGN ('(J_3RV_DELIV_PDF)VBDKL') TO <lfs_vbdkl>.
ASSIGN (lv_prog_and_field) TO <lfs_vbdkl>.
IF <lfs_vbdkl> IS ASSIGNED.
CLEAR <lfs_vbdkl>-vbeln. " хитрый способ выйти из прогр J_3RV_DELIV_PDF
ELSE.
"если в логике программы что-то поменялось - исключение!
RAISE EXCEPTION TYPE /sbis/cx_core
EXPORTING
textid = /sbis/cx_core=>/sbis/cx_core
lv_error_msg_ext = `Variable not assigned: '`
&& lv_prog_and_field && `'`
lv_error_msg_detail = ''.
ENDIF. " IF <lfs_vbdkl> IS ASSIGNED.
ENDIF.
ENDIF. " IF <lfs_prog_name> IS ASSIGNED.
CATCH /sbis/cx_core INTO cx_core.
DATA lv_cur_prog TYPE char255.
DATA lv_cur_form TYPE char255.
CALL METHOD /sbis/cl_core=>get_current_progname
IMPORTING
ev_prog_name = lv_cur_prog
ev_form_name = lv_cur_form.
" exception проходит через прогр печати без текста!
" а без exception нельзя - прогр печати печатает дальше.
" Передадим только текст через assign!!! а уже потом exception без текста.
FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core.
ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>.
IF <fs_exc> IS ASSIGNED.
<fs_exc>-error_msg_ext = cx_core->lv_error_msg_ext.
<fs_exc>-error_msg_detail = cx_core->lv_error_msg_detail
&& ` <= ` && lv_cur_prog && `->` && lv_cur_form.
ENDIF.
RAISE EXCEPTION TYPE /sbis/cx_core
EXPORTING
textid = cx_core->textid
lv_error_msg_ext = cx_core->lv_error_msg_ext
lv_error_msg_detail = cx_core->lv_error_msg_detail
&& ` <= ` && lv_cur_prog && `->` && lv_cur_form.
ENDTRY.
ENDMETHOD.
Вызов из формуляра SMARTFORM
Осуществляется в особенных случаях, когда в системе нет отдельной программы печати (например, в отраслевых решениях), или когда значительная часть логики перенесена в формуляр. Особенности вызова из формуляров - в необходимости прервать работу формуляра и корректно завершить основную программу после выхода из формуляра. Также необходимо чтобы данные формуляра, которые передаются в Сапер, были объявлены глобально. Вставить вызов кода необходимо в элемент смартформы "строки программы", где есть доступ к подготовленным данным печати. Например, в основной цикл по позициям. В инициализацию вставлять не имеет смысла - там нет доступа через assign к глобальным переменным формуляра, а также не обеспечивается корректный выход из формуляра/ФМ с rc=0.
Пример кода:
* TENSOR SBIS EDO
TRY.
DATA cx_root TYPE REF TO cx_root.
DATA lv_not_print TYPE c VALUE ''.
DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
CREATE OBJECT cl_mapping.
CALL METHOD cl_mapping->calc_doc_efg
EXPORTING
iv_ini_name = 'ZSF_ISU_INVOICE'
IMPORTING
ev_not_print = lv_not_print.
IF lv_not_print = 'X'.
* Set error message
CALL FUNCTION 'SSFRT_WRITE_ERROR'
EXPORTING
i_msgid = '00'
i_msgno = '208'
i_msgv1 = 'SBIS: not print'.
* Raise the excption
user_exception user_canceled.
ENDIF.
CATCH cx_root INTO cx_root.
ENDTRY.
Как правило, программа печати не требует изменений и сама формирует необходимый код возврата.
Вызов из формуляра PDF
Осуществляется в особенных случаях, когда в системе нет отдельной программы печати (например, в отраслевых решениях), или когда значительная часть логики перенесена в формуляр. Особенности вызова из формуляров - в необходимости прервать работу формуляра и корректно завершить основную программу после выхода из формуляра. Вставить вызов кода необходимо в интерфейсе формуляра в код инициализации или в подпрограмму, где есть доступ к подготовленным данным печати:
Пример кода:
**************************************************************
* TENSOR SBIS EDO *
**************************************************************
TRY.
DATA cx_root TYPE REF TO cx_root.
DATA lv_not_print TYPE c VALUE ''.
DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
CREATE OBJECT cl_mapping.
CALL METHOD cl_mapping->calc_doc
exporting
iv_ini_name = 'DP_TOVTORGPR_1175010' "
IMPORTING
ev_not_print = lv_not_print.
IF lv_not_print = 'X'.
return.
MESSAGE ID 'SU' TYPE '-' NUMBER 000 WITH 'SBIS_COMPLETE'
RAISING usage_error.
ENDIF.
CATCH cx_root INTO cx_root.
ENDTRY.
В программе печати необходимо предусмотреть корректный выход с правильным кодом возврата.
Пример кода:
CALL FUNCTION func_module_name
EXPORTING
/1bcdwb/docparams = fp_docparams
h_item = items
h_header = h_doc
IMPORTING
/1bcdwb/formoutput = ls_formoutput
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3.
**************************************************************
* TENSOR SBIS EDO - BEGIN *
**************************************************************
IF sy-subrc <> 0 AND sy-msgv1 = 'SBIS_COMPLETE'.
sy-subrc = 0.
CALL FUNCTION 'FPCOMP_FORM_END'
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
ELSEIF sy-subrc <> 0.
**************************************************************
* TENSOR SBIS EDO - END *
**************************************************************
retcode = sy-subrc.
PERFORM protocol_update.
MESSAGE e073 INTO gv_dummy.
PERFORM protocol_update.
ENDIF.