Converting Characters to Numbers in an FCMP Function
When using PROC FCMP to build a function that converts characters to numbers, you may find that in order to maximize your function's flexibility that you need to take precautions. Generally a function created with FCMP can be used directly in a DATA or SQL step, and indirectly in the macro language through the use of the %SYSFUNC macro function. However when the FCMP function includes the use of the INPUT or PUT functions, your FCMP function may fail when used with %SYSFUNC.
In the simplified example shown here, which is taken from a LinkedIn Discussion, the user wants to pass in a character string which is to be parsed (using SUBSTR) and then converted to a number using the INPUT function.
In this example the function VALID_NIP takes the first character of a character argument, multiplies it by 6, and returns the result.
PROC FCMP OUTLIB=work.functions.validation; function valid_nip(var1 $); sum = inputn(substr(var1,1,1),1.)*6 ; return(sum); endsub; RUN; options cmplib=work.functions; PROC SQL; CREATE TABLE WORK.PP_K AS SELECT age, valid_nip('8') as valid_nip FROM sashelp.class(where=(name='Alfred')); QUIT; proc print data=pp_k; run; %MACRO valid_nip(var1); %SYSFUNC(valid_nip(&var1)) %MEND; %put %valid_nip(888888888);
Notice that the FCMP function uses the INPUTN function rather than the INPUT function. This is the execution time version of this function. Because of the timing of events, the execution version of PUT (PUTN/PUTC) and INPUT (INPUTN/INPUTC) are often needed when working with compiled programs like macros and functions. In this case INPUT would work if the function was called directly in SQL as is done here in the first example, however when used through %SYSFUNC the execution time version is needed. Maximize your flexibility and always utilize the execution time versions of PUT and INPUT in FCMP.