顯示具有 ABAP/4 標籤的文章。 顯示所有文章
顯示具有 ABAP/4 標籤的文章。 顯示所有文章

2011年11月29日

用ABAP寄送mail單封處理


透過ABAP寄送mail時,過去都是用SCOT直接發出去
遇到server上有等待的mail時會一口氣全部送出去,這樣在測試區會造成不必要的郵件被送出去

可以改執行程式RSSOSOSTSTAT,如此就可以指定要寄送的郵件再送出

2011年10月31日

MV45AFZZ修改SO ITEM問題

有個需求是希望在SO的ITEM在修改VBKD時,能夠update VBAP某些欄位,進到MV45AFZZ去找到FORM USEREXIT_SAVE_DOCUMENT_PREPARE.直接新增修改邏輯。改完實際去測試會發現,若VBAP相關的欄位沒有修改時,save之後VBAP還是一樣的。

想要在FORM USEREXIT_SAVE_DOCUMENT_PREPARE修改VBAP的值有二個方式:
1 在VA02時就已經有VBAP的修改(解法不佳)
2 在FORM當中指定VBAP要強制修改(可行),做法如下:
在XVBAP[]當中找到要修改的VBAP並指定UPDKZ = 'U',要特別注意UPDKZ若已是'D'時表示這個item save之後會被刪除,千萬不要去修改UPDKZ。另外也要考慮這一筆VBAP若是新增時,不需要指定UPDKZ 。


2011年10月27日

SO 狀態說明讀取

下圖的狀態欄位經過讀取TABLE VBUK只能得到狀態碼,無法得到顯示的內文。若直接Call Function DOMAIN_VALUE_GET去讀到Domain的value也不是正確的。實際上SO的狀態說明是維護在TABLE TVBST當中,不是在Domain。



2011年5月26日

Smartform圖片用變數指定

在設計smartform時,遇到像LOGO的圖片需要依不用的條件指定時,可用以下的方式處理:

首先設定一個smartform的參數,資料類型是TDOBNAME


再來就是指字圖片的變數名稱,前後要用符號&

2011年5月18日

READ_EXCHANGE_RATE EUR匯率問題

在讀匯率資料時使用READ_EXCHANGE_RATE 進行EUR/USD的匯率讀取後
系統會回傳一個值DERIVED_RATE_TYPE = EURX
這個意思是系統會以EURX的匯率來讀取

可用TCODE OBBS進行設定

新增一筆時間較晚的設定將替代的匯率類型空白即可使用原匯率類型讀取匯率


2011年5月16日

Smartform 輸出總頁數問題

在設計SMARTFORM時,輸出總頁數會用到一個系統變數SFSY-FORMPAGES,通常是直接在內文使用&SFSY-FORMPAGES&輸出,但是遇到總頁數達到2位數時,就會顯示*

目前找到有二種解法:
1 改寫輸出方式
&SFSY-FORMPAGES& 改成 &SFSY-FORMPAGES(3ZC)&
2 修改內文所在視窗為最終視窗

讀取不同語言的Text Symbol

在一般情形下,ABAP處理Text Symbol時是依登入的語言來處理,
登入的語言若沒有維護對應的Text時,會直接參考程式建立時的Original版本
在報表處理上,遇到使用者想依資料的上的狀態來讀取Text時,就需要另外處理
以下公司設定的語言別為例:

**讀取公司語言別的Text
DATA: lt_pool LIKE TABLE OF textpool.
READ TEXTPOOL sy-repid INTO lt_pool LANGUAGE t001-spras.





2011年4月22日

將文字以指定的輸出長度分段

在報表輸出時,中文字佔了二個文字的長度,而Unicode系統的SAP中文字只算1個長度
報表格式上有長度限制時,就需要另外處理讓文字可以分段:
FUNCTION Z_STRING_SPLIT_TO_TABLE .
*"----------------------------------------------------------------
*"*"區域介面:
*" IMPORTING
*" REFERENCE(PI_STRING) TYPE STRING
*" REFERENCE(PI_SIZE) TYPE I DEFAULT 20
*" EXPORTING
*" VALUE(PE_LINECOUNT) TYPE I
*" TABLES
*" PT_STRING STRUCTURE UPS_YS_STRING_TABLE OPTIONAL
*"----------------------------------------------------------------


