Week 11, Part 7: Macros for Repetitive Processing¶

This macro’s utility is in automation, dynamic processing, and safety.

  • Dynamically loop over rows in a dataset
  • Extract variables safely, even if they contain & or %
  • Generate reports, filters, or custom SAS code for each row
  • Avoid manual, repetitive coding

More specifically, the macro

  • Takes a dataset (sashelp.class).

  • Stores all rows in a single macro variable, using a safe delimiter (|) for columns and spaces for rows.

  • Loops through each row (student) using macro logic.

  • Extracts variables (name, sex, age) from each row.

  • Each acts as row (e.g., prints a report for that student).

In [9]:
options nocenter nodate nonumber nosource symbolgen;
ods html close;

proc sql noprint;
  select catx('|', name, sex, age)
    into :student_list separated by ', '
  from sashelp.class;
quit;

%put %superq(student_list); /* safe display */
%put number of values: &sqlobs
The SAS System

NOTE: Writing HTML5(SASPY_INTERNAL) Body file: _TOMODS1
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

Alfred|M|14, Alice|F|13, Barbara|F|13, Carol|F|14, Henry|M|14, James|M|12, Jane|F|12, Janet|F|15, Jeffrey|M|13, John|M|12, 
Joyce|F|11, Judy|F|14, Louise|F|12, Mary|F|15, Philip|M|16, Robert|M|12, Ronald|M|15, Thomas|M|11, William|M|15
SYMBOLGEN:  Macro variable SQLOBS resolves to 19
number of values: 19
The SAS System

E3969440A681A2408885998500000011
In [11]:
options nocenter nodate nonumber symbolgen;
ods html close;
%macro student_reports;
    %local i n obs name sex age;
    /* Count number of students */
    %let n = %sysfunc(countw(%superq(student_list), %str( )));
    %do i = 1 %to &n;
        /* Extract one student record */
        %let obs = %qscan(%superq(student_list), &i, %str( ));
        /* Parse name, sex, age */
        %let name = %qscan(&obs,1,|);
        %let sex  = %qscan(&obs,2,|);
        %let age  = %qscan(&obs,3,|);

        /* Dynamic report for this student */
        title "Report for &name (Sex: &sex, Age: &age)";
        proc print data=sashelp.class noobs;
            where name="&name";
        run;
    %end;
%mend;
%student_reports
SAS Output

Report for Alfred (Sex: M, Age: 14,)

Name Sex Age Height Weight
Alfred M 14 69 112.5

Report for Alice (Sex: F, Age: 13,)

Name Sex Age Height Weight
Alice F 13 56.5 84

Report for Barbara (Sex: F, Age: 13,)

Name Sex Age Height Weight
Barbara F 13 65.3 98

Report for Carol (Sex: F, Age: 14,)

Name Sex Age Height Weight
Carol F 14 62.8 102.5

Report for Henry (Sex: M, Age: 14,)

Name Sex Age Height Weight
Henry M 14 63.5 102.5

Report for James (Sex: M, Age: 12,)

Name Sex Age Height Weight
James M 12 57.3 83

Report for Jane (Sex: F, Age: 12,)

Name Sex Age Height Weight
Jane F 12 59.8 84.5

Report for Janet (Sex: F, Age: 15,)

Name Sex Age Height Weight
Janet F 15 62.5 112.5

Report for Jeffrey (Sex: M, Age: 13,)

Name Sex Age Height Weight
Jeffrey M 13 62.5 84

Report for John (Sex: M, Age: 12,)

Name Sex Age Height Weight
John M 12 59 99.5

Report for Joyce (Sex: F, Age: 11,)

Name Sex Age Height Weight
Joyce F 11 51.3 50.5

Report for Judy (Sex: F, Age: 14,)

Name Sex Age Height Weight
Judy F 14 64.3 90

Report for Louise (Sex: F, Age: 12,)

Name Sex Age Height Weight
Louise F 12 56.3 77

Report for Mary (Sex: F, Age: 15,)

Name Sex Age Height Weight
Mary F 15 66.5 112

Report for Philip (Sex: M, Age: 16,)

Name Sex Age Height Weight
Philip M 16 72 150

Report for Robert (Sex: M, Age: 12,)

Name Sex Age Height Weight
Robert M 12 64.8 128

Report for Ronald (Sex: M, Age: 15,)

Name Sex Age Height Weight
Ronald M 15 67 133

Report for Thomas (Sex: M, Age: 11,)

Name Sex Age Height Weight
Thomas M 11 57.5 85

Report for William (Sex: M, Age: 15)

Name Sex Age Height Weight
William M 15 66.5 112
Macro-based automation¶

This approach is often used for:

  • Batch reporting (one report per customer/row)
  • Dynamic WHERE clauses
  • Parameter-driven calculations

You can completely automate tasks without manually changing SAS code each time.