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: 

Avoid convt_no_number

franzs
Participant
0 Kudos

Hello,

I want to avoid a short dump of type convt_no_number.

I've found that solution:


  DATA: gv_to_convert TYPE string VALUE 'abc',

        gv_int        TYPE p LENGTH 6 DECIMALS 3.

  TRY.

      gv_int = gv_to_convert.

    CATCH cx_sy_conversion_no_number.

      WRITE 'not a number'.

  ENDTRY.

Is there another cleaner solution? I'm searching e. g. a method like is_numeric().

Of course I can encapsulate the coding above in a own method ...

But is there any SAP method or function module for that check?

I searched in cl_abap* classes, but I didn't found anything.

Regards

Franz

21 REPLIES 21

alisson_fragozo
Explorer
0 Kudos

Hi Franz,

Use the CO operator, ex:

IF variable CO '0123456789'.

   WRITE: 'Is a number!'.

ENDIF.

0 Kudos

Well, that won't work with 123.45

Rob

0 Kudos

DATA: variable TYPE string VALUE '123.45'.

DATA: length TYPE i,

             last      TYPE i.

last = length = STRLEN( variable ).

SUBTRACT 1 FROM last.

IF variable(length) CO '1234567890.'

    AND variable+last(1) NE '.'

    AND variable(1) NE '.'.

   WRITE:/ 'Is a number'.

ENDIF.

0 Kudos

Well, I think the OP is asking for a cleaner solution.

And I don't think it works for "1234.567.89"

Rob

Message was edited by: Rob Burbank

0 Kudos

Decimal, Thousands Separators and minus sign (leading/trailing)  can also be language/country dependant. So I suppose the OP hopes for a standard method/function module that manage that as well as overflow.

But, I only find some method that use the TRY/MOVE/CATCH/ENDTRY syntax themselevs as IN CL_DBA_FORMAT=>IS_NUMERIC or similar methods...

data:
     num    type p.
   try.
     num = value.
     numeric = abap_true.
    catch cx_sy_conversion_no_number.
     numeric = abap_false.
    catch cx_sy_conversion_overflow.
     numeric = abap_false.
   endtry.

So in original code, replaced with

DATA: gv_to_convert TYPE string VALUE 'abc.
IF cl_dba_format=>is_numeric( value = gv_to_convert ) EQ abap_false.
   WRITE 'not a number'.
ENDIF.

Regards,

Raymond

0 Kudos

Even this doesn't work with 12,345.67


data: lo_check type ref to CL_DBA_FORMAT.

create OBJECT lo_check.

if lo_check->is_numeric( '12,345.67' ) = 'X'.

write: 'Good'.

else.

   write: 'not a number'.

ENDIF.

I think the logic needs to remove commas, dots, signs; if it raises  cx_sy_conversion_no_number and try again.

Regards,
Naimesh Patel

0 Kudos

Hi,

I think Raymond suggestion is the best. The class CL_DBA_FORMAT=>IS_NUMERIC will work as required. Just remember to write the input number to system format before calling the method.

Example: 12,345.67, or 12.234,67, etc.. To 12345.67

Regards,

Thales Schmidt

0 Kudos

Hi Raymond,

yes, you're right - I'm searching a standard method.

The solution with "IF ... CO .." seems not to solve the problem. There're to much country dependant possibilities ...

0 Kudos

Hi Thales Schmidt,

but how can I convert the input number into the correct format?

The input is entered by the user ...

Regards

Franz

0 Kudos

How about this type of implementation? I gave one more try when conversion error occurs after removing the dots, commas, and sign.


*

CLASS lcl_format DEFINITION.

   PUBLIC SECTION.

     CLASS-METHODS:

       is_numeric

         IMPORTING value TYPE any

         RETURNING value(numeric) TYPE flag.

ENDCLASS.                    "lcl_format DEFINITION

START-OF-SELECTION.

   IF lcl_format=>is_numeric( '23,123.45-' ) = 'X'.

     WRITE: 'number'.

   ELSE.

     WRITE: 'no'.

   ENDIF.

*

CLASS lcl_format IMPLEMENTATION.

   METHOD is_numeric.

     DATA:

       num    TYPE p DECIMALS 5,

       c_num  TYPE string.

     TRY.

         num = value.

         numeric = abap_true.

       CATCH cx_sy_conversion_no_number.

         "one more try

         c_num = value.

         REPLACE '-' WITH '' INTO c_num.

         REPLACE ALL OCCURRENCES OF '.' IN c_num WITH ''.

         REPLACE ALL OCCURRENCES OF ',' IN c_num WITH ''.

         numeric = lcl_format=>is_numeric( c_num ).

         "fail safe to avoid loops

         if numeric is INITIAL.

           exit.

         endif.

       CATCH cx_sy_conversion_overflow.

         numeric = abap_false.

     ENDTRY.

   ENDMETHOD.                    "is_numeric

ENDCLASS.                    "lcl_format IMPLEMENTAT

Regards,
Naimesh Patel

0 Kudos

Hi,

It depends on your location, and how users will enter the information.

For example, here in Brazil, users use comma to separate decimals and point to separate the thousands.

123.345,67

TRANSLATE number USING '. ,.'.

CONDENSE number NO-GAPS.

The above command would do the job.

If the input field is CHAR, you can also use the FM SCP_REPLACE_STRANGE_CHARS to replace strange characters. Or write a logic using the abap instruction REPLACE (using sy-abcde for example) to avoid letters.

But I think this solution is not what you are looking for, since you want a cleaner solution.

Regards,

Thales Schmidt

0 Kudos

Thanks Naimesh Patel.

But this doesn't seems to be cleaner to me ...

0 Kudos

Hi Thales Schmidt,

thank you for your idea.

But I think the cleanest solution is up to now to use the try/catch-logic.

Maybe an exception is not as evil as I think.

Regards

Franz

0 Kudos

Just a tiny bit cleaner (in case you are in 740 SP5 or above):

  1. DATA: gv_to_convert TYPE string VALUE 'abc. 
  2. IF NOT cl_dba_format=>is_numeric( gv_to_convert ). 
  3.    WRITE 'not a number'
  4. ENDIF.



Cheers,

Custodio

0 Kudos

Exceptions aren't evil in this case at all. It's the simplest, cleanest solution.

btw - to convert '123,456.789' to a number, use WRITE - left-justified no-grouping. That way you're not concerned with the users decimal/grouping setting.

0 Kudos

Hi Custodio,

thanks, but as you can read above - it doesn't work in my case.

Regards


Franz

0 Kudos

Hi Matthew Billingham,

I think you're right - I'll use exceptions ...

Regards

Franz

0 Kudos

Hi Franz,

You can use the function module 'CATS_NUMERIC_INPUT_CHECK'

Regards,

Yücel Vangölü

0 Kudos

Hi Yücel Vangölü,

thank you for your hint.

But it doesn't work for '123,456.78'.

Regards

Franz

buddhika_krishantha
Active Participant
0 Kudos

Use FM "NUMERIC_CHECK".

0 Kudos

Hi Buddhika Krishantha,

tanks, but seems to work only for integer values.

Regards

Franz