Num is a variable that's being defined two times, the first time outside the macro and later as a macro input. I'd like to reduce the number of times that a user will enter data. Any suggestions for how to consolidate the two inputs into one?
(The data step inside the macro can stand on its own, but I'm using this as an example for a larger macro that I'm working with.)
Thank you.
%let num = 3; /*input by user*/
data time;
input time1 - time#
infile datalines stopover; /*STOPOVER writes ERROR to sas log file if dataline values < num*/
datalines;
24 40 60
;
run;
%macro example(num);
data new;
set time;
array utime (&num) time1 - time#
do i = 1 to #
utime[i] = utime[i] + 1;
end;
drop i;
run;
%mend;
%example(num=3); /*input by user*/
quit;
Because the parameter name is the same as the external macro variable you cannot see the value of the external maaro variable when the macro is running.
If you make the parameter name (the name of the LOCAL macro variable) different than the name of the other macro variable then you can reference both inside the macro. Then you can add logic to use that value if the caller didn't provide a value for the parameter.
%macro example(local_num);
%if 0=%length(&local_num) and %symexist(num) %then
%let local_num=#
;
data new;
set time;
array utime (&local_num) time1 - time&local_num;
do i = 1 to &local_num;
utime[i] = utime[i] + 1;
end;
drop i;
run;
%mend;
Then the user can pass in a value or not.
%let num=3 ;
%example(5)
%example(local_num=7)
%example()
Or they can just pass in the value of the external macro variable in the call, which will work even when the local macro variable uses the same name.
%example(&num)
Because the parameter name is the same as the external macro variable you cannot see the value of the external maaro variable when the macro is running.
If you make the parameter name (the name of the LOCAL macro variable) different than the name of the other macro variable then you can reference both inside the macro. Then you can add logic to use that value if the caller didn't provide a value for the parameter.
%macro example(local_num);
%if 0=%length(&local_num) and %symexist(num) %then
%let local_num=#
;
data new;
set time;
array utime (&local_num) time1 - time&local_num;
do i = 1 to &local_num;
utime[i] = utime[i] + 1;
end;
drop i;
run;
%mend;
Then the user can pass in a value or not.
%let num=3 ;
%example(5)
%example(local_num=7)
%example()
Or they can just pass in the value of the external macro variable in the call, which will work even when the local macro variable uses the same name.
%example(&num)
Thanks for the replies, Tom and Paige.
I didn't think of using &num as the macro input, but that seems to work.
Thanks for links, Tom. You're right, it's more than what I need for this macro, but the step-by-step explanations are helpful.
Since the macro variable &NUM is given a value in the first line of the program, you don't need to give it a value again.
%example(num=&num)
Or, in this very simple example, where &NUM has a value in the first line of the program, you don't even have to use the NUM= argument when you define or call the macro. This should work as well:
%macro example;
...
%mend;
%example
Note I did create a SAS macro that will find the value for an existing macro variable that is currently hidden by the existence of another macro variable of the same name in a more local scope.
https://github.com/sasutils/macros/blob/master/symget.sas
If you want to use it as is then you will also need the %QLIST() macro from the same site.
https://github.com/sasutils/macros/blob/master/qlist.sas
You probably don't need it to fix your program, but it is a fun toy to play with.
%macro example(num);
%if 0=%length(&num) %then %let num=%symget(num);
....
%mend;
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: