BDC

BDC(batch data communication)是SAP常用的一種數據傳輸方法。用於一些數據量大,但是對速度又要求不高的數據傳輸。

    在實施中,很多開發顧問都忽略了BDC的日誌和出錯管理。這給用戶在使用中帶來了很大的不便。比如:哪些數據是成功生成的,哪些是失敗的?那些失敗的,原因的是什麼?程序問題還是數據問題?
    我覺得,既然是要做一套程序,那就應該儘可能地爲客戶考慮,減少日後的維護量。對於BDC程序來講,日誌和出錯管理應該是必備的。
    下面講一下,BDC的兩種通用寫法。
  1.  Call Transaction: 顧名思義,就是直接調用BDC進行數據批量導入。優點:方便快捷,程序處理方便。缺點:日誌管理能力差,需自己建透明表來維護數據。我只是把它用作測試用途,不做正式使用。
  2.  BDC Insert:這是一種不直接運行,而是將BDC程序生成session,間接運行的一種方法。優點:通過T-code SM35可以進行運行管理及日誌管理,方便查錯。缺點:相對方法1來說實現起來比較繁瑣。我主要是用這種方法來實現BDC功能。

下面主要來談一下BDC Insert這種方法。

  1. 需要在程序中調用 function 'BDC_INSERT'來把BDCDATA生成SESSION.
  2. 程序RSBDCSUB是執行SESSION的專用程序,要建立相應的VARIANT,後續建立JOB中使用
  3. 建立BATCH JOB來定期執行RSBDCSUB,從而實現,SESSION自動執行的目的
  4. 當然,不使用程序RSBDCSUB和JOB,每次手工在SM35中執行SESSION也是可以的

下面是我寫的一個實例:

