EDUCAÇÃO E TECNOLOGIA

Use the Custom ABAP Operator to call Customer code in ABAP system

このブログではSAP Data Intelligenceに接続されているSAP ABAPシステム間で、SAP Data Intelligenceパイプラインを用いたSAP ABAPシステムのデータ相互連携、並びにABAPシステム内で実装されたカスタマコード(汎用モジュール・BAPIなど)を呼び出す方法を紹介したいと思います。

システムに必要なバージョン:SAP S/4HANA 1909およびSAP S/4HANA CE 1911では、ABAPパイプラインエンジンが標準機能に含まれています。 古いリリース(SAP NetWeaver 7.0以降)の場合、ABAPパイプラインエンジンを取得するには、DMISアドオン(DMIS 2018SP02以降またはDMIS2011 SP17以降)をインストールする必要があります。

Custom ABAP OperatorではRFCを経由してABAPシステムで実装した拡張実装BAdIを呼び出し、データの連携を実現しております。拡張実装BAdI内ではカスタマコードを実装することが可能で、こちらの機能を利用する事によりデータの取得、データに更新及びBAPIなどを実行することが可能です。

実装に必要な手順は以下となります。

  • SAP Data Intelligenceから接続設定
      1. SAP Data IntelligenceのConnection ManagementでSAP S/4HANAとの接続設定を行います。
      2. SAP Data IntelligenceのLaunchpadで、Connection Managementを選択し、ボタン(+)をクリックします。
      3. 下記のように接続先SAP S/4HANAのホスト名などを設定し、ボタン(SAVE)を押します。
  • ABAPシステム側BAdI実装( こちらでは2種類のBAdI実装方法を紹介させて頂きます。)
    • レポートを実行する
      • この方法で作成されたBAdIでは基本パラメータやロジックが自動で実装されているため、マニュアルで設定が必要な作業を削減できます。
      1. トランザクションコードse38でレポートDHAPE_CREATE_OPERATOR_CLASS を実行し、クラスを作成します。
      2. その後、トランザクションコードse38でレポートDHAPE_CREATE_OPER_BADI_IMPL を実行し、BAdIを拡張します。
  • SAP Data Intelligence側のパイプラインを作成

    SAP Data Intelligence側のCustom ABAP Operatorのinport/outportを作成します。

    Connection Managementで設定した接続をABAP Connectionに設定し、ABAP Operatorの検索ヘルプを選択すると、使用可能なSAP ABAP システムのOperatorが表示されます。

こちらではSAP Data IntelligenceからABAP側のBAPIを使用し、受注伝票の受注数量を変更します。

全体的な流れでは、SAP Data Intelligence上に存在するファイル内で更新したい伝票番号と明細、及び変更したい数量が含まれます。

