Compiled by Rupesh R
The following macro needs to be applied for the purpose of presenting page numbers in Page X of Y format within the body of the document.
When calling the macro, the proc report code should be quoted by %nrstr as explained in step 1.a below. To avoid clutter of code, here the proc report code is created as a macro. This proc report code should contain a ‘compute before_page_’ block as described in the step 5 below.
%macro pageXofY (report= /* proc report code, quoted by %nrstr */ /*1.a*/
, dummy=dummy /* name of the dummy output file */
);
%global page pages len; /* 1.b*/
/-- first run --*/
%let page = 0;
%let len = 8; /* 1.c*/
filename _dummy &dummy.; /* 1.d*/
proc printto print = _dummy; run; /*1.e*/
%unquote (&report.) ;/* 1.f*/
proc printto; run;/*1.g*/
filename _dummy clear; /*1.h*/
%*-- second run --*;
%let pages = &page.; /*1.i*/
%let page = 0;/*1.j*/
%let len = %eval(%length(&pages.) * 2 + 4); /* 1.k*/
%unquote(&report.);/*1.l*/
%mend pageXofY;
Explanation of Macro
Step 1 (1.a): Using %nrstr function we mask the special characters and mnemonics .Here we mask & and % symbols in the proc report code.
Step 2 (1.b): Initialize three global macro variables
§ The variable ‘page’ returns the current page number
§ The variable ‘pages’ returns the total number of pages
§ The variable ‘len’ returns the expected length of the string ‘_XofY’ (2.c) .
Step 3 (1.c): The initial values of macro variables ‘page’ and ‘len’ are assigned as 0 and 8 respectively.
Step 4 (1.d): A dummy file path is defined for the output of proc printto
Step 5 (1.e): PRINTTO procedure is used for printing the output in the specified dummy file (_dummy).
Step 6 (1.f): The proc report code created for generating the output is executed using %unquote function in this step.
%UNQUOTE is to restore normal tokenization of a value whose tokenization was altered by a previous macro quoting function. %UNQUOTE takes effect during macro execution. If the value is not unmasked before it reaches the SAS compiler, the DATA step does not compile correctly and it produces error messages.
1) Execute the entire report procedure and generate an output to the specified file path “&dummy.”
2) In report procedure we should include the following set of statements.
compute before/after _page_;
call execute('%let page = %eval(&page. + 1);'); /* 2.a*/
length _XofY $&len.; /* 2.b. */
_XofY = symget('page') ' of ' symget('pages');/*2.c*/
line 'page ' _XofY $&len..; /* 2.d. */
endcomp;
Step 8 (1.h): Clear the dummy file.
Step 9 (1.i): Assign the current value of variable ‘page’ to the macro variable ‘pages’. i.e. we assign the total number of pages to the variable ‘pages’
Step 10 (1.j): Reset the variable ‘page’ to ‘0’.
Step 11 (1.k): Calculate the approximate length of the variable ‘_XofY’ based on current value of ‘pages’.
Step 12 (1.l): Re-execute the report procedure for getting the output as per the requirement.
data one;
do var = 1 to 100;
output;
end;
run;
%Macro Report;
proc report data=one nowd;
column var;
define var / display;
compute before _page_;/*2.a*/
call execute('%let page = %eval(&page. + 1);'); /* 2.b*/
length _XofY $&len.; /* 2.c. */
_XofY = symget('page') ' of ' symget('pages');/*2.d*/
line 'page ' _XofY $&len..; /* 2.e. */
endcomp;
run;
%Mend Report;
/* example usage */
options linesize=64 nonumber nodate;
%pageXofY(report=%nrstr(%Report));



