IDoc
IDoc(wedi)
IDoc:intermediate(媒介)document
IDoc是一种系统间通用的数据交换格式,通过IDoc接口可以实现SAP系统之间以及SAP系统与其他系统之间的数据交换。
基于IDoc的应用技术有:
ALE:多用于同一个企业中不同SAP系统之间的数据交换,通过IDoc格式的数据创建分布式系统
EDI(electronic data exchange,电子数据交换):用于实现不同企业间的电子数据交换
IDoc的事务码比较多,不常用的话记不住,但SAP提供了一个事务码列出的基本上所有的IDoc相关的事务码,即wedi,运行结果如下:
Process code处理代码设定(WE41、WE42、WE40、WE64)
处理代码用于确定数据写入IDoc或从IDoc读取的处理方式,处理代码对应具体的功能模块或者工作流。入站和出站处理的伙伴参数中都可以指定处理代码
对于IDoc异常处理,有如下两种类型的处理代码,通过WE40进行设置:
系统处理代码,应用于入站或出站过程中的IDoc异常重处理
状态处理代码,应用于状态确认过程中的异常处理
消息类型和处理代码之间的关系是多对多,即一个消息类型的处理可通过多个处理代码实现;而一个处理代码也可以应用于多个消息类型。要查看一个业务过程中消息类型的可用处理代码,可以首先找到该消息类型,然后通过事务WE64列出消息类型全部可用处理代码:
Idoc生成XML(WE60)
Tools--ALE--ALE Administration--Services--Documentation进入文档工具,可选输出为XML
基本概念
ALE
ALE(Application Link and Enabling)是SAP专门为SAP与SAP之间所设计的整合中间件。ALE从SAP 3.0版本开始就作为SAP整个应用体系的一部分,分布式数据交换提供了可靠安全的通讯机制。ALE的设计,原本作为两个SAP流程之间的一种消息传递服务,使SAP与SAP的业务流程之间数据能够有效的交换,为两个独立的SAP系统提供整合服务。不过随着应用的发展,ALE接口机制也成为了其它非SAP系统的标准整合方式。
EDI
EDI(Electronic Document Interchange,电子数据交换)其实就是采用标准格式的电子数据,用于在通讯网络中在业务伙伴间交换业务文档所用。你可这样理解EDI,就是大家都按相同的排列放置数据到一个数据文档中,并按相同的排列解析此文档以得到所需的内容。 EDI又被叫做无纸化交换。
IDoc
IDoc(Intermediate Document,中转文档)是SAP提供的系统整合专用的数据/消息格式,它通过ALE方式来进行交换,而SAP就是IDoc提供了EDI的支持,你也可以把IDoc认为是EDI的一个实现。
交换
EDI的交换有两个流程:
? 外发(Outbound process或简称OP)
接收(Inbound process或简称IP)
SAP也是完全遵循着EDI的这两个流程,并做了相应的实现。在外发过程中:
1. 应用文档被创建
2. IDoc生成
3. IDoc从SAP传送到操作系统
4. IDoc被转换成EDI标准格式
5. EDI文件被传送到业务伙伴处(所以业务伙伴可以没有SAP,因为EDI是个标准)
6. EDI子系统将传送的状态回报给SAP
在接收过程中:
1. EDI文档被接收
2. EDI文档被转换成IDoc
3. IDoc传送到SAP层
4. 应用文档在SAP中创建
5. 应用文档现在可供浏览了
IDoc的特性
每个IDoc都被分派了唯一的号码,用于跟踪及其后参考所用
IDoc包含多个段(segment),而段内包含有多个字段
IDoc包含有三种类型的记录:一条控制记录,一个或多个数据记录,一个或多个状态记录
端口(Port)
端口用于外发流程,它判断EDI子系统程序名称、IDoc文件传送到操作系统的目录,IDoc文件名和RFC目的地
RFC目的地
用于定义到远程系统通讯连接的特性以及需要调用何种功能
Partner Profile
Partner Profile指定在外发过程中所用的各类组件(业务伙伴号、IDoc类型、信息类型、端口、处理码等),通讯方式(异步或同步)以及当错误时通知何人
IDoc定义及扩展(WE30)
IDoc type:IDoc结构,不同的SAP业务对象对应不同的IDoc类型(一个或多个)。IDoc类型中定义了数据段以及数据段的层级和次序
标准SAP系统提供的IDoc类型称为基本类型(Basic type),该类型可以通过IDoc扩展(Extention)进行调整,即在SAP IDoc类型结构的基础上增加新的数据段或者在数据段中增加新字段
通过事务码WE30,可以查看IDoc类型的定义结构:
如下面的FIDCCP01 IDoc类型对应于业务对象:账务凭证(FI Document):
从上图可以看出 IDoc类型中的数据段有层级的
IDoc基本类型(Basic type)、扩展(Extension)类型
如果是自己完全创建一个新的类型,不扩展任何类型,则选择“Basic Type”,否则如果是要从已存在类型来扩展出新的类型时,需要选择“Extension”,并且需要指定basic type:
在IDoc的控制记录数据库表中,通过下列字段来确定IDoc类型:
l IDOCTYP,基本类型名称
l CIMTYP,扩展名称
如,ORDERS01是一个SAP标准系统中的IDoc类型:
l 该IDoc类型的控制记录字段IDOCTYP值为ORDERS01;
l 该IDoc类型的控制记录字段CIMTYP为空;
IDoc类型ORDERS01被用户扩展之后,则:
l 该IDoc类型的控制记录字段IDOCTYP值为ORDERS01;
l 该IDoc类型的控制记录字段CIMTYP为其扩展名,如ZORDERS01;
一个标准系统中的IDoc类型只能被扩展一次
除去使用SAP标准或扩展该IDoc类型之外,还可以完全不依赖于SAP标准IDoc,开发新的IDoc类型,并通过为其分配处理代码完成相关处理过程
数据段类型和数据段定义(WE31)
数据段是IDoc的基本结构块,用于存放应用数据。
数据段是IDoc结构组件,是IDoc的构成的单元。它由Segment type(数据段类型)与Segm. definition(数据段定义)两部分组成,其中Segment type的名称与SAP版本无关,但Segm. definition名称是与SAP版本有关的,外部系统就是根据Segm. definition名称来确定当前数据段的版本的:
SAP提供的标准数据段类型定义中,Segment type名称以“E1”开头,而Segm. definition名称则以“E2”开头(如果为用户自定的数据段,则数据段类型名应以“Z1”开头,数据段定义名称应以“Z2”开头),且后面跟上版本号(如上面的006),如数据段类型E1FIKPF对应多个版本的数据段定义(包括最初版本在内共7个版本):
双击006版本,即可查看数据段类型F1FIKPF的最新具体定义,如上上图所示。
IDoc数据段中各个字段的数据类型均为字符类型(如上上图中的Export leng),在出站时已将原数据类型都转换为字符型了。另外,在ABAP程序中,访问IDoc中的具体某个字段时,需要通过Segment type(数据段类型)名而不是Segm. definition(数据段定义)名,如:E1FIKPF-BUKRS,而不是E2FIKPF006-BUKRS之类的。
IDoc Type中的数据段类型实质上都是定义在数据字典中的ABAP结构(如上图数据段类型E1FIKPF ,在SE11显示如下,但数据段之间的层级关系在结构里没有体现出来,再就是层级关系起什么作用?):
IDoc类型定义相关函数
除IDoc类型定义工具外,SAP还提供了一系列与IDoc类型和数据段开发相关的功能模块
函数组EDIM中的SAP内部功能模块用于操作IDoc基本类型和扩展:
IDoc版本控制
通过数据段Segment定义工具 WE31定义段时,版本由工具自动控制,如在定义时,工具会根据当前修改的次数来管理版本号,以下Segm.definition不能输入,是自动生成的:
当前版本发布后,就可以通过按钮增加下一个版本(前提条件是当前版本已经发布):
发布当前版本:
如果在同一个SAP系统版本中(如这里为731)点击按钮增加一个新的版本时,状态栏会出现警告(这是因为在同一SAP版本中不必要创建不同版本的数据段,完全可以先通过菜单“取消发布”后,再次在原来版本上修改数据段),回车,可继续增加新版本:
所以,每个发布创建之后,开发工作都会产生新的IDoc版本。所有旧版本仍然存储于系统中,从而保留了将现有版本回设为旧版本的可能,确保向后兼容,所以同样为了向后兼容,新的IDoc版本相对旧版本只能增加数据段和数据字段,而不能减少
在出站处理过程中,需要通过伙伴参数注明IDoc类型,并指定数据段的SAP发布版本。如果指定一个旧版本的发布,IDoc类型中所有数据段都回设为对应的旧版;如果该字段为空,则使用当前发布相关的最新所有活动版本
在入站处理过程中,不需要再次进行版本相关的设定,IDoc接口将负责识别版(根据Segment数据段名来确定)本并进行数据处理
IDoc其他工具
WE02:IDoc显示工具
WE09:在不知道IDoc类型、伙伴参数等技术细节情况下,有时不能通过IDoc控制记录中的信息来确定一个IDoc,如在需要通过其中所包含的应用数据来确定一个IDoc的情况下。如,需要查找包含物料A001的采购订单,此时就需要通过IDoc查找工具,该工具可以查找数据库及已经归档文件中的IDoc
IDoc状态(BD87)
配置IDoc应用示例
环境介绍
在同一套IDES系统中,将两个client模拟成发送方与接收方。因为所需传送的数据是client相关的,所以这个方案可行。
选择了800作为发送方,而810作为接收方。我将从800发送物料主数据到810中。
操作步骤
第一步为Client创建逻辑系统(SALE)
在ALE过程中,消息在系统之间,每一个ALE分布处理的参与系统必须拥有唯一的ID,这个ID即为逻辑系统。一般一个逻辑系统代指一个集团如果没有两个SAP系统,可以在一个SAP系统中的两个不同的Client端完成。我选择了800作为发送方,而810作为接收方。我将从800发送物料主数据到810中
如果参与ALE的两个集团不在同一SAP系统中,则需要在两边系统中分别为这两个集团设定逻辑系统名称,且要相同;如果是在同一SAP系统中不同集团之间,则只需要进行一次逻辑系统名称的定义即可,因为该设定是跨集团Client的。
第二步为Client指派逻辑系统(SALE)
定义好逻辑系统名后,可将名分配给相关的集团
系统中已经分配了逻辑系统的,只能重新分配了(即修改逻辑系统):
第三步维护RFC目标(SM59)
ALE的通信实例技术是RFC,需要为数据交换的对方维护RFC目标,以建立通信连接。由于是在SAP系统之间通信,所以选择ABAP连接类型
名称最好跟逻辑系统名称一致,以便于自动生成partner profile
第四步在发送端创建Distribution Model(BD64)
分布模型用于描述业务对象在逻辑系统间的分布流程。分布模型视图将所有系统分布情景组织起来集中维护,一旦在其视图中为两个逻辑系统分配了消息类型或BAPI,即建立了两个系统之间的连接
点击“创建模型视图”按钮:
选择刚创建的模型视频,点击“添加消息类型”按钮(或者点击“Add BAPI”以BAPI的方式实例ALE)
第五步在发送系统中创建伙伴参数(BD82)
伙伴参数(partner profile)是Idoc发送和接收过程中的基本连接设定。在ALE中,需要将另一方设为伙伴,定义类型为逻辑系统的伙伴参数,才可完成通信。
输入BD82(或在BD64界面选中上一步所创建的模型视图,则点击菜单,这样在下图中就不用输入模型视图了),在下图中输入分布模型视图(为上一步所创建的模型视图)以及伙伴系统,伙伴系统应该ALE另一方的逻辑系统名,而不是当前系统:
选择执行功能后,系统将自动生成逻辑伙伴、端口(自动分配)以及输出参数。成功生成接收系统810伙伴参数后,日志界面:
第六步检查发送端端口配置(WE21)
IDoc或其状态记录总是通过端口和外部系统进行传递的,是IDoc接口中系统通信相关的基础配置,代表SAP系统和伙伴系统的通信途径。对于每个外部系统都至少需要配置一个端口。在端口配置需指定目标系统
上一步中,从日志发现自动创建了A000000059的端口,并且使用的是前面我们创建RFC目标,可以使用WE21,展开事务性RFC,可以查看:
目标系统使用的是前面创建的RFC接连
6种端口类型,应用于不同的的IDoc传输实现方式:
第七步在发送端修改伙伴参数文件Partner Profile(WE20)
伙伴参数可以通过WE20手工设定,这里是自动生成的
在第五步之后,创建自动产生伙伴参数文件,通过事务代码WE20,可以查看与修改刚创建好的伙伴参数。
每个在ALE过程中需要传输的消息类型都将添加到端口的出站参数中,本例中所需关注的是物料主数据对应的消息类型MATMAS(CREMAS为其他模型视图所生成的):
双击 MATMAS消息,可以对其修改,将基本类型修改为MATMAS01:
第八步向目的端发布Distribution Model(BD64)
在发送系统800中维护了分布模型视图并根据该视图生成接收系统伙伴参数之后,还需在接收系统810中为发送系统维护伙伴参数,但目前接收系统中还不存在ALE分布模型视图,因此不能够自动创建伙伴参数。一个简单的解决方法是:将相关的ALE分布模型视图发布到接收系统中,然后就可以通过同样的视图在目标系统中自动生成发送系统的伙伴参数了,在800系统中,进入BD64界面,并选中MATMAS消息(否则有可能发布不了):
再登录810查看:
第九步在目的端生成Partner profile(BD64)
登录到810,T-code:BD64
选定传输过来的Distribution Model,点击菜单Environment -> Generate Partner Profiles:
第十步检查接收端端口号(WE21)
已经自动建立了端口,并且使用的是此前建立的目标连接
第十一步调整接收端Partner Profile(WE20)
选择新创建的Partner Type:ZCLIENT800,双击Inbound下的MATMAS:
该界面中最重要的内容是处理代码(即为进行具体IDoc处理的功能模块或工作流的代号),数据在所指定的处理中被写入IDoc或是从IDoc中读取出
将其Process code改成MATM,保存。如果你不修改这个,默认情况下它自动选择了以A打头的Process code,而并非物料主数据需要的MATM处理码:
一旦传输数据过来后,相应的处理模型不对应,会产生错误:
至此,整个IDoc发送与接收配置工作已经完成。
测试
第一步在发送方创建物料
上面红框中需要输入,否则接收端可能接收不了。
此时登录到810用T-code:MM03来查找这个物料是不存在的。
第二步发送物料主数据(BD10)
输入你要传输的物料主数据(一定要输的,不然会当前client里的所有物料主数据发送到对端系统去),点执行这时再到810里用MM03就可以查看此物料了
第三步查看发送与接收的IDOC(BD87)
发送端:
接收端:
IDoc进阶应用
数据过滤
第一步在发送端设定过滤(BD64)
登录800,我们回到BD64,看到这个Distribution model下显示的是No filter set,也就是说没有设定过滤。双击No filter set
在新生成的Filter group中双击Material Type:
增加“成品”过滤条件,即只有物料类型为成品的物料才会被传输到目标系统:
最后确认并在BD64界面上保存
第二步在发送端重新分发Distribution model
选中过滤条件,依次点击如图菜单:
打开800检查,可看到已发布成功:
第三步测试
我们先在800端创建两个物料:zjzjmara2、zjzjmara3两个物料,类型分别为成品与半成品
创建完物料后,开始传输测试:
它会生成2个IDoc:
但只有1个会被发送,证明我们的过滤器起作用了:
段及字段过滤
如果只更新某些字段,而不是所有数据时,上面所提到的Distribution model过滤器就无法胜任了。那么又如何解决此问题呢?答案就是通过消息类型来对段及字段进行过滤。
第一步创建自定义消息类型(BD53)
输入此新类型从何处参照而来,这里输的是MATMAS:
这时会出现基于MATMAS下的IDoc数据结构树,其中绿色表示的是必须的字段,而红色表示的是可选的字段。
双击E1MARAM。假如我只想每次更新毛重和净重的值,而其它的值不修改目标系统的值,从弹出窗口列表我选择了BRGEW和NTGEW:
请注意,先钩先,再点击“选择”,最后点确认。点“选择”后,变为绿色:
最后保存,保存之后,查看整体效果:
(消息类型创建完成并保存之后,消息类型名与描述会在WE81中显示出来)
第二步创建物料及发送
T-code:MM01
在发送端800先创建一个新的物料,分别维护了毛重、净重和容量的值:
T-code:BD10
然后,在810中可以看到这个物料的对应值都被传送过来了:
第三步修改Partner profile(WE20)
选逻辑系统ZCLIENT810,在Outbound参数表中,将MATMAS删除,并点添加按钮:
最后结果:
第四步修改并分发Distribution model(BD64)
在发送端800中,删除原来MATMAS消息:
保存后,重新分发一下Distribution model,目的是让接收系统更新Distribution model:
模型修改后,需重新生成partner profile:
第五步修改目的端Partner profile
到接收端810端重新生成partner profile
选择ZCLIEN800,选中Inbound的参数中的MATMAS消息类型,删除它
然后点击新增按钮:
最后消息类型被替换成前面发送端创建新的消息类型了:
第六步测试
在800端,T-code:MM02
修改物料DEMO004,毛重改为400,净重改为300,而容量改为10:
T-code:BD10
发送数据,信息类型选为新建的ZMATMAS_DEMO,执行
再到810,T-code:MM03,看到的值中,毛重和净重已经改变而容量不变
数据转换
也会有这样的业务场景:当数据传输至目的端时,目的端的数值需要做一些转换。
比如仍是这个DEMO004的物料,现在希望其净重等于毛重,而容量是个常量值200:
第一步创建信息类型(BD53)
我现在需要把所有的字段都选择进来,所以先点E1MARAM,再点顶上的Select:
然后双击E1MARAM,从弹出的窗口中点全选按钮后,再点Select,最后确定:
要对所有的树状结构都做相同的操作,如果有子目录,要展开,完成后保存。最后的结果如下:
第二步创建规则(BD62)
创建了自己的规则,针对的是E1MARAM段:
第三步修改规则(BD79)
净重值设定为从毛重值处获取,而容量值为固定的200:
第四步指派规则与消息类型的对应关系(BD55)
第五步修改Partner Profile(WE20)
Outbound参数中选定了新建的消息类型
第六步修改Distribution model(BD64)
替换消息类型,保存并分发
第七步在目的端生成Partner Profile(BD64)
第八步调整目的端Partner profile(WE20)
调整Process code:
调整Inbound的消息类型:
第九步测试
T-code:MM02
只保留了毛重的消息:
T-code:BD10
回到810端进行查看:
自动同步
到目前为止,我们演示的都是手工发送IDoc,但在很多业务场景下,许多数据是需要自动触发来发送IDoc的,比如订单之类的。如何解决呢?SAP提供了Change Pointer这个工具可以帮助我们轻松的搞定这个需求,下面就来演示如何进行操作。
第一步激活Change Pointer(BD61)
在Change pointers activated – generally前打上勾,保存即可
第二步激活消息类型的Change pointer(BD50)
我这个例子中会用到自己的消息类型:ZMATMAS_DEMO2,这个消息类型直接从MATMAS中拷贝而来,只传送毛重、净重和容量三个字段,不做其它操作。
T-code:BD53
T-code:BD50
默认情况下这个消息类型不会出现在列表中,你可以添加,然后在后面的复选框中打上勾
第三步指定消息类型触发Change pointer的条件(BD52)
填入你所想要的对象、表名及字段名,这个示例演示的是当物料主数据中的毛重这个字段发生变化时,会触发Change pointer并生成IDoc发送,保存。
第四步测试
T-code:MM02
将毛重从400改为600,保存
T-code:SE38
运行报表RBDMIDOC
再到目的端810查看,数据修改成功:
另一个实验不再详细截图,即修改其它非毛重的值,再运行ABAP报表(只截了个运行报表时出现的报告,有0个数据产生),则此时目的端数据不会产生更改(因为IDoc没有生成且传送也没有发生):
我们可以将这个ABAP程序安排成后台进程,定期运行,这样就能自动发送设置好触发条件的IDoc了,下面做了个截屏,是用SM36安排后台进程时所做的定义:
只要把这个任务安排成定期执行的后台进程,自动发送就变成可能
自定义IDoc发送与接收实例
idoc是基于sap自己的类似xml格式的文档数据交换的方式。idoc基于文档,可以实现异步的。
该实例使用800发送端向810接收端发送Idoc进行实验
在发送端(outbound)中配置
以下步骤都是在Client 800进行设置
1、创建segment(WE31)
segment,类似于创建XML的节点及节点属性,即定义XML文档中的节点及节点属性。
这里先输入YPOHEAD,点击创建,在接下来的屏幕中,录入EBELN, BUKRS, BEDAT等字段及他们对应的data element:
接着创建YPOITEM,输入EBELN, EBELP, MATNR, MENGE, MEINS等字段及他们对应的data element:
保存后用SE11查看你将发现,系统自动添加了YPOHEAD和YPOITEM两个结构,每个字段都成了CHAR类型,长度就是WE31中的EXPORT LENG(输出长度)。
2、创建IDOC Type(WE30)
创建IDOC Type,定义结点间的相互逻辑关系
先输入YPOIDOC,然后点击创建,紧跟着点击create new进入:
在主界面中,先点击创建按钮,将YPOHEAD添加,设置Mandatory seg打勾,min = 1, max = 1,代表我们每个IDOC仅包含一张采购订单:
然后在YPOHEAD下添加YPOITEM,同样的Mandatory seg打勾,min = 1, max =99999:
3、创建Message Type(WE81)
先切换到编辑状态,然后点击New Entries,输入YPO_MESS_TYPE即可。
4、关联Message Type和IDOC Type(WE82)
5、创建接收端RFC Destination(SM59)
创建一个到接收端810的物理连接,由于是该实例是在同一个SAP系统内部进行实验,所以“连接类型”选择的是ABAP Connection连接,名为ZTO810:
6、创建到收端的端口(WE21)
注:这里讲的端口不是单纯的指定Socket端口号,而是指连接到RFC目标系统的统称,包括IP、端口等信息,实质上是在SM59创建的物理连接基础之上创建的另一种逻辑名而已
基于上面第5步创建的RFC Destionation,创建端口Port,类型选TRANSACTIONAL RFC,名为TO810PORT,RFC destination则填写ZTO810:
7、创建发送端Logical System并分配(SALE)
为发送端800创建逻辑系统 Z800LS:
并将逻辑系统分配到发送端800:
注:这里不需在本端(Client 800)创建此逻辑系统的合作和伴配置文件,但需要在810配置
8、创建接收端Logical System(SALE)
为接收端810创建逻辑系统 Z810LS,这将在下一步创建到接收端的合作伙伴配置文件Partner profile(WE20)时用到:
但与上面创建发送端逻辑系统不一样的是,在发送端系统800中是不需要将它分配给Client 810,但此分配操作需要在接收端810进行,这一分配操作请参考后面接收端(Inbound)配置章节
9、创建接收端合作和伴配置文件Partner profile(WE20)
合作和伴配置文件将Message Type消息类型、receiver port RFC目标端口、IDoc类型关联起来
创建一个patner no为Z810LS的合作和伴配置文件,该配置文件描述了将IDoc发往何处:
上图中合作伙伴编号填上一步创建的接收端逻辑系统,类型选择LS。Ty.选择是“用户”类型,代理人为本系统(发送端800)中的用户,如果在Idoc发送过程中出现什么问题,会向此用户发送邮件,这里要注意的是:这不是目标系统(接收端810)中的用户
当上面信息填好后,点击保存(保存之后才可以对Outbound parmtrs进行设置)。
然后,点击outbound下方的加号,创建一个outbound parameter。Message Type为YPO_MESS_TYPE,receiver port为TO810PORT,output mode选择Transfer idoc immed.,Basic Type填写YPOIDOC,保存即可:
10、通过Abap程序发送IDOC
程序的思路就是,把每个IDOC节点按字符串形式逐个添加,而字符串的添加次序自然也体现了IDOC节点间的逻辑关系。代码如下:
DATA: ls_pohead TYPE ypohead,"IDoc数据段:头
ls_poitem TYPE ypoitem,"IDoc数据段:Item
ls_edidc TYPE edidc,"IDoc的控制记录
lt_edidc TYPE TABLE OF edidc,
lt_edidd TYPE TABLE OF edidd WITH HEADER LINE."IDoc的数据记录
CLEAR ls_edidc.
*系统根据下面4行即可与WE20(合作和伴配置文件)设置关联起来
ls_edidc-mestyp = 'YPO_MESS_TYPE'. "Message Type
ls_edidc-idoctp = 'YPOIDOC'. "IDOC Type
ls_edidc-rcvprn = 'Z810LS'. "partner Number of Recipient接收方合作伙伴
ls_edidc-rcvprt = 'LS'. "partner Type of Receiver接收方类型为逻辑系统
*添加IDOC节点
CLEAR lt_edidd.
lt_edidd-segnam = 'YPOHEAD'."头节点
lt_edidd-dtint2 = 0.
CLEAR ls_pohead.
ls_pohead-ebeln = '4001122334'."采购单号
ls_pohead-bukrs = '1000'."公司代码
ls_pohead-bedat = '20090630'."日期
lt_edidd-sdata = ls_pohead. "节点内容:ls_pohead结构中的数据最后被拼接成字符串再赋值给lt_edidd-sdata,最大长度不能超过1000
APPEND lt_edidd.
CLEAR lt_edidd.
lt_edidd-segnam = 'YPOITEM'."Item节点
lt_edidd-dtint2 = 0.
CLEAR ls_poitem.
ls_poitem-ebeln = '4001122334'."采购单号
ls_poitem-ebelp = '0001'."Item行号
ls_poitem-matnr = '000000000000004527'."物料号
ls_poitem-menge = '3'."数量
ls_poitem-meins = 'ST'."单位
lt_edidd-sdata = ls_poitem.
APPEND lt_edidd.
CLEAR lt_edidd.
lt_edidd-segnam = 'YPOITEM'."Item节点
lt_edidd-dtint2 = 0.
CLEAR ls_poitem.
ls_poitem-ebeln = '4001122334'."采购单号
ls_poitem-ebelp = '0002'."Item行号
ls_poitem-matnr = '000000000000009289'."物料号
ls_poitem-menge = '5'."数量
ls_poitem-meins = 'M'."单位
lt_edidd-sdata = ls_poitem.
APPEND lt_edidd.
CALL FUNCTION 'MASTER_IDOC_DISTRIBUTE'"发送IDoc
EXPORTING
master_idoc_control = ls_edidc "IDoc控制记录
TABLES
communication_idoc_control = lt_edidc "接收:用来接收IDoc发送情况
master_idoc_data = lt_edidd "IDoc数据记录
EXCEPTIONS"
error_in_idoc_control = 1
error_writing_idoc_status = 2
error_in_idoc_data = 3
sending_logical_system_unknown = 4
OTHERS = 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
COMMIT WORK.
WRITE: 'Idoc sent:'.
LOOP AT lt_edidc INTO ls_edidc.
NEW-LINE.
WRITE: 'Idoc number is', ls_edidc-docnum,
'; receiver partner is', ls_edidc-rcvprn,
'; sender partner',ls_edidc-sndprn.
ENDLOOP.
ENDIF.
选中消息,并点击“处理”按钮后,该消息就会发往目的客户端810,状态从准备发送到成功发送:
发送的数据可以选择数据记录节点来查看:
以上都是在发送端800进行的,下面登录到接收端810去看看IDoc接收情况:
由于在接收端810未配置到发送端800的合作伙伴配置文件,所以出错。
下面章节在接收端810中进行发送端800的相关配置
在接收端(Inbound)中配置
以下步骤都是在Client 810进行设置
由于该实例是在同一服务器的同一实例中进行的,又由于Segment、IDoc Type、Message Type这些都是跨Client的,所以上面1、2、3、4步就不需要在810端再次配置了,这些是共享的(但如果不是在同一服务器上,则需要像上面那样进行配置)
1、创建发送端RFC Destination(SM59)
创建一个到发送端810的物理连接
2、创建发送端的端口(WE21)
基于上面创建的RFC Destionation,创建端口Port,类型选TRANSACTIONAL RFC,名为FRM800PORT,RFC destination则填写上面创建的RFC远程目标ZFROM800:
3、将接收端Logical System分配到Client 810(SALE)
如果是在不同的服务器中,则这里需要像在发送端那样:发送端逻辑系统Z800LS与接收端逻辑系统Z810LS都需要被创建,并且还需要将接收端逻辑系统Z810LS分配到Client 810,并且还需要以发送端逻辑系统Z800LS为基础创建发送端合作伙伴配置文件
由于是在同一服务器的同一实例中,所以在发送端中创建的发送端逻辑系统Z800LS与接收端逻辑系统Z810LS在此端是通用共享,这里不需要再次创建(outbound中已经创建了这两个逻辑系统了),但(outbound章节中并未分配到具体的Client)Z810LS逻辑系统没有分配到相应的Client,这一步操作需要在接收端完成,所以需要在此进行分配:
4、创建入站处理函数
创建一个function:Y_IDOC_PO_PROCESS.
当IDOC设置完毕之后,SAP可以自动调用该Funtion Module处理IDOC,所以这个函数的参数接口是有规范的,可以从IDOC_INPUT_BBP_IV这些标准函数拷贝参数接口部分:
"ypohead\ypoitem实为上面定义的IDoc类型
DATA: ls_chead TYPE ypohead,
ls_citem TYPE ypoitem.
CLEAR idoc_contrl.
READ TABLE idoc_contrl INDEX 1.
IF idoc_contrl-mestyp <> 'YPO_MESS_TYPE'.
RAISE wrong_function_called.
ENDIF.
LOOP AT idoc_contrl.
LOOP AT idoc_data WHERE docnum = idoc_contrl-docnum.
CASE idoc_data-segnam.
WHEN 'YPOHEAD'.
"直接将字符赋值给结构,贬值过程中会按照结构中的字段长度来划分各字段
ls_chead = idoc_data-sdata.
WRITE: / 'Head',ls_chead.
WHEN 'YPOITEM'.
ls_citem = idoc_data-sdata.
WRITE: / 'Item',ls_citem.
WHEN OTHERS.
ENDCASE.
ENDLOOP.
"根据数据处理情况设置当前IDoc处理的状态
IF 1 = 0.
CLEAR idoc_status.
idoc_status-docnum = idoc_contrl-docnum."当前正处理的IDoc
idoc_status-status = '53'. "IDOC处理成功
APPEND idoc_status.
ELSE.
CLEAR idoc_status.
idoc_status-docnum = idoc_contrl-docnum.
idoc_status-status = '51'. "IDOC不成功
idoc_status-msgty = 'E'. "错误信息
idoc_status-msgid = 'YMSG'.
idoc_status-msgno = '001'.
APPEND idoc_status.
ENDIF.
ENDLOOP.
ENDFUNCTION.
5、注册入站处理函数(BD51)
填入函数名Y_IDOC_PO_PROCESS,Input Type=1
6、将入站函数与IDOC Type/Message Type关联(WE57)
Function Module输入Y_IDOC_PO_PROCESS,其下的Type填写F;IDOC Type下的Basic Type填写YPOIDOC;Message Type填写YPO_MESS_TYPE;Direction填写2(Inbound)
7、创建Inbound Process Code(WE42)
Process Code输入YPC_PO,在Option ALE下选择Processing with ALE service,在Processing Type下选择function module:
保存后,在随后的窗口中,输入Inbound Module为Y_IDOC_PO_PROCESS。
8、创建发送端合作和伴配置文件Partner profile(WE20)
由于在发送端800中已创建了发送端逻辑系统Z800LS ,所以在此端不需要在创建(发送端逻辑系统Z800LS),只是需要以此为基础创建和伴配置文件:
9、测试 BD87
在接收端810使用BD87,登录进去后,会看到发送端发送过来的IDoc,但由于先前还没有配置发送伙伴配置文件,所以失败了:
现在在入站处理理函数中设置断点:
再执行BD87事务,继续处理出错的消息,最后发现处理成功:
调试程序时,发现数据也传递过来了: