= SAS Macro Functions = <> ---- == Defining Functions == A macro function resolves to a value. To be as flexible as a macro function, certain restrictions must be adhered to. Chiefly a data step or process cannot be invoked. {{{ %macro exist(dsname); %sysfunc(exist(&dsname)) %mend exist; }}} === Using SAS Functions === To use a SAS function inside a macro, the `%sysfunc` macro function must be used. `%sysfunc` cannot take nested SAS functions, but can take nested macro functions. {{{ %let mon_title = %sysfunc(left(%qsysfunc(mdy(&mon,1,&curr_yr), monname9.))); }}} Remember the availability of the quoted `%qsysfunc`. In this context, the most contentious special character is the comma, which can be confused for an argument delimiter. This results in an error: {{{ %let date=%sysfunc(left(%sysfunc(today(),worddate.))); /* ^ June 7, 2002 ^ left(June 7, 2002) ^ Error: `left` takes only one argument */ }}} This will not: {{{ %let date=%sysfunc(left(%qsysfunc(today(),worddate.))); }}} ---- == Using Functions in the Data Step == A macro function can be called within a data step using `resolve()`. `resolve` actually can be used to get the value of any type of macro, including a macro variable. `resolve()` can be called in three ways: {{{ method1 = resolve("&mymacro"); method2call = '&mymacro'; method2 = resolve(method2call); method3 = resolve(cats('&','my','macro')); }}} ---- == Built-in Functions == Given: {{{ %let a=Foo; %let b=%nrstr(&a bar); %let c=%nrstr(&a); }}} The following functions can be used as: ||'''Name''' ||'''Action''' ||'''Example Input''' ||'''Example Result''' || ||`%sysfunc(function call)` ||Evaluates a function call || || || ||`%qsysfunc(function call)` ||Same, but masks value || || || ||`%substr(value,position,length)` ||Copies a substring from a value by literal position ||`%substr(&c,1,2)` ||'Foo' || ||`%qsubstr(value,position,length)` ||Same, but masks value ||`%qsubstr(&c,1,2)` ||'&a' || ||`%scan(value,index,delimiter)` ||Copies a substring from a value by parsed position ||`%scan(&c,1,' ')` ||'Foo' || ||`%qscan(value,index,delimiter)` ||Same, but masks value ||`%qscan(&c,1,' ')` ||'&a' || ||`%upcase(value)` ||Translates lowercase into uppercase ||`%upcase(&c)` ||'Foo' || ||`%qupcase(value)` ||Same, but masks value ||`%qupcase(&c)` ||'&A' || ||`%lowcase(value)` position ||Translates uppercase into lowercase ||`%lowcase(&c)` ||'Foo' || ||`%qlowcase(value)` ||Same, but masks value ||`%qlowcase(&c)` ||'&a' || ||`%cmpres(value)` ||Strips leading/trailing and multiple whitespace || || || ||`%qcmpres(value)` ||Same, but masks value || || || ||`%left(value)` ||Strips leading whitespace || || || ||`%qleft(value)` ||Same, but masks value || || || ||`%eval(expression)` ||Evaluates expression using integer arithmetic ||`%eval(10/3)` ||'3' || ||`%sysevalf(expression)` ||Evaluates expression using floating point arithmetic ||`%sysevalf(10/3)` ||'3.333333' || ---- CategoryRicottone