BDC批量數據導入
BDC(Batch Data Communication),是SAP系統數據傳輸的主要技術之一,主要用於把數據大量大批輸入到SAP系統。
BDC方法與ABAP編程的關系密切,因此相對於LSMW、CATT等其他數據傳輸方式,BDC方法更靈活。
BDC是模擬屏幕操作(與按鍵精靈相似),記錄相關屏幕出現順序和處理過程,產生數據錄入的格式文件,通過調整數據文件后,再運行BDC產生ABAP程序,最后可能生成的ABAP程序進行修改,得到最終的數據錄入代碼片斷
SM35(包含SHDB)錄屏操作
該界面列出了所有通過BDC所執行的會話記錄:
輸入事務碼AS02后,點擊“開始記錄”按鈕,將會跳到AS02維護界面:
保存數據后,生成記錄:
如果是觸發PAI事件,則會使用 BDC_OKCODE 的字段來存儲相應的FunctonCode
從生成的錄屏記錄來看,不能確認界面上哪些字段會被錄入,哪些字段不會被錄入:沒輸入的(“次級編號”)有的錄了,但有的又沒錄上(“數量”等等沒輸入就沒錄進),但可以肯定一點的是不能編輯的輸入框是不會被錄入的。所以哪些錄入哪些不錄入,並沒有找到規則。
生成程序
帶服務器端測試數據文件
運行生成的報表程序如下:
REPORT zas02
NO STANDARD PAGE HEADING LINE-SIZE 255.
INCLUDE bdcrecx1.
PARAMETERS: dataset(132) LOWER CASE DEFAULT
'AS02_FILE'.
*** DO NOT CHANGE - the generated data section - DO NOT CHANGE ***
*
* If it is nessesary to change the data section use the rules:
* 1.) Each definition of a field exists of two lines
* 2.) The first line shows exactly the comment
* '* data element: ' followed with the data element
* which describes the field.
* If you don't have a data element use the
* comment without a data element name
* 3.) The second line shows the fieldname of the
* structure, the fieldname must consist of
* a fieldname and optional the character '_' and
* three numbers and the field length in brackets
* 4.) Each field must be type C.
*
*** Generated data section with specific formatting - DO NOT CHANGE ***
DATA: BEGIN OF record,
* data element: ANLN1
anln1_001(012),
* data element: ANLN2
anln2_002(004),
* data element: BUKRS
bukrs_003(004),
* data element: TXA50_ANLT
txt50_004(050),
* data element: ANLHTXT
anlhtxt_005(050),
* data element: AKTIVD
aktiv_006(010),
END OF record.
*** End generated data section ***
START-OF-SELECTION.
PERFORM open_dataset USING dataset."打開文件
PERFORM open_group.
DO.
READ DATASET dataset INTO record."從文件中讀取數據
"當文件讀取到最后時,退出循環
IF sy-subrc <> 0. EXIT. ENDIF.
PERFORM bdc_dynpro USING 'SAPLAIST' '0100'.
PERFORM bdc_field USING 'BDC_CURSOR'
'ANLA-BUKRS'.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
PERFORM bdc_field USING 'ANLA-ANLN1'
record-anln1_001.
PERFORM bdc_field USING 'ANLA-ANLN2'
record-anln2_002.
PERFORM bdc_field USING 'ANLA-BUKRS'
record-bukrs_003.
PERFORM bdc_dynpro USING 'SAPLAIST' '1000'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BUCH'.
PERFORM bdc_field USING 'BDC_CURSOR'
'ANLA-TXT50'.
PERFORM bdc_field USING 'ANLA-TXT50'
record-txt50_004.
PERFORM bdc_field USING 'ANLH-ANLHTXT'
record-anlhtxt_005.
PERFORM bdc_field USING 'ANLA-AKTIV'
record-aktiv_006.
"該Form實際上就是通過下面語句來實現的,同時包括了對運行
"過程中產生的消息進行了處理,調用該Form時不需要再對消息
"進行額外的處理。客制化(如消息狀態以紅綠燈方式來顯示)消息處理可以參考《ABAP Practical Example App.docx》文檔
* CALL TRANSACTION TCODE USING BDCDATA
* MODE CTUMODE
* UPDATE CUPDATE
* MESSAGES INTO MESSTAB.
PERFORM bdc_transaction USING 'AS02'.
ENDDO.
PERFORM close_group.
PERFORM close_dataset USING dataset."關閉文件
編輯服務器端上生成的測試數據文件
上一節生成的程序過程,選擇了生成測試文件,該文件存入在服務器上。下面介紹如何查看SAP應用服務器上所生的文件信息。
在SM35界面上,點擊會輸入SHDB,在SHDB操作界面,打開文件監視器:
SAP會為每個文件夾存放的路徑定義一個“目錄參數的名稱”,如用戶所創建的文件存放在SAP應用服務器的“DIR_SAPUSERS”下:
雙擊即可看到該目錄下的所有文件,如本例中創建的“AS02_FILE”:
雙擊該文件,即可查看該文件的內容,內容就是上面錄屏時界面上錄入的數據:
可以通過SAP提供的工具CG3Y,將此文件下載到本地后進行編輯:
修改好后,再通過工具CG3Z將文件上傳到服務器上:
將文件上傳到服務器上后,可以將錄入程序在后台運行,適合於大批量需要耗時較長的數據處理。
CG3Y、CG3Z文件每行字符超長問題
CG3YDOWNLOAD服務器文件(如果是ASC模式下載,每行只能256個字符,解決方案是函數C13Z_FILE_DOWNLOAD_ASCII的L_DATA_TAB改為TYPE STRING)
CG3ZUPLOAD本地文件到服務器中(如果是ASC模式上傳,每行只能256個字符,解決方案是函數C13Z_FILE_UPLOAD_ASCII的L_DATA_TAB改為TYPE STRING)
不帶測試數據文件
如果在生成代碼時選擇的是“從記錄中傳輸”,則生成的代碼非常簡單,但較之上面需要修改很多才能使用:
REPORT zas022
NO STANDARD PAGE HEADING LINE-SIZE 255.
INCLUDE bdcrecx1.
START-OF-SELECTION.
PERFORM open_group.
PERFORM bdc_dynpro USING 'SAPLAIST' '0100'.
PERFORM bdc_field USING 'BDC_CURSOR'
'ANLA-ANLN1'.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
PERFORM bdc_field USING 'ANLA-ANLN1'
'11000001'.
PERFORM bdc_field USING 'ANLA-ANLN2'
'0'.
PERFORM bdc_field USING 'ANLA-BUKRS'
'0005'.
PERFORM bdc_dynpro USING 'SAPLAIST' '1000'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BUCH'.
PERFORM bdc_field USING 'BDC_CURSOR'
'ANLA-TXT50'.
PERFORM bdc_field USING 'ANLA-TXT50'
'AAA'.
PERFORM bdc_field USING 'ANLH-ANLHTXT'
'BBB'.
PERFORM bdc_field USING 'ANLA-AKTIV'
'2006.04.19'.
PERFORM bdc_transaction USING 'AS02'.
PERFORM close_group.
從本地讀取測試數據文件
從前面生成的程序來看,引用了系統標准的Include程序bdcrecx1,這里可以將BDC處理的核心代碼拷貝出來,如存放到一個自定義的Include文件zbdcrecx1中,自定義程序中不再考慮DataSet及BDC Group的方法,主要需要拷貝的內表定義包括BDCDATA、MESSTAB;需要拷貝的Form如下:
精簡后的Include文件zbdcrecx1:
*----------------------------------------------------------------------*
* data definition
*----------------------------------------------------------------------*
* Batchinputdata of single transaction
DATA: bdcdata LIKE bdcdata OCCURS 0 WITH HEADER LINE."用來存儲屏幕字段參數值,傳遞錄屏參數
* messages of call transaction
DATA: messtab LIKE bdcmsgcoll OCCURS 0 WITH HEADER LINE."記錄執行BDC過程中產生的消息
* message texts
TABLES: t100.
*----------------------------------------------------------------------*
* Start new transaction according to parameters *
*----------------------------------------------------------------------*
FORM bdc_transaction USING tcode ctumode.
DATA: l_mstring(480).
DATA: l_subrc LIKE sy-subrc.
A:代表無論出錯與否每個畫面都顯示;
E:只是在出錯時顯示;
N:代表無論出錯與否每個畫面都不顯示。
REFRESH messtab.
CALL TRANSACTION tcode USING bdcdata
MODE ctumode"A:調試 N:不顯示 E:錯誤時調試
UPDATE 'A'"A:異步 B:同步 L:本地更新
MESSAGES INTO messtab.
l_subrc = sy-subrc.
WRITE: / 'CALL_TRANSACTION',
tcode,
'returncode:'(i05),
l_subrc,
'RECORD:',
sy-index.
LOOP AT messtab.
SELECT SINGLE * FROM t100 WHERE sprsl = messtab-msgspra
AND arbgb = messtab-msgid
AND msgnr = messtab-msgnr.
IF sy-subrc = 0.
l_mstring = t100-text.
IF l_mstring CS '&1'.
REPLACE '&1' WITH messtab-msgv1 INTO l_mstring.
REPLACE '&2' WITH messtab-msgv2 INTO l_mstring.
REPLACE '&3' WITH messtab-msgv3 INTO l_mstring.
REPLACE '&4' WITH messtab-msgv4 INTO l_mstring.
ELSE.
REPLACE '&' WITH messtab-msgv1 INTO l_mstring.
REPLACE '&' WITH messtab-msgv2 INTO l_mstring.
REPLACE '&' WITH messtab-msgv3 INTO l_mstring.
REPLACE '&' WITH messtab-msgv4 INTO l_mstring.
ENDIF.
CONDENSE l_mstring.
WRITE: / messtab-msgtyp, l_mstring(250).
ELSE.
WRITE: / messtab.
ENDIF.
ENDLOOP.
REFRESH bdcdata.
ENDFORM.
*----------------------------------------------------------------------*
* Start new screen *
*----------------------------------------------------------------------*
FORM bdc_dynpro USING program dynpro.
CLEAR bdcdata.
bdcdata-program = program.
bdcdata-dynpro = dynpro.
bdcdata-dynbegin = 'X'.
APPEND bdcdata.
ENDFORM.
*----------------------------------------------------------------------*
* Insert field *
*----------------------------------------------------------------------*
FORM bdc_field USING fnam fval.
CLEAR bdcdata.
bdcdata-fnam = fnam.
bdcdata-fval = fval.
APPEND bdcdata.
ENDFORM.
新創建一個XLS文件,並輸入測試數據:
REPORT zjzj_bdc_localfile.
TYPE-POOLS: truxs.
DATA:it_raw TYPE truxs_t_text_data."
PARAMETERS: p_file LIKE ibipparms-path.
INCLUDE:zbdcrecx1.
DATA: BEGIN OF record OCCURS 0,
anln1_001(012),
bukrs_002(004),
txt50_003(050),
anlhtxt_004(050),
END OF record.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file."選擇文件時彈出選擇對話框
CALL FUNCTION 'F4_FILENAME'
EXPORTING
field_name = 'P_FILE'
IMPORTING
file_name = p_file.
START-OF-SELECTION.
CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
EXPORTING
i_line_header = 'X' "表示測試文件的第一行為頭,從第二行開始讀取
i_tab_raw_data = it_raw
i_filename = p_file
TABLES
i_tab_converted_data = record[].
CHECK NOT record[] IS INITIAL.
LOOP AT record.
PERFORM bdc_dynpro USING 'SAPLAIST' '0100'.
PERFORM bdc_field USING 'BDC_CURSOR'
'ANLA-BUKRS'.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
PERFORM bdc_field USING 'ANLA-ANLN1'
record-anln1_001.
PERFORM bdc_field USING 'ANLA-BUKRS'
record-bukrs_002.
PERFORM bdc_dynpro USING 'SAPLAIST' '1000'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BUCH'.
PERFORM bdc_field USING 'BDC_CURSOR'
'ANLH-ANLHTXT'.
PERFORM bdc_field USING 'ANLA-TXT50'
record-txt50_003.
PERFORM bdc_field USING 'ANLH-ANLHTXT'
record-anlhtxt_004.
PERFORM bdc_transaction USING 'AS02' 'E'.
ENDLOOP.
BDC后台運行
先貼上,以后研究
BDC(batch data communication)是SAP常用的一種數據傳輸方法。用於一些數據量大,但是對速度又要求不高的數據傳輸。
在實施中,很多開發顧問都忽略了BDC的日志和出錯管理。這給用戶在使用中帶來了很大的不便。比如:哪些數據是成功生成的,哪些是失敗的?那些失敗的,原因的是什么?程序問題還是數據問題?
我覺得,既然是要做一套程序,那就應該盡可能地為客戶考慮,減少日后的維護量。對於BDC程序來講,日志和出錯管理應該是必備的。
下面講一下,BDC的兩種通用寫法。
1. Call Transaction: 顧名思義,就是直接調用BDC進行數據批量導入。優點:方便快捷,程序處理方便。缺點:日志管理能力差,需自己建透明表來維護數據。我只是把它用作測試用途,不做正式使用。
2. BDC Insert(即CALL Function):這是一種不直接運行,而是將BDC程序生成session(但不立即運行,需要手工或通過RSBDCSUB專用程序來運行會話)。優點:通過T-code SM35可以進行運行管理及日志管理,方便查錯。缺點:相對方法1來說實現起來比較繁瑣。我主要是用這種方法來實現BDC功能。
下面主要來談一下BDC Insert這種方法。
1. 需要在程序中調用 function 'BDC_INSERT'來把BDCDATA生成SESSION.
2. 通過程序RSBDCSUB來執行SESSION(后續建立JOB中使用,目前手動運行會話)
3. 建立BATCH JOB來定期執行RSBDCSUB,從而實現SESSION自動執行的目的
4. 當然,不使用程序RSBDCSUB和JOB,每次手工在SM35中執行SESSION也是可以的
下面是我寫的一個實例:
TABLES: COAS, CEPC.
*-----------------------------------------------------------------------
* Internal Tables and Work Areas
*-----------------------------------------------------------------------
DATA: BEGIN 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.
DATA: BEGIN OF GT_EXISTS OCCURS 0. "existed IO
INCLUDE STRUCTURE GT_TABLE.
DATA: END OF GT_EXISTS.
DATA: BEGIN OF GT_PRFT_CNTR OCCURS 0."the profit center not existing IO
INCLUDE STRUCTURE GT_TABLE.
DATA: END OF GT_PRFT_CNTR.
DATA: BEGIN OF GT_SUBMIT OCCURS 0. "the submitted IO
INCLUDE STRUCTURE GT_TABLE.
DATA: END OF GT_SUBMIT.
DATA: BEGIN OF GT_BDCDATA OCCURS 0. "BDC DATA
INCLUDE STRUCTURE BDCDATA.
DATA: END OF GT_BDCDATA.
DATA: BEGIN OF GT_MESSTAB OCCURS 10. "message table
INCLUDE STRUCTURE BDCMSGCOLL.
DATA: END OF GT_MESSTAB.
DATA: GT_IMESG LIKE MESG OCCURS 0 WITH HEADER LINE.
*-----------------------------------------------------------------------
* Variables
*-----------------------------------------------------------------------
DATA: GV_GROUP(12) TYPE 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(1) TYPE C,
GV_LIN TYPE I. "number of orders
DATA: GV_C170(170),
GV_C_ULINE(50) VALUE '__________________________________________________'.
*$*$----------------------------------------------------------------$*$*
*$*$ Selection Screen $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* Selection Screen
*-----------------------------------------------------------------------
PARAMETERS: BDCTYPE(1) TYPE C DEFAULT 'B' NO-DISPLAY,
BDCMODE LIKE BDCRUN-BDC_AMODUS DEFAULT 'A' NO-DISPLAY.
SELECTION-SCREEN COMMENT 10(70) TEXT-001.
PARAMETERS: IN_FILE(128) DEFAULT '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.
通過RSBDCSUB運行會話
DATA: p_groupid LIKE apqi-groupid.
DATA: p_user LIKE sy-uname.
* PERFORM bdc_open_group.
* PERFORM pre_bdc.
* PERFORM bdc_insert_group.
* PERFORM bdc_close_group .
* PERFORM get_session_state USING p_groupid .
* PERFORM write_error.
**************************************************************
FORM bdc_open_group .
CONCATENATE sy-datum sy-uzeit INTO p_groupid.
CALL FUNCTION 'BDC_OPEN_GROUP' "open session
EXPORTING
client = sy-mandt
* DEST = FILLER8
group = p_groupid
* HOLDDATE = FILLER8
keep = 'X'
user = p_user
* RECORD = FILLER1
* IMPORTING
* QID =
EXCEPTIONS
client_invalid = 1
destination_invalid = 2
group_invalid = 3
group_is_locked = 4
holddate_invalid = 5
internal_error = 6
queue_error = 7
running = 8
system_lock_error = 9
user_invalid = 10
OTHERS = 11.
ENDFORM. " BDC_OPEN_GROUP
************************************************************
FORM pre_bdc .
REFRESH bdcdata.
PERFORM bdc_dynpro USING 'SAPLMR1M' '0300'.
PERFORM bdc_field USING 'BDC_CURSOR' 'G_BUDAT'.
PERFORM bdc_field USING 'BDC_OKCODE' '=CANC'.
PERFORM bdc_field USING 'RBKPV-BELNR' i_belnr.
PERFORM bdc_field USING 'RBKPV-GJAHR' i_gjahr.
PERFORM bdc_field USING 'UF05A-STGRD' i_stgrd.
PERFORM bdc_field USING 'G_BUDAT' i_budat.
ENDFORM.
*************************************************************
FORM bdc_insert_group .
CALL FUNCTION 'BDC_INSERT'
EXPORTING
tcode = tcode
TABLES
dynprotab = bdcdata
EXCEPTIONS
internal_error = 1
not_open = 2
queue_error = 3
tcode_invalid = 4
printing_invalid = 5
posting_invalid = 6
OTHERS = 7.
ENDFORM. " BDC_INSERT_GROUP
*********************************************************
FORM bdc_close_group .
CALL FUNCTION 'BDC_CLOSE_GROUP'
EXCEPTIONS
not_open = 1
queue_error = 2
OTHERS = 3.
SUBMIT rsbdcsub WITH mappe EQ p_groupid
WITH von EQ sy-datum
WITH bis EQ sy-datum
WITH fehler EQ '.'
EXPORTING LIST TO MEMORY
AND RETURN.
WAIT UP TO 10 SECONDS .
ENDFORM. " BDC_CLOSE_GROUP
**********************************************************
FORM get_session_state USING p_session.
CLEAR: itab1,itab1[].
itab1-groupid = p_groupid.
itab1-belnr = i_belnr.
itab1-gjahr = i_gjahr.
itab1-stgrd = i_stgrd.
itab1-budat = i_budat.
itab1-erdat = sy-datum.
itab1-uzeit = sy-uzeit.
itab1-ernam = sy-uname.
itab1-text = i_text.
APPEND itab1.
PERFORM insert_zszd219.
SELECT SINGLE apqi~mandant apqi~groupid apqi~qid apqi~qstate
apql~temseid
INTO (ijob-mandant,ijob-groupid,ijob-qid,ijob-qstate,ijob-temseid)
FROM apqi INNER JOIN apql
ON apql~mandant = apqi~mandant
AND apql~groupid = apqi~groupid
AND apql~qid = apqi~qid
WHERE apqi~groupid = p_session
AND apqi~datatyp = 'BDC'
AND apqi~mandant = sy-mandt .
IF sy-subrc = 0 AND ijob-qstate = 'F'.
READ TABLE itab1 INDEX 1.
itab1-state = 'F'.
MODIFY itab1 INDEX 1.
PERFORM insert_zszd219.
WRITE: / 'Cancel Invoice Sucessful'.
ELSEIF sy-subrc = 0 AND ijob-qstate <> 'F'.
PERFORM read_bdc_log_plain TABLES logtable USING ijob-temseid ijob-mandant.
ELSEIF sy-subrc <> 0.
WRITE:/ 'Job name: ',p_session,' has not finish.'.
ENDIF.
CHECK NOT bdclm[] IS INITIAL.
LOOP AT itab1.
READ TABLE bdclm WITH KEY tcode = 'MR8M'
tcnt = sy-tabix.
CHECK sy-subrc = 0.
MOVE-CORRESPONDING itab1 TO errtab.
IF bdclm-mart = 'E'.
errtab-mess = bdclm-longtext.
ELSE.
errtab-mess = 'Cancel Invoice Sucessful'.
ENDIF.
APPEND errtab.
CLEAR errtab.
ENDLOOP.
ENDFORM.
*********************************************************
FORM write_error .
DATA: count TYPE i.
count = 0.
LOOP AT errtab.
IF count = 0.
FORMAT COLOR 3 ON.
WRITE: /01 errtab.
FORMAT COLOR 3 OFF.
SKIP 1.
ELSE.
WRITE: /01 errtab.
ENDIF.
count = 1.
ENDLOOP.
ENDFORM. " WRITE_ERROR
CATT批量數據維護(SCAT、SCEM)
CATT 全稱 Computer Aided Test Tool(計算機輔助測試工具),也是批量數據維護工具。與BDC類似的是,CATT的數據操作也是通過錄制屏幕的方式來實現的,但是有自己的優勢:
l BDC導入本地數據需要通過輔助開發程序來實現,而CATT則可以直接讀取本地文件;
l BDC讀取文件到內存后再進行處理,可以方便地通過ABAP代碼來實現數據的檢查或者轉換,但是CATT則是比較直接的數據錄入,相比之下,BDC的控制會更加靈活。
l CATT操作簡單,可以由模塊顧問錄制好后再提供給用戶直接使用,只需要用戶按顧問提供的測試數據模板文件提供數據即可
若是基本的數據錄入或修改的話,CATT實現起來會更加的簡單
本實例還是以修改資產主數據事務AS02為例來演示
因AS02屬於賬務控制模塊,所以選擇C0:
點擊“保存”按鈕后,再修改“類型”為“C CATT”類型(注:如果不先保存,直接選 C CATT 時會報錯):
保存后,再輸入SCEM事務碼,操作界面與SCAT基本類似:
點擊“記錄”按鈕后,就是AS02事務操作界面了:
與上面BDC中的示例一樣,修改后保存,會回到SCEM界面,此時記錄框中有了“結束並復制”按鈕:
點擊“結束並復制”按鈕后,將會看到測試界面修改界面,左邊菜單項中為錄制過程中的屏幕及操作的消息輸出(這里為第三項):
SCEM操作完后,保存所有,然后再回到SCAT界面,並執行“導出”,將會導出本地數據錄入模板:
導入的文件為Txt文件,可以使用Excel打開進行維護,新增的數據必須按文件中的位置來填寫:
測試文件修改好后,進入執行界面:
執行后,輸出日志: