Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Convert formatted amount to internal SAP format

Peter_Inotai
Active Contributor
0 Kudos
10,697

Hi,

I have to output spelled amount in a SAP Script form.

For this I use SAPScript command PERFORM and generate the spelled amount with FM SPELL_AMOUNT.

However in my subroutine I need the amount unformatted otherwise I got ABAP dump CONVT_NO_NUMBER / CX_SY_CONVERSION_NO_NUMBER.

I already found this thread, but it didn't really work for me:

My example:

3.520,00 MXN

Any idea?

Thanks,

Peter

1 ACCEPTED SOLUTION

Former Member
0 Kudos
1,352

You can try this - Have one variable in cHAR format which you can use to display and other in Currency format which you can pass to the function module. Populate new Currency variable at the same time as when you populate the other variable and use the same.

26 REPLIES 26

Former Member
0 Kudos
1,353

You can try this - Have one variable in cHAR format which you can use to display and other in Currency format which you can pass to the function module. Populate new Currency variable at the same time as when you populate the other variable and use the same.

0 Kudos
1,352

Thanks Ashish, but when I try to pass char format variable to currency format variable I got the mentioned short dump:

CONVT_NO_NUMBER / CX_SY_CONVERSION_NO_NUMBER

Peter

0 Kudos
1,352

Hi peter,

Try Function module :

BAPI_CURRENCY_CONV_TO_INTERNAL

and then use SPELL_AMOUNT.

Regards,

Lanka

0 Kudos
1,352

Hi Lanka,

BAPI_CURRENCY_CONV_TO_INTERNAL works fine in SE37, however I have no idea how to convert the format CHAR 255 from ITCSY-VALUE to the format of DEC 23/4 of BAPICURR-BAPICURR:-(((((

Thanks,

Peter

0 Kudos
1,352

Hi Peter,

Please define a data variable as

data : v_amount type BAPICURR-BAPICURR,

V_Amt type xeban-preis.

Move ITCSY-VALUE to v_amount.

Call function 'BAPI_CURRENCY_CONV_TO_INTERNAL '

Exporting

currency = 'USD'

Amount External = V_Amount

Importing

Amount External = V_Amt

Regards,

Lanka

0 Kudos
1,352

You will still need to get rid of the comma.



report zrich_0003.

data: input type  bapicurr-bapicurr .
data: c(20) type c.
data: output(15) type p decimals 2.


c = '215,654.54'.

clear sy-subrc.
while sy-subrc = 0.
  replace ',' with space into c.
endwhile.
condense c no-gaps.
input = c.

call function 'BAPI_CURRENCY_CONV_TO_INTERNAL'
  exporting
    currency                   = 'USD'
    amount_external            = input
    max_number_of_digits       = 20
 importing
    amount_internal            = output
*   RETURN                     =
          .

check sy-subrc = 0.

Regards,

Rich Heilman

0 Kudos
1,352

I cannot move the value as I got short dump CONVT_NO_NUMBER / CX_SY_CONVERSION_NO_NUMBER:

Move ITCSY-VALUE to v_amount.

Peter

0 Kudos
1,352

Right, you need to get rid of, at least, the comma. See my above post.

Regards,

Rich Heilman

0 Kudos
1,352

Hi peter,

Can you define ITCSY-VALUE as Char.

Lanka

0 Kudos
1,352

My problem is that the user setting can be different:

c = '3.520,00'.

or

c = '3,520.00'.

Peter

0 Kudos
1,352

Then you must get rid of both commans and decimal points. Look at this code. Notice that the fomat of the value has changed, and it still works.



report zrich_0003.

data: input type  bapicurr-bapicurr .
data: c(20) type c.
data: output(15) type p decimals 2.


<b>c = '215.654,54'.</b>
clear sy-subrc.
while sy-subrc = 0.
  replace ',' with space into c.
endwhile.
clear sy-subrc.
while sy-subrc = 0.
  replace '.' with space into c.
endwhile.
condense c no-gaps.
input = c / 100.


call function 'BAPI_CURRENCY_CONV_TO_INTERNAL'
  exporting
    currency                   = 'USD'
    amount_external            = input
    max_number_of_digits       = 20
 importing
    amount_internal            = output
*   RETURN                     =
          .

write:/ output.

Regards,

Rich Heilman

0 Kudos
1,352

Thanks. It's defined as char 255.

Maybe I share my code to give more info:

* eject
*=======================================================================
* Get Spelled Amount
*=======================================================================
FORM get_spelled_amount
     TABLES in_tab  STRUCTURE itcsy
            out_tab STRUCTURE itcsy.

  DATA:
  lv_c_fkwrt        TYPE itcsy-value,
  lv_bapi_fkwrt     TYPE bapicurr-bapicurr,
  lv_fkwrt          TYPE komk-fkwrt,
  lv_waerk          TYPE komk-waerk,
  lv_spras          TYPE vbdkr-spras,
  lv_spelled_amount TYPE spell-word,
  lwa_words         TYPE spell.

  BREAK-POINT.

  READ TABLE in_tab WITH KEY 'KOMK-FKWRT'.
  IF sy-subrc = 0.
    lv_c_fkwrt = in_tab-value.
  ENDIF.

  READ TABLE in_tab WITH KEY 'KOMK-WAERK'.
  IF sy-subrc = 0.
    lv_waerk = in_tab-value.
  ENDIF.

  READ TABLE in_tab WITH KEY 'VBDKR-SPRAS'.
  IF sy-subrc = 0.
    lv_spras = in_tab-value.
  ENDIF.

*  lv_bapi_fkwrt = lv_c_fkwrt. ????

  CALL FUNCTION 'BAPI_CURRENCY_CONV_TO_INTERNAL'
    EXPORTING
      currency                   = lv_waerk
      amount_external            = lv_c_fkwrt
      max_number_of_digits       = 18
   IMPORTING
      amount_internal            = lv_fkwrt
*   RETURN                     =
            .


  CALL FUNCTION 'SPELL_AMOUNT'
    EXPORTING
      amount    = lv_fkwrt
      currency  = lv_waerk
      filler    = ' '
      language  = lv_spras
    IMPORTING
      in_words  = lwa_words
    EXCEPTIONS
      not_found = 1
      too_large = 2
      OTHERS    = 3.
  IF sy-subrc <> 0.
    lv_spelled_amount = lwa_words-word.
  ELSE.
    lv_spelled_amount =  space.
  ENDIF.


  REFRESH out_tab.

  out_tab-name  = 'LV_SPELLED_AMOUNT'.
  out_tab-value = lv_spelled_amount.

  APPEND out_tab.

ENDFORM.                    "get_spelled_amount

0 Kudos
1,352

Hi Peter,

I think BAPI convert currency will consider all the user settings for currency formats and it convert that into internal format.

Or you can use Rich's suggestion.

Regards,

Lanka

0 Kudos
1,352

I'm mainly worried about this statement:

input = c / 100.

I don't think every currency has only two digit after the comma or dot.

Peter

0 Kudos
1,352

Ok, how about this. Program will read the string backwards untill it finds a comma or decimal, it will mark with an X and handle it after getting rid of all other commas and decimals.



report zrich_0003.

data: input type  bapicurr-bapicurr .
data: c(50) type c.
data: output(15) type p decimals 2.
data: length type i.
data: offset type i.


c = '215.654,5423'.
length = strlen( c ).
offset = length - 1.

while sy-subrc = 0.
  if c+offset(length) ca ',.'.
    c+offset(1) = 'X'.
    sy-subrc = 4.
  endif.
  offset = offset - 1.
endwhile.

clear sy-subrc.
while sy-subrc = 0.
  replace ',' with space into c.
endwhile.
clear sy-subrc.
while sy-subrc = 0.
  replace '.' with space into c.
endwhile.

replace 'X' with '.' into c.
condense c no-gaps.
input = c.


call function 'BAPI_CURRENCY_CONV_TO_INTERNAL'
  exporting
    currency                   = 'USD'
    amount_external            = input
    max_number_of_digits       = 20
 importing
    amount_internal            = output
*   RETURN                     =
          .

write:/ output.

Regards,

Rich Heilman

0 Kudos
1,352

Thanks a lot Rich for your help!!!

Meanwhile I found TCURX, which could be useful for checking Decimal Places in Currencies (only the ones, which has not 2).

Sorry, but I worried about this statement:

replace 'X' with '.' into c.

I'm not sure it's ok for all users. What if user has comma as a separator?

Anyway I'll talk to the functional side, to collect most of the used currencies and add them to an if statement, probable it will be easier.

Also I'll check if I can fetch the data from the DB in all the case, that would be much easier...but I'm not sure that during printing it's always available with the latest value.

Thanks a lot for everyone, who helped me especially for Rich!

Peter

0 Kudos
1,352

That statement is just replacing the decimal point in the value. Earlier we changed it to "X". The internal format in the system is always, "." as the decimal separator.

Please make sure to award points for any helpful answers. Thanks.

Regards,

Rich Heilman

0 Kudos
1,352

Peter,

you could try to get the user configuration in the USR01 table, get the decimal point and take the correct action for each one.

The field is the DCPFM, if the value is 'X' decimal point is '.' (dot), else will be ',' (comma).

Try change your user configuration, the second tab in the SU3 transaction.

Regards,

0 Kudos
1,352

Peter,

the examples given by Rich works fine.

See another little example below, and let us know when you solved your problem.

Regards,

REPORT zwteste NO STANDARD PAGE HEADING LINE-SIZE 255.

DATA: lc_amount(255),

lc_dcpfm,

lp_amount LIKE komk-fkwrt.

DATA: spelled_amount TYPE spell.

PARAMETER: amount LIKE komk-fkwrt,

currency LIKE komk-waerk,

spras LIKE vbdkr-spras.

WRITE amount TO lc_amount CURRENCY currency.

CONDENSE lc_amount NO-GAPS.

WRITE: / 'External value......:', lc_amount(50).

SELECT SINGLE dcpfm

INTO lc_dcpfm

FROM usr01

WHERE bname EQ sy-uname.

IF lc_dcpfm EQ 'X'.

TRANSLATE lc_amount USING ', '.

ELSEIF lc_dcpfm EQ 'Y'.

TRANSLATE lc_amount USING ',.'.

ELSE.

TRANSLATE lc_amount USING ',X'.

TRANSLATE lc_amount USING '. '.

TRANSLATE lc_amount USING 'X.'.

ENDIF.

CONDENSE lc_amount NO-GAPS.

WRITE: / 'External to Internal:', lc_amount(50).

lp_amount = lc_amount.

CALL FUNCTION 'SPELL_AMOUNT'

EXPORTING

amount = lp_amount

currency = currency

  • FILLER = ' '

language = spras

IMPORTING

in_words = spelled_amount

EXCEPTIONS

not_found = 1

too_large = 2

OTHERS = 3

.

IF sy-subrc <> 0.

WRITE / 'Error in SPELL_AMOUNT function'.

ELSE.

CONCATENATE spelled_amount-word spelled_amount-decword

INTO spelled_amount-word

SEPARATED BY space.

WRITE: / 'Spelled amount......:',

spelled_amount-word(100),

/ spelled_amount-word+100(100) UNDER spelled_amount-word,

/ spelled_amount-word+200(55) UNDER spelled_amount-word.

Message was edited by: Washington Oliveira

0 Kudos
1,352

>Please make sure to award points for any helpful answers.

As I already marked one post as Solved my problem (yes, it was a little bit too early), I can mark all the other post only as Helpful answer, Very helpful answer is not possible.

I tried to remove the Solved my problem flag, but it was not possible.

Sorry about this, I would reward them as Very helpful answer, but it doesn't seem to be possible.

Thanks for the answers, I'll check them tomorrow when I have access to our system and provide feedback, but I'm about 99% sure that it will work.

Peter

0 Kudos
1,352

HI Peter Inotai

HERE IS THE CODE FOR HOW TO HANDLE THE <b>AMOUNT</b> FIELD, WHATEVER BE THE USER PROFILE (DECIMAL NOTATION).

HERE <b>FIELD_NUM</b> = AMOUNT(VALUE).

***********************************************


SELECT SINGLE DCPFM FROM USR01
             INTO VAR_DCPFM WHERE BNAME EQ SY-UNAME.

  IF VAR_DCPFM EQ 'X'.
    REPLACE ALL OCCURRENCES OF ',' IN: FIELD_NUM WITH ''.
  ELSEIF VAR_DCPFM EQ ''.
    REPLACE ALL OCCURRENCES OF '.' IN: FIELD_NUM WITH ''.
    TRANSLATE FIELD_NUM USING ',.'.
  ELSEIF VAR_DCPFM EQ 'Y'.
    TRANSLATE FIELD_NUM USING ',.'.
  ENDIF.

***********************************************

NOW FIELD_NUM CONTAINS VALUE IN FORMAT = 1234.50

CHEERS,

VIJAY RAHEJA

0 Kudos
1,352

Thanks a lot for everyone, who helped me!!!

The following program worked fine for me almost all cases.

Fm SPELL_AMOUNT behaved strange for currency BEF.

REPORT z_bc_s_test.

CONSTANTS:
c_zero TYPE spell-decword VALUE 'ZERO'.

DATA:
lv_c_fkwrt        TYPE itcsy-value,
lv_bapi_fkwrt     TYPE bapicurr-bapicurr,
lv_fkwrt          TYPE komk-fkwrt,
lv_waerk          TYPE komk-waerk,
lv_spras          TYPE vbdkr-spras,
lv_dcpfm          TYPE usr01-dcpfm,
lv_spelled_amount TYPE spell-word,
lwa_words         TYPE spell.

PARAMETERS:
    p_fkwrt TYPE itcsy-value,
    p_waerk TYPE itcsy-value,
    p_spras TYPE itcsy-value.


lv_waerk   = p_waerk.
lv_spras   = p_spras.
lv_c_fkwrt = p_fkwrt.

SELECT SINGLE dcpfm
       INTO lv_dcpfm
       FROM usr01
       WHERE bname = sy-uname.

IF lv_dcpfm EQ 'X'.
  REPLACE ALL OCCURRENCES OF ',' IN lv_c_fkwrt WITH ''.
ELSEIF lv_dcpfm EQ ''.
  REPLACE ALL OCCURRENCES OF '.' IN lv_c_fkwrt WITH ''.
  TRANSLATE lv_c_fkwrt USING ',.'.
ELSEIF lv_dcpfm EQ 'Y'.
  TRANSLATE lv_c_fkwrt USING ',.'.
ENDIF.

lv_fkwrt = lv_c_fkwrt.

*CALL FUNCTION 'BAPI_CURRENCY_CONV_TO_INTERNAL'
*  EXPORTING
*    currency                   = lv_waerk
*    amount_external            = lv_bapi_fkwrt
*    max_number_of_digits       = 18
* IMPORTING
*    amount_internal            = lv_fkwrt
**   RETURN                     =
*          .

CALL FUNCTION 'SPELL_AMOUNT'
  EXPORTING
    amount    = lv_fkwrt
    currency  = lv_waerk
    filler    = ' '
    language  = lv_spras
  IMPORTING
    in_words  = lwa_words
  EXCEPTIONS
    not_found = 1
    too_large = 2
    OTHERS    = 3.

IF sy-subrc = 0.

  IF lwa_words-decword = c_zero OR lwa_words-decword IS INITIAL.
    lv_spelled_amount = lwa_words-word.
  ELSE.
    CONCATENATE lwa_words-word lwa_words-decword
           INTO lv_spelled_amount
           SEPARATED BY ' . '.
  ENDIF.

ELSE.
  lv_spelled_amount =  space.
ENDIF.


WRITE: lv_spelled_amount.

andreas_mann3
Active Contributor
0 Kudos
1,352

Hi

try that fm:

Andreas

RichHeilman
Developer Advocate
Developer Advocate
0 Kudos
1,352

How about this?



report zrich_0003 .


data: i type i.

data: c(10) type c.
data: p(10) type p decimals 2.

c = '3.520,00'.

catch system-exceptions convt_no_number = 1.
  p = c.
endcatch.

if sy-subrc  = 1.
  clear sy-subrc.
  while sy-subrc = 0.
    replace ',' with space into c.
  endwhile.
  clear sy-subrc.
  while sy-subrc = 0.
    replace '.' with space into c.
  endwhile.
  condense c no-gaps.
endif.

p = c / 100.

write:/ p.

Regards,

Rich Heilman

0 Kudos
1,352

Thanks Rich.

My problem that this approach doesn't work if the user defaults are different (e.g.: , and . are the other way around).

Probable it wouldn't work for all currency either.

Is there any SAP Function module for this?

Something like 'CONVERT_DATE_TO_INTERNAL' for dates?

Thanks,

Peter

0 Kudos
1,352

you have to move

p = c / 100.

to place within ENDIF.

Otherwise, it should issue wrong value when input < 1000 because it cause no problem ( sy-subrc = 0 ,not 1).