2

I'm looking for a Visual FoxPro function which is similar to the PHP function is_numeric().
I have found this, but I could not use VARTYPE or TYPE because the variable is always a character string which contains digits only.

I found ISDIGIT() function, but the manual says that it only checks the first character.

Determines whether the leftmost character of the specified character expression is a digit (0 through 9).

  ISDIGIT(cExpression)

Parameters
cExpression

Specifies the character expression that ISDIGIT( ) tests. Any characters after the first character in cExpression are ignored.

I would create my own function using the regular expression object VBScript.RegExp

FUNCTION isNumeric( tcValue )
    LOCAL oRE
    oRE = CreateObject("VBScript.RegExp")
    oRE.Pattern = '^[0-9]+$'
    RETURN oRE.test( tcValue )      
ENDFUNC

? isNumeric( '123' )

But, is there any function provided by FoxPro for this purpose?
Am I just overlooking?

Also same for ISALHPA() which determines whether the leftmost character in a character expression is alphabetic. I want to check if the variable contain only alphabets.

Community
  • 1
  • 1
Sithu
  • 4,752
  • 9
  • 64
  • 110
  • No, there is no language function that does this. A function like Frank has posted below is the only way. – Alan B Dec 14 '12 at 13:43

6 Answers6

5

You can create your own function like this.

FUNCTION IsAllDigits
    LPARAMETERS tcSearched, tcOptionalSearch

    * tcSearched = the string of characters to test.
    * tcOptionalSearch = optional, additional characters to allow.

    LOCAL lcSearch
    m.lcSearch = "01234567989" + IIF(VARTYPE(m.tcOptionalSearch) = "C", m.tcOptionalSearch, "")

    LOCAL lcRemaining
    m.lcRemaining = CHRTRAN(m.tcSearched, m.lcSearch, "")

    RETURN ( LEN(m.lcRemaining) = 0 )
ENDFUNC
Frank Perez
  • 993
  • 8
  • 18
  • Thanks Frank! Yours is tricky. But can we check the decimal points? For example, "12.34" is numeric, but "12.34.56 is not numeric. – Sithu Dec 21 '12 at 09:21
  • Just add "." to the list of permitted characters and add a test that checks that OCCURS('.', m.tcSearched) <= 1. – Tamar E. Granor Mar 01 '13 at 21:30
2

This could work for ISDIGIT() or ISALPHA().

Function IsAllDigits(myValue)
   lReturn = .t. 
   FOR i = 1 TO LEN(myvalue)
      IF !ISDIGIT( SUBSTR(myValue, i, 1)  )
         lReturn = .f.
         EXIT
      ENDIF
   ENDFOR
   RETURN lReturn
ENDFUNC
Jerry
  • 6,357
  • 8
  • 35
  • 50
1
FUNCTION ISNUMERIC
    LPARAMETERS cVal
    LOCAL llNumeric, lnLen, lcChr, lnDecs, lnVal

    llNumeric = VARTYPE(cVal) = "N"      && Donkey has sent a numeric value
    lnDecs = 0

    DO CASE
        CASE llNumeric
        CASE VARTYPE(cVal)<>"C"          && Not a character
        OTHERWISE
            cVal = ALLTRIM(cVal)         && Trim spaces
            lnLen = LEN(cVal)            && How many characters
            llNumeric = .T.              && Assume
            i = 0
            DO WHILE llNumeric AND i<lnLen
                i = i+1
                lcChr = SUBSTR(cVal,i,1)        && Get next char
                    lnVal = VAL(lcChr)
                DO CASE
                CASE lcChr = "0"                && Allowed
                CASE lnVal>0                    && 1 - 9 OK
                CASE INLIST(lcChr, "-", "+")    && Allowed but ONLY at the start
                    llNumeric = i = 1
                CASE lcChr = "."                && Decimal point but ONLY one
                    lnDecs = lnDecs+1
                    llNumeric = lnDecs = 1
                OTHERWISE
                    llNumeric = .F.
            ENDCASE
        ENDDO
    ENDCASE
    RETURN llNumeric
ENDFUNC
Sithu
  • 4,752
  • 9
  • 64
  • 110
Hugh CB
  • 31
  • 2
  • Perfect! upvoted! Yours can even check decimal points and negative values. But I don't much like the while loop because it may be called during a long process or even in the nested loops. – Sithu Dec 21 '12 at 09:27
  • I think we can use `ATC()`, `OCCURS()` to check each character instead of the loop, for example, "-" and "+" must be at the first position. We can use `ATC()` for this case. And the string cannot contain two dots ".". We can use `OCCURS()` for this case. – Sithu Dec 21 '12 at 09:34
1

How about a one liner?

Function IsNumeric
Lparameters pString
Return  m.pString == Chrtran(m.pString, Chrtran(m.pString, "0123456789", ""), "")
EndFunc

You can any other valid characters to "0123456789" like "." or ","

Carlos Alloatti
  • 193
  • 2
  • 9
1

There is more simple to test if a string is numeric or not :

  • If String="123" => val('String')>0
  • If String="AB123" => val('String')=0

That's all...

patrick
  • 19
  • 1
0

Using only Visual Fox Pro, you can do something like this:

FUNCTION is_numeric(var_name)
    error_trigger=.f. &&** first initialization 
    &&** evaluate("any_char") will generate an error so I'm using TRY-CATCH-ENDTRY  
    TRY  
      EVALUATE(var_name)
    CATCH &&** evaluate() generates an error then the string is character
      WAIT WINDOW "character"   
      error_trigger=.t. &&** there was an error returned by evaluate()
      EXIT  && stop and jump after ENDTRY
    ENDTRY 
    IF error_trigger=.f. &&** there was no error returned by evaluate() then the string was numeric
       WAIT WINDOW "numeric"
    ENDIF 
ENDFUNC 

Then call to the function:
is_numeric("333") will show: numeric
is_numeric("aaa") will show: character
is_numeric("333a333") will show: character
I hope it will help you

gavroche
  • 249
  • 3
  • 12