2010年11月24日

預留單MB_RESERVATION_BADI method DATA_CHECK處理

有一個客戶希望在預留單Movement 201時進行成本中心及費用科目預算檢查(利用KP06設定),不通過時不允許save。

以下是利用BADI MB_RESERVATION_BADI時的重點:
1 IS_RESB有成本中心和會計科目,可以利用來讀COSP的計劃值。
2 讀取未刪除的預留單,需求數量減去領料數量才是要卡控的數量。
3 金額可考慮抓標準價格或異動平均單價。
4 利用I_NEW_ITEM = 'X'判斷create時沒有科目指派,要直接去table T030找出會計科目,規則要問一下MM顧問。

2010年11月22日

BADI ME_PROCESS_PO_CUST method CHECK拋出多筆message

使用BADI ME_PROCESS_PO_CUST時,method CHECK可以一次檢查所有的PO內容
要將訊息輸出時,從doc看不到該怎麼處理,以下是help的提醒:
Never use the ABAP statement MESSAGE in the BAdI ME_PROCESS_PO_CUST.

再進一步找尋,發現要用macro處理:
INCLUDE MM_MESSAGES_MAC.
MMPUR_MESSAGE_FORCED 'E' 'ZMM01' '001' LV_MSGV1 LV_MSGV2 LV_MSGV3 LV_MSGV4.
MMPUR_MESSAGE_FORCED 'E' 'ZMM01' '002' LV_MSGV1 LV_MSGV2 LV_MSGV3 LV_MSGV4.

2010年11月17日

利用BADI ME_PROCESS_PO_CUST進行PO check

BADI ME_PROCESS_PO_CUST當中有一個method CHECK可以進行整個PO的檢查。
要注意的是parameter只有IM_HEADER,並且是object形態。

以下是取得內容的範例:

*取得header
IM_HEADER->GET_DATA( ).
*取得item,一樣是object形態
IM_HEADER->GET_ITEMS( ).

檢查後若要拋出錯誤,直接用message即可。
MESSAGE E888(SABAPDOCU) WITH LV_MSGV1 LV_MSGV2 LV_MSGV3 LV_MSGV4.

利用BADI ME_PURCHDOC_POSTED將PO資訊在SAVE後寫入Addon Table

PO在save之後的BADI ME_PURCHDOC_POSTED只有一個Method POSTED,作用是在這個時間得到完整的PO資訊,可以寫到Addon Table。
要注意的地方是PO create時, IM_EKPO不會有PO number,只存在 IM_EKKO-EBELN當中。

2010年11月15日

用K_GROUP_SELECT查詢Cost Object Group

寫CO的報表時,用到Cost Object的選擇條件時常會加上Group來查詢,在處理VALUE-REQUEST時可以用FM K_GROUP_SELECT處理,以下是範例:

1 Profit Center Group
CALL FUNCTION 'K_GROUP_SELECT'
EXPORTING
CLASS = '0106'
FIELD_NAME = 'RPRCTR '
TABLE = 'GLPCT '
IMPORTING
SET_NAME = P_PCGRU
EXCEPTIONS
NO_SET_PICKED = 1.

2 Cost Center Group
CALL FUNCTION 'K_GROUP_SELECT'
EXPORTING
FIELD_NAME = 'KOSTL'
IMPORTING
SET_NAME = P_KSGRU
EXCEPTIONS
NO_SET_PICKED = 1

3 Internal Order Group
CALL FUNCTION 'K_GROUP_SELECT'
EXPORTING
FIELD_NAME = 'AUFNR'
IMPORTING
SET_NAME = P_AUFGR
EXCEPTIONS
NO_SET_PICKED = 1.

4 Cost Element Group
CALL FUNCTION 'K_GROUP_SELECT'
EXPORTING
FIELD_NAME = 'KSTAR'
KTOPL = 'XXX'
IMPORTING
SET_NAME = P_GRP
EXCEPTIONS
NO_SET_PICKED = 1.

2010年11月9日

Park Document Posting使用SGL Ind 的item寫入Profit Center

遇到一個需求在FI Park Document使用SGL Ind,此時不能輸入Profit Center,希望能夠有機會自行決定。


SAP的New GL有一個default profit center的BADI FAGL_3KEH_DEFPRCTR,透過這個就可以達到目的。


作法是在park doc的doc header reference寫入要決定的profit center,再利用FAGL_3KEH_DEFPRCTR的interface IF_SET_DEFPRCTR 的Method SET_DEFAULTPRCTR處理。


