BookmarkSubscribeRSS Feed
krish_saptak
Calcite | Level 5
I want to create Page X of Y in PROC Report in UNIX with only listing destination active. I dont want to send output to html or pdf or rtf destination.
4 REPLIES 4
Doc_Duke
Rhodochrosite | Level 12
You can do it if you really want to, but it is a pain. Because SAS is designed to handle arbitrarily large data problems, it doesn't store things like the total number of pages; that generally requires creating the entire report before printing any of it.

Which is what you will have to do: Run PROC REPORT once, capture the number of pages printed, store it in a macro variable, reset the page count to 0, add the macro variable to the title or footer, and, finally, re-run the REPORT. Ugh.
Cynthia_sas
SAS Super FREQ
Hi:
My .02...as Doc says...UGH -- the method of generating Page X of Y page numbers in LISTING is not wonderful.

However, the totally wonderful ODS developers have implemented Page X of Y page numbering for RTF and PDF output (not LISTING) using ODS ESCAPECHAR functionality...through the use of {PAGEOF} for ODS RTF and the use of {THISPAGE} and {LASTPAGE} for ODS PDF -and- ODS RTF.

There have been many previous forum postings on how to product Page X of Y page numbering using ODS destinations other than LISTING and most of my Pharma and CRO students use ODS ESCAPECHAR routinely to achieve this kind of page numbering.

cynthia
RolandRB
Calcite | Level 5
See my Spectre (Clinical) reporting system on the web. It does this.
ScottBass
Rhodochrosite | Level 12

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 *******/


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

Health and Life Sciences Learning

 

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.

LEARN MORE

Discussion stats
  • 4 replies
  • 3507 views
  • 0 likes
  • 5 in conversation