说明:查询当前日期之前最新的汇率。
根据原币和汇率时,取凭证日期之前最近的汇率,SQL查询时不能直接使用凭证日期,应该先转换为系统日期,然后才能进行查询。
以下代码实现:
根据交货单上的交货日期,查询交货日期上个月月末的汇率,如果不存在则继续往前查找,直至最新。如交货日期2010-12-15,则查找上个月月末2010-11-30维护的汇率,否则找10月末的,依次递推。
分成4步:
1)'FIMA_DATE_CREATE' 求得上月最后一天;
2)将最后一天转换为系统内部日期;
3)查询汇率有效起始日期,比较关系(大于小于)与外部日期正好相反;
4)将汇率有效起始日期(转为外部日期)代入汇率函数:'READ_EXCHANGE_RATE'。
即: 最后一天 —— 转为系统内部日期 —— 汇率有效起始日期 —— 汇率函数取汇率。
DATA : l_YFKD LIKE MKPF-BLDAT, " 预付款日 中间变量
l_gdatu LIKE TCURR-gdatu, " 日期
l_ukurs LIKE TCURR-ukurs. " 汇率
DATA : l_last_day TYPE DVALUT.
DATA: l_foreign_factor LIKE tcurr-ffact, "汇率转换因子
l_local_factor LIKE tcurr-tfact.
LOOP AT item_out.
*————以下处理原币、本位币计算—————
READ TABLE it_po WITH key EBELN = item_out-EBELN
EBELP = item_out-EBELP.
MOVE-CORRESPONDING it_po to item_out.
if item_out-WAERS = 'JPY' or item_out-WAERS = 'KRW'.
item_out-ZYBJE_S = item_out-ERFMG * item_out-NETPR / 10 .
else.
item_out-ZYBJE_S = item_out-ERFMG * item_out-NETPR .
endif.
IF item_out-WAERS <> 'CNY'.
* 1)求上月最后一天 CALL FUNCTION 'FIMA_DATE_CREATE' EXPORTING i_date = item_out-BLDAT i_months = '-1' i_set_last_day_of_month = 'X' IMPORTING e_date = l_last_day.
" 输入20101215 得到l_last_day :20101130
* 2) 将外部日期转换为系统内部日期
CALL FUNCTION 'CONVERSION_EXIT_INVDT_INPUT'
EXPORTING
input = l_last_day
IMPORTING
output = l_last_day.
" 将 20101130转换为内部日期,得到l_last_day :79898869
* 3)取最近一个月的汇率起始有效日期
* GE —— >= 。 不大于上月月底的,取数据时正好相反处理采用GE
" 关于日期比较:
" 20101130日,转换为系统内部日期时为99999999-20101130=79898869,在20101130日之前的日期(aa< = 20101130),则:
" 转换为系统内部日期后 99999999-bb<= 99999999-20101130,即 bb >= 79898869 (对应gdatu GE l_last_day)。
SELECT MIN( gdatu ) INTO l_gdatu FROM tcurr WHERE kurst = 'M' AND fcurr = item_out-WAERS
AND tcurr = 'CNY' and gdatu ge l_last_day.
IF sy-subrc = 0.
" 4)自定义日期转换,去除了将20101130强制转换为2010-11-30 的write输出
" 也可以直接用99999999直接减,再按格式输出。
CALL FUNCTION 'Z_CONVERSION_EXIT_INVDT_OUTPUT'
EXPORTING
input = l_gdatu
IMPORTING
output = l_last_day.
IF item_out-WAERS is NOT INITIAL.
" 5)读取汇率
CALL FUNCTION 'READ_EXCHANGE_RATE'
EXPORTING
date = l_last_day
foreign_currency = item_out-WAERS
local_currency = 'CNY'
IMPORTING
exchange_rate = l_ukurs
foreign_factor = l_foreign_factor
local_factor = l_local_factor.
ENDIF.
" 本币 = 原币金额 * l_ukurs * l_local_factor / l_foreign_factor .
IF sy-subrc <> 0.
l_ukurs = 1. l_foreign_factor = 1. l_local_factor = 1.
ENDIF.
item_out-UKURS = l_ukurs.
item_out-BWERT_S = item_out-ZYBJE_S * l_ukurs * l_local_factor / l_foreign_factor .
ENDIF.
ELSE.
item_out-BWERT_S = item_out-ZYBJE_S.
endif.
* 暂不考虑预付款比例问题
item_out-ZYBJE = item_out-ZYBJE_S .
item_out-BWERT = item_out-BWERT_S .
* ……
MODIFY item_out.
CLEAR item_out.
ENDLOOP.
另外: 'Z_CONVERSION_EXIT_INVDT_OUTPUT' 是参考'CONVERSION_EXIT_INVDT_OUTPUT' 的函数,主要代码
INPUT 定义不变,OUTPUT定义为DVALUT。
FUNCTION Z_CONVERSION_EXIT_INVDT_OUTPUT.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(INPUT)
*" EXPORTING
*" VALUE(OUTPUT) TYPE DVALUT
*"----------------------------------------------------------------------
DATA: CHDAT(8) TYPE C,
HOUTPUT(8) TYPE N, "Hilfsfeld zum Aufbereiten der Jahre>=9000
DATUM LIKE SY-DATUM,
FEHLER(1) TYPE C.
DATA: HILF1(9) TYPE C,
OUTDATUM TYPE D.
IF INPUT <> SPACE.
HILF1 = '99999999' - INPUT.
TRANSLATE HILF1(5) USING ' 0'.
CONDENSE HILF1 NO-GAPS.
OUTDATUM = HILF1.
WRITE OUTDATUM TO OUTPUT. " 去除了原函数中的强制转化为XXXX-XX-XX的10位输出,采用8位输出。
ELSE.
OUTPUT = SPACE.
ENDIF.
ENDFUNCTION.
说明:日期转换其实很简单,不用所谓的自定义函数。在SAP 的Demo中 (abapdocu ,
BC -Abap Programming->The Abap programming Language->Process Data)
![](https://i-blog.csdnimg.cn/blog_migrate/55f51ce3fa05d8f2703146b0c06875f4.jpeg)
“convert date
DATA: odate TYPE d VALUE '19955011',
idate LIKE odate.
DATA field(8) TYPE c.
field = odate. WRITE / field.
CONVERT DATE odate INTO INVERTED-DATE idate.
field = idate. WRITE / field.
CONVERT INVERTED-DATE idate INTO DATE odate.
field = odate. WRITE / field.
结果:![](https://i-blog.csdnimg.cn/blog_migrate/b1918e3dabeaecae5d7ce97b3ed1c8ca.jpeg)