以下是sample:
METHOD IF_SET_DEFPRCTR~SET_DEFAULTPRCTR.
   CHECK IS_ACCIT-XBLNR NE SPACE.
  CD_PRCTR = IS_ACCIT-XBLNR.
ENDMETHOD.

2010年11月5日

BAPI_ACC_DOCUMENT_POST 建立Park文件

遇到客戶的新需求:透過interface轉進SAP建立會計文件時,只需要建立Park文件,不要Post。


系統上並沒有這樣功能的的FM及BAPI,只好把辦法想到enhancement及BADI。找到之前寫過的BADI ACC_DOCUMENT直接使用CHANGE這個Method。


只要在Method中指定欄位值C_ACCHD-STATUS_NEW = 2.建立的文件就是Park文件。

2010年10月29日

FI posting 替換 RECN account

最近有個需求是要在VF01及MIRO時,把RECN科目替換成關係人的RECN科目。但是SAP Note 42615裡特別提到有些fields在substitution不會work,也不會有message。


改往BTE去處理,用event1120替換科目。找到1120的interface之後,copy至ZPROCESS_00001120。發現structure BSEG_SUBST並沒有提供科目的field HKONT。直接append structure把field加進去,之後再寫code。


以下範例僅供參考:

  FIELD-SYMBOLS:  TYPE BSEG_SUBST.
  DATA: VAR_NAME(30).
**MIRO
  DATA: XEKBE LIKE EKBE OCCURS 10 WITH HEADER LINE,
        XEKPO LIKE EKPO OCCURS 10 WITH HEADER LINE,
        TMP_EKPO LIKE EKPO.
**billing
  DATA: XVBRPVB LIKE VBRPVB OCCURS 10 WITH HEADER LINE.

**Logic
  READ TABLE T_BKPF INDEX 1.
  CASE T_BKPF-BLART.
    WHEN 'RE'.
      VAR_NAME = '(SAPLMRMP)XEKBE[]'.
      ASSIGN (VAR_NAME) TO .
      CHECK SY-SUBRC = 0.
      XEKBE[] = .

      LOOP AT XEKBE.
        SELECT FROM EKPO WHERE EBELN = XEKBE-EBELN
                             AND EBELP = XEKBE-EBELP
                             AND ( KNTTP = 'A' OR KNTTP = 'K' ).
          APPEND EKPO TO XEKPO.
        ENDSELECT.
      ENDLOOP.
      CHECK XEKPO[] IS NOT INITIAL.

      LOOP AT XEKPO.
        IF XEKPO-NETWR > TMP_EKPO-NETWR.
          TMP_EKPO = XEKPO.
        ENDIF.
      ENDLOOP.
      CLEAR LFA1.

      LOOP AT T_BSEG WHERE KOART = 'K'.
        READ TABLE T_BSEGSUB WITH KEY TABIX = SY-TABIX ASSIGNING .
        SELECT SINGLE FROM LFA1 WHERE LIFNR = T_BSEG-LIFNR
                                    AND KTOKK = 'Z101'.
        IF SY-SUBRC = 0.    "關係人
          CASE TMP_EKPO-KNTTP.
            WHEN 'A'.
              -HKONT = '0021460001'.
            WHEN 'K'.
              -HKONT = '0021901001'.
          ENDCASE.
        ELSE.    "非關係人
          CASE TMP_EKPO-KNTTP.
            WHEN 'A'.
              -HKONT = '0021450001'.
            WHEN 'K'.
              -HKONT = '0021700002'.
          ENDCASE.
        ENDIF.
      ENDLOOP.
    WHEN 'RV'.
      VAR_NAME = '(SAPMV60A)XVBRP[]'.
      ASSIGN (VAR_NAME) TO .
      CHECK SY-SUBRC = 0.
      XVBRPVB[] = .
      READ TABLE XVBRPVB INDEX 1.
      CHECK SY-SUBRC = 0.
      SELECT SINGLE FROM VBAK WHERE VBELN = XVBRPVB-AUBEL
                                  AND AUART = 'ZSLA'.
      CHECK SY-SUBRC = 0.
      SELECT SINGLE FROM KNA1 WHERE KUNNR = VBAK-KUNNR AND KTOKD = 'Z005'.
      IF SY-SUBRC = 0.
        LOOP AT T_BSEG WHERE KOART = 'D'.
          READ TABLE T_BSEGSUB WITH KEY TABIX = SY-TABIX ASSIGNING .
          IF SY-SUBRC = 0.
            -HKONT = '0011550001'.
          ENDIF.
        ENDLOOP.
      ELSE.
        LOOP AT T_BSEG WHERE KOART = 'D'.
          READ TABLE T_BSEGSUB WITH KEY TABIX = SY-TABIX ASSIGNING .
          IF SY-SUBRC = 0.
            -HKONT = '0011460001'.
          ENDIF.
        ENDLOOP.
      ENDIF.
  ENDCASE.


