Remote Function Call (RFC, удалённый вызов функций) – стандартный интерфейс для обмена данными между SAP и не SAP системами. Интерфейс передачи данных основан на CPI-C или TCP/IP. Стандартная справка по теме RFC или курс BC415.
Особенности RFC функций
- Когда вы вызываете ФМ локально, он работает в том же рабочем процессе что и вызывающая программа. Если вы вызываете ФМ удаленно, он запускается в отдельном рабочем процессе (ЛЕР – LUW, логическая единица работы) если удаленная система является R/3 системой.
- В качестве удаленной системы могут быть R/3 система, R/2 система или другая внешняя не SAP система, для не SAP систем существует специальная RFC-SDK библиотека, с помощью которой может быть реализован клиент-сервер для RFC.
- При вызове RFC модуля, в программе его вызывающий срабатывает неявный DB Commit (исключение tRFC, qRFC, bgRFC). Поэтому вызовы RFC не должны находиться между OpenSQL операторами.
- В интерфейсе ФМ RFC необходимо явно определять тип для каждого параметра, ссылки (LIKE) запрещены.
Настроить назначение для RFC вызова можно через транзакцию SM59 (Таблица RFCDES). Подробнее о настройке RFC соединений можно посмотреть в курсе BC415.
Назначение RFC вызовов
Назначение RFC вызова определяется с помощью ключевого слова DESTINATION. В качестве параметра может принимать имя удаленной системы, SPACE, NONE, BACK.
- SPACE – локальный вызов ФМ (по умолчанию). В случае если не указать DESTINATION в параметрах вызова RFC, функция будет выполнена локально, как обычная без создания своего LUW.
- NONE – Запуск происходит так же локально, основное отличие в том, что вызов доходит до указанного в настройках шлюза и регистрируется в качестве удаленного вызова. Создается свой DB LUW.
- BACK – используется внутри синхронных RFC функций, для запуска RFC функций в той системе которая их вызвала.
Обработка исключений при вызовах RFC
При вызове RFC модуля могут возникать следующие исключения:
- COMMUNICATION_FAILURE – возникает в том случае, когда не настроено соединение для указанной системы в поле DESTINATION, либо когда соединение не могло быть установлено.
- SYSTEM_FAILURE – возникает в случае, если на удаленной системе не существует вызываемого модуля, либо в случае других неполадок в RFC вызовах.
- RESOURCE_FAILURE – возникает при вызове асинхронных RFC, в случае если нет свободных ресурсов на сервере приложений группы.
Типы RFC функций:
- Синхронные RFC (sRFC) – при вызове sRFC рабочий процесс приостанавливает свою работу, до тех пор, пока не будет выполнен sRFC модуль. Модуль выполняется в отдельном DB LUW.
В случае, когда вы вызываете несколько sRFC подряд из одной группы функций, глобальные данные группы функций будут доступны до тех пор, пока не будет вызвана последняя функция из данной группы.
Если в sRFC внутри себя вызывает CALL SCREEN, CALL TRANSACTION или отображение списка, вызываемые экраны будут отображены в программе запустившей sRFC, но только если в SM59 указан диалоговый удаленный доступ, иначе система выдаст исключение SYSTEM_FAILURE.
- Асинхронные RFC вызовы (aRFC) – удаленная функция начинает работать параллельно сразу после её вызова, при этом рабочий процесс не приостанавливает свою работу. Асинхронный вызов срабатывает при вызове ФМ с ключевыми словами: STARTING NEW TASK <ИмяЗадачи>. Модуль выполняется в отдельном DB LUW. aRFC можно так же использовать в фоновом выполнении.
Для получения результатов работы aRFC необходимо при вызове указать на процедуру обработки результатов, задается она с помощью ключевого слова: PERFORMING <ИмяПроцедуры> ON END OF TASK. Процедура в качестве первого параметра должна содержать переменную, в которую будет записано имя задачи (имя данной переменной не имеет значения). Для получения данных из aRFC, внутри данной процедуры, используется обязательная команда (если ее не задать в процедуре, система выдаст исключение — COMMUNICATION_FAILURE): RECEIVE RESULTS FROM FUNCTION <ИмяARFC>, c параметрами IMPORTING, TABLES, EXCEPTIONS которые будут переданы из aRFC.
Процедура не должна иметь в своем теле операторы, прерывающие выполнение программы, такие как: CALL SCREEN, SUBMIT, COMMIT WORK, WAIT, RFC вызовы, сообщения с типами W и I.
Для ожидания выполнения aRFC вызовов существует ключевое слово WAIT UNTIL <Условие>. Если после вызова aRFC условие выполняется, программа сразу же начинает свое выполнение после WAIT UNTIL. В случае если не выполняется, программа снова проверяет условие. Данный процесс повторяется до тех пор, пока условие не будет выполнено или не будут выполнены все aRFC вызовы.
Пример программы запускающей 2 aRFC функции и ожидающей выполнение обоих:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
REPORT zaRFC_demo. DATA: lv_flag1, lv_flag2. CALL FUNCTION 'Z_PAR_TEST' STARTING NEW TASK 'TASK1' PERFORMING receive_results_from_rfc ON END OF TASK EXPORTING COUNT = 2. CALL FUNCTION 'Z_PAR_TEST' STARTING NEW TASK 'TASK2' PERFORMING receive_results_from_rfc ON END OF TASK EXPORTING COUNT = 2. WAIT UNTIL lv_flag1 = abap_true AND lv_flag2 = abap_true. IF sy-subrc = 0. WRITE 'Все aRFC выполнены успешно'. ELSE. WRITE 'Все aRFC закончены, однако условие не выполнено'. ENDIF. FORM receive_results_from_rfc USING taskname. CASE taskname. WHEN 'TASK1'. lv_flag1 = abap_true. WHEN 'TASK2'. lv_flag2 = abap_true. ENDCASE. " Обязательно необходимо вызвать получение результата работы aRFC RECEIVE RESULTS FROM FUNCTION 'Z_PAR_TEST'. ENDFORM. FUNCTION Z_PAR_TEST. *"---------------------------------------------------------------------- *"*"Локальный интерфейс: *" IMPORTING *" VALUE(COUNT) TYPE I *" EXPORTING *" VALUE(INDEX) TYPE I *"---------------------------------------------------------------------- DATA: tmp TYPE float. DO 5000000 TIMES. tmp = tmp * 2. " Умножение 0 на 2 очень длительная операция ;) ENDDO. INDEX = tmp. ENDFUNCTION. |
Если в качестве имени задачи в вызове aRFC указать TASK3, условия выполнены не будут.
aRFC вызовы могут вызываться в одной SAP системе, но на разных серверах приложений, тем самым распределяя нагрузку между ними. Для распределения aRFC вызовов между серверами приложений служат так называемые RFC группы (тр. SM59). Для определения в какой именно группе вызывать aRFC служит ключевое слово – DESTINATION IN GROUP <ИмяГруппы>. Если в качестве имени группы указать DEFAULT, вызов будет происходить на любой из определенных групп, в зависимости от их загруженности, если все группы будут заняты, система выдаст исключение – RESOURCE_FAILURE.
SAP Help на тему распараллеливания.
Пример распараллеливания вычислений с помощью групп:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
REPORT ztst_call_async_rfc. PARAMETERS: p_para TYPE char1 DEFAULT 'X' AS CHECKBOX. TYPES: BEGIN OF t_tasklist, taskname(4) TYPE C, " Задача RESULT TYPE char50, " Статус обработки END OF t_tasklist. DATA: lv_calls TYPE I VALUE 10, " Количество запусков функции lv_max_tasks TYPE I, " Переменная для хранения максимального числа задач lv_free_tasks TYPE I, " Переменная для хранения числа свободных задач lv_number_of_tasks_in_use TYPE I, " Количество задач в работе lv_started_rfc_calls TYPE I VALUE 0, " Кол-во запущенных задач lv_finished_rfc_calls TYPE I VALUE 0, " Кол-во завершенных задач lv_exception_flag(1) TYPE C, " Флаг ошибки запуска задачи из-за нехватки ресурсов lv_taskname(4) TYPE N VALUE '0001', " Имя задачи lt_tasklist TYPE TABLE OF t_tasklist. " Журнал обработки RFC вызовов. DATA: " Для обработки времени работы lv_start_time TYPE timestampl, lv_end_time TYPE timestampl, lv_diff TYPE timestampl. FIELD-SYMBOLS: <fs_tasklist> TYPE t_tasklist. START-OF-SELECTION. IF p_para EQ 'X'. GET TIME STAMP FIELD lv_start_time. * Получение максимального числа задач и кол-во свободных для использования задач. CALL FUNCTION 'SPBT_INITIALIZE' EXPORTING group_name = '' IMPORTING max_pbt_wps = lv_max_tasks free_pbt_wps = lv_free_tasks EXCEPTIONS invalid_group_name = 1 internal_error = 2 pbt_env_already_initialized = 3 currently_no_resources_avail = 4 no_pbt_resources_found = 5 cant_init_different_pbt_groups = 6 OTHERS = 7. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ELSE. WRITE : / 'Макисмальное число задач для выполнения параллельно обработки: ', 80 lv_max_tasks RIGHT-JUSTIFIED. WRITE : / 'Доступное кол-во задач: ', 50 lv_free_tasks RIGHT-JUSTIFIED. ULINE. DO lv_calls TIMES. PERFORM call_rfc. " Запуск RFC задачи " call_rfc - запускает на выполнение RFC функцию в отдельном задаче (асинхронно), " в случае если нет свободных задач, или произошла ошибка выделения задачи, " ожидает пока не завершаться предыдущие задачи, после завершения продолжает данный цикл. ENDDO. " Последняя задержка пока не отработают все "последние" задачи. WAIT UNTIL lv_finished_rfc_calls = lv_calls. SKIP 2. WRITE : / 'Журнал работы RFC функций:'. ULINE. LOOP AT lt_tasklist ASSIGNING <fs_tasklist>. WRITE : / <fs_tasklist>-taskname, <fs_tasklist>-RESULT. ENDLOOP. SKIP. GET TIME STAMP FIELD lv_end_time. lv_diff = lv_end_time - lv_start_time. WRITE: /(50) 'Время работы', lv_diff. ENDIF. ELSE. GET TIME STAMP FIELD lv_start_time. " Запуск функции в последовательной обработке DO lv_calls TIMES. CALL FUNCTION 'Z_PAR_TEST' EXPORTING COUNT = 2 EXCEPTIONS OTHERS = 99. ENDDO. GET TIME STAMP FIELD lv_end_time. lv_diff = lv_end_time - lv_start_time. WRITE: /(50) 'Время работы', lv_diff. ENDIF. *&---------------------------------------------------------------------* *& Form call_rfc *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* FORM call_rfc. ADD 1 TO lv_number_of_tasks_in_use. * Внимание: количество свободных задач для параллельной обработки делится между всеми * пользователями, крайне не желательно использовать все (lv_free_tasks) для расчётов, * их количество настраивается в тр. RZ12. В случае если все свободные задачи заняты кем * то, программа выдаст сообщение об ошибке (Нехватке ресурсов ПФЗ), после вызова SPBT_INITIALIZE " Если количество процессов в работе будет превышать кол-во свободных задач, " остановим программу на ожидание освобождения задач. IF lv_number_of_tasks_in_use > lv_free_tasks. WRITE : / 'Ожидаем пока завершатся предыдущие задачи'. WAIT UNTIL lv_number_of_tasks_in_use < lv_free_tasks. ENDIF. CALL FUNCTION 'Z_PAR_TEST' STARTING NEW TASK lv_taskname "DESTINATION IN GROUP DEFAULT PERFORMING receive_results_from_rfc ON END OF TASK EXPORTING COUNT = 2 * Так как используется асинхронный вызов RFC параметры импорта здесь не указываются, * результат работы будет получаен в форме receive... EXCEPTIONS communication_failure = 1 system_failure = 2 resource_failure = 3. * Чтобы узнать на каком сервере приложений будет запущена задача, необходимо сразу после запуска * воспользоваться ФМ - SPBT_GET_PP_DESTINATION * Чтобы исключить выполнение задачи на полученном сервере приложений используется ФМ: SPBT_DO_NOT_USE_SERVER * * Администрирование групп параллельной обработки выполняется через транзакцию - RZ12 * Мануал по этому делу тут: http://help.sap.com/saphelp_nw04/helpdata/en/fa/096e92543b11d1898e0000e8322d00/frameset.htm * Пример обработки: ** 1 - system crash occured on the receiving side ** 2 - connection or communication problem with RFC-Destination * CALL FUNCTION 'SPBT_GET_PP_DESTINATION' * IMPORTING rfcdest = lf_rfcdest. * * CALL FUNCTION 'SPBT_DO_NOT_USE_SERVER' * EXPORTING server_name = lf_server * EXCEPTIONS * invalid_server_name = 1 * no_more_resources_left = 2 * pbt_env_not_initialized_yet = 3 * OTHERS = 4. * IF sy-subrc <> 0. * cf_task_failure = chars. "e-message -> missing log * EXIT. * ENDIF. CASE sy-subrc. WHEN 0. WRITE : / 'Запущена новая задача с именем: ', lv_taskname. APPEND INITIAL LINE TO lt_tasklist ASSIGNING <fs_tasklist>. <fs_tasklist>-taskname = lv_taskname. lv_started_rfc_calls = lv_started_rfc_calls + 1. ADD 1 TO lv_taskname. WHEN 1 OR 2. "Communications failure * Означает что сервер приложений не доступен; нет необходимости обрабатывать данное исключение, WHEN 3. " Нет свободных задач, ожидаем. IF lv_exception_flag = SPACE. lv_exception_flag = 'X'. WRITE : / 'Нет доступных задач ждем пока освободятся...'. WAIT UNTIL lv_finished_rfc_calls >= lv_started_rfc_calls. ELSE. WRITE : / 'Повторное ожидание освобождения задач...'. WAIT UNTIL lv_finished_rfc_calls >= lv_started_rfc_calls. IF sy-subrc = 0. " Ожидание было успешным CLEAR lv_exception_flag. ELSE. " Ожидание прервано, сбой в RFC вызове, прерывание обработки WRITE : / 'RFC вызов прерван'. EXIT. ENDIF. ENDIF. ENDCASE. ENDFORM. "call_rfc *&---------------------------------------------------------------------* *& Form receive_results_from_rfc *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->VALUE(P_TASKNAME) text *----------------------------------------------------------------------* FORM receive_results_from_rfc USING VALUE(p_taskname). lv_number_of_tasks_in_use = lv_number_of_tasks_in_use - 1. * Обновить статус задачи READ TABLE lt_tasklist WITH KEY taskname = p_taskname ASSIGNING <fs_tasklist>. IF sy-subrc = 0. <fs_tasklist>-RESULT = 'Задача успешно завершена'. ELSE. READ TABLE lt_tasklist WITH KEY taskname = lv_taskname ASSIGNING <fs_tasklist>. IF sy-subrc = 0. <fs_tasklist>-RESULT = 'Ошибка в обработке задачи'. ENDIF. ENDIF. * Получение результатов обработки функции, в данном случае ничего не получаем RECEIVE RESULTS FROM FUNCTION 'Z_PAR_TEST'. lv_finished_rfc_calls = lv_finished_rfc_calls + 1. ENDFORM. "RECEIVE_RESULTS_FROM_RFC |
aRFC вызовы так же как и sRFC могут вызывать внутри себя диалоги, но их использование в данном контексте выглядит сомнительно, более подробно рассмотрено в курсе (BC415).
- Транзакционные RFC (tRFC) – асинхронные и синхронные вызовы RFC отрабатывают каждый в своем DB LUW (ЛЕР), транзакционные RFC срабатывают в одном DB LUW, тем самым позволяют группировать их вызовы с возможностью отката в случае ошибок в одном из tRFC вызове. Запуск tRFC осуществляется с помощью ключевого слова IN BACKGROUND TASK. Программа, запустившая tRFC, не приостанавливает свою работу, вызов tRFC происходит тогда, когда программа вызовет COMMIT WORK. В момент вызова tRFC не происходит вызова неявного DB COMMIT. tRFC, так же как и aRFC вызываются асинхронно, однако получить результат работы этих функций как в aRFC невозможно. Для просмотра созданных tRFC-LUW служит транзакция SM58.
Все tRFC вызовы сохраняются в таблицах: ARFCSSTATE и ARFCSDATA. Если вы не хотите вызывать tRFC немедленно после COMMIT WORK, вы можете вызвать ФМ START_OF_BACKGROUNDTASK (до COMMITWORK) и задать время и дату запуска для накопленных tRFC вызовов.
После выполнения COMMIT WORK в случае успешного локального обновления (в рамках LUW основной программы), накопленные данные создают фоновую задачу, в случае успешного выполнения этой задачи все данные из таблиц tRFC удаляются. Если задача не была выполнена, срабатывает механизм повтора или отката.
Так, например если связь с удаленной системой не была установлена, срабатывает автоматический повтор выполнения задания. По умолчанию количество повторов равно 30, интервал ожидания равен 15 минутам.
В случае если во втором из двух tRFC вызовов произошел сбой, сообщение с типом A или X или вызов исключения через RAISE после успешного выполнения первого происходит следующее:
- Все изменения сделанные в текущем LUW (а он один на все tRFC) откатываются
- Происходит запись в журнал вызова tRFC (тр. SM58)
Для принудительного отката всех изменений или отмены tRFC-LUW служит ФМ — RESTART_OF_BACKGROUNDTASK.
В случае если вызовы tRFC происходят на разных системах (DESTINATION ‘A’, DESTIONATION ‘B’), для каждой из них создается свой tRFC-LUW, вызовы tRFC группируются в зависимости от назначения.
Для вызова tRFC отдельно от остальных можно воспользоваться ключевым словом: AS SEPARATE UNIT.
Каждый tRFC-LUW имеет свой уникальный ID, для его получения можно использовать ФМ: ID_OF_BACKGROUNDTASK (вызывать перед COMMIT WORK). Используя данный ID можно определить статус для tRFC-LUW через ФМ — STATUS_OF_BACKGROUNDTASK.
- qRFC – RFC функции выполняемые в порядке очереди. При использовании tRFC мы не можем контролировать порядок запуска tRFC модулей, другими словами порядок их вызова может не соответствовать порядку их запуска. qRFC в отличие от tRFC, позволяют нам контролировать порядок их запуска.
Для размещения tRFC вызовов в порядке FIFO (первый пришел, первый вышел) необходимо перед каждым tRFC вызовом указывать имя очереди, делается это с помощью ФМ: TRFC_SET_QUEUE_NAME:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
CALL FUNCTION 'TRFC_SET_QUEUE_NAME' EXPORTING qname = 'Q1'. CALL FUNCTION 'A1' IN BACKGROUND TASK. CALL FUNCTION 'TRFC_SET_QUEUE_NAME' EXPORTING qname = 'Q1'. CALL FUNCTION 'A2' IN BACKGROUND TASK. COMMIT WORK. CALL FUNCTION 'TRFC_SET_QUEUE_NAME' EXPORTING qname = 'Q1'. CALL FUNCTION 'B1' IN BACKGROUND TASK. CALL FUNCTION 'TRFC_SET_QUEUE_NAME' EXPORTING qname = 'Q1'. CALL FUNCTION 'B2' IN BACKGROUND TASK. |
Имя очереди может содержать 24 символа, исключая % и *.
Для администрирования qRFC вместо транзакции SM58 используется транзакция — SMQ1. Таблица, в которой хранятся данные qRFC — TRFCQOUT.
- Фоновые RFC (bgRFC). SAP рекомендует использовать их вместо tRFC и qRFC для лучшей производительности. bgRFC, в отличие от tRFC и qRFC, позволяют приложениям записывать данные полученные позже от вызванных программ. Кроме того можно организовывать зависимые последовательности вызовов, так например вызов создающий входящую поставку будет выполнен только после выполнения вызова создающего закупочный заказ. bgRFC вызываются с помощью ключевого слова IN BACKGROUND UNIT <oref>, где <oref> — ссылка на класс реализующий интерфейс IF_BGRFC_UNIT.
Более подробная информация о bgRFC находится тут.
Транзакции, используемые при работе с RFC
- ST22 – просмотр дампов, вызываемых RFC
- SMGW – монитор шлюза RFC подключений
- Журналы работы: на стороне вызовов – ST05, на стороне вызываемой системы SM59, на стороне шлюза – SMGW
BAPI функции
Для обмена бизнес данными, между SAP и не SAP системами, был создан так называемый Business Framework. Центральной его частью является хранилище бизнес объектов (BOR – Business Object Repository). Каждый бизнес объект обеспечивает объектно-ориентированный подход к хранению бизнес данных и работы с бизнес процессами. Например, вызывая методы бизнес объектов, мы тем самым манипулируем бизнес данными, за которые он отвечает, не заботясь о техническом вопросе (связях в таблицах и т.п.)
Бизнес объект состоит из следующих частей:
- Технические данные – внутренний номер, номер релиза SAP системы, с которой он доступен и т.п.
- Список интерфейсов, которые поддерживает объект – интерфейс определяет поведенческую структуру объекта
- Ключевые поля – атрибуты, которые однозначно идентифицируют объект. (Номер закупочного заказа)
- Атрибуты – могут быть как поля из базы данных, так и рассчитываемые во время работы с объектом (виртуальные), ссылки на другие объекты (Бизнес объект «Заказ на закупку» например, может иметь ссылки на объекты входящих поставок)
- Методы – представляют собой вызовы R/3 транзакций, функциональных модулей или другого ABAP кода. BAPI как раз и представляют собой реализацию методов бизнес объектов.
- События – используются в основном в Workflow. Например, сделать рассылку поставщикам при создании закупочного заказа.
BAPI – реализация метода бизнес объекта, представляет собой функциональный модуль RFC. BAPI могут вызываться как синхронно (COMMIT WORK AND WAIT), так и асинхронно т.е. ожидая выполнения работы функции или нет.
BAPI могут представлять различные действия над объектом:
- Создание объекта
- Запрос атрибутов объекта
- Изменение атрибутов объекта
BAPI могут вызываться из различных приложений: офисных приложений (через VBA), JAVA и С++ программ и т.п.
Все BAPI после своей работы возвращают результат в виде внутренней таблицы с одной из структур: BAPIRETURN, BAPIRETURN1, BAPIRET1, BAPIRET2, BAPIRET1_FIX. В связи с этим в BAPI нет обработки исключений как в стандартных ФМ. Все эти структуры содержат в себе следующие поля:
- TYPE – тип сообщения: S(uccess), E(rror), W(arning), I(nformation)
- ID (класс сообщений)
- NUMBER (номер сообщения в классе)
- MESSAGE (текст сообщения)
- MESSAGE_V1, MESSAGE_V2, MESSAGE_V3, MESSAGE_V4 (переменные сообщений)
Если транзакция выполнена успешно, то в таблице RETURN не будет существовать записей с типом ошибки «Е». Должно присутствовать сообщение с типом ошибки «S».
Обновление в BAPI всегда происходит в IN UPDATE TASK (см. документацию по ключевому слову IN UPDATE TASK или курс по обновлению БД – BC414). Внутри BAPI никогда не вызывается COMMIT WORK. Для подтверждения или отката LUW всегда должны использоваться ФМ: BAPI_TRANSCATION_COMMIT, BAPI_TRANSACTION_ROLLBACK, разница между данными ФМ и COMMIT WORK (ROLLBACK WORK) в том что они чистят внутренние переменные используемые при вызовах BAPI, если этого не делать могут возникать проблемы при повторном вызове BAPI. Все BAPI вызванные в программе до вызова BAPI_TRANSCATION_COMMIT (BAPI_TRANSCATION_ROLLBACK) вызываются в одном LUW. Для просмотра всех имеющихся в системе BAPI служит транзакция BAPI (запускает BAPI EXPLORER).
Курс, в котором рассматривается создание собственных BAPI — BC417.
Благодарю, Михаил!
Очень хорошо все расписано. Мне очень нравится читать Ваш блог, что-то узнаю новое, что-то вспоминаю. Так держать, успехов во всем!
Спасибо!
Присоединяюсь — потрясающий блог! Много полезной новой информации, доступно и понятно изложено всё!
Спасибо!!!
Спасибо большое, Михаил!
Грамотно и доходчиво, подкреплено примерами! После прочтения Ваших статей вопросов не возникает, разве что сам невнимательно прочел. Удачи!
Добрый день.
По поводу отсутствия COMMIT’а в BAPI: COMMIT_CONTROL = ‘E’ не считается за COMMIT?
Добрый день.
Честно говоря не знаю о чём Вы, видимо это специфика каких-то конкретных BAPI.