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!
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.