【ABAP增强】基于函数的出口CMOD
? ? ? ? 與基于源碼的出口不同的是,該類出口將依據函數結構指定具體的輸入/輸出參數。SAP已經為每一個該類出口對象分配了對應的函數,程序執行中,會調用該函數檢查其對應的代碼。如果需要實現某個程序的增強,首先必須找到其對應的出口。
1、出口所對應函數的查找
這里介紹一種逆向的查找法,首先通過源碼找到函數,然后通過函數來找到出口對象。
函數名稱有三個部分組成,命名規則為:EXIT_<程序名>_<3位數字>。
首四個字母一定是固定的EXIT,表示用戶出口;
第二個部分為程序名;
第三個部分為3位數字的序列號。
基于函數的出口在程序中通過引用代碼“CALL CUSTOMER-FUNCTION <3位數字>”來調用,以VA01的主程序SAPMV45A為例,在程序中查找包含“CALL CUSTOMER-FUNCTION”的字符串,可以找到例如代碼“?call?customer-function?'003'”,具體如下圖所示:
根據出口的命名規則,可以判定這個出口所對應的函數名稱為“EXIT_SAPMV45A_003”,然后通過SE37開啟這個函數,可以看到這個函數中指定了一個預留的程序,名稱為“ZXVVAU05”,具體如下圖所示:
程序名“ZXVVAU05”為SAP的預留程序名,以Z開頭的程序可以在SAP中直接創建和維護。在代碼中雙擊該程序名,若程序沒有被創建,系統將提示在系統中按該名稱進行創建新的程序。
2、通過函數來查找出口對象
上面我們介紹了如何通過程序源碼來查找出口所對應的函數,但是程序執行中并不會直接調用該函數,必須先確認該函數所對應的出口對象是否被激活,再通過該對象來引用函數。函數與出口對象的關系是一一對應的,該對應關系被保存在透明表MODSAP中,其中NAME字段為出口對象的名稱,TYPE為出口對象的類型(E:功能退出,S:屏幕,T:表,C:GUI代碼),MEMBER為出口對應的函數名稱,通過該表可以查找到函數“EXIT_SAPMV45A_003”所對應的出口對象名稱為“V45A0003”。
需要注意的是,一個函數只會對應一個出口,但是一個出口對應可以對應多個函數,如“V45A0003”可以同時對應“EXIT_SAPMV45A_003”和“EXIT_SAPMV45A_004”兩個函數。
出口對象的描述則保存在表MODSAPT表中,具體如下圖所示:
3、出口對象的查看和維護
這里我們介紹一下如何查看和修改該出口對象屬性及參數。
通過事務代碼SMOD可以查看并修改該出口對象。
單擊工具欄的執行按鈕可以輸入出口對象所包含的函數清單,并可以查看該出口對象目前的狀態,若該出口對象未被激活,其輸出清單將會由紅色的圖標來表示,否則會顯示綠色的圖標,可以通過工具欄按鈕來激活該對象,可以被激活的對象才可以在程序執行的時候被調用,如下圖所示:
返回到初始頁面,單擊“顯示”按鈕,查看該出口對象的屬性,如下圖所示:
單擊工具欄中的“組件”按鈕,可以查看該出口對象所包含的組件清單,如下圖所示:
雙擊組件清單中功能模塊名稱則可以直接進入該函數的維護頁面,通過該頁面可以看到該函數的具體結構。
4、通過CMOD實現銷售訂單控制增強實例
那么找到了出口之后我們該如何應用呢?下面將通過一個實例介紹如何在出口中實現SAP標準程序的增強。
要應用基于函數的出口首先必須先維護一個自定義的CMOD項目對象,輸入事務代碼CMOD進入項目管理維護工具。首先需要建立一個項目對象,具體步驟如下:
<1>因為本出口是針對SD模塊功能的,所以首先需要在項目字段中輸入自定義名稱“ZSD01”,具體如下圖所示:
<2>單擊CMOD為維護屏幕中的“創建”按鈕,進入CMOD的屬性維護界面。
從屬性頁面可以看到,其工具欄包括三個按鈕,首先為“編輯”按鈕,用戶切換該對象的編輯狀態,另外兩個工具欄按鈕屬性簡介如下。
增強分配(Enhancement assignments):分配增強的組件對象。
組件(Parts):列出組件中所對應的功能函數。
<3>保存屬性設置之后,首先單擊“增強分配”按鈕,系統進入組件對象維護頁面,可以在一個項目中同時輸入對個增強組件對象,需要注意的是,一個組件對象只能被引用一次,若在本CMOD項目中被引用了,那么這個組件就不可能在其他的CMOD中輸入。
本例就輸入之前我們找到的組件對象“V45A0003”,如下圖所示:
<4>保存所輸入的組件對象后,單擊維護頁面中的“組件”按鈕,系統進入到組件列表頁面。該頁面中將列出組件所包含的功能函數,如組件對象“V45A0003”包含了“EXIT_SAPMV45A_003”和“EXIT_SAPMV45A_004”兩個功能函數,若同時維護了多個組件對象,則會在該頁面中將所有的函數對象按順序列出來。
從頁面中也可以看到組件對象的狀態,在組件所對應的列表表頭,會有一個指示圖標來標示該對象的狀態。組件對象必須激活才能使用,若未激活,將顯示一個紅色的指示圖標,激活后則是一個綠色的圖標。在函數一欄,也會有一個圖標指示該函數的Include程序是否被激活,具體如下圖所示:
<5>以“EXIT_SAPMV45A_003”函數為例,雙擊該函數名稱進入到函數維護頁面,雙擊該函數中預留的程序“ZXVVAU05”,若該程序還未被創建,系統將會提示:
<6>我們創建上面這個對象,系統中創建“ZXVVAU05”這個程序,“ZXVVAU05"為一個include程序,其屬性與普通程序基本類似。接下來首先要了解一下“EXIT_SAPMV45A_003”函數的結構,其接口參數如下。
Importing參數:
XVBAK:用于保存訂單的表頭數據。
 XVBUK:用于保存訂單抬頭的狀態等數據。
 XKOMK:用戶保存訂單中行項目的定價等信息。
