BW增强-BAdI(初级)
BADI增強
- 1. 數據源增強
- 2. BADI Provider
- 插播
- 插播結束
- 3. 變量 Exit
1. 數據源增強
想到哪寫到哪。。。
對數據源添加字段,寫代碼來填充字段值。或者更改抽取方式。
原先我們是用RSAP0001這個CMOD里面的增強。這些我們是要建在一個project里面的。
在這個project里面就不能被復用了。
Function exit一共四個。
這個有時候就比較亂,因為一個include里面會有很多個數據源增強。有時候人家已經增強過了,你還再去弄一遍。當然這種情況一般沒有。。。
如果有一種增強,把數據源分開。那么每個數據源能看到自己的增強。。。
SAP提供了一個classical BADI, 不是new的。RSU5_SAPI_BADI.
這個BADI可以有很多個implementation(Multiple use那里打鉤了)
在RSA3抽取進入debug模式,可以設置斷點到class cl_exithandler 這里可以看到data extractor里面是調用了這個BADI的。也就是說這個BADI里面咱就可以增強數據源抽取了。
這個interface只有兩個方法。
點進interface里面的方法里面,看參數。
然后去se19搞implementation。
建了implementation之后,就會有個新的class給你建了,因為咱得通過這個繼承interface的class來實現。
那么在class里面是可以繼續再建method的。
我看我們這里前人的思路是,先把DATA_TRANSFORM這個方法和它的參數都給復制出來成一個新的模板方法:_TEMPLATE_DATASOURCE,然后給它整成一個靜態方法。然后以后的可以把它當做個參照。
然后在DATA_TRANSFORM里面寫代碼:
METHOD if_ex_rsu5_sapi_badi~data_transform. ********************************************************** * To implement an exit for a * datasource create your own method by copying the * method _TEMPLATE_DATASOURCE and rename it to the name * of your datasource. In case you enhance a Business * Content datasource skip the 0 at the beginning (e.g. * Datasource 0FI_AR_3 -> Method FI_AR_3 * The method is then called by the Exit Framework *********************************************************DATA: ls_oltpsource TYPE rsaot_s_osource,lo_data TYPE REF TO data,lv_method TYPE seocmpname.FIELD-SYMBOLS: <lt_data> TYPE STANDARD TABLE. * check if any data is extractedCHECK c_t_data IS NOT INITIAL. *retrieve information about the DatasourceCALL FUNCTION 'RSA1_SINGLE_OLTPSOURCE_GET'EXPORTINGi_oltpsource = i_datasourcei_objvers = 'A'IMPORTINGe_s_oltpsource = ls_oltpsourceEXCEPTIONSno_authority = 1not_exist = 2inconsistent = 3OTHERS = 4.IF sy-subrc <> 0.EXIT.ENDIF. * create data for Extract StructureCREATE DATA lo_data TYPE TABLE OF (ls_oltpsource-exstruct).ASSIGN lo_data->* TO <lt_data>.ASSIGN c_t_data TO <lt_data>. * get method name for datasourcelv_method = i_datasource.CASE lv_method(1).WHEN '0' OR '2'. * shift by one character as methods can't start with a numberSHIFT lv_method.WHEN OTHERS. "Do nothingENDCASE. * check method is implementedCHECK check_method_exists( lv_method ) = 'X'. *execute the Datasource enhancementCALL METHOD (lv_method)EXPORTINGi_datasource = i_datasourcei_updmode = i_updmodei_t_select = i_t_selecti_t_fields = i_t_fieldsCHANGINGc_t_data = <lt_data>c_t_messages = c_t_messages. ENDMETHOD.這個里面的思路就是以數據源名字建自己的方法。然后就用這一個implementation。
數據源抽取就會自動來到這個BADI下面。如果找到他自己的增強方法,那就執行增強。沒找到就啥也不執行。
當然這里首先得有check_method_exists這個方法。
那么同時還得有個存儲所有method的表。得自建。然后還得寫這個方法邏輯。怪復雜的。
簡單的方法也有。
那就是直接在類下面加數據源增強的方法。然后用case直接去調用吧。
到S4HANA的時候,就是用HANA Optimized ABAP code了。也就是把code給推到數據庫層。在數據庫層做計算。只把相關的記錄給傳遞到展示層。
也就是去eclipse里面找對應數據源的extract structure然后去建一個append structure先。
建的時候要把那個annotation改了extensible。。。
接下來就還是一樣的步驟,去建個BADI的implementation,然后寫代碼了。
新寫法加@,CDS里面就是這種。select在loop底下,因為在HANA上搞了。不用考慮性能。
當然如果習慣寫在loop上面也行。畢竟家底再厚也經不起數據量大的造法。
在之前ABAP里面就是只從需要的表里和C_T_DATA對應關聯字段選出相關的數據到內表。
然后loop 這個C_T_DATA再讀內表把內表的那個行的新字段給拿過來。
來回顧一下,就是說首先for all entries啥也不是,就是個inner join。
然后去read table with key把需要的字段從內表給取過來。
現在是用inner join來寫。新的SQL語句寫法。那就是下面這樣式的:
types: begin of ls_acdoca,rldnr type fins_ledger,rbukrs type bukrs,gjahr type gjahr,belnr type belnr_d,docln type docln6,netdt type netdt,end of ls_acdoca.DATA: it_acdoca TYPE STANDARD TABLE OF ls_acdoca,SOURCE_DATA TYPE STANDARD TABLE OF FINS_ACDOCA_BW,wa_data TYPE FINS_ACDOCA_BW.FIELD-SYMBOLS: <fs_acdoca> type ls_acdoca,<l_s_data> TYPE FINS_ACDOCA_BW.sort SOURCE_DATA BY rldnr rbukrs gjahr belnr docln.Case i_datasource.WHEN '0FI_ACDOCA_10'.IF C_T_DATA is not initial. SOURCE_DATA[] = C_T_DATA[].select a~rldnr, a~rbukrs, a~gjahr, a~belnr, a~docln, a~netdtfrom acdoca as aINNER JOIN @SOURCE_DATA AS bON a~rldnr = b~rldnrAND a~rbukrs = b~rbukrsAND a~gjahr = b~gjahrAND a~belnr = b~belnrAND a~docln = b~doclninto TABLE @it_acdoca. ENDIF.SORT it_acdoca BY rldnr rbukrs gjahr belnr docln.LOOP AT C_T_DATA ASSIGNING <l_s_data>.READ TABLE it_acdocaASSIGNING <fs_acdoca>with key rldnr = <l_s_data>-rldnrrbukrs = <l_s_data>-rbukrsgjahr = <l_s_data>-gjahrbelnr = <l_s_data>-belnrdocln = <l_s_data>-docln.if sy-subrc = 0.<l_s_data>-zznetdt = <fs_acdoca>-netdt.endif.ENDLOOP.clear SOURCE_DATA.ENDCASE.** 補充:從另一個更好理解的角度出發,也就是說你可以自己建一個類。然后在類的接口里直接繼承它。
接著去method里寫完了。那么要調用這個類的方法,還得從BADI那里進去建一個BADI implementation。
在建完了implementation后面要寫個class的地方把你的class寫進去。
2. BADI Provider
SAP給了一個例子。這個是能搜到的。
這個BADI Provider是點不開的,也沒有圖形化界面來創建它。
它是通過增強點RSO_BADI_PROVIDER來創建的。
跑query的時候data manager是直接來跑這個BADI里面的method的。
這個BADIprovider只能是基于infoobject來的,不能是field。可以給這個BADI provider分配給InfoArea去。然后在BW modeling tools里面就能看到它了。如果不給分配InfoArea,那就默認在NODESNOTCONNECTED這個infoarea下面。
然后呢,這個provider還可以放到CP里面去。But, 只能用在union里面,不能用在join里。還怪奇怪的。
導航屬性也得通過ABAP代碼給寫活了。
S_RS_BDPR這個授權對象來給BADI provider的權限哦。傳輸對象也是BDPR。傳輸的時候照這個。
這個BADI RSO_BADI_PROVIDER下面是有這個interface:IF_RSO_BADI_PROV。就上面那個圖。
里面的7個methods:
兩個來get infoprovider信息的。
兩個get時間戳的。
三個來搞runtime信息的。
1.GET_INFOPROVIDER_NAMES 默認會加3B當infoprovider的前綴。
2.GET_INFOPROVIDER_FIELDS 返回BADI Provider的結構。對應的三個exporting parameters得有數據:E_TSX_CHARACTERISTICS,E_TS_KEYFIGURES,E_TS_GROUPS.
這個E_TS_GROUPS就是用來把特性分組的,因為DSO里面或者CP里面是可以把不同的字段分組的。
導航屬性也能被加進去。
3.GET_METADATA_TIMESTAMP 主數據可以被寫進buffer里來提高性能,這個方法就是來返回時間戳的。如果返回的時間和buffer里面的時間不一樣,buffer里面的條目就被刪除,重新填充。
4. GET_DATA_TIMESTAMP 包含最近更改BADI的時間,如果寫了這個方法,那么OLAPcache就可以用上了。
對于SAP提供的例子3BVBFIGL01。這個是用來給資產負債表和損益表用的。這個定義是基于ABAP類 CL_BW4C_FIGL_BSPL_IMPL
數據是通過function group B/S and Profit/Loss (BW4C_FIGL) 從ADSO FI-GL: New GL – Balances (/IMO/D_FIGL12) 讀取的。
BADI provider里面的infoobject就從這個ADSO出。
如果我們要去自己改這個BADI provider,那么首先就是要在增強點RSO_BADI_PROVIDER里建一個BADI implementation。然后在這個BADI implementation下面建一個class implementation。class可以直接去繼承它的模板BAdi Provider for BSPL Reporting (CL_BW4C_FIGL_BSPL)
那就只需要去搞GET_CUSTOMIZING這一個方法就行了。
在這個方法里就得去確定,1. 財務數據是從哪個infoprovider來的。
2. 我們要建的這個BADI provider的名字,描述和Infoarea
3. BSPL報表的功能模塊名字(默認是BW4C_FIGL_DATA_GET)
而且BADI里面的filter的值要和你的GET_CUSTOMIZING里面的BADI Provider的名字相同。
插播
我們現在好像在搞ERP升級,升級到S4的話,那就有一個很大的不同了。
原先我們那些數據源都是基于Function Module的。我自己還寫了幾個基于FM的數據源。但是S4了以后,數據源都改成基于CDS view的了。
那就是說我以后得把這些數據源都改了。
SAP提供了一個ABAP wrapper的程序來call這些FM填充一個臨時表,然后用個簡單的CDS view從這些臨時表來建數據源。
那么另外一個方案就是建個BADI provider來復用這些FM。然后把他們放到CP里。然后把它用成個轉換的源。但是缺點顯而易見,不是個物理存儲的,也不會說給你delta抽取了。
但是我們還沒升級到那,而且SAP大概也有其他的方式提供,只不過我不知道罷了。
插播結束
3. 變量 Exit
RSROA_VARIABLES_EXIT_BADI
這個是用來填充變量的。這個BAdI的類回去call PROCESS這個方法。
原先我們是用FM EXIT_SAPLRRS0_001這個來搞客戶出口變量的。后來就都復制到新的上去了。
右鍵implementation新建,然后基于類CL_RSROA_VAR_SMOD來新建enhancement implementation。
等這個enhancement的implementation建好了,然后別退出。繼續勾選它。
接下來就能進入到BADI的implementation了,需要建class了。
也就是說一共有三個:enhancement implementation,BADI implementation,implementating class.
等這些都搞好了激活了。
這些都激活搞好了以后呢,設置filter。
這里設置filter其實我有點暈。我并沒有完全理解。
反正暫時它是這么設置的。和里面的變量是characteristic還是formula或者text啥的我不知道怎么個關系。暫時先故考慮這個了。
但是i_step肯定要了解的。
i_step = 1 就是在用戶輸入前就調用的參數。
i_step = 2 就是用戶輸入后調用的參數。只適用于不是用戶input的也不能被屏幕打開前就填值的參數。
i_step = 3 我好像沒看見在哪里用到。我倒是看見有個i_step = 0和1 是一起用來分析的。不過這個還有待以后具體研究。
1) I_STEP = 1: Call is made directly before variable entry.
2) I_STEP = 2: Call is made directly after variable entry. This step is only _executed if the same variable is not input-ready and could not be filled for I_STEP = 1.
3) I_STEP = 3: In this call, you can check the values of the variables. When an exception (RAISE) is triggered, the variable screen appears again. I_STEP = 2 is then also called again.
4) I_STEP = 0: The enhancement is not called from the variable screen. The call can originate from the authorization check or from the monitor.
總結
以上是生活随笔為你收集整理的BW增强-BAdI(初级)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于OpenCV及Python的数独问题
- 下一篇: Pascal voc 数据集下载网址