The advantages of defining macro variables outside the macro function

1.2k Views Asked by At

I have a stubborn lecturer who insists that defining all macro variables inside the parenthesis of the macro statement like this

%MACRO TEST(Var1= , Var2= , Var3= );

What are the advantages of this? What are the advantages of actually defining your function like this instead:

%LET var1= <Insert long list of 50 variables here>;
%LET var2= <name of input data>;
%LET var3= <group by variables>;

%MACRO TEST;

I argue that the second option provides clarity and a neat coding structure, could anyone point out any other advantages or disadvantages of the two methods?

4

There are 4 best solutions below

1
On

Two main points:

  • Use of global variables is widely considered to be bad practice.
  • Using your system, how would you write out multiple calls to the same macro in different places in your code? How would you keep track of which parameter lists correspond to which macro calls?
0
On
  1. Macro variable scope - having variables only available within the macro ensures that any previously declared macro variables are not used by accident. If you accidentally run things out of order, with your method you're likely to run into issues.
  2. It makes it clear what parameters the macro requires - otherwise you have to read the code, find all the & and declare them at the top.
  3. Less typing overall
  4. You can set default values within the parameter list and then only list/call what options you need when declaring.

Macro definition:

%macro test(var1 = , var2 = , var3 = 25);

Macro call/execution:

%test(var1 = 5, var2 = 4);

What value will var3 have in the macro?

  1. You're still using very simple cases and a lot of the more complicated usages work better when you have parameters. Consider the case with calling the same macro 50 times for different parameters which happen to be in a data set. You can use CALL SYMPUTX() for each but then you'll run into timing issues of when the macro is called and such. Whereas using CALL EXECUTE and the parameters inline makes it very easy.

PS. In general, the odds are 99% your lecturer will be correct at this point in time when you're starting out. Assuming that will help you frame your questions differently, rather than trying to prove someone wrong (which is how your question is coming across) you'll be looking at understanding how something works. Also, it's possible that your lecturer will be online as well so if they see your questions at some point you won't come across as a know-it-all kid. Ultimately that's your choice though.

0
On

The only time you'd ever want to do this is if you have global variables that will appear throughout the program. For example, it is not uncommon to have special setup or initialization programs to hold commonly-referred values, especially when going between development and production. This can make things easier to handle when promoting a program, or easier to adjust if certain things change later on (such as a directory location or hostname).

For example, the below macro can change some global macro variables to point to certain directories that differ between two servers depending on where the code is run.

%macro dev_prod;
    %global directory inlib outlib;

    %if(&syshostname. = production-server.company.com) %then %do;
        %let directory = C:\prodlocation;
        %let inlib     = C:\prodlib;
        %let outlib    = C:\outlib;
    %end;
        %else %if(&syshostname. = dev-server.company.com) %then %do;
            %let directory = C:\devlocation;
            %let inlib     = C:\devlib;
            %let outlib    = C:\outlib;
        %end;
%mend;
%dev_prod;

In general, you want to use local macro variables in macros that perform specific functions. For example, the below macro regresses on variables on a dataset:

%macro regression(data=, dep=, indep=);
    proc reg data=&data.;
        model  &dep. = &indep.;
    run;
%mend;
%regression(data=sashelp.cars, dep=horsepower, indep=msrp); 
3
On

It depends on how the macros will be used. Global macros can be very helpful and as you pointed out provide clarity if they are used correctly. For example, if I have a bunch of SAS programs that need to run in order to generate data sets or reports, I would put them in a wrapper program and use global macros.

%Let year = 2019;
%Let State = CA;
%let Dept = DOE;

%macro MakeRpt;

%include "MakeData.sas";
.
. more %include statements
.
%include "GenerateReport.sas";

%mend;

%makeRpt;

However, if I'm making a macro "utility" that will be called by a user whenever they need it, using local macros makes the most sense. It's really a question of how a macro will be used as to whether global or local makes more sense.