Watch this Ask the Expert session to learn how to automate repetitive tasks using macro programming.
Watch the Webinar
You will learn about:
Context/background of the SAS macro facility.
Macro variables.
Macro conditional processing.
The questions from the Q&A segment held at the end of the webinar are listed below and the slides from the webinar are attached.
Q&A
Do macros work with imported data files?
Yes. Macros do not care how the data was imported into a SAS table. If it’s a table that SAS can use, a macro can work with it equally well. Essentially, the macro performs copy and paste on the underlying code, which then compiles and executes as if it had been typed manually.
Can you also use the macro name in the worktable name?
Absolutely. For example:
%let t = snack;
data work.&t; /* outputs to work.snack*/
Is explicitly specifying the work library just good practice?
Specifying the library isn't required, and I wouldn't necessarily call it best practice, but it's a habit of mine because it helps me remember which library is being used. It also makes it clearer for anyone reviewing my code. The reason for this question is likely to clarify that if you don't specify a library, it will default to the work library.
Does using a macro make macro variables unnecessary?
Using the macro means you don't need to have %let statements outside of it, since the macro variables are scoped locally within the macro. For example, search word exists only inside snack report.
How can macros be used in predictive analytics?
Predictive analytics isn’t my specialty, but I can say that macros are generally useful for situations where you need to modify a piece of code and rerun it with small changes. For example, with the snack report, you might need to adjust one filter and update the report title, repeating this process several times. While macros can handle more complex tasks, at a beginner level, their strength is in automating repetitive changes. If you're running predictive analytics for all 50 states, for instance, you could set up a macro to process Alabama, then Alaska, and so on — automating those filter changes each time, rather than editing them manually.
Can macros be used in a loop or can macros do loops?
Yes, macros can definitely do loops. While this example may not lend itself perfectly to an iterative loop, macros can perform loops quite effectively. For instance, I could write a loop from i equals 1 to 10, using %put to output notes in the log stating "i =" and the value of i. Please note, it's not just a DO loop; it must be a %DO loop. If you omit the percent symbol, SAS will become confused. By using this, I can reference the macro variable &i later in my code. When I run this, I can look in the log and see notes: "i = 1," "i = 2," all the way up to "i = 10."
This capability allows for more complex uses. You can also create conditional loops, such as %DO %WHILE or %DO %UNTIL.
Could you explain the SYSFUNC function in more detail? When does %sysfunc execute? When first encountered or when the macro variable is called? Is SYSFUNC also used outside macros? Is %sysfunc required in your second line program?
Basically, %sysfunc tells the macro processor to run a function, and it executes as soon as the computer encounters its closing parenthesis. If there’s a macro variable inside, it gets resolved — meaning SAS replaces it with its value — right when SAS finds its last character. So, imagine the computer reading code with %sysfunc: it sees %sysfunc, knows it has to run a function, and looks for the closing parenthesis. Along the way, if it finds a macro variable like &searchword, it resolves it immediately (say, to "puff"). When the closing parenthesis appears, the function executes, such as converting text to uppercase.
This all happens while the text is being processed. For example, in a TITLE statement, the adjustment is made before the statement runs. As SAS reads the TITLE statement, it processes any %sysfunc and macro variable, resolving them before the TITLE statement ends with a semicolon. So you get the correct output ("PUFF") in the TITLE statement when it executes.
This is a very quick introduction. There’s a full macro programming course that covers these basics in depth over five half days. While we’re just skimming the surface now, that course would have you building and practicing macro programming yourself.
Is there a maximum number of macros you can have in your program?
There is no set limit that I am aware of. If one exists, it would likely be in the thousands, so for practical purposes, there isn’t a restriction. The number of macros is mainly limited by your available hardware.
Earlier, you were making a point about semicolons, and you put two semicolons after a RUN statement. Could you go over that point again?
Absolutely, let me clarify. The point I was making is that for the %snack_report macro call, you don't need a semicolon at the end. Why is that? It’s because, once the macro facility has performed all its find-and-replace operations, the macro call becomes equivalent to regular SAS code.
If you add a semicolon after a macro call, it’s just like placing a semicolon at the end of the corresponding SAS code. Adding an extra semicolon after a RUN statement is harmless, but it’s not necessary.
Can you show how to cycle the macro through both pretzel and puff concurrently?
It’s a more advanced topic. Here is how I’d approach it:
/* As written, ProductList value must be | separated */
%macro snackReportList(productList);
%let i = 1;
%let currentSnack = %scan(&productList, &i, |); /* separate &productList into pieces based on |. Return the i_th piece */
%do %while (¤tSnack ^= ); /* do while ¤tSnack has a non-null value */
%put ¤tSnack;
%snackReport(¤tSnack)
%let i = %sysEvalF(&i + 1); /* increase i by 1 */
%let currentSnack = %scan(&productList, &i, |); /* get new value of ¤tSnack */
%end;
%mEnd snackReportList;
%snackReportList(pretzel| puff| pencil) /* Test example */
Is Macro still useful with SAS Viya, or is it outdated?
Macros remain useful with Viya because Viya still has the compute server, allowing you to perform SAS 9 programming within Viya. They’re also helpful with CAS, since macro processing simply performs find-and-replace operations on your code before it compiles and executes. For example, if you’re not currently connected to a CAS server, but you run something like "proc casutil load data=&table", you can still use a macro variable. Suppose "table" is "sashelp.cars"—the macro substitution would occur before those instructions are sent to CAS.
That said, if you’re programming in CASL, there are some elegant ways to perform text manipulation outside of macros, so you do have alternatives. Still, macros remain a powerful option for SAS programmers, including those working in SAS Viya.
Does color coding inside of macros disappear in SAS Studio? If so, is there a trick to get it back (like the trick for SAS EG)?
There are many versions of SAS Studio, so I don’t want to over promise. In the version I use, the color coding stays. If your version removes color coding, try the same trick I used in Enterprise Guide: “%macro a; %mEnd a; /* restore color coding */”
Can I do the trick coloring in SAS Base?
Much like Studio, I don’t want to overpromise, since multiple versions exist. It works in the version I have.
Can you show a dynamic date example in the date9. format that pulls a min/max date from a data table to use as a filter?
proc sql;
select max(dateColumn) format=date9.
into :maxDateColumn /* makes &maxDateColumn holding result of max(dateColumn) calculation in select clause */
from inputTable
;
quit;
I add a . (dot) at the end of macro variables when being called, for example &searchword. Is it still necessary?
If there is trailing text immediately following the macro variable, yes. For example, “&searchWord.s” requires a dot to separate the &searchWord and s. “&searchWord s” does not require a dot, because the space separates &searchWord and s.
Trick to color coding in SAS Enterprise Guide, could you please show the difference without this or with this how it looks once again?
If searchword is defined globally and then also defined within a macro, which version is called at runtime?
Inside the macro, the local one will be used. Outside the macro, the global one will be used.
You answered the question about doing loops within a macro, but can you do loops outside a macro so it can be run for all values in an array instead of typing %macroname() multiple times?
In classic SAS programming, a macro is needed to make a loop. However, there are parts of SAS, like CASL, in which arrays behave like python
Recommended Resources
SAS Macro Language 1 class
SAS Macro Language Reference Documentation
Please see additional resources in the attached slide deck.
Want more tips? Be sure to subscribe to the Ask the Expert board to receive follow up Q&A, slides and recordings from other SAS Ask the Expert webinars.
... View more