Donna
Donna

Reputation: 149

How to test if string is numeric using Progress 4GL

Does Progress 4GL have a function for testing whether a string is numeric, like PHP's is_numeric($foo) function?

I've seen the function example at http://knowledgebase.progress.com/articles/Article/P148549 to test if a character in a string is numeric. Looks like it has a typo, btw.

But I would think the language would be a built-in function for this.

Upvotes: 5

Views: 14720

Answers (5)

David Moses Letlape
David Moses Letlape

Reputation: 11

Works 100% of the time

FUNCTION is-num RETURNS LOGICAL
    (INPUT cString AS CHARACTER):
    DEFINE VARIABLE iZeroCode    AS INTEGER   NO-UNDO.
    DEFINE VARIABLE iNineCode    AS INTEGER   NO-UNDO.
    DEFINE VARIABLE cChar        AS CHARACTER NO-UNDO.
    DEFINE VARIABLE iCount       AS INTEGER   NO-UNDO.

    DO iCount = 1 TO LENGTH(cString):
        ASSIGN iZeroCode = ASC("0")
               iNineCode = ASC("9")
               cChar     = SUBSTRING(cString,iCount,1).                           

        IF NOT(ASC(cChar) >= iZeroCode AND ASC(cChar) <= iNineCode)    THEN DO:
            RETURN FALSE.
        END.
    END.
    RETURN TRUE.
END.

Upvotes: 1

ns2016
ns2016

Reputation: 63

I was looking at this myself recently. The approved answer given to this doesn't work in 100% situations.

If the user enters any of the following special string characters: ? * - or + the answer won't work.
A single plus or minus(dash) is converted to 0 which you may not want.
A single question mark character is valid value which progress recognises as unknown value at which again you may not want.
A single or group asterisks on their own also get converted to 0.
If you run the following code you'll see what I mean.

DISP DECIMAL("*")
     DECIMAL("**")
     DECIMAL("?")
     DECIMAL("+")
     DECIMAL("-").

The following additional code maybe useful to get around this

DEFINE VARIABLE iZeroCode    AS INTEGER   NO-UNDO.
DEFINE VARIABLE iNineCode    AS INTEGER   NO-UNDO.
DEFINE VARIABLE chChar       AS CHARACTER NO-UNDO.

ASSIGN iZeroCode = ASC("0")
       iNineCode = ASC("9")
       chChar    = SUBSTRING(cNumber,1,1).                           

IF NOT(ASC(chChar) >= iZeroCode AND ASC(chChar) <= iNineCode)    THEN DO:
    MESSAGE "Invalid Number..." VIEW-AS ALERT-BOX.
END.

Upvotes: 5

W0lfw00ds
W0lfw00ds

Reputation: 2096

This code handles any numeric strings - even if the used Character is longer than the max Decimal length etc.

FUNCTION isNumeric RETURNS LOGICAL (textvalue AS CHAR):
    DEF VAR i AS INT NO-UNDO.

    IF textvalue = ? THEN RETURN TRUE.

    DO i = 1 TO (LENGTH(textvalue) - 1):
        INT(SUBSTRING(textvalue, i, (i + 1))) NO-ERROR.
        IF ERROR-STATUS:ERROR THEN RETURN FALSE.
    END.

    RETURN TRUE.
END FUNCTION.

Upvotes: 2

AquaAlex
AquaAlex

Reputation: 380

Do not need a function can jsut do a straight conversion.

ASSIGN dNumber = DECIMAL(cNumber) NO-ERROR. 
IF ERROR-STATUS:ERROR THEN
DO:
    {Handle issues}        
END.

or if it is always whole numbers can use INTEGER instead of DECIMAL.

Upvotes: 6

Tom Bascom
Tom Bascom

Reputation: 14020

The language does not have a built-in "isNum()" type of function.

An alternative to the kbase method would be:

function isNum returns logical ( input s as character ):
  define variable n as decimal no-undo.
  assign
    n = decimal( s )
    no-error
  .
  return ( error-status:num-messages = 0 ).
end.

display isNum( "123" ) isNum( "xyz" ).

Upvotes: 4

Related Questions