Hi
Is it possible to specify multiple values for one macro parameter, for example :
%macro Links (ClientId=);
code
code
%mend Links;
%Links (ClientId=1,2,3,4);
So yes:
%macro Links (ClientId=);
code;
%mend Links;
data have;
do client=1 to 4;
output;
end;
run;
data _null_;
set have;
call execute('%Links (ClientId='||strip(put(client,best.))||');');
run;
Sure, you can, but I would not use a comma as a separating character:
%Macro Links(ClientID=);
/* maybe work on a list .. */
%Let i=1;
%Let ID=%Scan(&ClientID.,1,' ');
%Do %While (&ID^=);
%Put **&ID.**;
%Let i=%Eval(&ID.+1);
%Let ID=%Scan(&ClientID.,&i.,' ');
%End;
%Mend;
%Links(ClientID=1 2 3 4);
Hmmm, I think I could be missing something here. I am trying to get the macro to iterate once for every value of ClientId, but I am not sure that this is what it was intended for.
Hi,
So what is it your trying to achieve? You can pass a delimited list of data in as User24feb has mentioned. There is also another syntax for parmbuff which you can pass any number of parameters in. You could also generate the code which is my preference.
data have;
client="ABC"; output;
client="BBD"; output;
run;
data _null_;
set have;
call execute('%Links('||strip(client)||');'); /* Creates a macro call for each row of dataset */
run;
Without knowing exactly what you want to achieve though its hard to provide concrete examples.
Basically, I want the macro to iterate for each value of ClientId, something like this (assume there are only 4 ClientID's : 1,2,3,4) :
%macro Links (ClientId=);
code
code
%mend Links;
%Links (ClientId=1);
%macro Links (ClientId=);
code
code
%mend Links;
%Links (ClientId=2);
%macro Links (ClientId=);
code
code
%mend Links;
%Links (ClientId=3);
%macro Links (ClientId=);
code
code
%mend Links;
%Links (ClientId=4);
So yes:
%macro Links (ClientId=);
code;
%mend Links;
data have;
do client=1 to 4;
output;
end;
run;
data _null_;
set have;
call execute('%Links (ClientId='||strip(put(client,best.))||');');
run;
Thanks RW9, much appreciated
Oops, one last thing RW9. Our ClientID's are not in numerical order, so would, for example, be 1,5,7,9. How would I phrase the do loop (where you say do client=1 to 4) to accommodate this ?
I will also compress the code a bit now you have seen it:
%macro Links (ClientId=);
code;
%mend Links;
data have;
do client=1,5,7,9;
call execute('%Links (ClientId='||strip(put(client,best.))||');');;
end;
run;
Thanks again - perfect !
Yes you could, but then you need to parse the parameter and build a %do loop inside the macro.
If you wish to execute the whole macro for each value, you might want to look at calling the macro multiple times instead. If you have many values, you could drive this by storing the values in a data set, and call the macro dynamically by call execute.
Use minoperator
%macro Links (ClientId=) / minoperator ;
%if &ClientId in 1 2 3 4 %then %do ;
code
code
%mend Links;
%Links (ClientId=1 )
%Links (ClientId=2 )
%Links (ClientId=12 )
Xia Keshan
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.