使用 IDoc 开发业务对象

可以在 SAP 中将 ABAP 扩展模块的 WebSphere 业务对象定义为 IDoc。IDoc 是 SAP 的 EDI 解决方案(称为 ALE,应用程序链接启用)的一部分。它们的定义存储在 SAP 的 BOR(业务对象资源库)中,且可以在 SAP 系统中在全局范围访问它。这利用 ALE 的定义部分来解释 SAP 应用程序中的 WebSphere 业务对象并对它们进行语法分析,以准备好供 SAP 本机 API 使用。适配器提供了一个 IDoc 处理程序,该 IDoc 处理程序支持使用 IDoc 开发的业务对象。

IDoc 处理程序包含两个功能模块。其它 ABAP 处理程序(例如,“动态检索”和“动态事务”)只包含单个功能模块。

/CWLD/RFC_DO_VERB_NEXTGEN 将业务对象数据传递至 IDoc 处理程序 /CWLD/IDOC_HANDLER。此 IDoc 处理程序(它是所有对象类型通用的)使用业务对象的特定于应用程序的信息来获得指定的 IDoc 的类型,并用该业务对象数据重新组成该 IDoc 的结构。在它重新格式化数据之后,通用 IDoc 处理程序将把业务对象数据传递至特定于对象的 IDoc 处理程序(基于业务对象类型与它的查询描述的组合),该过程处理与 SAP 本机 API 的集成。在特定于对象的 IDoc 处理程序完成对业务对象数据的处理之后,它以 IDoc 格式将业务对象数据返回至 /CWLD/IDOC_HANDLER。此通用 IDoc 处理程序现在将业务对象数据转换为它的原始格式并将它返回至 /CWLD/RFC_DO_VERB_NEXTGEN

图 75 举例说明了 IDoc 处理程序的基本体系结构。

图 75. IDoc 处理程序体系结构


要使用适配器提供的 IDoc 处理程序,您必须在 SAP 应用程序中定义 IDoc。可以使用 SAP 交付的或客户构建的 IDoc。因为 IDoc 定义必须反映 SAP 的 WebSphere 业务对象的定义,所以适配器提供 SAPODA 来基于 IDoc 生成 WebSphere 业务对象定义。

使用 SAPODA 来生成业务对象定义

可以使用 SAPODA 来基于 IDoc 生成 ABAP 扩展模块的业务对象定义:

重要提示:
必须以英语登录到 SAP 系统以使用 SAPODA。

当使用 SAPODA 来生成业务对象定义时,可以使用“业务对象设计器”来查看和修改定义。有关使用 SAPODA 的更多信息,请参阅使用 SAPODA 生成业务对象定义

在定义 IDoc 之后,为业务对象必须支持的每个查询描述创建一个功能模块。每个功能都应具有以下接口以确保
/CWLD/IDOC_HANDLER 可以调用它:

*" IMPORTING
 *"        VALUE(OBJECT_KEY_IN) LIKE /CWLD/LOG_HEADER-OBJ_KEY OPTIONAL
 *"        VALUE(INPUT_METHOD) LIKE  BDWFAP_PAR- NPUTMETHD OPTIONAL
 *"        VALUE(LOG_NUMBER) LIKE /CWLD/LOG_HEADER-LOG_NR OPTIONAL 
 *" EXPORTING
 *"        VALUE(OBJECT_KEY_OUT) LIKE /CWLD/LOG_HEADER-OBJ_KEY 
 *"        VALUE(RETURN_CODE) LIKE /CWLD/RFCRC_STRU-RFCRC 
 *"        VALUE(RETURN_TEXT) LIKE /CWLD/LOG_HEADER-OBJ_KEY 
 *" TABLES
 *"        IDOC_DATA STRUCTURE  EDID4
 

IDoc 处理程序和创建、更新和删除查询描述

支持创建、更新和删除操作的 IDoc 处理程序接收已格式化为 IDoc 的业务对象数据。这些操作的角色是将业务对象数据与 SAP 的“调用事务”API 结合在一起并生成对象键。仅会将对象键从 /CWLD/IDOC_HANDLER 传递回连接器,而不会传递业务对象数据。/CWLD/IDOC_HANDLER 将业务对象数据存储在内存中,并将对象键插入父业务对象中标记为 IsKey 的第一个属性中。然后,/CWLD/IDOC_HANDLER 将业务对象数据传递回连接器。

注:
当 WebSphere InterChange Server 是集成代理程序时,因为映射基础结构需要保存 ObjectEventId 以进行动态交叉引用,所以维护业务对象数据非常重要。

