BDC、CATT批量数据维护

时间:2024-02-21 14:43:06

BDC批量数据导入... 19

SM35(包含SHDB)录屏操作... 19

生成程序... 22

带服务器端测试数据文件... 22

编辑服务器端上生成的测试数据文件... 23

CG3YCG3Z文件每行字符超长问题... 24

不带测试数据文件... 25

从本地读取测试数据文件... 25

BDC后台运行... 28

通过RSBDCSUB运行会话... 35

CATT批量数据维护(SCATSCEM... 37

BDC批量数据导入

BDC(Batch Data Communication),是SAP系统数据传输的主要技术之一,主要用于把数据大量大批输入到SAP系统。

BDC方法与ABAP编程的关系密切,因此相对于LSMWCATT等其他数据传输方式,BDC方法更灵活。

BDC是模拟屏幕操作(与按键精灵相似),记录相关屏幕出现顺序和处理过程,产生数据录入的格式文件,通过调整数据文件后,再运行BDC产生ABAP程序,最后可能生成的ABAP程序进行修改,得到最终的数据录入代码片断

SM35(包含SHDB)录屏操作

该界面列出了所有通过BDC所执行的会话记录:

image037

单击image038按钮,进行SHDB屏幕录制界面:

image039

输入事务码AS02后,点击“开始记录”按钮,将会跳到AS02维护界面:

image040

保存数据后,生成记录:

image041

image042

image043

如果是触发PAI事件,则会使用 BDC_OKCODE 的字段来存储相应的FunctonCode

image044

 

从生成的录屏记录来看,不能确认界面上哪些字段会被录入,哪些字段不会被录入:没输入的(“次级编号”)有的录了,但有的又没录上(“数量”等等没输入就没录进),但可以肯定一点的是不能编辑的输入框是不会被录入的。所以哪些录入哪些不录入,并没有找到规则。

image045

生成程序

带服务器端测试数据文件

image046

 

运行生成的报表程序如下:

image047

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界面上,点击image048会输入SHDB,在SHDB操作界面,打开文件监视器:

image049

SAP会为每个文件夹存放的路径定义一个“目录参数的名称”,如用户所创建的文件存放在SAP应用服务器的“DIR_SAPUSERS”下:

image050

 

双击即可看到该目录下的所有文件,如本例中创建的“AS02_FILE”:

image051

 

双击该文件,即可查看该文件的内容,内容就是上面录屏时界面上录入的数据:

image052

 

可以通过SAP提供的工具CG3Y,将此文件下载到本地后进行编辑:

image053

image054

 

修改好后,再通过工具CG3Z将文件上传到服务器上:

image055

 

将文件上传到服务器上后,可以将录入程序在后台运行,适合于大批量需要耗时较长的数据处理。

CG3YCG3Z文件每行字符超长问题

CG3YDOWNLOAD服务器文件(如果是ASC模式下载,每行只能256个字符,解决方案是函数C13Z_FILE_DOWNLOAD_ASCIIL_DATA_TAB改为TYPE STRING)

CG3ZUPLOAD本地文件到服务器中(如果是ASC模式上传,每行只能256个字符,解决方案是函数C13Z_FILE_UPLOAD_ASCIIL_DATA_TAB改为TYPE STRING)

image056

不带测试数据文件

如果在生成代码时选择的是“从记录中传输”,则生成的代码非常简单,但较之上面需要修改很多才能使用:

image057

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中,自定义程序中不再考虑DataSetBDC Group的方法,主要需要拷贝的内表定义包括BDCDATAMESSTAB;需要拷贝的Form如下:

image058

精简后的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文件,并输入测试数据:

image059

 

image060

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.

image061

 

BDC后台运行

先贴上,以后研究

 

 

BDCbatch 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.   当然,不使用程序RSBDCSUBJOB,每次手工在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(12TYPE 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批量数据维护(SCATSCEM

CATT 全称 Computer Aided Test Tool(计算机辅助测试工具),也是批量数据维护工具。与BDC类似的是,CATT的数据操作也是通过录制屏幕的方式来实现的,但是有自己的优势:

l  BDC导入本地数据需要通过辅助开发程序来实现,而CATT则可以直接读取本地文件;

l  BDC读取文件到内存后再进行处理,可以方便地通过ABAP代码来实现数据的检查或者转换,但是CATT则是比较直接的数据录入,相比之下,BDC的控制会更加灵活。

l  CATT操作简单,可以由模块顾问录制好后再提供给用户直接使用,只需要用户按顾问提供的测试数据模板文件提供数据即可

 

若是基本的数据录入或修改的话,CATT实现起来会更加的简单

 

本实例还是以修改资产主数据事务AS02为例来演示

image062

 

AS02属于账务控制模块,所以选择C0

image063

点击“保存”按钮后,再修改“类型”为“C CATT”类型(注:如果不先保存,直接选 C CATT 时会报错):

image064

 

保存后,再输入SCEM事务码,操作界面与SCAT基本类似:

image065

点击“记录”按钮后,就是AS02事务操作界面了:

image066

image067

与上面BDC中的示例一样,修改后保存,会回到SCEM界面,此时记录框中有了“结束并复制”按钮

image068

点击“结束并复制”按钮后,将会看到测试界面修改界面,左边菜单项中为录制过程中的屏幕及操作的消息输出(这里为第三项):

image069

image070

image071

单击image072字段检查按钮,会在右边屏幕上增加工具条:

image073

image074

image075image076

image077image078

SCEM操作完后,保存所有,然后再回到SCAT界面,并执行“导出”,将会导出本地数据录入模板:

image079

导入的文件为Txt文件,可以使用Excel打开进行维护,新增的数据必须按文件中的位置来填写:

image080

测试文件修改好后,进入执行界面:

image081

执行后,输出日志:

image082