SAP BDC

首先简单解释一下BDC(Batch Data Conversion):
在SAP系统里,由于某种原因,可能需要重复输入数据,(数据不同,但是操作是相同的,典型的情形就是切换系统的时候,旧系统的数据需要导入SAP),大致过程不外乎是这样: 输入一个t-code,
进入一个某个屏幕,然后输入一个值(有时还要加上一些附加的checkbox选项等),点执行或者确定按钮,
进入另一个屏幕,在某些字段输入值(也可能是标注checkbox选中或者不选中)或者修改这些字段里的值。
然后按“Eneter”……
最后按“SAVE”……,
一条记录完成了,继续下一条,如此循环。

上面所述的情形,如果让一个“人”来做的话,可能是真是受不了的。但是对于计算机来说,就很简单了。

SAP通过一个特殊的程序(T-code:SHDB)把用户的一次业务操作的所有过程记录下来。

从用户输入transaction code(事务代码),点下“Start Recording”开始,对于用户的来说是一次普通的业务操作,但是SAP却在记录:
1.光标放到哪个字段,(在程序中不用改变)
2.填入了什么值,(变量,循环中的Internal Table 某个字段)
3.点击了什么按钮(在程序中不用改变)

本次操作的作为一个“代表”,是一个“模板”,告诉SAP系统以怎样的方式来执行程序,也就是用计算机的语言来描述如果手工操作的话应该是怎样的一个过程。
 

  用BDC技术编程时,有以下几个步骤:
1.把外部的数据源(Txt,Excel等)用读进internal table或者用do enddo循环。
2.在循环里,把用SHDB记录的步骤重复执行N次,(N = Dialog屏幕数量)这时实际上并没行完成数据的入,系统只是在“填表”,填一个叫做“BDCData”的Internal Table。
填完bdcdata以后,用call transaction ‘XXXX’ using bdc……这个命令来真正的commit动作或者call function 'BDC_Insert'在建立一个session。并把执行的结果返回给messtab这个Internal Table

现在假想一种情境,来做一个演示的BDC程序。
由于业务上的需要,某公司打算将某些物料的描述都在后面加上指定的文本Group X,所以需要修改已经存在的物料数据,用T-code:MM02,

外部数据是TXT文本,记录有N条,如下:

Material NO.     Description
6000-00001      XXXXXXX(Group A)
2098-00001      fdfladsfladfl(Group B )
2059-00009      dfdsfreddfalfasfa(Group A)
2003-00003      iadfdafdf,adfasf(Group D)
……
……
下面是“录”操作的过程,在命令栏里输入T-code :SHDB,进入如下屏幕:

 点New Recodring,出现如下屏幕:

其中Recording 的名字是任意给的。MM02是需要录的事务代码。

按下“Start Recording”,就会进入“Change Material”,这时,以下的操作对于用户来说是一次普通修改物料描述操作,尽管系统在记录所有的操作。


输入一个物料后,点击“Select View(s)”

 

假设我们只选“Basic Data 1”和“Basic Data 1”
然后点击绿色的小勾“Enter”

我们在该物料后面添加一个“Group A”,描述改为:


……

然后点“SAVE”,保存这次修改。

现在SAP回到了SHDB,

先点“SAVE”,保存Recording :Ztest,然后点”Back”,返回SHDB的第一屏。

选中“Ztest”,然后点击“Program”,由SAP自动生成一个程序。


在上面的对话框中输入程序的名字(注意SAP的命名规范,Y或者Z开头),确认输入

再输入一些程序的属性信息如下:

点击“Source Code”,指定“Develop Class”等后,就可以进入ABAP Editor,产生如下代码:

report ZBDCTEST
      no standard page heading line-size 255.

include bdcrecx1.

parameters: dataset(132) lower case.
***    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: MATNR
       MATNR_001(018),
* data element: XFELD
       KZSEL_01_002(001),
* data element: XFELD
       KZSEL_02_003(001),
* data element: MAKTX
       MAKTX_004(040),
* data element: MEINS
       MEINS_005(003),
* data element: MTPOS_MARA
       MTPOS_MARA_006(004),
* data element: GEWEI
       GEWEI_007(003),
     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 'SAPLMGMM' '0060'.
perform bdc_field       using 'BDC_CURSOR'
                             'RMMG1-MATNR'.
perform bdc_field       using 'BDC_OKCODE'
                             '=AUSW'.
perform bdc_field       using 'RMMG1-MATNR'
                             record-MATNR_001.
perform bdc_dynpro      using 'SAPLMGMM' '0070'.
perform bdc_field       using 'BDC_CURSOR'
                             'MSICHTAUSW-DYTXT(02)'.
perform bdc_field       using 'BDC_OKCODE'
                             '=ENTR'.
perform bdc_field       using 'MSICHTAUSW-KZSEL(01)'
                             record-KZSEL_01_002.
perform bdc_field       using 'MSICHTAUSW-KZSEL(02)'
                             record-KZSEL_02_003.
perform bdc_dynpro      using 'SAPLMGMM' '4004'.
perform bdc_field       using 'BDC_OKCODE'
                             '=BU'.
perform bdc_field       using 'BDC_CURSOR'
                             'MAKT-MAKTX'.
perform bdc_field       using 'MAKT-MAKTX'
                             record-MAKTX_004.
perform bdc_field       using 'MARA-MEINS'
                             record-MEINS_005.
perform bdc_field       using 'MARA-MTPOS_MARA'
                             record-MTPOS_MARA_006.
perform bdc_field       using 'MARA-GEWEI'
                             record-GEWEI_007.
perform bdc_transaction using 'MM02'.

enddo.

perform close_group.
perform close_dataset using dataset.

上面的程序的主要逻辑为:

open dataset “读取外部数据源

do.“循环
 
 perform 填充BDCDATA子程序
 perform bdc_transcation

endo.

Close dataset.

注意上面的Include程序里有两个重要的form.

*-------------------------------------------------------------------*
*        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.
 if fval <> nodata.
   clear bdcdata.
   bdcdata-fnam = fnam.
   bdcdata-fval = fval.
   append bdcdata.
 endif.
endform.

另外还有两个重要的internal table声明。bdcdata及messtab

*       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.

选取部分最关键(典型)的代码如下:

do.

read dataset dataset into record.“逐行读出txt文本中的记录,
请参:read dataset
if sy-subrc <> 0. exit. endif.    “如出错就退出

以下执行子程序(粗斜体部分)

屏幕①
A、指定bdc_dynpro的实参,告知系统dialog程序名称:SAPLMGMM,及screen number:0060
perform bdc_dynpro      using 'SAPLMGMM' '0060'.

B、指定bdc_field的实参,告知系统把光标放在哪个字段,这里是“RMMG1-MATNR,物料”
perform bdc_field       using 'BDC_CURSOR'
'RMMG1-MATNR'.
C、告知系统ok_code是什么,也可以认为是去点哪个按钮,这里是左上角的“Select View(s)”
perform bdc_field       using 'BDC_OKCODE'
                            '=AUSW'.
这里是通过read dataset 读取的外部的文件中的记录,record是一个用于临时保存数据的仅有一行的work area。程序在运行进,record-matnr_001应该是一个具体的物料代码。
perform bdc_field       using 'RMMG1-MATNR'
record-MATNR_001.

屏幕②是类似的
perform bdc_dynpro      using 'SAPLMGMM' '0070'.
perform bdc_field       using 'BDC_CURSOR'
                             'MSICHTAUSW-DYTXT(02)'.
perform bdc_field       using 'BDC_OKCODE'
                             '=ENTR'.
perform bdc_field       using 'MSICHTAUSW-KZSEL(01)'
                             record-KZSEL_01_002.
perform bdc_field       using 'MSICHTAUSW-KZSEL(02)'
record-KZSEL_02_003.

③同样先指定程序名称及屏幕号,然后指定光标位置,值,OK_Code
perform bdc_dynpro      using 'SAPLMGMM' '4004'.
perform bdc_field       using 'BDC_OKCODE'
                             '=BU'.
perform bdc_field       using 'BDC_CURSOR'
                             'MAKT-MAKTX'.
perform bdc_field       using 'MAKT-MAKTX'
                             record-MAKTX_004.
perform bdc_field       using 'MARA-MEINS'
                             record-MEINS_005.
perform bdc_field       using 'MARA-MTPOS_MARA'
                             record-MTPOS_MARA_006.
perform bdc_field       using 'MARA-GEWEI'
record-GEWEI_007.

以上的步骤实际上在一个叫做bdcdata的internal table中填入了一些关于调用哪个程序(包括屏幕号码),在哪些字段中,填入什么值,点击什么按钮等信息。
下面的一个步骤才真正的向系统写入数据
call function 'BDC_Insert',建立session,一般是后台运行,能给出Log信息

call transaction不建立session,直接执行。
执行后返回的消息保存在messtab中。

perform bdc_transaction using 'MM02'.

enddo.

perform close_group.
perform close_dataset using dataset.

 

