Currency Converting Factor(货币转换因子)
Currency Converting Factor(货币转换因子)
ABAP编程中,有个概念很重要,即Currency Converting Factor(货币转换因子)。可能很多ABAP初学者都不知道这是什么东西,这里我们就简单探讨下。
1. 什么是货币转换因子
在SAP中,货币是维护在TCURC表里面,这从Domain: WAERS中可以看到。
不过这里我们要介绍的是表TCURX,它维护了货币金额的小数位。比如JPY日元,在该表是0。正常的货币都是2位小数的。那么,该表有什么意义呢?我们来看下面的例子。
DATA: netwr TYPE p DECIMALS 2.
netwr = '1.3'.
WRITE: netwr CURRENCY 'JPY'.
netwr = '1.3'.
WRITE: netwr CURRENCY 'JPY'.
输出的结果是130,即1.3*100,我们说日元的转换因子为100。这是因为TCURX定义了日元没有小数位,那么数据库表的实际数字 1.3 就解释成了130。反过来就是,我们认为的130日元,在数据库里存储成了1.3。这个过程都是SAP自动处理的。
同理,小数位为1的,其转换因子为10;而RMB因为小数位为2,其转换因子为1,这也是系统的默认值。
2. 如何将CURR字段赋给DEC(P)字段
如果要将一个CURR字段赋值给类型为DEC(P)的字段,则要考虑货币转换因子的影响。当我们写与外系统集成的接口时,这就显得很有必要了。
这里介绍个函数:CURRENCY_CONVERTING_FACTOR,它可用于读取货币转换因子。
DATA: v LIKE vbap-netwr,
p TYPE p DECIMALS 2,
cur LIKE vbap-waerk,
factor TYPE p DECIMALS 3.
p TYPE p DECIMALS 2,
cur LIKE vbap-waerk,
factor TYPE p DECIMALS 3.
v = '1.3'.
cur = 'JPY'.
CALL FUNCTION 'CURRENCY_CONVERTING_FACTOR'
EXPORTING
currency = cur
IMPORTING
factor = factor
EXCEPTIONS
too_many_decimals = 1
OTHERS = 2.
IF sy-subrc <> 0.
factor = 1.
ENDIF.
p = v * factor.
WRITE: p.
这样,我们与外系统集成时,应该以p作为接口参数,130日元就不会错误地成了1.3日元。
3. ABAP编程中需要注意的地方
在编程中,我们对CURR字段要多加以注意,下面简单举几个应用例子。
(1) List中,当输出CURR字段时,记得指定对应的货币.
    如: WRITE: vbap-netwr CURRENCY vbap-waerk.
(2) Screen中,对于CURR字段,需要设置对应的货币字段,

(3) ALV中,需要对FIELD CATALOG进行设置.
    如: ls_cfieldname = 'WAERS'. "这里的WAERS是内表中的另一字段
附上一段自己的代码:
  DATA:v_price    TYPE zrn_code1_price,
lv_netpr TYPE zrn_code1_price,
factor TYPE p DECIMALS 3.
v_price = '12.50603'.
CALL FUNCTION 'CURRENCY_CONVERTING_FACTOR'
EXPORTING
currency = 'USD'
IMPORTING
factor = factor
EXCEPTIONS
too_many_decimals = 1
OTHERS = 2.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
lv_netpr = v_price * factor.
WRITE: / lv_netpr.
lv_netpr TYPE zrn_code1_price,
factor TYPE p DECIMALS 3.
v_price = '12.50603'.
CALL FUNCTION 'CURRENCY_CONVERTING_FACTOR'
EXPORTING
currency = 'USD'
IMPORTING
factor = factor
EXCEPTIONS
too_many_decimals = 1
OTHERS = 2.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
lv_netpr = v_price * factor.
WRITE: / lv_netpr.
实际项目中的例子:
  想更新Scheduling Agrement中的condition, reason code price1的值减去原来的netvalue的值就是需要增加的value.