2010年10月19日

FI park document 檢查 2/2

前篇提到park document save時,借貸要相等的做法是用BTE event 2213,但是error時會整個交易Exit。


我想解法應該不只一種,就用ECC6以後才有的Enhancement Implementation處理:
1 以F-65為例,先找到save時在PAI檢查的PAI module。
2 進一步找到include program LF040F00裡面的form beleg_parken_pruefen,從這段code當中發現是用來做save檢查的。
3 直接在form上面enhance,Enhancement Implementation名稱就取叫ZEH_LF040F00。
4 在enhancement加入以下code:


data: h_wrbtr type wrbtr,
      s_wrbtr 
type wrbtr.
  
LOOP AT xbseg .
    
case xbseg-SHKZG.
      
when 'H'.
        h_wrbtr = h_wrbtr + xbseg-wrbtr.
      
when 'S'.
        s_wrbtr = s_wrbtr + xbseg-wrbtr.
    endcase.
  ENDLOOP.
  
check h_wrbtr ne s_wrbtr.
  
message e888(SABAPDOCU) with '借貸金額不平,請修改明細項目!'.


5 最後記得要active。

FI park document 檢查 1/2

新project在FI有個很特殊的需求:
1 park document的item輸入時檢查利潤中心和成本中心不可空白。
2 park document save時,借貸要相等。

需求1本想用validation做,一試之下發現不行。
退而求其次,改用BTE event 2213,試了之後檢查是可行的,但有個缺點只能在save時檢查,並且一旦檢查出錯誤時,就Exit,失敗!

想來想去差點就無解了,突然想到一個幾乎失傳的技術(RWIN_CHECK),我最早看到是在R/3 4.0有人這麼做過。

考慮利潤中心和成本中心是在item的coding block,所以就copy標準的function FI_COBL_CHECK到ZFI_COBL_CHECK。
在裡面加入以下park doc的檢查code:

IF I_COBL-VORGN = 'RFBV'. * BREAK IBM_KEN.
CASE I_COBL-HKONT(3).
WHEN '006' OR '007'.
IF I_COBL-KOSTL = ''.
SUBRC = 12.
ENDIF.
ENDCASE.

SELECT SINGLE FSTAG INTO FSTAG FROM SKB1
WHERE BUKRS = I_COBL-BUKRS
AND SAKNR = I_COBL-HKONT
AND FSTAG = 'G005'.
IF SY-SUBRC = 0 AND I_COBL-PRCTR = ''.
SUBRC = 13.
ENDIF.
ENDIF.

之後再補上message

WHEN 12.
MESSAGE E888(SABAPDOCU) WITH '成本中心欄位不可空白!!'.
WHEN 13.
MESSAGE E888(SABAPDOCU) WITH '利潤中心欄位不可空白!!'.

完成之後要將table TRWPR補上ZFI_COBL_CHECK設定。

park document save可用失敗的BTE來做,但一樣會Exit,解法下篇再說。

2010年10月12日

IE01自動寫入asset值

友人提問:在IE01要如何能自動帶入asset的值


在IDES找了一下,發現有個EXIT_SAPMIEQ0_001很有機會,但是沒有提供asset的field,所以動手用append structure加一下fields




二個structure都要加,下圖只show一個


加完之後,建立一個asset 


之後加入code



UPDATE_DATA_EZ-BUKRS = '0001'.
UPDATE_FLAGS_EZ-BUKRS = 'X'.
UPDATE_DATA_EZ-ANLNR = '000000020000'.
UPDATE_FLAGS_EZ-ANLNR = 'X'.
UPDATE_DATA_EZ-ANLUN = '0000'.
UPDATE_FLAGS_EZ-ANLUN = 'X'.


CMOD就略過,直接建立IE01


測試自動給值,所以直接保存


asset已寫入

2010年9月25日

BAPI_QUALNOT_CREATE 建立Q3通知單處理訂單號碼及作業號碼

最近想起上個project有個透過interface從MES轉入生產訂單異常,在SAP用BAPI開出QN時,要把訂單號碼及作業號碼寫入的問題。


1 以下是在IDES建立的QN,訂單號碼及作業號碼是直接填入的


2 在BAPI_QUALNOT_CREATE傳入的NOTIFHEADER只找到PROD_ORDER是生產訂單,卻找不到作業號碼對應的field


3 進table AFVC找到field AUFPL及APLZL,剛好可以對應到NOTIFHEADER,改填入這二個field


BAPI_TRANSACTION_COMMIT前要記得先處理BAPI_QUALNOT_SAVE

2010年9月24日

TBB1過帳替換special GL indicator科目

友人提問:TR的TBB1可以替換vendor的special GL indicator科目嗎?


1 進入IDES測試,建立一筆TR交易後執行TBB1測試


2 執行後結果,借方科目是總帳科目,過帳碼是40


3 Implement BADI TPM_ACCIF_TRAC,在Method ACCIT_EXIT修改借方的內容
過帳對象是vendor 1000
科目是160000
過帳碼 21
科目類型 K


  CH_ACCIT_D-LIFNR = '0000001000'.
  CH_ACCIT_D-HKONT = 
'0000160000'.
  CH_ACCIT_D-BSCHL = 
'21'.
  CH_ACCIT_D-KOART = 
'K'.


4 再執行一次TBB1測試,會計科目及過帳碼已經修改成功


5 再修改一次Method ACCIT_EXIT,過帳碼改為29,特殊總帳指示碼改為A,再加入稅碼V0(IDES設定替換後的科目要帶稅碼,在此不特別處理)


  CH_ACCIT_D-LIFNR = '0000001000'.
  CH_ACCIT_D-HKONT = 
'0000160000'.
  CH_ACCIT_D-BSCHL = 
'29'.
  CH_ACCIT_D-UMSKZ = 
'A'.
  CH_ACCIT_D-KOART = 
'K'.
  CH_ACCIT_D-MWSKZ = 
'V0'.


6 再執行一次TBB1測試,過帳碼29已經修改成功,會計科目還是160000


7 正式過帳看看傳票結果,TBB1的科目160000已替換成A類的科目159000



2010年9月21日

設備(IE01/IE02/IE03)客製欄位及BAPI處理

友人提問:設備(IE01/IE02/IE03)的客製欄位如何用BAPI處理?


新增客製欄位就用IDES練習

1 找到設備的table EQUI SAP有預留一個customer include CI_EQUI,直接在這個structure做append structure,命名ZAEQUI
新增一個field ZZMATNR


2 在CMOD新增一個Project,Assignment Enhancement ITOB0001,使用第一個screen exit


3 新增一個function group ZEQUI並建立screen 0100,將新增field 放入screen layout,記得要選Subscreen。(PBO/PAi處理略)



4 在Function exit EXIT_SAPLITO0_001及EXIT_SAPLITO0_002寫入適當code(略)

5 進IE01/IE02/IE03看看結果


6 以上是新增screen exit顯示customer include field,接下來是重點使用bapi,進入BAPI browser找到BAPI_EQUI_CREATE,怎麼找也找不到有CI_EQUI的interface


7 只好改為copy bapi的方式,先找到BAPI_EQUI_CREATE的function group ITOB_BAPI_EQ,直接copy整個function group及
BAPI_EQUI_CREATE,名字前面加個Z

8 發現code DATA: L_ITOB_REC LIKE ITOB,ITOB當中就有CI_EQUI,二話不說馬上修改,在import新增I_CI_EQUI LIKE CI_EQUI,並在CALL FUNCTION 'EQUIPMENT_SAVE'  之前將I_CI_EQUI寫入L_ITOB_REC


L_ITOB_REC-ZZMATNR = I_CI_EQUI-ZZMATNR.


9 經過測試,以上的方法是可行的

2010年9月17日

從BSEG找COPA特性值

友人提問,從FI doc上面要怎麼找到COPA的特性值?

從上圖可以看到FB03直接可查到COPA的特性值,找BSEG只能找到FIELD PAOBJNR,原來COPA的table和img有關,可用CE4*_ACCT在SE11找到table


以IDES為例,company code 1000對應的table就是CE4IDEA_ACCT,在SE16輸入PAOBJNR號碼來找看看:


執行後結果:



2010年9月15日

F110 找出下次付款日

友人提問:在F110自動付款中如何找出下次付款日




檢查標準程式發現是用Data Clusters方式存在,不方便直接使用SQL查詢
要改用Import,以下節錄F110VFP0中的程式碼:


  F110ID-LAUFD   = F110V-LAUFD.
  F110ID-LAUFI   = F110V-LAUFI.
  F110ID-OBJKT   = KON_PARAM.
  F110VERSIONPAR = SPACE.
  REFRESH: BUKTAB, FKTTAB, SLKTAB, SLDTAB, TRCTAB, USRTAB,
           FAETAB, JOBTAB.
  CLEAR:   BUKTAB, FKTTAB, SLKTAB, SLDTAB, TRCTAB, USRTAB,
           FAETAB, JOBTAB, F110C,  TRCOPT, F110VERSIONPAR.
  
