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 。
想要在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圖片用變數指定
2011年5月18日
READ_EXCHANGE_RATE EUR匯率問題
在讀匯率資料時使用READ_EXCHANGE_RATE 進行EUR/USD的匯率讀取後
系統會回傳一個值DERIVED_RATE_TYPE = EURX
這個意思是系統會以EURX的匯率來讀取
可用TCODE OBBS進行設定
系統會回傳一個值DERIVED_RATE_TYPE = EURX
這個意思是系統會以EURX的匯率來讀取
可用TCODE OBBS進行設定
2011年5月16日
Smartform 輸出總頁數問題
在設計SMARTFORM時,輸出總頁數會用到一個系統變數SFSY-FORMPAGES,通常是直接在內文使用&SFSY-FORMPAGES&輸出,但是遇到總頁數達到2位數時,就會顯示*
目前找到有二種解法:
1 改寫輸出方式
&SFSY-FORMPAGES& 改成 &SFSY-FORMPAGES(3ZC)&
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.
登入的語言若沒有維護對應的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
*"----------------------------------------------------------------
*"*"區域介面:
*" 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.
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
要抓的是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這次正常:
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
在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顧問。
以下是利用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.
要將訊息輸出時,從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.
要注意的是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當中。
要注意的地方是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.
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.
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文件。
系統上並沒有這樣功能的的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。
以下範例僅供參考:
改往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.
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'.
WHEN 'K'.
ENDCASE.
ELSE. "非關係人
CASE TMP_EKPO-KNTTP.
WHEN 'A'.
WHEN 'K'.
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.
ENDIF.
ENDLOOP.
ELSE.
LOOP AT T_BSEG WHERE KOART = 'D'.
READ TABLE T_BSEGSUB WITH KEY TABIX = SY-TABIX ASSIGNING
IF SY-SUBRC = 0.
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。
我想解法應該不只一種,就用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。
訂閱:
文章 (Atom)