Step 1: 计算netprice的合计值(currency是reason code price的currency) 
  METHOD convert_to_local_currency.
DATA: lv_convert_amout TYPE zcurrency_convert,
lv_exchange_rate TYPE tcurr-ukurs,
lv_foreign_factor TYPE tcurr-ffact,
lv_local_factor TYPE tcurr-tfact,
lv_rate TYPE c LENGTH 14.
CLEAR: ex_convert_amount,ex_rate_not_found,lv_convert_amout.
CALL METHOD me->convert_currency_to_external
EXPORTING
im_currency = im_foreign_currency
im_internal_amount = im_convert_amount
IMPORTING
ex_external_amount = lv_convert_amout.
IF im_foreign_currency = im_local_currency.
ex_convert_amount = lv_convert_amout.
ELSE.
CLEAR: lv_exchange_rate,lv_foreign_factor,lv_local_factor,lv_rate.
CALL FUNCTION 'READ_EXCHANGE_RATE'
EXPORTING
client = sy-mandt
date = im_translation_date
foreign_currency = im_foreign_currency
local_currency = im_local_currency
type_of_rate = 'M'
IMPORTING
exchange_rate = lv_exchange_rate
foreign_factor = lv_foreign_factor
local_factor = lv_local_factor
EXCEPTIONS
no_rate_found = 1
no_factors_found = 2
no_spread_found = 3
derived_2_times = 4
overflow = 5
zero_rate = 6
OTHERS = 7.
IF sy-subrc = 0.
lv_rate = lv_exchange_rate / ( lv_foreign_factor / lv_local_factor ).
ex_convert_amount = lv_convert_amout * lv_rate.
ELSE.
CALL FUNCTION 'FORMAT_MESSAGE'
EXPORTING
id = c_msgid_zsara
lang = sy-langu
no = c_num-n057
v1 = im_foreign_currency
v2 = im_local_currency
IMPORTING
msg = ex_rate_not_found
EXCEPTIONS
not_found = 1
OTHERS = 2.
ENDIF.
ENDIF.
ENDMETHOD.
DATA: lv_convert_amout TYPE zcurrency_convert,
lv_exchange_rate TYPE tcurr-ukurs,
lv_foreign_factor TYPE tcurr-ffact,
lv_local_factor TYPE tcurr-tfact,
lv_rate TYPE c LENGTH 14.
CLEAR: ex_convert_amount,ex_rate_not_found,lv_convert_amout.
CALL METHOD me->convert_currency_to_external
EXPORTING
im_currency = im_foreign_currency
im_internal_amount = im_convert_amount
IMPORTING
ex_external_amount = lv_convert_amout.
IF im_foreign_currency = im_local_currency.
ex_convert_amount = lv_convert_amout.
ELSE.
CLEAR: lv_exchange_rate,lv_foreign_factor,lv_local_factor,lv_rate.
CALL FUNCTION 'READ_EXCHANGE_RATE'
EXPORTING
client = sy-mandt
date = im_translation_date
foreign_currency = im_foreign_currency
local_currency = im_local_currency
type_of_rate = 'M'
IMPORTING
exchange_rate = lv_exchange_rate
foreign_factor = lv_foreign_factor
local_factor = lv_local_factor
EXCEPTIONS
no_rate_found = 1
no_factors_found = 2
no_spread_found = 3
derived_2_times = 4
overflow = 5
zero_rate = 6
OTHERS = 7.
IF sy-subrc = 0.
lv_rate = lv_exchange_rate / ( lv_foreign_factor / lv_local_factor ).
ex_convert_amount = lv_convert_amout * lv_rate.
ELSE.
CALL FUNCTION 'FORMAT_MESSAGE'
EXPORTING
id = c_msgid_zsara
lang = sy-langu
no = c_num-n057
v1 = im_foreign_currency
v2 = im_local_currency
IMPORTING
msg = ex_rate_not_found
EXCEPTIONS
not_found = 1
OTHERS = 2.
ENDIF.
ENDIF.
ENDMETHOD.
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号