IMPORT BUKTAB FKTTAB SLKTAB SLDTAB TRCTAB USRTAB
         FAETAB JOBTAB F110C  TRCOPT F110VERSIONPAR
         
FROM DATABASE RFDT(FB) ID F110ID.


FKTTAB就是parameter的internal table

2010年9月13日

MM03子頁面顯示圖片

前篇提到MM03顯示新的子頁面,在上面放了一張圖片,以下步驟說明如何完成:


1 進入Tcode SMW0,選擇Binary data for WebRFC applications,將圖片上傳至SAP,object name取名叫MY_PIC1


2 在function group ZMGD1 copy screen 1002,給號0200。並在screen layout 拉出一個customer control 取名C_CONTAINER,並在flow logic 新增一個PBO module SET_PICTURE,並填入以下程式碼:


  DATA: G_PICTURE TYPE REF TO CL_GUI_PICTURE,
         G_CUSTOM_CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER,
         URL 
TYPE LENGTH 255.

  
CLASS CL_GUI_CFW DEFINITION LOAD.

  
IF G_CUSTOM_CONTAINER IS INITIAL.

    
CREATE OBJECT G_CUSTOM_CONTAINER
      
EXPORTING
        CONTAINER_NAME              = 
'C_CONTAINER'
      
EXCEPTIONS
        CNTL_ERROR                  = 
1
        CNTL_SYSTEM_ERROR           = 
2
        CREATE_ERROR                = 
3
        LIFETIME_ERROR              = 
4
        LIFETIME_DYNPRO_DYNPRO_LINK = 
5
        
OTHERS                      6.
    
IF SY-SUBRC NE 0.
      
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
                 
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    
CREATE OBJECT G_PICTURE
      
EXPORTING
        PARENT = G_CUSTOM_CONTAINER
      
EXCEPTIONS
        ERROR  = 
1
        
OTHERS 2.
    
IF SY-SUBRC NE 0.
      
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
                 
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    
PERFORM LOAD_PIC_FROM_DB USING 'MY_PIC1' CHANGING URL. * load picture
    
CALL METHOD G_PICTURE->LOAD_PICTURE_FROM_URL
      
EXPORTING
        URL    = URL
      
EXCEPTIONS
        ERROR  = 
1
        
OTHERS 2.
    
IF SY-SUBRC NE 0.
      
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
                 
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    
CALL METHOD CL_GUI_CFW=>FLUSH
      
EXCEPTIONS
        CNTL_SYSTEM_ERROR = 
1
        CNTL_ERROR        = 
2.

  ENDIF.



3 新增一個form routine LOAD_PIC_FROM_DB,可參考程式RSDEMO_DIALOGBOX_CONTROL並修改為可傳入Object Name(詳略)


4 進入Tcode OMT3B修改IMG

MM03新增子頁面

最近友人問我一個MM03新增子頁面並顯示圖片的問題,一直以來只知道可以新增,手癢之下在IDES練習了一下,把過程放上來


首先在se80 copy一個function group MGD1, 取名就叫做ZMGD1吧(不必copy function module)
再來就是到IMG設定新的子頁面,Tcode OMT3B,要選項目21
Copy Basic Data 2,號碼不要重覆,就給85
選取新增的Basic Data 3再雙擊subscreen
在第一個項目維護新function group的main program以及screen number
設定完成,進MM03看看吧(使用IDES最常用料號100-100),多了一個新的view
MM03果然出現了我們新增的view(如何顯示圖片略,請看下一篇)

2010年9月7日

修正Billing Doc匯率

最近有個案子碰到在Create Billing Doc時,很彈性的給定匯率
找了一下,有一支程式RV60AFZC裡面的EXIT可以自行加入程式碼直接將匯率寫入
以下是範例:


FORM USEREXIT_FILL_VBRK_VBRP.
DATA: L_UKURS LIKE TCURR-UKURS.
IF VBRK-WAERK NE 'TWD'.
  CALL FUNCTION 'READ_EXCHANGE_RATE'
    EXPORTING
      CLIENT                  = SY-MANDT
      DATE                    = SY-DATUM
      FOREIGN_CURRENCY        = VBRK-WAERK
      LOCAL_CURRENCY          = VBRK-STWAE
      TYPE_OF_RATE            = VBRK-KURST
    IMPORTING
      EXCHANGE_RATE           = L_UKURS   .  
  IF SY-SUBRC = 0.
    VBRK-KURRF = L_UKURS.
  ENDIF.
ENDIF.
ENDFORM.