DATA: LV_CHAR(4096),
LV_STRLEN TYPE I, "輸入字串長度
LV_STRCOUNT TYPE I VALUE 0, "字串計數器
LV_COUNTER TYPE I, "長度計數器
LV_LEN TYPE I. "長度變數

*****計算出字串長度
LV_STRLEN = STRLEN( PI_STRING ).
*****將String轉成char
LV_CHAR = PI_STRING.
*****利用CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH
*****計算出顯示長度後依條件分割
WHILE LV_STRCOUNT < LV_STRLEN.
LV_COUNTER = 1.
WHILE LV_COUNTER <= PI_SIZE.
CALL METHOD CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH
EXPORTING
FIELD = LV_CHAR+LV_STRCOUNT(LV_COUNTER)
RECEIVING
LEN = LV_LEN.
IF LV_LEN = PI_SIZE.
PT_STRING-LINE = LV_CHAR+LV_STRCOUNT(LV_COUNTER).
APPEND PT_STRING.
LV_STRCOUNT = LV_STRCOUNT + LV_COUNTER - 1.
EXIT.
ELSE.
LV_LEN = LV_STRCOUNT + LV_COUNTER.
IF LV_LEN = LV_STRLEN.
PT_STRING-LINE = LV_CHAR+LV_STRCOUNT(LV_COUNTER).
APPEND PT_STRING.
LV_STRCOUNT = LV_STRCOUNT + LV_COUNTER - 1.
ENDIF.
LV_COUNTER = LV_COUNTER + 1.
ENDIF.
ENDWHILE.
LV_STRCOUNT = LV_STRCOUNT + 1.
ENDWHILE.

*****計算分割後的字串數
DESCRIBE TABLE PT_STRING LINES PE_LINECOUNT.
ENDFUNCTION.

2011年4月12日

日期加減月份的處理

有個需求要抓最近半年內的文件,比如說2011年3月底的半年內,
要抓的是2010/10/1~2011/3/31範圍內的文件
可以利用HR的FM來處理,HR_HK_ADD_MONTH_TO_DATE,範例如下:

CALL FUNCTION 'HR_HK_ADD_MONTH_TO_DATE'
  EXPORTING
    dmm_datin = '20110331'
    dmm_count = '5'
    dmm_oper  = '-'
    dmm_pos   = 'X'
  IMPORTING
    dmm_daout = g_date
  EXCEPTIONS
    unknown   = 1
    OTHERS    = 2.

g_date+6(2) = '01'.  "2010/10/01


2011年2月11日

BAPI_ACC_DOCUMENT_POST 建立Park文件TAX item問題

還是用BAPI_ACC_DOCUMENT_POST 建立Park文件的問題。TAX item要在code裡面先處理好,借貸才會相等。步驟如下:

1 Tax不存入internal table ACCOUNTGL,要存入ACCOUNTTAX,指定的ITEMNO_ACC要正確。
2 處理 CURRENCYAMOUNT時,除了field AMT_DOCCUR要有稅額,field AMT_BASE稅基也要一併處理。

處理完成後進行測試,發現以下新的問題,金額借貸不相等,但是item相加是正常的???



檢查tax amount多了,要清除為0


做法:用BADI ACC_DOCUMENT的method CHANGE

DATA: WA_ACCTX TYPE ACCBSET.
LOOP AT C_ACCTX INTO WA_ACCTX.
CLEAR WA_ACCTX-FWSTE.
MODIFY C_ACCTX FROM WA_ACCTX .
ENDLOOP.

再RUN一次BAPI_ACC_DOCUMENT_POST這次正常:

2011年2月10日

由payment term決定baseline date的function module

繼上次寫到的用BAPI_ACC_DOCUMENT_POST 建立Park文件之後出現了新的問題:
在vendor的line item上面只寫入payment term是不夠的,baseline date會變成空的,post時還要再補上baseline date。

以下是計算vendor baseline date的function module
FI_TERMS_OF_PAYMENT_PROPOSE

要計算customer時用這個:GET_BASELINE_DATE

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。