SAS programmers have long wanted the ability to control the flow of their SAS programs without having to resort to complex SAS macro programming. With SAS 9.4 Maintenance 5, it's now supported! You can now recently came to light on SAS Support Communities. (Thanks to Super User Tom for asking about it.)
Prior to this change, if you wanted to check a condition -- say, whether a data set exists -- before running a PROC, you had to code it within a macro routine. It would look something like this:
/* capture conditional logic in macro */ %macro PrintIfExists(); %if %sysfunc(exist(work.result)) %then %do; proc means data=work.result; run; %end; %else %do; %PUT WARNING: Missing WORK.RESULT - report process skipped.; %end; %mend; /* call the macro */ %PrintIfExists();
Now you can simplify this code to remove the %MACRO/%MEND wrapper and the macro call:
/* If a file exists, take an action */ /* else fail gracefully */ %if %sysfunc(exist(work.result)) %then %do; proc means data=work.result; run; %end; %else %do; %PUT WARNING: Missing WORK.RESULT - report process skipped.; %end;
Here are some additional ideas for how to use this feature. I'm sure you'll be able to think of many more!
Run "debug-level" code only when in debug mode
When developing your code, it's now easier to leave debugging statements in and turn them on with a simple flag.
/* Conditionally produce debugging information */ %let _DEBUG = 0; /* set to 1 for debugging */ %if &_DEBUG. %then %do; proc print data=sashelp.class(obs=10); run; %end;
If you have code that's under construction and should never be run while you work on other parts of your program, you can now "IF 0" out the entire block. As a longtime C and C++ programmer, this reminds me of the "#if 0 / #endif" preprocessor directives as an alternative for commenting out blocks of code. Glad to see this in SAS!
/* skip processing of blocks of code */ /* like #if 0 / #endif in C/C++ */ %if 0 %then %do; proc ToBeDetermined; READMYMIND = Yes; run; %end;
Run code only on a certain day of the week
I have batch jobs that run daily, but that send e-mail to people only one day per week. Now this is easier to express inline with conditional logic.
/*If it's Monday, send a weekly report by email */ %if %sysfunc(today(),weekday1.)=2 %then %do; options emailsys=smtp emailhost=myhost.company.com; filename output email subject = "Weekly report for &SYSDATE." from = "SAS Dummy <firstname.lastname@example.org>" to = "email@example.com" ct ='text/html'; ods tagsets.msoffice2k(id=email) file=OUTPUT(title="Important Report!") style=seaside; title "The Weekly Buzz"; proc print data=amazing.data; run; ods tagsets.msoffice2k(id=email) close; %end;
Check a system environment variable before running code
For batch jobs especially, system environment variables can be a rich source of information about the conditions under which your code is running. You can glean user ID information, path settings, network settings, and so much more. If your SAS program needs to pick up cues from the running environment, this is a useful method to accomplish that.
/* Check for system environment vars before running code */ %if %sysfunc(sysexist(ORACLE_HOME)) %then %do; %put NOTE: ORACLE client is installed.; /* assign an Oracle library */ libname ora oracle path=corp schema=alldata authdomain=oracle; %end;
Limitations of %IF/%THEN in open code
As awesome as this feature is, there are a few rules that apply to the use of the construct in open code. These are different from what's allowed within a %MACRO wrapper.
First rule: your %IF/%THEN must be followed by a %DO/%END block for the statements that you want to conditionally execute. The same is true for any statements that follow the optional %ELSE branch of the condition.
And second: no nesting of multiple %IF/%THEN constructs in open code. If you need that flexibility, you can do that within a %MACRO wrapper instead.
And remember, this works only in SAS 9.4 Maintenance 5 and later. That includes the most recent release of SAS University Edition, so if you don't have the latest SAS release in your workplace, this gives you a way to kick the tires on this feature if you can't wait to try it.