SAP Enhancement
(一)什麼是增強(Enhancement)?
簡單地說,增強就是ERP系統中標準程序的出口,在該出口中由用戶根據企業實際需求編寫客戶化邏輯代碼。增強是ERP系統設計時考慮到企業實際的流程有可能和系統默認標準流程不同,在標準流程框架下專門留的接口,每個接口對應一個客戶化函數,這些出口函數有標準處理程序傳入的參數和輸出參數,用戶可根據系統輸入參數做條件編寫適合本企業流程的邏輯,然後通過輸出參數傳輸回。
(二)用戶增強分類
SAP的用戶增強通常包括下面3類。
1.E類:Enhancement exits,即通常所謂的用戶出口(User_exit )
用戶出口也叫功能出口(Function Exit)。
使用Tcode:SE37搜索EXIT*,找到的函數大都是做系統預留的出口函數,前面說過,用戶出口是標準程序留給用戶的接口,標準程序通常不允許用戶任意修改,如果修改需要申請Access Key,而且修改標準程序可能導致的錯誤ERP公司通常是不負責的。在SAP中,自定義的程序通常以保留字Y或Z開頭,因此,出口函數中都預包含了一個Z開頭的程序。
2.C類:GUI接口(GUI codes)
3.S類:屏幕增強(Screen Exit)
比如,在建立採購訂單,工單和固定資產主數據時,系統都預留屏幕增強,也就是說允許用戶自定義用戶輸入界面並編寫相應的輸入輸出處理程序。
在各類增強中,可能還用戶自己定義結構或表格,系統對應類型T類。比如增強MM06E005
允許用戶建立兩個結構CI_EKKODB和CI_EKPODB。
接下來將重點介紹功能出口的應用。
(三)組織用戶增強
相關增強表格:
MODSAP:增強表格
TFDIR:包括出口函數在內的所有函數表(E類)
CUATEXTS:修改 GVI 界面,界面: 菜單文本被客戶(C類)
TSDIR:動態程序區 CALL CUSTOMER SUBSCREEN(S類)
* 對於以EXIT開頭的出口函數,TFDIR-MAND值爲C表示此出口函數被激活。
相關增強檢查函數:
MODX_FUNCTION_ACTIVE_CHECK:檢查E類用戶出口是否被激活。
MODX_MENUENTRY_ACTIVE_CHECK:檢查C類增強激活狀況
MODX_SUBSCREEN_ACTIVE_CHECK: 檢查S類增強激活狀況
你可能會發現,SAP的各模塊的任何一個事務碼(Tcode)對應的標準程序都留下了大量的用戶出口,正是SAP靈活的配置功能和強大的用戶出口才使其產品輕鬆應對各種複雜需求成爲可能,系統還爲能快速找到和激活這些增強進行了有效組織,各類增強被記錄在table中並且提供了相關檢查函數,從而更方便企業用戶。
熟悉ABAP開發的朋友通常都收集了一個可以輸入事務碼快速找到系統留下的所有出口的程序,下表就是一個檢測系統增強被激活的簡單參考程序。
* 該程序可以檢測出系統所有被激活的用戶增強. * By Stone Fu. on 2006/11/07 . * Used to find out all the activated user-exit of SAP . report zfindactexit . tables: modsap,tfdir. data : begin of itab_exit occurs 0, funcname like tfdir-funcname, mand like tfdir-mand, name like modsap-name, end of itab_exit . data : field1(30). select a~funcname a~mand b~name into table itab_exit from tfdir as a inner join modsap as b on a~funcname = b~member where a~mand = 'C' and a~funcname = b~member . format color col_heading intensified on. write:/1 sy-vline, 2 'Enhancement Name', 21 sy-vline , 22 'Activated Exit Function', 95 sy-vline. write:/(95) sy-uline. loop at itab_exit. format color col_normal intensified off. write:/1 sy-vline, 2 itab_exit-name hotspot on, 21 sy-vline , 22 itab_exit-funcname, 95 sy-vline. endloop. at line-selection. get cursor field field1. set parameter id 'MON' field sy-lisel+1(10). call transaction 'SMOD' and skip first screen. |
有一種直接有效的查找用戶出口增強的方法,就是使用函數MODX_FUNCTION_ACTIVE_CHECK,如圖1。
圖1中的判斷語句If tfdir-mand = aktiv_flag(常數C)則出口函數active標誌=’X’,表示該用戶出口被激活,處理邏輯將從標準程序轉入出口函數,在該語句設置斷點然後運行任一個事務碼,都會調用該函數判斷是否存在用戶出口。
(四)增強應用實例
業務背景:如果採購訂單已經做了發票校驗後,則不再允許用戶修改價格。
相關程序:MM06EFPO_POT_FUELLEN|MM06EF0C_CUSTSCR1_ITEM_SET_DAT
相關Tcode:SMOD|CMOD
如果沒有啓動採購審批功能,SAP標準功能是允許用戶隨時修改採購價格的,不同的企業有對採購價格控制有不同的策略,甲企業規模較小爲了省事可能爲以後數月的採購開了一個大采購單,如果中途材料價格變動則直接修改價格就行,乙集團則嚴格控制採購價格,採購價格由總部集中維護,各企業採購員只需要維護採購數量等信息等,真因如此,ERP系統顯然不會去禁止用戶修改價格,如果企業確實需要如此,則可通過增強實現。
前面已經介紹過如何通過在函數MODX_FUNCTION_ACTIVE_CHECK設置斷點跟蹤系統每個事務預留的用戶出口,你很快將發現增強MM06E005的EXIT_SAPMM06E_017用戶出口非常適合此業務背景。
首先來看看增強的EXIT_SAPMM06E_017用戶出口(以下稱017出口)處理流程,Include程序MM06EFPO_POT_FUELLEN被專門用來處理增強出口,調用了子程序CUSTSCR1_ITEM_SET_DATA_
PAI(對應下一級Include程序MM06EF0C_CUSTSCR1_ITEM_SET_DAT),分析Include程序MM06EF0C_CUSTSCR1_ITEM_SET_DAT的代碼,如下表,這個程序是從系統原本Copy出來的,注意本人所加的附註粗體部分:
*----------------------------------------------------------------------- * User-Exit für Positionsfelder versorgen (PAI) FORM custscr1_item_set_data_pai USING im_no_screen LIKE fc_call. "770427 DATA: l_ucomm LIKE sy-ucomm, l_enj_call TYPE c. STATICS: first_call(1) TYPE c VALUE 'X', active LIKE sy-calld. ENHANCEMENT-POINT CUSTSCR1_ITEM_SET_DATA_PAI_02 SPOTS ES_MM06EF0C_CUSTSCR1_I_SET_DAT INCLUDE BOUND . *$*$-Start: CUSTSCR1_ITEM_SET_DATA_PAI_02-------------------------------------------------------$*$* ENHANCEMENT 1 OI0_COMMON_MM06EF0C_ITEM_S_DAT. "active version * C5030897 I.Twardowski Implementation of BADI for OGSD PERFORM OI0_BADISCR1_ITEM_SET_DATA_PAI. ENDENHANCEMENT. *$*$-End: CUSTSCR1_ITEM_SET_DATA_PAI_02-------------------------------------------------------$*$* IF NOT first_call IS INITIAL. CLEAR first_call. *註釋: MODX_FUNCTION_ACTIVE_CHECK用來檢查017出口是否被激活,如果激活則執行之. CALL FUNCTION 'MODX_FUNCTION_ACTIVE_CHECK' EXPORTING cprogname = 'SAPMM06E' funcnumber = '017' IMPORTING active = active EXCEPTIONS not_found = 1 OTHERS = 2. IF NOT sy-subrc IS INITIAL. CLEAR active. ENDIF. ENDIF. CHECK NOT active IS INITIAL. IF fc_vorga EQ cva_en. l_enj_call = 'X'. ELSE. l_enj_call = space. ENDIF. *-Define Data: DATA: lt_usr_tekpo LIKE bekpo OCCURS 0, lt_usr_teket LIKE beket OCCURS 0, lt_usr_tekkn LIKE ekknu OCCURS 0, lt_usr_tkomv LIKE tkomv OCCURS 0. *-Copy Tables: lt_usr_tekpo[] = pot[]. lt_usr_teket[] = ett[]. lt_usr_tekkn[] = knt[]. lt_usr_tkomv[] = tkomv[]. l_ucomm = ok-code. *註釋:調用出口的一般步驟是先定義數據(Define Data),多爲內表或工作區,再將參數賦予這些內表(Copy Tables),相當於*建立了原始參數的一個鏡象. *-User Exit: *如果017出口增強被激活則執行它. CALL FUNCTION 'EXIT_SAPMM06E_017' EXPORTING i_ekpo = ekpo i_ekpo_old = *ekpo i_ekko = ekko i_aktyp = aktyp i_bstyp = ekko-bstyp i_no_screen = im_no_screen "770427 i_lfa1 = lfa1 i_lfm1 = lfm1 i_rekpo = rekpo i_kekpo = kekpo i_aekpo = aekpo i_reban = reban i_mt06e = mt06e i_eina = *eina i_eine = *eine i_komp = komp i_ucomm = l_ucomm i_enj_call = l_enj_call TABLES tekpo = lt_usr_tekpo teket = lt_usr_teket tekkn = lt_usr_tekkn tkomv = lt_usr_tkomv EXCEPTIONS OTHERS = 0. ENDFORM. "CUSTSCR1_ITEM_SET_DATA_PAI |
上面的程序代碼非常簡單,相信聰明的讀者看了對ERP增強的設計思路會開始有一定了解。
現在你可以通俗理解,增強就是ERP設計者在合適的地點設置了一些合適的遊戲規則並提供了一些有意義的遊戲給用戶自己玩耍!獨樂樂,與人樂樂,孰樂?好玩的東西應該留點給用戶自己樂呵樂呵。
接下來開始編寫增強程序,可以使用Tcode:SMOD直接激活增強或CMOD建立一個項目包含一個或多個增強,如圖2,輸入增強MM06E005並激活它,然後在EXIT_SAPMM06E_017出口函數中編寫代碼。
在圖2中,我們發現增強MM06E005包括用戶出口和屏幕增強(Screen Exit),屏幕增強允許用戶在採購訂單自定義用戶界面,從而使採購訂單包含更多企業客戶化的信息,這種屏幕增強在固定資產模塊中更始發揮到極致。
EXIT_SAPMM06E_017包含程序ZXM06U42,程序ZXM06U42示例代碼如下表,這段客戶化代碼邏輯十分簡單,爲了方便說明,本人註釋出該出口函數的輸入參數,該出口沒有輸出參數,也就是說,你只能根據輸入參數進行判斷而不能更改任何數據:
*增強 ZXM06U42的示例代碼 *By Stone.Fu 2007/01/02 *"*"Lokale Schnittstelle: *IMPORTING/TABLES是輸入的單個參數和輸入的內表參數 *" IMPORTING *" VALUE(I_EKPO) LIKE EKPO STRUCTURE EKPO *" VALUE(I_AKTYP) *" VALUE(I_BSTYP) LIKE EKKO-BSTYP *" VALUE(I_NO_SCREEN) *" VALUE(I_LFA1) LIKE LFA1 STRUCTURE LFA1 *" VALUE(I_LFM1) LIKE LFM1 STRUCTURE LFM1 *" VALUE(I_EKKO) LIKE EKKO STRUCTURE EKKO *" VALUE(I_REKPO) LIKE EKPO STRUCTURE EKPO OPTIONAL *" VALUE(I_KEKPO) LIKE EKPO STRUCTURE EKPO OPTIONAL *" VALUE(I_AEKPO) LIKE EKPO STRUCTURE EKPO OPTIONAL *" VALUE(I_REBAN) LIKE EBAN STRUCTURE EBAN OPTIONAL *" VALUE(I_MT06E) LIKE MT06E STRUCTURE MT06E OPTIONAL *" VALUE(I_EINA) LIKE EINA STRUCTURE EINA OPTIONAL *" VALUE(I_EINE) LIKE EINE STRUCTURE EINE OPTIONAL *" VALUE(I_EKPO_OLD) LIKE EKPO STRUCTURE EKPO OPTIONAL *" VALUE(I_KOMP) LIKE KOMP STRUCTURE KOMP OPTIONAL *" VALUE(I_UCOMM) LIKE SY-UCOMM OPTIONAL *" VALUE(I_ENJ_CALL) OPTIONAL *" TABLES *" TEKPO STRUCTURE BEKPO OPTIONAL *" TEKET STRUCTURE BEKET OPTIONAL *" TEKKN STRUCTURE EKKNU OPTIONAL *" TKOMV STRUCTURE KOMV OPTIONAL *"---------------------------------------------------------------------- *判斷程序代碼如下: DATA ZWATEKPO like BEKPO. TABLES EKBE . * 輸入的內表參數TEKPO記錄該採購單所有的原始舊數據 . * 輸入的I_EKPO 參數表示當前處理的PO行項目,其包含的是採購行項目的最新更新數據 . READ TABLE TEKPO INTO ZWATEKPO WITH KEY EBELP = I_EKPO-EBELP . ***只對ME21N/22/23才生效. check SY-TCODE = 'ME22N ' or SY-TCODE = 'ME22N' or SY-TCODE = 'ME23N' . ***EKBE是PO history 表,如有Q,R表示有發票校驗歷史,不允許更改價## SELECT SINGLE * FROM EKBE WHERE EBELN = I_EKPO-EBELN AND EBELP = I_EKPO-EBELP AND ( BEWTP = 'Q' OR BEWTP = 'R' ) . *如果SY-SUBRC =0表示發票已經校驗,不允許更改價格。 CHECK SY-SUBRC = 0 . *判斷數據更改後新採購行項目的單價是否和從數據庫讀出的原始行項目單價一致 IF I_EKPO-NETPR <> ZWATEKPO-NETPR . MESSAGE E001(00) with '採購訂單行項目已經進行發票校驗,不再允許修改價格 ENDIF. |
如果你熟悉增強,你會發現一些用戶出口都會傳入舊數據和更新後的新數據以方便兩者比較,和財務模塊的替代(Substitution)不同,ERP系統一般對增強保留嚴謹態度,通常只允許在出口中做檢查工作,這一點類似財務模塊的檢查(Validation)。
(五)再次淺析增強
企業實施ERP的目的之一就是實現各部門信息共享,避免數據孤島,以一個簡單的採購收貨爲實例,倉庫人員只要在收貨時輸入採購訂號,收貨日期,物料收貨數量和倉位,系統將自動產生各模塊數據,對財務數據,系統根據輸入的採購訂單號找到採購訂單主數據中的工廠,通過在組織結構中設置的工廠和公司代碼的對應關係找到相應公司代碼;通過收貨物料的Valuation class和收貨的移動類型找到對應科目,通過收貨數量*採購單價得到本次該料庫存金額,通過物料主數據獲得業務範圍和利潤中心,這樣財務憑證數據自動收集完畢;如果物料採用標準價格出現採購差異並將差異科目的模認成本對象對應到獲利分析段,則將數據寫入利潤分析模塊等等;我要說的是,在這些複雜的邏輯背後,任何一個模塊收集過程中存在校驗,任何校驗失敗ERP系統都將停止業務交易,比如說校驗收貨日期不在物料期間或會計期間允許範圍,校驗失敗向用戶提示錯誤,比如預算模塊找不到對應基金中心提示錯誤中止交易等,當所有的校驗完畢,系統將數據Commit到數據庫,這些校驗是系統標準的,而增強則是系統預留給用戶的,和系統的校驗一樣,在任何模塊的增強中只要是出現錯誤都將停止本次業務交易。在圖3中出現的檢查/替代/增強/字段移動/推導等關鍵詞,實際上這些東東都可看成系統增強,即使用客戶化代碼增強標準功能。
有趣的是,SAP的各種增強的代碼編寫都是極其簡單的,象檢查/替代/字段移動/推導/派生用戶甚至只要簡單將對應的源字段和目標字段拖拖拽拽關聯關聯就行,代碼是自動生成的,即使涉及Coding也是非常簡單的。神奇的是,作爲SAP顧問你甚至可以對編程和數據庫毫不瞭解,實際上很都SAP顧問的確如此,你只要專注於業務藍圖實現就行,這一點值得國內管理軟件設計同行學習,在管理軟件設計過程中,同樣是細節決定成敗。
新一代增強BADI (Tcode:SE17|SE18)
BADI(Business Add-In)是一種新的功能增強概念,它使用類、接口及方法等面向對象的概念,採用一種使用面向對象的方法來進行SAP 增強。