СБИС Сапёр - Вызов из программ печати — различия между версиями

Материал из razgovorov.ru
Перейти к: навигация, поиск
Строка 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 мы либо печатаем, либо выходим из программы с правильным кодом возврата.
  
==Вызов из подпрограммы или BADI==
+
==Вызов из подпрограммы==
 
Особенности вызова из подпрограмм заключается в том, что дополнительно необходимо прервать несколько подпрограмм. Для этого признак делается глобальным и проверяется после выхода из подпрограмм непосредственно перед печатью.
 
Особенности вызова из подпрограмм заключается в том, что дополнительно необходимо прервать несколько подпрограмм. Для этого признак делается глобальным и проверяется после выхода из подпрограмм непосредственно перед печатью.
  
Строка 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

Общая концепция

Алгоритм формирования электронного документа следующий:

  1. программа печати рассчитывает данные необходимые для печати.
  2. перед вызовом формуляра управление передается в SBIS SAPPER. SAPPER проверяет кто инициатор вызова программы печати.
    1. Если это не SAPPER, то он возвращает управление программе печати (все как обычно).
    2. Если это 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.


Редактор smartforms


Пример кода:

* 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

Осуществляется в особенных случаях, когда в системе нет отдельной программы печати (например, в отраслевых решениях), или когда значительная часть логики перенесена в формуляр. Особенности вызова из формуляров - в необходимости прервать работу формуляра и корректно завершить основную программу после выхода из формуляра. Вставить вызов кода необходимо в интерфейсе формуляра в код инициализации или в подпрограмму, где есть доступ к подготовленным данным печати:

Редактор 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.