Tables:
XVBKD:保存表頭相關憑證信息。
 XVBFA:保存行項目憑證流信息。
 XVBAP:保存訂單行項目物料相關信息。
 XVBUP:保存行項目的狀態信息。
該出口在訂單保存時候被調用,調用時,接口將傳遞訂單相關數據,同之前一講,我們也是對訂單的類型做控制。
if xvbak-auart = 'ZOR1' and xvbkd-bstkd is initial.message '該類型下采購訂單編碼為必輸!' type 'E'. endif.修改代碼后,務必要激活所新建的CMOD項目,否則出口是不會在被執行時識別,接下來可以通過實際的業務操作來測試增強效果。
5、通過程序查找CMOD出口
下面介紹一下如何直接通過數據表中的信息來查找某事務代碼所有相關的出口信息。
在SAP中,所有程序名稱及事務代碼以及程序中所包含的對象信息都會被保存在數據表TADIR中,其中主要字段包含:
PGMID:為請求和任務中的程序標示,目前SAP程序中的所有資源對象都是以”R3TR“來標示的;
OBJECT:表示對象類型,如PROG為程序,TRAN為事務代碼,SMOD為增強類型等;
OBJ_NAME:表示對象名稱;
DEVCLASS:表示開發類。
在SAP的標準程序設計邏輯中,所有的程序、事務代碼、增強都是用了相同的開發類,所以可以根據程序名稱或者事務代碼先找到它定義的開發類,再根據開發類來查找其對應的SMOD增強對象,至于對象的描述,可以從數據庫表MODSAPT中獲取,下面分享一個查找的實例給大家。
REPORT ZEXIT. TABLES : TSTC,TADIR,MODSAPT,MODACT,TRDIR,TFDIR,ENLFDIR,SXS_ATTRT ,TSTCT. DATA : JTAB LIKE TADIR OCCURS 0 WITH HEADER LINE. DATA : FIELD1(30). DATA : V_DEVCLASS LIKE TADIR-DEVCLASS. PARAMETERS : P_TCODE LIKE TSTC-TCODE,P_PGMNA LIKE TSTC-PGMNA. DATA WA_TADIR TYPE TADIR.START-OF-SELECTION.IF NOT P_TCODE IS INITIAL.SELECT SINGLE * FROM TSTC WHERE TCODE EQ P_TCODE.ELSEIF NOT P_PGMNA IS INITIAL.TSTC-PGMNA = P_PGMNA.ENDIF.IF SY-SUBRC EQ 0.SELECT SINGLE * FROM TADIRWHERE PGMID = 'R3TR'AND OBJECT = 'PROG'AND OBJ_NAME = TSTC-PGMNA.MOVE : TADIR-DEVCLASS TO V_DEVCLASS.IF SY-SUBRC NE 0.SELECT SINGLE * FROM TRDIRWHERE NAME = TSTC-PGMNA.IF TRDIR-SUBC EQ 'F'.SELECT SINGLE * FROM TFDIRWHERE PNAME = TSTC-PGMNA.SELECT SINGLE * FROM ENLFDIRWHERE FUNCNAME = TFDIR-FUNCNAME.SELECT SINGLE * FROM TADIRWHERE PGMID = 'R3TR'AND OBJECT = 'FUGR'AND OBJ_NAME EQ ENLFDIR-AREA.MOVE : TADIR-DEVCLASS TO V_DEVCLASS.ENDIF.ENDIF.SELECT * FROM TADIR INTO TABLE JTABWHERE PGMID = 'R3TR'AND OBJECT IN ('SMOD', 'SXSD')AND DEVCLASS = V_DEVCLASS.SELECT SINGLE * FROM TSTCTWHERE SPRSL EQ SY-LANGUAND TCODE EQ P_TCODE.FORMAT COLOR COL_POSITIVE INTENSIFIED OFF.WRITE:/(19) 'Transaction Code - ',20(20) P_TCODE,45(50) TSTCT-TTEXT.SKIP.IF NOT JTAB[] IS INITIAL.WRITE:/(105) SY-ULINE.FORMAT COLOR COL_HEADING INTENSIFIED ON. * Sorting the internal TableSORT JTAB BY OBJECT.DATA : WF_TXT(60) TYPE C,WF_SMOD TYPE I,WF_BADI TYPE I,WF_OBJECT2(30) TYPE C.CLEAR : WF_SMOD, WF_BADI , WF_OBJECT2. * Get the total SMOD.LOOP AT JTAB INTO WA_TADIR.AT FIRST.FORMAT COLOR COL_HEADING INTENSIFIED ON.WRITE:/1 SY-VLINE,2 'Enhancement/ Business Add-in',41 SY-VLINE ,42 'Description',105 SY-VLINE.WRITE:/(105) SY-ULINE.ENDAT.CLEAR WF_TXT.AT NEW OBJECT.IF WA_TADIR-OBJECT = 'SMOD'.WF_OBJECT2 = 'Enhancement' .ELSEIF WA_TADIR-OBJECT = 'SXSD'.WF_OBJECT2 = ' Business Add-in'.ENDIF.FORMAT COLOR COL_GROUP INTENSIFIED ON.WRITE:/1 SY-VLINE,2 WF_OBJECT2,105 SY-VLINE.ENDAT.CASE WA_TADIR-OBJECT.WHEN 'SMOD'.WF_SMOD = WF_SMOD + 1.SELECT SINGLE MODTEXT INTO WF_TXTFROM MODSAPTWHERE SPRSL = SY-LANGUAND NAME = WA_TADIR-OBJ_NAME.FORMAT COLOR COL_NORMAL INTENSIFIED OFF.WHEN 'SXSD'. * For BADisWF_BADI = WF_BADI + 1 .SELECT SINGLE TEXT INTO WF_TXTFROM SXS_ATTRTWHERE SPRSL = SY-LANGUAND EXIT_NAME = WA_TADIR-OBJ_NAME.FORMAT COLOR COL_NORMAL INTENSIFIED ON.ENDCASE.WRITE:/1 SY-VLINE,2 WA_TADIR-OBJ_NAME HOTSPOT ON,41 SY-VLINE ,42 WF_TXT,105 SY-VLINE.AT END OF OBJECT.WRITE : /(105) SY-ULINE.ENDAT.ENDLOOP.WRITE:/(105) SY-ULINE.SKIP.FORMAT COLOR COL_TOTAL INTENSIFIED ON.WRITE:/ 'No.of Exits:' , WF_SMOD.WRITE:/ 'No.of BADis:' , WF_BADI.ELSE.FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.WRITE:/(105) 'No userexits or BADis exist'.ENDIF.ELSE.FORMAT COLOR COL_NEGATIVE INTENSIFIED ON.WRITE:/(105) 'Transaction does not exist'.ENDIF.AT LINE-SELECTION.DATA : WF_OBJECT TYPE TADIR-OBJECT.CLEAR WF_OBJECT.GET CURSOR FIELD FIELD1.CHECK FIELD1(8) EQ 'WA_TADIR'.READ TABLE JTAB WITH KEY OBJ_NAME = SY-LISEL+1(20).MOVE JTAB-OBJECT TO WF_OBJECT.CASE WF_OBJECT.WHEN 'SMOD'.SET PARAMETER ID 'MON' FIELD SY-LISEL+1(10).CALL TRANSACTION 'SMOD' AND SKIP FIRST SCREEN.WHEN 'SXSD'.SET PARAMETER ID 'EXN' FIELD SY-LISEL+1(20).CALL TRANSACTION 'SE18' AND SKIP FIRST SCREEN.ENDCASE.執行效果如下:
最后若我們需要刪除該CMOD項目增強,必須先取消激活狀態方可刪除。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【ABAP增强】基于函数的出口CMOD的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 【ABAP增强】基于源代码的增强
 - 下一篇: 【ABAP增强】基于BADI的增强