SAP BDC(Batch Data Conversion )技术之我见

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

如果数据量非常大的话,让一个“人”来做的话,可能是真是受不了的。但是对于计算机来说,就很简单了。
SAP通过一个特殊的程序(T-code:SHDB)把用户的一次业务操作的所有过程记录下来。
从用户输入transaction
code(事务代码),点下“Start
Recording”开始,对于用户的来说是一次普通的业务操作,但是SAP却在记录:
1.光标放到哪个字段,(在程序中不用改变)
2.填入了什么值,(变量,循环中的Internal
Table
某个字段)
3.点击了什么按钮(在程序中不用改变)
本次操作的作为一个“代表”,是一个“模板”,告诉SAP系统以怎样的方式来执行程序,也就是用计算机的语言来描述如果手工操作的话应该是怎样的一个过程。
在实际应用中,有两种方法生成BDC数据,一种就是上面提到的先把数据导入到内表中,另一种就是直接通过程序中处理的数据循环调用BDC子程序。
BDC中的两个非常重要的子例程是
*----------------------------------------------------------------------*
*       
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.
第一个子程序是记录当前程序进入了哪个屏幕,第二个程序是记录用户想要在屏幕字段上输入的字段值,
只要循环调用这两个子程序,即可生成bdcdata.
生成bdcdata之后,调用事务码如下:
   
CALL TRANSACTION 'MEK1' USING bdcdata MODE 'E' UPDATE 'S'
           
MESSAGES INTO itab_msg.


以上两个子程序可以被直接COPY到自己的程序中使用,碰到特殊数据时进行修改使用,这是BDC 的核心程序。


要仔细研究!
二、实例
具体步骤是:t-code:shdb-->new recording-->record
name,tranzaction code-->enter(start recording)
回车之后就会进入你想要调用的事务码中


图1
一步一步完成需要的操作,就会出现你刚才操作的记录,这记录你操作的整个过程,包含你的输入值,你操作的功能码等等。如图2.



退出到shdb界面。保存刚才的操作点-->program,输入程序名-->
程序描述-->点源代码进入程序


刚才的所有操作就会生成BDC程序,其实包含你所输入的数据,以及你所操作的功能码
参考生成的程序,调用BDC进行数据操作。具体生成的代码如下:
report
ZZZZ
       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: KSCHA
        KSCHL_001(004),
* data element:
EKORG
        EKORG_002(004),
* data element: WERKS_D
       
WERKS_003(004),
* data element: ELIFN
        LIFNR_004(010),
* data
element: EMLIF
        ZZEMLIF_005(010),
* data element: MATNR
       
MATNR_01_006(018),
* data element: KODATAB
        DATAB_007(010),
*
data element: KODATBI
        DATBI_008(010),
* data element:
KSTBM
        KSTBM_01_009(019),
* data element: KSTBM
       
KSTBM_02_010(019),
* data element: KBETR
        KBETR_01_011(016),
*
data element: KBETR
        KBETR_02_012(016),
* data element:
KODATAB
        DATAB_013(010),
* data element: KODATBI
       
