Here is a macro which does this. Comment out the calls to %m_parmv, replace with your own error checking. Extensive use cases are in the macro header.
Although it requires two passes of the data, one to count pages, one to renumber pages, SAS processes text files very fast. I haven't found this approach to be a performance problem - I have renumbered 50,000+ pages with an acceptable degree of performance.
Hope this helps...
/*=====================================================================
Study Number : Standard Global Macro
Program Name : m_pagexofy.sas
Purpose : Add page numbers to output, usually in the
form of "Page x of Y".
SAS Version : SAS 9.1.3
Input Data : N/A
Output Data : N/A
Macros Called : m_parmv
Originally Written by : Scott Bass
Date : 31AUG2010
Program Version # : 1.0
=======================================================================
Modification History : Original version
=====================================================================*/
/*----
Usage:
title;
footnote;
%macro create_sample_output;
first generate some sample output ;
filename old temp; * best practice - use a temporary file for initial file ;
filename new temp;
alternative files, useful for debugging by viewing in an editor ;
filename old "c:\temp\old.lst";
filename new "c:\temp\new.lst";
send your desired output to the working file ;
proc printto print=old new;
run;
options pageno=1;
proc print data=sashelp.shoes (obs=40) noobs uniform;
var region--inventory;
run;
release the output file ;
proc printto;
run;
%mend;
options mprint;
options ps=20 ls=80;
options nocenter nodate number;
title "Testing the m_pagexofy macro";
%create_sample_output;
now post-process the file to generate "Page x of Y" output ;
you can overwrite the source file ;
%m_pagexofy(infile=old);
or you can create a new file ;
%create_sample_output;
%m_pagexofy(infile=old,outfile=new);
note quotes are not needed in the output file ;
an "advanced" algorithm is used to determine a fileref vs. physical file ;
%m_pagexofy(infile="c:\temp\old.lst",outfile=c:\temp\new.lst);
this is the default style ;
you must use of ));
%m_pagexofy(infile=old,outfile=new,style=[Page > of < are "borrowed" from the
equivalent field codes in Microsoft Word.
The DELIM parameter should be unique to the generated output, i.e.
should occur once and only once per page. Typically it is specified in
a title or footnote statement.
The DELIM parameter must be 20 characters or less.
Normally the longest line in the output is used to determine the
effective linesize. This works fine if you have the number option set
when the output is generated, since the page number will be right
justified within the pagesize in effect when the output was generated,
and then overwritten when the output is re-paginated. However, if no
titles were used, or the nonumber option was in effect, you can use the
LS parameter to explicitly set the linesize used to justify the page
renumbering.
By default the "Page x of Y" output is right justified using this
derived linesize. Use the JUSTIFY parameter to override the default
justification.
If you specify LEFT or CENTER justification, you'll likely want to turn
off titles, or use a user-specified delimiter, or you'll probably get
unwanted results (the page renumbering overlaying other title text).
-
*/
%macro m_pagexofy
/*----
Add page numbers to output, usually in the form of "Page x of Y"
-
*/
(INFILE= /* Input file (REQ). */
,OUTFILE= /* Output file (Opt). */
/* If blank, the input file is overwritten. */
,STYLE=Page " represents the current page number. */
/* "/",numpages,"/i"),-1,style);
len=length(style);
/* if a user-defined delimiter was specified blank it out */
if (pattern ne "\f") then
substr(line,found,length(pattern))=repeat(" ",length(pattern)-1);
/* derive the column pointer based on JUSTIFY parameter */
/* need to check if first character is a form feed and, if so,
then offset the column pointer by 1 so we do not delete (overwrite) the form feed */
ff=prxmatch("/\f/",substr(_infile_,1,1));
select (justify);
when ("R")
do;
col=(ls-len)+ff;
substr(line,col,len)=style;
end;
when ("L")
do;
col=1+ff;
substr(line,col,len)=style;
end;
when ("C")
do;
col=int((ls - len)/2)+ff;
substr(line,col,len)=style;
end;
otherwise
do; /* must be an explicit column number */
col=input(justify,8.);
substr(line,col,len)=style;
end;
end;
end;
varlen=lengthn(line);
put line $varying. varlen;
end;
stop;
run;
%quit:
%mend;
/******* END OF FILE *******/
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Need courses to help you with SAS Life Sciences Analytics Framework, SAS Health Cohort Builder, or other topics? Check out the Health and Life Sciences learning path for all of the offerings.