下面的样本代码表示以下流:

  1. 初始化全局数据。
  2. 将 IDoc 解构到工作表中。
  3. 构建 BDC。使用 /CWLD/INBIDOC_FRMS0 中的表单来将数据从内部表传送至 BDC 表以在对象之间获取一致的行为。
  4. 创建“调用事务”。
  5. 捕获对象键。

以下样本代码支持 SAP 销售报价创建:

*- Initialize working variables and internal tables
   PERFORM INITIALIZE_IN.
  
 *- I01(MF): Begin IDoc interpretation
   PERFORM LOG_UPDATE(/CWLD/SAPLLOG) USING C_INFORMATION_LOG TEXT-I01
                                      SPACE SPACE SPACE.
  
 *- Interpret IDoc data structure
   IF NOT IDOC_DATA[] IS INITIAL.
  
 *- Move IDoc to internal tables
     PERFORM INTERPRET_IDOC.
  
 *- Check some of the input fields
     PERFORM CHECK_INPUT.
  
 *- If key values were missing, exit function
     IF RETURN_CODE NE 0.
     EXIT.
   ENDIF.
  
 *- E01(MF): No Idoc data lines sent for processing.
   ELSE.
  
     RETURN_CODE = 2.
     RETURN_TEXT = TEXT-E01.
     EXIT.
  
   ENDIF.
  
 *- Build the BDC session for transaction VA21.
   PERFORM BUILD_BDC_VA21.
  
 *- Call Transaction
   PERFORM LOG_UPDATE(/CWLD/SAPLLOG) USING C_INFORMATION_LOG TEXT-I02
                                      'VA21' C_BLANK C_BLANK.
  
   CALL TRANSACTION 'VA21' USING BDCDATA
                            MODE INPUT_METHOD
                          UPDATE 'S'
                        MESSAGES INTO BDC_MESSAGES.
  
 *- Capture return code and object key from transaction
   PERFORM PREPARE_RETURNED_MESSAGE.
  
 ENDFUNCTION.
 

“创建”逻辑具有两个主要功能:

转换 IDOC 结构

“创建”逻辑的第一部分是执行转换任务,该任务将 IDoc 结构中的数据转换为工作数据结构。为此,您需要创建类似于下内容的代码:

loop at idoc_data.
  
     case idoc_data-segnam.
       when 'ZSQVBAK'.                  " Header Data
         move idoc_data-sdata to zsqvbak.
  
       when 'ZSQVBUK'.                  " Status Segment
         move idoc_data-sdata to zsqvbuk.
  
       when 'ZSQVBP0'.                  " Partner Header Level
         move idoc_data-sdata to zsqvbp0.
  
       when 'ZSQVBAP'.                  " Item Detail
         move idoc_data-sdata to zsqvbap.
  
       when 'ZSQVBA2'.                  " Item Detail Part 2
         move idoc_data-sdata to zsqvba2.
  
       when 'ZSQVBUP'.                  " Item Status
         move idoc_data-sdata to zsqvbup.
  
       when 'ZSQVBKD'.                  " Commercial data
         move idoc_data-sdata to zsqvbkd.
  
       when 'ZSQKONV'.                  " Condition
         move idoc_data-sdata to zsqkonv.
  
       when 'ZSQVBPA'.                  " Partner Item Level
         move idoc_data-sdata to zsqvbpa.
  
     endcase.
  
   endloop.
 

创建入站调用事务逻辑

创建逻辑的第二部分执行将数据添加至 SAP 应用程序数据库这一操作。您可以使用提供的功能(例如,BAPI 和 SAP 标准功能),也可以使用定制开发的“调用事务”功能。记住,如果您使用提供的功能,在将来的发行版中它可能会更改。建议您使用“调用事务”而不是写入数据库。“调用事务”允许您开发定制功能,它与 SAP 数据库更改无关,并且特定于您需要的作用域和功能。

要将业务对象数据传递到 SAP 中,可以生成某些 ABAP 代码,其方法是通过使用 IBM WebSphere BI Station(事务 /n/CWLD/HOME)中的“入站向导”和使用 SAP BDC 记录器,也可以手工开发它。

“入站向导”记录创建事务的活动,并使用 BDC 逻辑创建文本文件。对于“销售报价”示例,记录了事务 VA21。

要使用“入站向导”来记录事务 VA21:

  1. 转至 IBM WebSphere BI Station(事务 /n/CWLD/HOME)。
    重要提示:
    当使用 IBM WebSphere BI Station 来生成业务对象定义或 ABAP 处理程序时,您必须以英语登录到 SAP 系统。WebSphere BI Station 日志仅以英语提供。
  2. 在“开发”选项卡上单击“入站向导”按钮。
  3. 输入以下信息:
  4. 单击“记录”。
  5. 逐步执行支持业务对象功能的事务。使用所有必需的字段和屏幕。完成时,保存事务。
  6. 选择想要包括为业务对象中的元数据的组件。将光标放在该组件上,然后单击“选择/取消选择子树”按钮(F9)。缺省情况下,将选择所有组件。
  7. 生成新的动态对象或源代码。

以下样本代码摘录自生成的 BDC 会话的前面几行:

* Sales doc. Initial screen Create
 perform dynpro_new using 'SAPMV45A' '0101' .
  
 * Sales document type
 perform dynpro_set using 'VBAK-AUART' 'QT' .
  
 * Distribution channel
 perform dynpro_set using 'VBAK-VTWEG' 'sourcefield' .
  
 * Division
 perform dynpro_set using 'VBAK-SPART' 'sourcefield' .
  
 * Function Command
 perform dynpro_set using 'BDC_OKCODE' '=ENT2' .
  
 * 4.0: Screen Container for Overview Screens (normal header)
 perform dynpro_new using 'SAPMV45A' '4001' .
  
 * Sold-to party
 perform dynpro_set using 'KUAGV-KUNNR' '238' .
  
 * Ship-to party
 perform dynpro_set using 'KUWEV-KUNNR' '238' .
  
 * Function Command
 perform dynpro_set using 'BDC_OKCODE' '=KKAU' .
  
 * 4.0: Screen container for document header screens
 perform dynpro_new using 'SAPMV45A' '4002' .
  
 * Date until which bid/quotation is binding (valid-to date)
 perform dynpro_set using 'VBAK-BNDDT' '20000630' .
 

还可以使用 SAP 的 BDC 记录器(事务 SHDB)。以下样本代码是使用 BDC 记录器生成的:

start-of-selection. 
  
 read dataset dataset into record.
  if sy-subrc <> 0. exit. endif.
  
  perform bdc_dynpro      using 'SAPMV45A' '0101'.
  perform bdc_field       using 'BDC_CURSOR'
                                'VBAK-AUART'.
  perform bdc_field       using 'BDC_OKCODE'
                                '=ENT2'.
  perform bdc_dynpro      using 'SAPMV45A' '4001'.
  perform bdc_field       using 'BDC_OKCODE'
                                '=KKAU'.
  perform bdc_field       using 'BDC_CURSOR'
                                'KUWEV-KUNNR'.
  perform bdc_field       using 'KUAGV-KUNNR'
                                record-KUNNR_001.
  perform bdc_field       using 'KUWEV-KUNNR'
 

此方法的输出没有来自第一个方法的业务对象注释,不是太可取。使用 SAP 的 BDC 记录器的优点是它生成独立的方法来验证 BDC 的记录。

另一种方法是手工生成 BDC。对于整个创建功能建议不要采用此方法,它只不过是对先前方法的补充。如果输入数据导致 SAP 事务产生更多屏幕或弹出框,则这种方法在需要为这些屏幕或弹出框添加逻辑时很有用。

IDoc 处理程序和检索查询描述

支持“检索”查询描述的特定于对象的 IDoc 处理程序不接收来自 /CWLD/IDOC_HANDLER 的业务对象数据。实际上,/CWLD/IDOC_HANDLER 使用特定于对象的 IDoc 处理程序功能的 OBJECT_KEY_IN 参数,仅传递标记为 IsKey 的第一个属性的值。特定于对象的 IDoc 处理程序负责使用此属性的值来检索与使用 ABAP SQL 的业务对象的实例相关的所有信息,并以适当的 IDoc 结构来格式化这些数据。

注:
在键是由多个字段组成的情况下,事件检测机制(或者,当 WebSphere InterChange Server 是集成代理程序时,则为映射)将这些字段的值并置成顶级业务对象的第一个键属性。/CWLD/IDOC_HANDLER 采用此并置键并将它装入其 OBJECT_KEY_IN 参数。特定于对象的 IDoc 处理程序必须将 OBJECT_KEY_IN 参数的值语法解析为多个键字段。要维护此功能,使用 /CWLD/IDOC_HANDLER 时不要为该键指定名称-值对。

下面的代码片段举例说明了用于检索“销售报价”的特定于对象的 IDoc 处理程序。“销售报价”业务对象从 VBAKVBUKVBPOVBAPVBUPVBKDKNOVVBPA 这些表中检索数据。这些表遵循 IDoc 类型 ZSLSQUOT 的层次结构和基数。该代码执行下列操作:

  1. 初始化全局数据。
  2. 从 SAP 应用程序数据库返回业务对象数据。
  3. 根据返回的数据构建 IDoc 并将该数据返回至 /CWLD/IDOC_HANDLER

