[SAP ABAP開發技術總結]IDoc


 

18.4.     IDoc

IDoc是基於文檔,用作異步傳輸數據的載體,類似於XML

18.4.1.           數據段類型和數據段定義(WE31

數據段是IDoc結構組件,是IDoc的構成的單元。它由Segment type(數據段類型)Segm. definition(數據段定義)兩部分組成,其中Segment type的名稱與SAP版本無關,但Segm. definition名稱是與SAP版本有關的,外部系統就是根據Segm. definition名稱來確定當前數據段的版本的:

image335

SAP提供的標准數據段類型定義中,Segment type名稱以“E1”開頭,而Segm. definition名稱則以“E2”開頭(如果為用戶自定的數據段,則數據段類型名應以“Z1”開頭,數據段定義名稱應以“Z2”開頭),且后面跟上版本號(如上面的006),如數據段類型E1FIKPF對應多個版本的數據段定義(包括最初版本在內共7個版本):

image336

雙擊006版本,即可查看數據段類型F1FIKPF的最新具體定義,如上上圖所示

 

IDoc數據段中各個字段的數據類型均為字符類型(如上上圖中的Export leng),在出站時已將原數據類型都轉換為字符型了。另外,在ABAP程序中,訪問IDoc中的具體某個字段時,需要通過Segment type(數據段類型)名而不是Segm. definition(數據段定義)名,如:E1FIKPF-BUKRS,而不是E2FIKPF006-BUKRS之類的。

 

IDoc Type中的數據段類型實質會在數據字典中的創建相應的結構,如上圖數據段類型E1FIKPF

image337

18.4.2.           IDoc定義(WE30

IDoc類型中定義了數據段以及數據段的層級和次序

image338

標准SAP系統提供的IDoc類型稱為基本類型(Basic type),該類型可以通過IDoc擴展(Extention)進行調整,即在SAP IDoc類型結構的基礎上增加新的數據段或者在數據段中增加新字段

image339

如果是自己完全創建一個新的類型不擴展任何類型則選擇Basic Type”,否則如果是要從已存在類型來擴展出新的類型時需要選擇Extension”,並且需要指定basic type

image340

18.4.3.           自定義IDoc發送與接收實例

該實例使用800發送端向810接收端發送Idoc進行實驗

18.4.3.1.       發送端800outbound)配置

1、創建segmentWE31

segment類似於創建XML的節點及節點屬性,即定義XML文檔中的節點及節點屬性

image341

image342

2、創建IDOC TypeWE30

創建IDOC Type,定義結點間的相互邏輯關系

先輸入YPOIDOC,然后點擊創建,緊跟着選擇create new

image343

在主界面中,先點擊創建按鈕,將YPOHEAD添加,設置Mandatory seg打勾,min 1 max 1,代表我們每個IDOC僅包含一張采購訂單

image344

然后在YPOHEAD下添加YPOITEM,同樣的Mandatory seg打勾,min 1 max 99999

 image345

image346

3、創建Message TypeWE81

 先切換到編輯狀態,然后點擊New Entries,輸入YPO_MESS_TYPE即可。

image347

4、關聯Message TypeIDOC TypeWE82

image348

5、創建接收端RFC DestinationSM59 

創建一個到接收端810物理連接,由於是該實例是在同一個SAP系統內部進行實驗,所以“連接類型”選擇的是ABAP Connection連接,名為ZTO810

image349

image350

6、創建到收端的端口(WE21 

注:這里講的端口不是單純的指定Socket端口號,而是指連接到RFC目標系統的統稱,包括IP、端口等信息,實質上是在SM59創建的物理連接基礎之上創建的另一種邏輯名而已

基於上面第5步創建的RFC Destionation,創建端口Port,類型選TRANSACTIONAL RFC,名為TO810PORTRFC destination則填寫ZTO810

image351 image352

7、創建發送端Logical System並分配(SALE 

為發送端800創建邏輯系統 Z800LS

image353 image354

並將邏輯系統分配到發送端800

image355 image356

注:這里不需要為本端(Client 800)在本端創建發送端邏輯系統的合作和伴配置文件,但需要在接收端810中配置

8、創建接收端Logical SystemSALE 

為接收端810創建邏輯系統 Z810LS,這將在下一步創建到接收端的合作伙伴配置文件Partner profileWE20)時用到:

image357

但與上面創建發送端邏輯系統不一樣的是,在發送端系統800中是不需要將它分配給Client 810,而分配操作是在接收端810中進行的,這一分配操作請參考后面接收端(Inbound)配置章節

9、創建接收端合作和伴配置文件Partner profileWE20 

合作和伴配置文件將Message Type消息類型receiver port RFC目標端口IDoc類型關聯起來

創建一個patner noZ810LS的合作和伴配置文件,該配置文件描述了將IDoc發往何處

image358

上圖中合作伙伴編號填上一步創建的接收端邏輯系統,類型選擇LSTy.選擇是“用戶”類型,代理人為本系統(發送端800)中的用戶,如果在Idoc發送過程中出現什么問題,會向此用戶發送郵件。當上面信息填好后點擊保存保存之后才可以對Outbound parmtrs進行設置

然后點擊outbound下方的加號創建一個outbound parameterMessage TypeYPO_MESS_TYPEreceiver portTO810PORToutput mode選擇Transfer idoc immed.Basic Type填寫YPOIDOC保存即可

image359

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.

image360

image361

選中消息,並點擊“處理”按鈕后,該消息就會發往目的客戶端810,狀態從准備發送到成功發送:

image362

發送的數據可以選擇數據記錄節點來查看:

image363

image364

以上都是在發送端800進行的,下面登錄到接收端810去看看IDoc接收情況:

image365

由於在接收端810未配置到發送端800的合作伙伴配置文件,所以出錯。下面章節在接收端810中進行發送端800的相關配置

18.4.3.2.       接收端810Inbound)配置

由於該實例是在同一服務器的同一實例中進行的,又由於SegmentIDoc TypeMessage Type這些都是跨Client的,所以上面1234步就不需要在810端再次配置了,這些是共享的(但如果不是在同一服務器上,則需要像上面那樣進行配置

1、創建發送端RFC DestinationSM59 

創建到發送端810物理連接

image366

image367

2、創建發送端的端口(WE21

基於上面創建的RFC Destionation,創建端口Port,類型選TRANSACTIONAL RFC,名為FRM800PORTRFC destination則填寫上面創建的RFC遠程目標ZFROM800

image368 image369

3、將接收端Logical System分配到Client 810SALE 

如果是在不同的服務器中,則接收端需要像在發送端那樣:發送端邏輯系統Z800LS與接收端邏輯系統Z810LS都需要被創建,並且還需要將接收端邏輯系統Z810LS分配到Client 810,並且還需要以發送端邏輯系統Z800LS為基礎創建發送端合作伙伴配置文件

由於是在同一服務器的同一實例中,所以在發送端中創建的發送端邏輯系統Z800LS與接收端邏輯系統Z810LS在此端是通用共享,這里不需要再次創建(outbound中已經創建了這兩個邏輯系統了),但(outbound章節中並未分配到具體的ClientZ810LS邏輯系統沒有分配到相應的Client,這一步操作需要在接收端完成,所以需要在此進行分配:

image370

4、創建入站處理函數 

創建一個functionY_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_PROCESSInput Type1

image371

6、將入站函數與IDOC Type/Message Type關聯(WE57

Function Module輸入Y_IDOC_PO_PROCESS,其下的Type填寫FIDOC Type下的Basic Type填寫YPOIDOCMessage Type填寫YPO_MESS_TYPEDirection填寫2(Inbound)

image372

7、創建入站處理代碼Inbound Process CodeWE42

Process Code輸入YPC_PO,在Option ALE下選擇Processing with ALE service,在Processing Type下選擇function module,保存后,在隨后的窗口中,輸入Inbound ModuleY_IDOC_PO_PROCESS

image373 image374

8、創建發送端合作和伴配置文件Partner profileWE20 

由於在發送端800中已創建了發送端邏輯系統Z800LS ,所以在此端不需要在創建(發送端邏輯系統Z800LS),只是需要以此為基礎創建和伴配置文件,保存后,點擊加號增加進站參數:

image375 image376

image377

9、測試 BD87

在接收端810使用BD87,登錄進去后,會看到發送端發送過來的IDoc,但由於先前還沒有配置發送伙伴配置文件,所以失敗了:

image365[1]

現在在入站處理理函數中設置斷點:

image378

再執行BD87事務,繼續處理出錯的消息,最后發現處理成功:

image379

image380

調試程序時,發現數據也傳遞過來了:

image381


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM