可以在 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 处理程序的基本体系结构。
要使用适配器提供的 IDoc 处理程序,您必须在 SAP 应用程序中定义 IDoc。可以使用 SAP 交付的或客户构建的 IDoc。因为 IDoc 定义必须反映 SAP 的 WebSphere 业务对象的定义,所以适配器提供 SAPODA 来基于 IDoc 生成 WebSphere 业务对象定义。
可以使用 SAPODA 来基于 IDoc 生成 ABAP 扩展模块的业务对象定义:
当使用 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 的业务对象数据。这些操作的角色是将业务对象数据与 SAP 的“调用事务”API 结合在一起并生成对象键。仅会将对象键从 /CWLD/IDOC_HANDLER 传递回连接器,而不会传递业务对象数据。/CWLD/IDOC_HANDLER 将业务对象数据存储在内存中,并将对象键插入父业务对象中标记为 IsKey 的第一个属性中。然后,/CWLD/IDOC_HANDLER 将业务对象数据传递回连接器。
下面的样本代码表示以下流:
以下样本代码支持 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 结构中的数据转换为工作数据结构。为此,您需要创建类似于下内容的代码:
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:
以下样本代码摘录自生成的 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 处理程序不接收来自 /CWLD/IDOC_HANDLER 的业务对象数据。实际上,/CWLD/IDOC_HANDLER 使用特定于对象的 IDoc 处理程序功能的 OBJECT_KEY_IN 参数,仅传递标记为 IsKey 的第一个属性的值。特定于对象的 IDoc 处理程序负责使用此属性的值来检索与使用 ABAP SQL 的业务对象的实例相关的所有信息,并以适当的 IDoc 结构来格式化这些数据。
下面的代码片段举例说明了用于检索“销售报价”的特定于对象的 IDoc 处理程序。“销售报价”业务对象从 VBAK、VBUK、VBPO、VBAP、VBUP、VBKD、KNOV 和 VBPA 这些表中检索数据。这些表遵循 IDoc 类型 ZSLSQUOT 的层次结构和基数。该代码执行下列操作:
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.