The original discussion was on SAS-L. The OP wanted to replace blanks with ',' in his macro variable strings.
eg. Have: %let a=a b c d; Want a=a,b,c,d.
So I came up with the following Macro:
%macro com (a=);
%let a1=;
%do i=1 %to %sysfunc(countw(&a));
%let a1=%sysfunc(catx(%str(,),&a1,%scan(&a,&i)));
%end;
%let a=&a1;
%put &a;
%mend;
%com (a=a b c d)
It works for the purpose, but it generate an error message as:
ERROR: %SYSEVALF function has no expression to evaluate.
Please help me to figure it out why.
Thanks in advance,
Haikuo
Haikuo,
OK, first I have to comment and then I'll make a guess as to the cause.
This is a very dangerous macro to use. It is missing this key statement:
%local a1 i;
If I were to call this macro, it would change the value of existing macro variables named &A1 or &I. Those macro variables might exist in the %GLOBAL symbol table, or they might exist in the %LOCAL symbol table for a macro that calls this macro. But that is what makes this macro dangerous to use.
My guess as to where the error comes from is the first pass through the %DO loop, when &A1 is null. To test this (I can't, I'm home today), try these changes.
What's there now:
%let a1=;
%do i=1 %to ...;
Try this instead:
%let a1=%scan(&a,1);
%do i=2 %to ...;
See if the error disappears.
Haikuo,
OK, first I have to comment and then I'll make a guess as to the cause.
This is a very dangerous macro to use. It is missing this key statement:
%local a1 i;
If I were to call this macro, it would change the value of existing macro variables named &A1 or &I. Those macro variables might exist in the %GLOBAL symbol table, or they might exist in the %LOCAL symbol table for a macro that calls this macro. But that is what makes this macro dangerous to use.
My guess as to where the error comes from is the first pass through the %DO loop, when &A1 is null. To test this (I can't, I'm home today), try these changes.
What's there now:
%let a1=;
%do i=1 %to ...;
Try this instead:
%let a1=%scan(&a,1);
%do i=2 %to ...;
See if the error disappears.
Thanks, Astounding. Comments well received. So What it means is that %sysfunc has problem with macro variable of null value, but still process it reluctanly?
My guess:
%sysfunc in combination with catx is calling %sysevalf in a way that we cannot see.
It's a sort of a black box. We can see what goes in and what comes out, but can only guess at the internal workings.
15 %let a=1 2 3 4;
16 %put original -> &a;
original -> 1 2 3 4
17
18 %let a=%sysfunc(prxchange(%quote(s/\s+/,/),-1,&a));
19 %put prxchange -> &a;
prxchange -> 1,2,3,4
20
21 %let a=%sysfunc(translate(%quote(&a),'2c'x,'20'x));
22 %put translate -> &a;
translate -> 1,2,3,4
Actually. you don't need function catx();
%macro com (a=);
%let a1=%scan(&a,1);
%do i=2 %to %sysfunc(countw(&a));
%let a1=&a1.,%scan(&a,&i);
%end;
%let a=&a1;
%put &a;
%mend;
%com (a=a b c d)
Ksharp
Good call, Ksharp!
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.