18.4. IDoc
IDoc是基於文檔,用作異步傳輸數據的載體,類似於XML
18.4.1. 數據段類型和數據段定義(WE31)
數據段是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中的數據段類型實質會在數據字典中的創建相應的結構,如上圖數據段類型E1FIKPF:
18.4.2. IDoc定義(WE30)
IDoc類型中定義了數據段以及數據段的層級和次序
標准SAP系統提供的IDoc類型稱為基本類型(Basic type),該類型可以通過IDoc擴展(Extention)進行調整,即在SAP IDoc類型結構的基礎上增加新的數據段或者在數據段中增加新字段
如果是自己完全創建一個新的類型,不擴展任何類型,則選擇“Basic Type”,否則如果是要從已存在類型來擴展出新的類型時,需要選擇“Extension”,並且需要指定basic type
18.4.3. 自定義IDoc發送與接收實例
該實例使用800發送端向810接收端發送Idoc進行實驗
18.4.3.1. 發送端800(outbound)配置
1、創建segment(WE31)
segment,類似於創建XML的節點及節點屬性,即定義XML文檔中的節點及節點屬性。
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發送過程中出現什么問題,會向此用戶發送郵件。當上面信息填好后,點擊保存(保存之后才可以對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的相關配置
18.4.3.2. 接收端810(Inbound)配置
由於該實例是在同一服務器的同一實例中進行的,又由於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事務,繼續處理出錯的消息,最后發現處理成功:
調試程序時,發現數據也傳遞過來了:












































![image365[1] image365[1]](/image/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNzE3NjE0LzIwMTUwMi8wMTE0NTMxOTc2OTQzOTcucG5n.png)



