BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Haikuo
Onyx | Level 15

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

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

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.

View solution in original post

6 REPLIES 6
Astounding
PROC Star

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
Onyx | Level 15

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?

Astounding
PROC Star

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.

FriedEgg
SAS Employee

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

Ksharp
Super User

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

Haikuo
Onyx | Level 15

Good call, Ksharp!

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 7196 views
  • 2 likes
  • 4 in conversation