IDoc 类型 ZSLSQUOT 的特定于对象的 IDoc 处理程序代码片段是:

*- Clear the interface structures.
   clear: g_text, object_key_out, return_code, return_text, idoc_data.
   refresh: idoc_data.
  
 *  If no key value is specified, log it as an error and exit.
   if object_key_in is initial or
      object_key_in = c_cxignore_const.
     perform log_update(/cwld/sapllog) using c_error_log text-e02
                                      space space space.
     return_code = 1.
     return_text = text-e02.
     exit.
   endif.
  
   perform initialize_global_structures.
  
   perform fill_internal_tables.
   if not return_code is initial.
     exit.
   endif.
  
 * Build Idoc segments from internal tables
   perform fill_idoc_inttab.
  
   return_code = 0.
   return_text = text-s01.
  
   perform log_update(/cwld/sapllog) using c_information_log text-s01
                                      space space space.
 endfunction.
 

两个最重要的参数是表示入站键的 OBJECT_KEY_IN 和表示出站数据的 IDOC_DATA。注意,OBJECT_KEY_IN 可能是一个表示多键的并置字符串(这取决于您定义的约定)。特定于对象的 IDoc 处理程序对并置值进行语法分析,并将它的各个部分装入适当的键字段。要维护此功能,使用 /CWLD/IDOC_HANDLER 时不要为该键指定名称-值对,这一点很重要。

VBAK 表驱动子表的选择标准,因此将把每个表都装入工作表中。您可以使用 VBAK 表来检索具有其它键的子表。因此,对于“销售报价”示例,代码如下所示:

form fill_internal_tables.
  
   * Get information from VBAK, VBUK, VBAP, VBKD, KONV, VBPA
  
   select single * from vbak
          where vbeln = object_key_in.
  
   if sy-subrc <> 0.
     perform log_update(/cwld/sapllog) using c_error_log text-e01
                                  object_key_out c_blank c_blank.
     return_code = '1'.
     g_text = text-e01.
     replace '&' with order_number into g_text.
     return_text = g_text.
  
     exit.
   endif.
  
   select single * from vbuk
          where vbeln = vbak-vbeln.
  
   select * from vbap into table t_vbap
          where vbeln = vbak-vbeln.
  
   * Continue for other tables
 

以下代码用来将请求的数据从应用程序数据库复制到内部表和工作变量。然后,该代码创建直接对应于 WebSphere 业务对象定义的段并将这些段放置在 SAP 段结构中。

在某些情况下,为了使 IDoc 类型和工作结构之间的字段紧密匹配,您可以执行对应于 ABAP 移动的命令。在其它情况下,将字段从工作表手工移动至 IDoc 类型表更可取,因为只需要移动相对较少的字段而不是移动结构中的所有字段。不过,它只用来将数据从工作数据结构转换为 IDoc 结构,然后转换为平面数据字段。

代码为:

form fill_idoc_inttab.
  
 perform fill_zsqvbak." Fill the Sales Quote Header
 perform fill_zsqvbuk." Fill the Sales Quote Status
 perform fill_zsqvbap." Fill Sales Quote Lines
  
 endform." FILL_IDOC_INTTAB
  
 *-- fill the Sales Quote Header
 form fill_zsqvbak.
  
     clear idoc_data.
   clear zsqvbak.
   idoc_data-segnam = 'ZSQVBAK'.
  
   move-corresponding vbak to zsqvbak.
   move zsqvbak to idoc_data-sdata.
     append idoc_data.
  
 endform." FILL_ZSQVBAK
  
 *-- fill the Sales Quote Header Status
 form fill_zsqvbuk.
  
     clear idoc_data.
   clear zsqvbuk.
   idoc_data-segnam = 'ZSQVBUK'.
  
   move-corresponding vbuk to zsqvbuk.
   move zsqvbuk to idoc_data-sdata.
     append idoc_data.
  
 endform." FILL_ZSQVBAK
  
 *-- fill the Sales Quote Line and the Line Child segments
 form fill_zsqvbap.
  
   loop at t_vbap.
     clear idoc_data.
     clear zsqvbap.
     idoc_data-segnam = 'ZSQVBAP'.
  
     move-corresponding t_vbap to zsqvbap.
     move zsqvbap to idoc_data-sdata.
     append idoc_data.
  
     perform fill_zsqvba2.
     perform fill_zsqvbup.
     perform fill_zsqvbkd.
     perform fill_zsqkonv.
     perform fill_zsqvbpa.
  
  
   endloop.
  
 endform.
  
 *-- fill second part of vbap
 form fill_zsqvba2.
 " etc.
 

Copyright IBM Corp. 1997, 2004