そのデータをABAP側に渡して数量の更新を行います。更新のステータス及び更新後の受注伝票のデータをSAP Data Intelligence側に返してSAP Data Intelligence側のファイルを格納します。

  • ファイル内容:
    • 0000000022/000010/450
  • サンプルコード:ローカルクラスの内容(カスタマコード)
    • CLASS lcl_process DEFINITION INHERITING FROM cl_dhape_graph_proc_abstract. PUBLIC SECTION. METHODS: if_dhape_graph_process~on_start REDEFINITION. METHODS: if_dhape_graph_process~on_resume REDEFINITION. METHODS: if_dhape_graph_process~step REDEFINITION. DATA: mo_util TYPE REF TO cl_dhape_util_factory, mo_in TYPE REF TO if_dhape_graph_channel_reader, mo_out TYPE REF TO if_dhape_graph_channel_writer. ENDCLASS. CLASS lcl_process IMPLEMENTATION. METHOD if_dhape_graph_process~on_start.
      * mo_out->write_copy( 'abap operator 処理起動' ) . "This method is called when the graph is submitted. "Note that you can only check things here but you cannot initialize variables. ENDMETHOD. METHOD if_dhape_graph_process~on_resume. "This method is called before the graph is started. "Read parameters from the config here
      * mv_myparameter = to_upper( if_dhape_graph_process~get_conf_value( '/Config/myparameter' ) ). "Do initialization here. mo_util = cl_dhape_util_factory=>new( ). mo_in = get_port( 'in' )->get_reader( ). mo_out = get_port( 'out' )->get_writer( ). ENDMETHOD. METHOD if_dhape_graph_process~step. "This method caled in a loop as long as the graph is alive rv_progress = abap_false. CHECK mv_alive = abap_true. DATA : ldf_string TYPE string, ldf_result TYPE string. IF mo_in->has_data( ). CHECK mo_out->is_blocked( ) <> abap_true. mo_in->read_copy( IMPORTING ea_data = ldf_string ). DATA: salesdocument TYPE vbeln, order_header_in TYPE bapisdh1, order_header_inx TYPE bapisdh1x, order_item_in TYPE TABLE OF bapisditm, order_item_inx TYPE TABLE OF bapisditmx, order_item_inl LIKE LINE OF order_item_in, order_item_inxl LIKE LINE OF order_item_inx, return1 TYPE TABLE OF bapiret2, returnmessage TYPE bapiret2, schedule_lines TYPE TABLE OF bapischdl, schedule_linesx TYPE TABLE OF bapischdlx, schedule_linesl LIKE LINE OF schedule_lines, schedule_linesxl LIKE LINE OF schedule_linesx, ldf_vbeln TYPE vbeln, ldf_string2 TYPE string, ldf_string3 TYPE string, message TYPE string. SPLIT ldf_string AT '/' INTO ldf_vbeln ldf_string2 ldf_string3. order_header_inx-updateflag = 'U'. order_item_inl-itm_number = ldf_string2 . APPEND order_item_inl TO order_item_in. order_item_inxl-itm_number = ldf_string2 . order_item_inxl-updateflag = 'U'. APPEND order_item_inxl TO order_item_inx.. schedule_linesl-itm_number = ldf_string2 . schedule_linesl-sched_line = '0001'. schedule_linesl-req_qty = ldf_string3. APPEND schedule_linesl TO schedule_lines. schedule_linesxl-itm_number = ldf_string2. schedule_linesxl-sched_line = '0001'. schedule_linesxl-updateflag = 'U'. schedule_linesxl-req_qty = 'X'. APPEND schedule_linesxl TO schedule_linesx.. CALL FUNCTION 'BAPI_SALESORDER_CHANGE' EXPORTING salesdocument = ldf_vbeln order_header_inx = order_header_inx TABLES return = return1 order_item_in = order_item_in order_item_inx = order_item_inx schedule_lines = schedule_lines schedule_linesx = schedule_linesx. IF sy-subrc = '0'. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. ELSE. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. ENDIF. READ TABLE return1 INTO returnmessage INDEX LINES( return1 ). CALL FUNCTION 'Z_GET' EXPORTING salesorder_vbeln = ldf_vbeln IMPORTING salesorder_data_json = message. mo_out->write_copy( returnmessage-message && message ) . rv_progress = abap_true. ELSEIF mo_in->is_closed( ). mo_out->close( ). rv_progress = abap_true. ENDIF. ENDMETHOD. ENDCLASS. 
  • 実行結果:更新の結果及び受注伝票のデータがSAP Data Intelligence側へ返されて、ファイルに書き込ました。

以下はBAdIを実装する際に注意が必要な点になります。

  • BAdIをレポートで自動拡張する際に、フィルタの値がcom.sap.abap.はじめになっていますが、これはSAP ABAP Operatorを使用するときの値である為、Custom ABAP Operatorを使用する場合は、custom.com.sap.abap.のはじめの値を変更しなければなりません。それと同時にGET INFOメソッドのRS_INFOパラメータのname項目の値も変更が必要です。
  • 入力出力パラメータが複数の場合、NEW_PROCESSメソッドのRS_INFOパラメータのInports(あるいはExport)が下記のように記入する必要があります。
  • Inportパラメータを受ける際には一点注意する必要があります。基本Operatorの処理ロジックはSTEPに実装されています。データの受信に関わらず呼び出される場合があるため、inportデータをロジックに読み込みする前に、inportデータが存在するかどうかのチェックが必要です。もしチェック(check mo_in->has_data( ))されない場合、もしくはinportにデータがないとき下記のダンプが発生します。また、複数のinportのデータが同じタイミングで受信されない場合、すべてのポートにデータが受信されるまで待つか、あるいはデータを個別に読み取り、Operator内に保存して、すべてのデータが利用可能になった後に次の手順を実行する必要があります。 実行中、Operator変数はメモリに残りますので、そこに安全に保存/キャッシュできます。

こちらのブログではCustom ABAP Operatorの使用方法について簡単に紹介頂きました。

Custom ABAP Operatorを活用することにより、SAP S/4HANAとSAP Data Intelligenceの間でのデータの連携や更新をすることができます。また、必要に応じてSAP S/4HANAの様々モジュールを呼び出すことができる為、非常に役立つ機能だと思います。ぜひ皆様にもご活用いただけることを願っております。