Many programmers will add debugging features (e.g., PROC PRINT, PROC FREQ, PROC CONTENTS) to their programs and then remove them or comment them out when they think they are done testing. Instead of doing this, consider using macros that can be controlled by a global macro variable to turn debugging output on/off.
A sample program is shown below, along with three sample macros for PROC PRINT, PROC FREQ, and PROC CONTENTS that can be added to your SAS autocall library.
Consider the following simple program that reads in some data, applies some logic, and includes debugging output based on a value being specified for the macro variable Debug. Note how the debugging macros use the %GLOBAL statement to ensure that the macro variable exists. Thus, if the Debug macro is set to null or not defined at all, no debugging output is produced.
The programmer can easily turn debugging on/off by either updating or removing the %LET statement.
The sample program and all three macros can be found in the SampleDebuggingMacros.zip file attached to this article.
%let Debug = Y; /* turn debugging on - any non-blank value turns debugging on */
data demoTest;
set sashelp.class;
if sex = 'M' and age le 12 then Category = '1';
else if sex = 'F' and age le 13 then Category = '2';
else if age lt 16 then Category = '3';
else Category = '4';
run;
/* display all the rows */
%testPrint(data=demoTest);
run;
/* verify data set attributes */
%testContents(data=demoTest)
run;
/* verify recode logic */
%testFreq(data=demoTest,tables=Category*Sex*Age)
run;
%macro testPrint(data = _last_ /* data set to print if debugging turned on */
,var = _all_ /* variables to print */
,obs = /* number of observations to print */
,titleline = 3 /* title line for test print title */
,options = label /* used to pass in any other desired options */
);
/*------------------------------------------------------------------------------------------
Invoke PROC PRINT if debugging option is enabled.
Debugging can be turned on by setting the global macro variable "debug"
to a non-null value.
No run; statement is included after the PROC PRINT so the programmer can
follow the testPrint macro call with their own title and footnote
statements. If debugging is not turned on, the title/footnote statements
will only be used for later output if they are not over-written.
|------------------------------------------------------------------------------------------|
| MAINTENANCE HISTORY |
|------------------------------------------------------------------------------------------|
| DATE | BY | DESCRIPTION |
|----------|-----------|-------------------------------------------------------------------|
| Dec 2006 | Don H | Original Creation
|-----------------------------------------------------------------------------------------*/
%global Debug; /* ensure it exists */
%if %length(&obs) ne 0 %then
%do; /* subset of observations being printed */
%let titleLine = title&titleLine "Test Print of &obs Observations from &data";
%let obs = (obs=&obs);
%end; /* subset of observations being printed */
%else %let titleLine = title&titleLine "Test Print of &data";
%if %length(&Debug) gt 0 %then
%do; /* flag set - produce debugging output */
run;
proc print data=&data&obs &options;
&titleLine;
/* no run; statement provided so the macro call call be followed by
programmer specfied title and footnote statements which are then
followed by a run; statement
*/
%end; /* flag set - produce debugging output */
%mend testPrint;
%macro testContents(data = _last_ /* data set to print if debugging turned on */
,titleline = 3 /* title line for test print title */
,options = /* used to pass in any other desired options */
);
/*------------------------------------------------------------------------------------------
Invoke PROC CONTENTS if debugging option is enabled.
Debugging can be turned on by setting the global macro variable "debug" to a non-null value.
No run; statement is included after the PROC CONTENTS so the programmer can
follow the testContents macro call with their own title and footnote
statements. If debugging is not turned on, the title/footnote statements
will only be used for later output if they are not over-written.
|------------------------------------------------------------------------------------------|
| MAINTENANCE HISTORY |
|------------------------------------------------------------------------------------------|
| DATE | BY | DESCRIPTION |
|----------|-----------|-------------------------------------------------------------------|
| Dec 2006 | Don H | Original Creation
|-----------------------------------------------------------------------------------------*/
%global Debug; /* ensure it exists */
%if %length(&Debug) gt 0 %then
%do; /* flag set - produce debugging output */
run;
proc contents data=&data &options;
title&titleLine "Test PROC CONTENTS for &data";
/* no run; statement provided so the macro call call be followed by
programmer specfied title and footnote statements which are then
followed by a run; statement
*/
%end; /* flag set - produce debugging output */
%mend testContents;
%macro testFreq(data = _last_ /* data set to report on if debugging turned on */
,tables = /* frequency tables to generate */
,tableoptions = list /* options for the tables statement, eg, LIST, MISSING, etc. */
,titleline = 3 /* title line for test print title */
);
/*------------------------------------------------------------------------------------------
Invoke PROC FREQ if debugging option is enabled.
Debugging can be turned on by setting the global macro variable "debug"
to a non-null value.
No run; statement is included after the PROC FREQ so the programmer can
follow the testFreq macro call with their own title and footnote
statements. If debugging is not turned on, the title/footnote statements
will only be used for later output if they are not over-written.
|------------------------------------------------------------------------------------------|
| MAINTENANCE HISTORY |
|------------------------------------------------------------------------------------------|
| DATE | BY | DESCRIPTION |
|----------|-----------|-------------------------------------------------------------------|
| Dec 2006 | Don H | Original Creation
|-----------------------------------------------------------------------------------------*/
%global Debug; /* ensure it exists */
%if %length(&tables) = 0 %then
%do; /* required parameter not specified */
%put ERROR: Parameter Tables not specified. It is a required parameter for macro testFreq.;
%end; /* required parameter not specified */
%else %if %length(&Debug) gt 0 %then
%do; /* flag set - produce debugging output */
run;
proc freq data=&data;
tables &tables/&tableOptions;
title&titleLine "Test PROC FREQ for &data";
/* no run; statement provided so the macro call call be followed by
programmer specfied title and footnote statements which are then
followed by a run; statement
*/
%end; /* flag set - produce debugging output */
%mend testFreq;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.