再给一个简明的非SAP自动生成的程序如下(旧版SAP31I),这个程序略去了读取外部数据的程序,没有用循环,只是用Matnr从屏幕上接收用户输入的一个物料。

REPORT ZBDC1 .

TABLES:MARA.

DATA:BEGIN OF BDCDATA OCCURS 0.
    INCLUDE STRUCTURE BDCDATA.
DATA:END OF BDCDATA.

PARAMETERS:MATNR LIKE MARA-MATNR.
PARAMETERS:P_MODE TYPE C DEFAULT 'N'.

START-OF-SelectION.
 PERform PROCESS_CC02.
 PERform PROCESS_CC03.
 PERform PROCESS_CC04.
 PERform PROCESS_CC05.
 CALL TRANSACTION 'MM02' USING BDCDATA MODE P_MODE Update 'S'.
END-OF-SelectION.

form PROCESS_CC02.
  PERform BDC_DYNPRO USING 'SAPLMGMM' '0060'.
  PERform BDC_FIELD  USING 'BDC_OKCODE' '/00'.
  PERform BDC_FIELD  USING 'RMMG1-MATNR' MATNR.
ENDform. "process_cc02

form PROCESS_CC03.
  PERform BDC_DYNPRO USING 'SAPLMGMM' '0070'.
  PERform BDC_FIELD  USING 'BDC_OKCODE' 'ENTR'.
  PERform BDC_FIELD  USING 'MSICHTAUSW-KZSEL(11)' 'X'.
ENDform. "process_cc03

form PROCESS_CC04.
  PERform BDC_DYNPRO USING 'SAPLMGMM' '0080'.
  PERform BDC_FIELD  USING 'BDC_OKCODE' 'ENTR'.
  PERform BDC_FIELD  USING 'RMMG1-WERKS' 'TH10'.
ENDform. "process_cc04

form PROCESS_CC05.
  PERform BDC_DYNPRO USING 'SAPLMGMM' '3000'.
  PERform BDC_FIELD  USING 'BDC_OKCODE' 'BU'.
ENDform. "process_cc05

form BDC_DYNPRO USING PROGRAM DYNPRO.
  CLEAR BDCDATA.
  BDCDATA-PROGRAM = PROGRAM.
  BDCDATA-DYNPRO = DYNPRO.
  BDCDATA-DYNBEGIN = 'X'.
  APPEND BDCDATA.
ENDform.

form BDC_FIELD USING FNAM FVAL.
  CLEAR BDCDATA.
  BDCDATA-FNAM = FNAM.
  BDCDATA-FVAL = FVAL.
  APPEND BDCDATA.
ENDform.


总结一下:
对于一个BDC程序来说,

有两个固定的internal table 需要声明:bdcdata和messtab,名称可以变,但是声明时一定要
*       Batchinputdata of single transaction
data:   abc   like bdcdata    occurs 0 with header line.
*       messages of call transaction
data:   def   like bdcmsgcoll occurs 0 with header line.
Like 后面的table type(这里是一个structure)是不能改变的。

有两个固定功能的form:bdc_dynapro和 bdc_field
名称同样是任意的,但是程序代码应该是相同的,

(强烈建议不要改动,因为会给自己添加麻烦)

另个还有一个Internal Table或者work area是用来放从外部读进来的数据的,结构应该和你的外部文件的有相关的字段结构。

一次读进全部的记录然后循环处理 loop at [internal table] …… process……endloop。
或者一条一条读进并处理,然后循环读下一条 do …… process…… enddo。

其中Process 分为两个部分:1.填充bdcdata表。
                         2.Call transaction or Call Function ‘BDC_Inser’返回消息放入Messtab.

另外有一个经验之谈:

1、录“操作”的时候,不要有“多余”的操作,(什么是多余的操作?自己思考吧)如果有,就重新录吧,不然这些操作也被记录下来,程序每次都要做一些不必要的动作。
2、尽量用鼠标去点击按钮,而不要只是敲“Enter”。
3、光标的位置一般也可以不指定,也就是perform bdc_field using ‘BDC_CURSOR’ ‘XXXX-XXXX’通常可以不用写。不过,据说有时候去了也会出问题,加上去就没了,这个我就不知道了。呵~

 

 

 

 

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也是可以的


下面是我写的一个实例:

*----------------------------------------------------------------------*
* 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
*-----------------------------------------------------------------------
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.


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zcywset15/archive/2008/07/29/2728001.aspx

你可能感兴趣的:(数据结构,C++,c,C#,Excel)