SPAN { font-family: "Courier New"; font-size: 10pt; color: #000000; background: #FFFFFF; } .L1S31 { font-style: italic; color: #808080; } .L1S32 { color: #3399FF; } .L1S33 { color: #4DA619; } .L1S52 { color: #0000FF; } *----------------------------------------------------------------------*
* Program Name: Z_KEVIN_ADV_BDC
* Project     : N/A
* Author      : Kevin.Zhang
* Date        : 2007.1.1
* Module      : N/A
* Description : Advanced BDC
*
*
*
* Special features: N/A
*
*
*----------------------------------------------------------------------*
* Modifications:
* Author      Date     Commented as  Description
*-----------  --------  -----------  ----------------------------------*
*
*----------------------------------------------------------------------*

REPORT   Z_KEVIN_ADV_BDC.
*$*$----------------------------------------------------------------$*$*
*$*$       Global Types, Data Statements, Ranges, Constants         $*$*
*$*$----------------------------------------------------------------$*$*

*-----------------------------------------------------------------------
*                   Tables
*-----------------------------------------------------------------------
TABLES : COAS, CEPC.

*-----------------------------------------------------------------------
*                    Internal Tables and Work Areas
*-----------------------------------------------------------------------
DATABEGIN  OF  GT_TABLE OCCURS  0 ,    "internal order table
        AUART LIKE  AUFK-AUART,       "order type
        AUFNR LIKE  AUFK-AUFNR,       "order number
        KTEXT LIKE  AUFK-KTEXT,       "description
        BUKRS LIKE  AUFK-BUKRS,       "company code
        GSBER LIKE  AUFK-GSBER,       "business area
        PRCTR LIKE  AUFK-PRCTR,       "profit center
        FUNCA LIKE  AUFK-FUNC_AREA,   "function area
 END  OF  GT_TABLE.

DATABEGIN  OF  GT_EXISTS OCCURS  0 .   "existed IO
        INCLUDE  STRUCTURE  GT_TABLE.
DATAEND  OF  GT_EXISTS.

DATABEGIN  OF  GT_PRFT_CNTR OCCURS  0 ."the profit center not existing IO
        INCLUDE  STRUCTURE  GT_TABLE.
DATAEND  OF  GT_PRFT_CNTR.

DATABEGIN  OF  GT_SUBMIT OCCURS  0 .   "the submitted IO
        INCLUDE  STRUCTURE  GT_TABLE.
DATAEND  OF  GT_SUBMIT.

DATABEGIN  OF  GT_BDCDATA OCCURS  0 .  "BDC DATA
        INCLUDE  STRUCTURE  BDCDATA.
DATAEND  OF  GT_BDCDATA.

DATABEGIN  OF  GT_MESSTAB OCCURS  10"message table
        INCLUDE  STRUCTURE  BDCMSGCOLL.
DATAEND  OF  GT_MESSTAB.
DATA : GT_IMESG LIKE  MESG OCCURS  0  WITH  HEADER  LINE .
*-----------------------------------------------------------------------
*                  Variables
*-----------------------------------------------------------------------
DATA : GV_GROUP(12TYPE  C  VALUE  'INTERNAL_ORD' ,      "BDC Name
      GV_USER(12 )  TYPE  C ,                           "BDC User
      GV_KEEP(1 )   TYPE  C  VALUE  'X' ,                 " ' '=Delete,'X'=keep after processing
      GV_HOLDDATE  LIKE  SY-DATUM.                    "Date

DATA :  GV_FLAG(1TYPE  C ,
       GV_LIN TYPE  I .                                "number of orders

DATA : GV_C170(170 ),
      GV_C_ULINE(50VALUE  '__________________________________________________' .


*$*$----------------------------------------------------------------$*$*
*$*$                      Selection Screen                          $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
*                   Selection Screen
*-----------------------------------------------------------------------
PARAMETERS : BDCTYPE(1TYPE  C  DEFAULT  'B'  NO -DISPLAY,
            BDCMODE    LIKE  BDCRUN-BDC_AMODUS DEFAULT  'A'  NO -DISPLAY.

SELECTION-SCREEN  COMMENT  10 (70TEXT -001 .
PARAMETERS : IN_FILE(128DEFAULT  'C:/TEMP/*.txt' .
SELECTION-SCREEN  SKIP  1 .
*-----------------------------------------------------------------------
*                   At Selection Screen
*-----------------------------------------------------------------------

*--------- AT SELECTION-SCREEN ON VALUE-REQUEST ----------
AT  SELECTION-SCREEN  ON  VALUE -REQUEST FOR  IN_FILE.

  CALL  FUNCTION  'WS_FILENAME_GET'
    EXPORTING
      DEF_FILENAME     = '*.txt'
      DEF_PATH         = 'C:/DATA'
      MASK              = ',All Files,*.*,Text Files,*.txt;*.doc.'
      MODE              = 'O'
      TITLE             = 'Please choose file to use '
    IMPORTING
      FILENAME         = IN_FILE
    EXCEPTIONS
      INV_WINSYS       = 1
      NO_BATCH         = 2
      SELECTION_CANCEL = 3
      SELECTION_ERROR  = 4
      OTHERS            = 5 .


*$*$----------------------------------------------------------------$*$*
*$*$                          Main Program                          $*$*
*$*$----------------------------------------------------------------$*$*

*--------- START-OF-SELECTION ----------
START-OF -SELECTION.

  REFRESH  GT_TABLE.

* Uploading the data which will be inserted into the internal table
  CALL  FUNCTION  'WS_UPLOAD'
    EXPORTING
      FILENAME            = IN_FILE
      FILETYPE            = 'DAT'
    TABLES
      DATA_TAB            = GT_TABLE
    EXCEPTIONS
      CONVERSION_ERROR    = 1
      FILE_OPEN_ERROR     = 2
      FILE_READ_ERROR     = 3
      INVALID_TABLE_WIDTH = 4
      INVALID_TYPE        = 5
      NO_BATCH            = 6
      UNKNOWN_ERROR       = 7
      OTHERS               = 8 .

  IF  SY-SUBRC <> 0 .
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                 'Unable to upload input file '
                                 IN_FILE ''  '' .
  ENDIF .

  SORT  GT_TABLE BY   AUFNR GSBER DESCENDING .
  DELETE  ADJACENT  DUPLICATES  FROM  GT_TABLE COMPARING  AUFNR.

  PERFORM  OPEN_GROUP.
  PERFORM  FILL_BDC_DATA.
  PERFORM  BDC_CLOSE_GROUP.
  PERFORM  WRITE_REPORT.

*--------- END-OF-SELECTION ----------

*$*$----------------------------------------------------------------$*$*
*$*$                         Subroutines                            $*$*
*$*$----------------------------------------------------------------$*$*

*&---------------------------------------------------------------------*
*&      Form  OPEN_GROUP
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM  OPEN_GROUP.
  GV_USER = SY-UNAME.

  CALL  FUNCTION  'BDC_OPEN_GROUP'
    EXPORTING
      CLIENT    = SY-MANDT
      GROUP     = GV_GROUP
      HOLDDATE = GV_HOLDDATE
      KEEP     = GV_KEEP
      USER     = GV_USER.

  IF  SY-SUBRC <> 0 .
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF .
ENDFORM .                               " OPEN_GROUP

*&---------------------------------------------------------------------*
*&      Form  FILL_BDC_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM  FILL_BDC_DATA.

  CLEAR  GT_TABLE.

  LOOP  AT  GT_TABLE.
    CLEAR  GT_MESSTAB.
    CLEAR  GT_BDCDATA.
    REFRESH  GT_BDCDATA.
    REFRESH  GT_MESSTAB.
    CLEAR  GV_FLAG.

*   Check if Profit Center exists.
    SELECT  SINGLE  * FROM  CEPC
           WHERE  PRCTR = GT_TABLE-PRCTR.

    IF  SY-SUBRC <> 0 .
      CLEAR  GT_PRFT_CNTR.
      MOVE -CORRESPONDING GT_TABLE TO  GT_PRFT_CNTR.
      APPEND  GT_PRFT_CNTR.
      GV_FLAG = 'X' .
    ENDIF .

*   check if Internal Order has already been created.
    SELECT  SINGLE  * FROM  COAS
       WHERE  AUFNR = GT_TABLE-AUFNR.

    IF  SY-SUBRC = 0 .
      CLEAR  GT_EXISTS.
      MOVE -CORRESPONDING GT_TABLE TO  GT_EXISTS.
      APPEND  GT_EXISTS.
      GV_FLAG = 'X' .
    ENDIF .

    IF  GV_FLAG <> 'X' .

      PERFORM  BDCDATA USING :   'X'  'SAPMKAUF'  '0100' ,                 "order type
                               ' '  'COAS-AUART'  GT_TABLE-AUART,
                               ' '  'BDC_OKCODE'  '=KOKR' .

      PERFORM  BDCDATA USING :   'X'  'SAPLSPO4'  '0300' ,                 "control area
                               ' '  'SVALD-VALUE(01)'  '1000' ,
                               ' '  'BDC_OKCODE'  '=FURT' .

      PERFORM  BDCDATA USING :   'X'  'SAPMKAUF'  '0100' ,                 "ok code
                               ' '  'BDC_OKCODE'  '/00' .


      PERFORM  BDCDATA USING :   'X'  'SAPMKAUF'  '0600' ,                 "order master data
                               ' '  'COAS-AUFNR'  GT_TABLE-AUFNR,
                               ' '  'COAS-KTEXT'  GT_TABLE-KTEXT,
                               ' '  'COAS-BUKRS'  GT_TABLE-BUKRS,
                               ' '  'COAS-GSBER'  GT_TABLE-GSBER,
                               ' '  'COAS-PRCTR'  GT_TABLE-PRCTR,
                               ' '  'COAS-FUNC_AREA'  GT_TABLE-FUNCA,
                               ' '  'BDC_OKCODE'  '=SICH' .

*     PERFORM CALL_TRANSACTION. "for test purpose

      PERFORM  BDC_INSERT.
      MOVE -CORRESPONDING GT_TABLE TO  GT_SUBMIT.
      APPEND  GT_SUBMIT.

    ENDIF .
  ENDLOOP .
ENDFORM .                               " FILL_BDC_DATA

*&---------------------------------------------------------------------*
*&      Form  BDC_INSERT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM  BDC_INSERT.
  CALL  FUNCTION  'BDC_INSERT'
    EXPORTING
      TCODE     = 'KO01'
    TABLES
      DYNPROTAB = GT_BDCDATA.

  IF  SY-SUBRC <> 0 .
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF .

ENDFORM .                               " BDC_INSERT

*&---------------------------------------------------------------------*
*&      Form  BDC_CLOSE_GROUP
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM  BDC_CLOSE_GROUP.
  CALL  FUNCTION  'BDC_CLOSE_GROUP' .

  IF  SY-SUBRC <> 0 .
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF .


ENDFORM .                               " BDC_CLOSE_GROUP

*&---------------------------------------------------------------------*
*&      Form  CALL_TRANSACTION
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM  CALL_TRANSACTION.
  CALL  TRANSACTION  'KO01'  USING  GT_BDCDATA
                           MODE  BDCMODE
                       MESSAGES INTO  GT_MESSTAB.
*  IF SYST-SUBRC <> 0.
*    CALL FUNCTION 'WRITE_MESSAGE'
*         EXPORTING
*              MSGID = SY-MSGID
*              MSGNO = SY-MSGNO
*              MSGTY = SY-MSGTY
*              MSGV1 = SY-MSGV1
*              MSGV2 = SY-MSGV2
*              MSGV3 = SY-MSGV3
*              MSGV4 = SY-MSGV4
*              MSGV5 = ' '
*         IMPORTING
*              ERROR = ERROR
*              MESSG = MESSG
*              MSGLN = MSGLN.


ENDFORM .                               " CALL_TRANSACTION

*&---------------------------------------------------------------------*
*&      Form  BDCDATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_0310   text
*      -->P_0311   text
*----------------------------------------------------------------------*
FORM  BDCDATA USING  P_BEGIN P_FIELD1 P_FIELD2.

  CLEAR  GT_BDCDATA.
  CASE  P_BEGIN.
    WHEN  'X' .
      GT_BDCDATA-PROGRAM   = P_FIELD1.
      GT_BDCDATA-DYNPRO    = P_FIELD2.
      GT_BDCDATA-DYNBEGIN = 'X' .
    WHEN  SPACE.
      GT_BDCDATA-FNAM  = P_FIELD1.
      GT_BDCDATA-FVAL  = P_FIELD2.
  ENDCASE .
  APPEND  GT_BDCDATA.

ENDFORM .                               " BDCDATA
*&---------------------------------------------------------------------*
*&      Form  WRITE_REPORT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM  WRITE_REPORT.

   DESCRIBE  TABLE  GT_EXISTS LINES  GV_LIN.

  IF  GV_LIN >= 1 .
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                'The following Internal Orders already exist.'  ''  ''  '' .

    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                   GV_C_ULINE ''  ''  '' .
    LOOP  AT  GT_EXISTS.
      PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                GT_EXISTS-AUFNR ''  ''  '' .
    ENDLOOP .

    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                 GV_C_ULINE ''  ''  '' .
  ENDIF .


  DESCRIBE  TABLE  GT_PRFT_CNTR LINES  GV_LIN.


  IF  GV_LIN >= 1 .
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                  'The following Profit centers do not exist.'  ''  ''  '' .
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                   GV_C_ULINE ''  ''  '' .
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                    'Internal Order Profit Center.'  ''  ''  '' .

    LOOP  AT  GT_PRFT_CNTR.
      PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                GT_PRFT_CNTR-AUFNR
                                GT_PRFT_CNTR-PRCTR ''  '' .
    ENDLOOP .

    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                 GV_C_ULINE ''  ''  '' .
  ENDIF .


  DESCRIBE  TABLE  GT_SUBMIT LINES  GV_LIN.


  IF  GV_LIN >= 1 .
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                   'BDC was created for the following Internal Orders.'
                    ''  ''  '' .
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                   GV_C_ULINE ''  ''  '' .

    LOOP  AT  GT_SUBMIT.
      PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                GT_SUBMIT-AUFNR ''  ''  '' .
    ENDLOOP .

    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                   GV_C_ULINE ''  ''  '' .
  ENDIF .

  PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                  'The following Internal Orders have no Business Area.'
                  ''  ''  '' .
  PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                 GV_C_ULINE ''  ''  '' .

  DELETE  GT_TABLE WHERE  NOT  GSBER = ' ' .

  LOOP  AT  GT_TABLE.
    PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                              GT_TABLE-AUFNR ''  ''  '' .
  ENDLOOP .

  PERFORM  COLLECT_MESSAGES USING  'Z3'  'I'  '000'
                                 GV_C_ULINE ''  ''  '' .
ENDFORM .                               " WRITE_REPORT


*&---------------------------------------------------------------------*
*&      Form  COLLECT_MESSAGES
*&---------------------------------------------------------------------*
*       Collects messgaes into rep tree table and writes them to
*       screen for regular reporting
*----------------------------------------------------------------------*
*      -->P_MSGID  message id
*      -->P_MSGTY  messgae type
*      -->P_MSGNR  msg number
*      -->P_MSG1  text 1
*      -->P_MSG2  text 2
*      -->P_MSG3  text 3
*      -->P_MSG4  text 4
*----------------------------------------------------------------------*
FORM  COLLECT_MESSAGES USING     P_MSGID
                               P_MSGTY
                               P_MSGNR
                               P_MSGV1
                               P_MSGV2
                               P_MSGV3
                               P_MSGV4.

  CLEAR  GT_IMESG.

  GT_IMESG-ARBGB = P_MSGID.
  GT_IMESG-MSGTY = P_MSGTY.
  GT_IMESG-TXTNR = P_MSGNR.
  GT_IMESG-MSGV1+0 (2 ) = '@ ' .
  GT_IMESG-MSGV1+2 (48 ) = P_MSGV1.
  GT_IMESG-MSGV2 = P_MSGV2.
  GT_IMESG-MSGV3 = P_MSGV3.
  GT_IMESG-MSGV4 = P_MSGV4.
  APPEND  GT_IMESG.

  CONCATENATE  P_MSGV1 P_MSGV2 P_MSGV3 P_MSGV4
              INTO  GV_C170 SEPARATED  BY  SPACE.
  WRITE :/ GV_C170.

ENDFORM .                    " collect_messages

發佈了0 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章