DATBI_014(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 'SAPMV13A' '0100'.
perform bdc_field       using 'BDC_CURSOR'
                             
'RV13A-KSCHL'.

perform bdc_field       using
'BDC_OKCODE'
                              '/00'.
perform bdc_field       using 'RV13A-KSCHL'
                              record-KSCHL_001.
perform bdc_dynpro      using 'SAPMV13A' '1506'.
perform bdc_field       using 'BDC_CURSOR'
                             
'KOMG-MATNR(01)'.

perform bdc_field      
using 'BDC_OKCODE'

                              '/00'.
perform bdc_field       using 'KOMG-EKORG'
                              record-EKORG_002.
perform bdc_field       using 'KOMG-WERKS'
                              record-WERKS_003.
perform bdc_field       using 'KOMG-LIFNR'
                              record-LIFNR_004.
perform bdc_field       using 'KOMG-ZZEMLIF'
                             record-ZZEMLIF_005.
perform bdc_field       using
'KOMG-MATNR(01)'

                              record-MATNR_01_006.
perform bdc_dynpro      using 'SAPMV13A' '1506'.
perform bdc_field       using 'BDC_CURSOR'
                             
'TEXT_DEFAULT-TEXT(01)'.

perform
bdc_field       using 'BDC_OKCODE'

                              '=PSTF'.
perform bdc_dynpro      using 'SAPMV13A' '0303'.
perform bdc_field       using 'BDC_CURSOR'
                             
'KONM-KBETR(02)'.

perform bdc_field      
using 'BDC_OKCODE'

                              '/00'.
perform bdc_field       using 'RV13A-DATAB'
                              record-DATAB_007.
perform bdc_field       using 'RV13A-DATBI'
                              record-DATBI_008.
perform bdc_field       using
'KONM-KSTBM(01)'

                              record-KSTBM_01_009.
perform bdc_field       using
'KONM-KSTBM(02)'

                              record-KSTBM_02_010.
perform bdc_field       using
'KONM-KBETR(01)'

                              record-KBETR_01_011.
perform bdc_field       using
'KONM-KBETR(02)'

                              record-KBETR_02_012.
perform bdc_dynpro      using 'SAPMV13A' '0303'.
perform bdc_field       using 'BDC_CURSOR'
                             
'KONM-KSTBM(01)'.

perform bdc_field      
using 'BDC_OKCODE'

                              '=SICH'.
perform bdc_field       using 'RV13A-DATAB'
                              record-DATAB_013.
perform bdc_field       using 'RV13A-DATBI'
                              record-DATBI_014.
perform bdc_transaction using 'MEK1'.


enddo.


perform close_group.
perform close_dataset using dataset.


代码说明:


代码中红色部分就是生成的BDC操作,你可以根据需要进行必要的修改,以实现你需要的功能。


代码中蓝色的部分就是需要提供的输入值,你可以把值上传到BDC
RECORD中,也可以从程序的内表中


读取你所需要填入的值。如果是只导入数据,比如是主数据导入
,就可以把数据先上传到内表中,然后进行BDC操作。


如果是调用事务码进行某些操作,只要把数据填到适当的位置就可以了。
代码中黄色的部分是指当前正在处理的程序名以及屏幕号。


代码中紫色的部分是指当前光标所在的位置。即屏幕上第几行的哪个字段上。也就是当前是往这个字段填值。


代码中“表名-字段名(编号)”是指当前是在往屏幕上的这个字段的第几行填值。在这里,如果有多行需要数据输入,可以采用循环的方式进行,但是循环的时候需要用concatenate字符串连接来实现()内编号的递增。保证填入数据的正确性。这是一个细致的工作,但是只要按步骤来,应该不会出错的。


例如表itab中存放着所有需要的数据。并且屏幕上需要输入5行数据,每行三个字段。这时我们可以这样实现。


data: t1,t2,t3.
"注t1,t2,t3与每行的三个字段类型相一致


data m type c.


perform bdc_dynpro
using '程序名' '屏幕号'.    "进入屏幕


perform bdc_field
using 'BDC_CURSOR' '表名-字段名(01)'.


perform bdc_field
using 'BDC_OKCODE' '功能码'.


loop at itab into wa.


m = sy-tabix.


concatenate '表名-字段名(' m ')' into t1.


concatenate
'表名-字段名(' m ')' into t2.


concatenate
'表名-字段名(' m ')' into t3.


perform bdc_field using  t1 wa-t1.


perform bdc_field
using  t2 wa-t2.


perform bdc_field using  t3 wa-t3.


endloop.


对于多行输入或者从一个屏幕进入另一个屏幕之后需要多行输入的可以使用这种循环嵌套的方法实现


减少了代码重复。对于数据量很小的可以直接逐行填值。


代码中灰色部分“BDC_OKCODE“
”/00“等是指你所操作的功能码。包括回车,保存,双击等。分清功能码也是一项非常重要的工作。当这些工作都做完之后。所需要的bdcdata也就生成了。这时只需要使用bdcdata调用事务码就可以了。


CALL TRANSACTION 'MEK1' USING bdcdata MODE 'E'
UPDATE 'S'
            MESSAGES INTO itab_msg.


三、问题


当然,有时会遇到这样的情况,就是在遇到金额或者单位或者数量时,往往会出现错误提示:输入的字段比实际字段长。这时我们想明明输入的值和字段字义是一样的,为什么会出现这种错误提示呢?
其实这是做BDC的时候最需要注意的事,因为字段类型虽然一样,但是我们保存到BDCDaTA中的时候,数值等是按照默认长度保存的,但是我们输入的时候需要都这些多余的字符串删除掉,这时我们就需要对数据进行处理,有两种处理方法,一种就是用SHIFT移位操作删除多余的字符串,也可以通过修改子例程BDC_FIELD来实现。
假设我们需要输入金额,用第二种方法来实现,就可以这么修改子例程BDC_FIELD。
  DATA: it LIKE
bsid-dmbtr,
        fval2(13) TYPE c.
  IF fval <> it.
    MOVE
fval TO fval2.
    CLEAR bdcdata.
    bdcdata-fnam = fnam.
   
bdcdata-fval = fval2.
    APPEND bdcdata.
 
ENDIF.
调用的时候遇到金额、数量或者单位时,就定义这样一个子例程来供调用。就不会出现错误提示了。


对于出现单位在中文中没有定义的错误,可以参考http://www.cnblogs.com/clsoho/archive/2010/03/08/1680614.html

posted on 2012-04-13 11:48  小顾问  阅读(2543)  评论(0编辑  收藏  举报