FUNCTION IsNumeric RETURNS LOGICAL (picString AS CHARACTER, picType AS CHARACTER):
    DEFINE VARIABLE iNumericLoop       AS INTEGER    NO-UNDO.
    DEFINE VARIABLE iNumericCheckLoop  AS INTEGER    NO-UNDO.
    DEFINE VARIABLE cNumericCheck      AS CHARACTER  NO-UNDO.
    DEFINE VARIABLE lIsNumeric         AS LOGICAL    NO-UNDO.
    DEFINE VARIABLE lMisMatchFound     AS LOGICAL    NO-UNDO.
    DEFINE VARIABLE cDecimalIndicator  AS CHARACTER  NO-UNDO.
    DEFINE VARIABLE cPlaceIndicator    AS CHARACTER  NO-UNDO.
    DEFINE VARIABLE cTempString        AS CHARACTER  NO-UNDO.
    
    ASSIGN lIsNumeric = YES
           picString = TRIM (picString).
    IF SESSION:NUMERIC-FORMAT = "american" THEN ASSIGN
        cDecimalIndicator = "."
        cPlaceIndicator   = ",".
    ELSE ASSIGN
        cDecimalIndicator = ","
        cPlaceIndicator   = ".".
    CASE picType:
        WHEN "OnlyNumbers" THEN ASSIGN cNumericCheck = "0123456789".
        WHEN "Formatted"   THEN ASSIGN cNumericCheck = "0123456789,-.".
    END CASE.
    
    ASSIGN lMisMatchFound = YES.
    /* Check that there are no extra characters */
    DO iNumericLoop = 1 TO LENGTH (picString):
        DO iNumericCheckLoop = 1 TO LENGTH (cNumericCheck):
            IF SUBSTRING (picString,iNumericLoop,1) = SUBSTRING (cNumericCheck,iNumericCheckLoop,1) THEN ASSIGN lMisMatchFound = NO.
        END.
        IF lMisMatchFound THEN ASSIGN lIsNumeric = NO.
    END.
    
    IF picType = "Formatted" THEN DO:
        IF INDEX (picString,"-") > 0 AND
           INDEX (picString,"-") > 1 AND 
           INDEX (picstring,"-") < LENGTH (picstring) THEN ASSIGN lMisMatchFound = YES.
        IF INDEX (picString,"-") <> R-INDEX (picString,"-") THEN ASSIGN lMisMatchFound = YES.
        
        IF NUM-ENTRIES (picstring,"-") > 2 THEN ASSIGN lMisMatchFound = YES.
        IF NUM-ENTRIES (picstring,cDecimalIndicator) > 2 THEN ASSIGN lMisMatchFound = YES.
        IF R-INDEX (picString,cPlaceIndicator) > R-INDEX (picString,cDecimalIndicator) THEN ASSIGN lMisMatchFound = YES.
        ASSIGN cTempString = REPLACE (ENTRY (1,picString,cDecimalIndicator),"-","").
        
        IF NUM-ENTRIES (cTempString,cPlaceIndicator) > 1 THEN
        DO iNumericLoop = 1 TO NUM-ENTRIES (cTempString,cPlaceIndicator):
            IF LENGTH (ENTRY (inumericloop,cTempString,cPlaceIndicator)) = 0 OR 
               LENGTH (ENTRY (inumericloop,cTempString,cPlaceIndicator)) > 3 THEN ASSIGN lMisMatchFound = YES.
        END.
    END.
    IF lMisMatchFound THEN ASSIGN lIsNumeric = NO.
    RETURN lIsNumeric.
END FUNCTION.
FUNCTION IsLikeMask RETURNS LOGICAL (picString AS CHARACTER, picMask AS CHARACTER):
    DEFINE VARIABLE iMaskLoop  AS INTEGER    NO-UNDO.
    DEFINE VARIABLE lMaskMatch AS LOGICAL    NO-UNDO.
    ASSIGN lMaskMatch = YES.
    /*If the lengths are different then it doesn't exactly match the mask */
    IF LENGTH (picString) <> LENGTH (picMask) THEN RETURN FALSE.
    ELSE DO:
        DO iMaskLoop = 1 TO LENGTH (picString):
            /* If the place matches exactly then it's fine */
            IF SUBSTRING (picString,iMaskLoop,1) = SUBSTRING (picMask,iMaskLoop,1) THEN NEXT.
            IF REPLACE (SUBSTRING (picString,iMaskLoop,1),SUBSTRING (picString,iMaskLoop,1),"X") = SUBSTRING (picMask,iMaskLoop,1) THEN NEXT.
            ASSIGN lMaskMatch = NO.
            LEAVE.
        END.
        RETURN lMaskMatch.
    END.
END FUNCTION.
 
DISPLAY 
    IsLikeMask ("(012) 123-4567","(xxx) xxx-xxxx")
    IsLikeMask ("(012) 123-456","(xxx) xxx-xxxx")
    IsLikeMask ("(012) 123-456 ","(xxx) xxx-xxxx")
    IsLikeMask ("(012 )123-4567","(xxx) xxx-xxxx")
    IsLikeMask ("(012) 1234567","(xxx) xxx-xxxx")
    IsLikeMask ("(012) --------","(xxx) xxx-xxxx").
RUN ipCheckNumeric ("12345","OnlyNumbers").
RUN ipCheckNumeric (" 12345","OnlyNumbers").
RUN ipCheckNumeric ("-12345","Formatted").
RUN ipCheckNumeric ("-12345-","Formatted").
RUN ipCheckNumeric ("-12345.","Formatted").
RUN ipCheckNumeric ("-12345.,","Formatted").
RUN ipCheckNumeric ("-12345.23,3","Formatted").
RUN ipCheckNumeric ("-12345.6789","Formatted").
RUN ipCheckNumeric ("-12,,345.6789","Formatted").
RUN ipCheckNumeric ("-12,345.6789","Formatted").
RUN ipCheckNumeric ("12,345.6789-","Formatted").
 
PROCEDURE ipCheckNumeric:
    DEFINE INPUT  PARAMETER picString AS CHARACTER  NO-UNDO.
    DEFINE INPUT  PARAMETER picType   AS CHARACTER  NO-UNDO.
    MESSAGE picString isNumeric(picString,picType) VIEW-AS ALERT-BOX.
END PROCEDURE.