- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hello!
I'm trying to run my macro (%tti(number)) that performs a large series of operations using an input value of 'number'. I have 2000 such numbers that changes the output of the macro. I have looped though them all using a simple loop macro:
%macro loop(start,stop); %do iii=&start %to &stop; %tti(&iii); %end; %mend();
However, now I would like to create the same macro but no do start to stop but rather run the macro based on input numbers, lets says 3,5,7,33,99.
I have tried to use code presented on this forum with no success.
%do_this(3 5 7 33 99); %macro do_this(ids); %let num_ids=%sysfunc(countw(&ids)); %do i=1 %to &num_ids; %let this_id=%scan(&ids,&i,%str( )); %tti(&this_id); run; %end; %mend;
This macro runs the %tti() but using wrong input and sometimes gets stuck on the last input variable (in this case 99) and reruns it indefinitely. When inputting only 2 numbers in the list it only performs the 1st.
Any suggestions?
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Nothing serious is wrong with your posted code.
Make sure that the TTI macro is not changing the macro variables I or NUM_IDS.
Remember to ALWAYS declare the macro variables that are local to your macro as %LOCAL to avoid this type of issue when nesting macro calls. So your TTI macro might have a %DO loop that also using I as the index macro variable name. Like:
%macro tti(arg1);
%local i;
....
%do i=
...
%mend tti;
And if it does NOT have the %LOCAL statement then the macro variable I that the %DO loop would modify would be the one defined in DO_THIS instead.
So your little DO_THIS macro should do the same thing just in case you decide to call it from some other macro.
%macro do_this(ids);
%local num_ids i this_id;
%let num_ids=%sysfunc(countw(&ids));
%do i=1 %to &num_ids;
%let this_id=%scan(&ids,&i,%str( ));
%tti(&this_id);
%end;
%mend;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Nothing serious is wrong with your posted code.
Make sure that the TTI macro is not changing the macro variables I or NUM_IDS.
Remember to ALWAYS declare the macro variables that are local to your macro as %LOCAL to avoid this type of issue when nesting macro calls. So your TTI macro might have a %DO loop that also using I as the index macro variable name. Like:
%macro tti(arg1);
%local i;
....
%do i=
...
%mend tti;
And if it does NOT have the %LOCAL statement then the macro variable I that the %DO loop would modify would be the one defined in DO_THIS instead.
So your little DO_THIS macro should do the same thing just in case you decide to call it from some other macro.
%macro do_this(ids);
%local num_ids i this_id;
%let num_ids=%sysfunc(countw(&ids));
%do i=1 %to &num_ids;
%let this_id=%scan(&ids,&i,%str( ));
%tti(&this_id);
%end;
%mend;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks alot!
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Run your macro off a dataset with call execute():
data control;
input i;
datalines;
3
5
7
33
99
;
run;
data _null_;
set control;
call execute(cats('%nrstr(%tti(',i,'))'));
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I will try this! Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
The data step DO loop allows you to use a list of values like that. Why not just use a data step to generate the macro calls?
data _null_;
do id=3,5,7,33,99;
call execute(cats('%nrstr(%tti)(',id,')'));
end;
run;