SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
massi
Calcite | Level 5

Here is a sample macro

%macro pippo();

  %let separator_s =%str( );

  %let separator_c =%str(,);

  %let a=ciao;

  %let aa=%str(a=b);

  %let a= %sysfunc(catx(&separator_s,&a,&aa));

  %put &a;

%mend pippo;

%pippo;

I would like the macro variable "a" to be "ciao a=b"

However I get "ciao 0".

Any suggestion on why it is so?

Thank you very much

1 ACCEPTED SOLUTION

Accepted Solutions
data_null__
Jade | Level 19

You can do it but it takes strong quoting.  Double quoting if you will. :smileyplain: Note also that you should quote the first argument in CATX too, but I did not.

18         %macro pippo();
19        
20           %let separator_s =%str( );
21        
22           %let separator_c =%str(,);
23        
24           %let a=ciao = ciao;
25           %let b=ciao;
26           %let aa=a=b;
27        
28           %let a= %sysfunc(catx(&separator_s,%nrstr(%superq(a)),%nrstr(%superq(aa))));
29        
30           %put &a;
31        
32         %mend pippo;
33        
34         %pippo;
ciao = ciao a=b

View solution in original post

8 REPLIES 8
Tom
Super User Tom
Super User

You do not need any function or operator to connect strings in macro language.

%let separator_s =%str( );

%let separator_c =%str(,);

%let a=ciao;

%let aa=a=b;

%let a=&a&separator_s&aa;

%put &a;

The only thing you need is know that you can use a period to mark the send of your macro variable so that SAS does not get confused and try to use trailing text that as part of the macro variable name.  So you could assign the value of A this way and get the same result.

%let a=&a.&separator_s.&aa.;

Tom
Super User Tom
Super User

SAS is passing the function arguments through an implicit %sysevalf() before handing it off the CATX() function. %eval( a=b ) is 0 (false) because a does not equal b.  Hence CATX() sees only the text string 0 and so that is what it appends.

massi
Calcite | Level 5

Thank you very much Tom.

I was kind of thinking that but I was not sure.

But is there a way to avoid the pass through %sysevalf() and still use the catx function?

Why is there in the first place?

Tom
Super User Tom
Super User

Not that I know of.  It is useful when the function argument really is a number since you can use arithmetic in the call (&i + 1) without having either add a %EVAL() or create another macro variable.

You can build you own macro version of CATX.

%macro catx(sep) / parmbuff ;

%local string i result;

%let string=%qscan(&syspbuff,1,(),q);

%let i=%eval(2-(%bquote(&sep)=,));

%let result=%qscan(&string,&i,%str(,),q);

%do i=&i+1 %to %sysfunc(countw(&string,%str(,),q));

  %let result=&result.&sep.%scan(&string,&i,%str(,),q);

%end;

%unquote(&result)

%mend catx;

%let separator_s =%str( );

%let separator_c =%str(,);

%let a=ciao;

%let aa=%str(a=b);

%put space="%catx(&separator_s,&a,&aa)";

space="ciao a=b"

%put comma="%catx(&separator_c,&a,&aa)";

comma="ciao,a=b"

Message was edited by: Tom Abernathy

Added data_null_'s suggestion of using %nrstr().

%put sysfunc="%sysfunc(catx(&separator_s,%nrstr(&a),%nrstr(&aa)))";

sysfunc="ciao a=b"

data_null__
Jade | Level 19

You can do it but it takes strong quoting.  Double quoting if you will. :smileyplain: Note also that you should quote the first argument in CATX too, but I did not.

18         %macro pippo();
19        
20           %let separator_s =%str( );
21        
22           %let separator_c =%str(,);
23        
24           %let a=ciao = ciao;
25           %let b=ciao;
26           %let aa=a=b;
27        
28           %let a= %sysfunc(catx(&separator_s,%nrstr(%superq(a)),%nrstr(%superq(aa))));
29        
30           %put &a;
31        
32         %mend pippo;
33        
34         %pippo;
ciao = ciao a=b
yaswanthj
Fluorite | Level 6

try this..

%macro pippo();

  %let separator_s =%str( );

  %let separator_c =%str(,);

  %let a=ciao;

  %let aa=%str(a=b);

  %let a= %sysfunc(catx(&separator_s,&a,%nrstr(&aa)));

  %put &a;

%mend pippo;

%pippo;

massi
Calcite | Level 5

Both data_null and yaswanthj answers work.

Thank you very much.

This little problem bugged me for a couple of weeks.

leocrimson
Calcite | Level 5

Good for few other scenarios:

 

%let m_var;

 

data _null_;
set dataset;
call symput('m_var',catx(' ',symget('m_var'),variable _append));
run;

 

%put &m_var;

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

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
  • 8 replies
  • 121161 views
  • 8 likes
  • 5 in conversation