Sunteți pe pagina 1din 7

%macro pageof(

/* Specify a file or fileref.

*/

/* Physical file names should be in quotes.


/* Filerefs/DDnames should not be in quotes.

*/
*/

pgm
=,
output =,

/* program file to execute


/* output file

/* placement of page number text on print page


just =
topbot =
psadd =
pagetext
cc
=

center,
/* left, center, or right
bottom,
/* top or bottom
2,
/* number of lines from text
= Page PAGEX of PAGEN, /* page number text
!
/* character to use as form feed

*/
*/
*/
*/
*/
*/
*/
*/

);
/* Initialize global system options.

*/

options number pageno=1 formdlim="&cc";


/* Initialize column to begin reading
/* original output.

*/
*/

%let strt_col = 1;
/* Initialize system-specific files and options. */
/* Determine the operating system with automatic */
/* macro variable SYSSCP.
*/
%if &sysscp=HP 800 %then
%do;
filename temp1 'potemp1.txt';
filename temp2 'potemp2.txt';
%end;
%else
%if &sysscp=VMS or &sysscp=OS2 or &sysscp=WIN %then
%do;
/* Do not require the user to press enter to */
/* leave the X window brought up by an X
*/
/* statement.
*/
options noxwait;
filename temp1 'potemp1.txt';
filename temp2 'potemp2.txt';
%end;
%else
%if &sysscp=CMS %then
%do;

filename temp1 'potemp1 txt a';


filename temp2 'potemp2 txt a';
%let strt_col = %eval(&strt_col + 1);
%let psadd=%eval(&psadd + 2);
%end;
%else
%if &sysscp=OS %then
%do;
filename temp1 '&temp';
/* Cause a short time delay between
*/
/* allocations because the time value is used */
/* in the name of the temporary file.
*/
data _null_;
run;
filename temp2 '&temp';
%let strt_col = %eval(&strt_col + 1);
%let psadd=%eval(&psadd + 2);
%end;
/* Execute the user's program in a PRINTTO block */
/* to save the output for post processing.
*/
proc printto print=temp1 new;
%include &pgm;
proc printto;
run;
/* Set page eject back to the system default.

*/

options formdlim='';
/*
/*
/*
/*

Put the original LINESIZE= and PAGESIZE=


settings into macro variables for later use
by reading SASHELP.VOPTION and writing the
values into macro variables.

*/
*/
*/
*/

data _null_;
set sashelp.voption;
where optname='LINESIZE' or optname='PAGESIZE';
call symput(optname,setting);
run;
/* Route the output of a dummy PROC PRINT to the */
/* TEMP2 file to generate the next page number. */
proc printto print=temp2 new;

data _temp_;
x=1;
proc print;
options number;
proc printto;
run;
/* Read the first line of output to get the page */
/* number. Store the number in a macro variable. */
data _null_;
infile temp2 truncover;
input record $ 1-200;
call symput('lastpage',trim(left(put(input(reverse
(scan(reverse(record),1)),6.)-1,6.))));
stop;
run;
/* Adjust options.

*/

%let pagesize=%eval(&pagesize+&psadd);
options nodate nonumber ps=&pagesize;
/* Use macro logic to parse the text parameter
/* and create the appropriate DATA step syntax
/* to print the page number.

*/
*/
*/

/* Find the position of PAGEX in the string.

*/

%let xpos=%index(%nrbquote(&pagetext),PAGEX);
/* If PAGEX occurs at the beginning of the
/* string, substitute this:

*/
*/

%if &xpos=1 %then


%let maketext = trim(left(put(pagenum,6.))) ||
"%substr(&pagetext,6)";
%else
%do;
/* If PAGEX is not at the beginning of the
/* string, substitute this:

*/
*/

%let maketext = "%substr(&pagetext,1,&xpos-1)" ||


trim(left(put(pagenum,6.)));
/* If PAGEX is not at the end of the string, add */
/* the remainder of the string.
*/
%if &xpos+4 le %length(&pagetext) %then
%let maketext = &maketext ||
"%substr(&pagetext,&xpos+5)";
%end;
/* Find the position of PAGEN.

*/

%let npos = %index(&maketext,PAGEN);


/* Substitute the total page count for PAGEN.

*/

%let maketext = %qsubstr(&maketext,1,


&npos-1)%nrstr(&lastpage)%qsubstr(&maketext,
&npos+5);
/*
/*
/*
/*
/*
/*

Read in TEMP1 and check for carriage control. */


Each time carriage control is encountered,
*/
read the current page number and then rewrite */
it at the desired location along with the
*/
total page count. Otherwise write the original*/
record.
*/

data _null_;
infile temp1 length=len truncover eof=eof noprint;
length text $ 200 next_cc $ 10;
retain pagenum;
/* Use the option NOTITLES. Since the input
/* file already has titles, do not repeat
/* printing of the titles.

*/
*/
*/

file &output notitles n=ps line=cur_line


/* If the user does not want output to go to */
/* the OUTPUT window, then use these options: */
/* PRINT and OLD.
*/
%if "%upcase(&output)" ne "PRINT" %then %do;
print old
%end;
;
/* Read a line of output. Scan for carriage
/* control and page number.

*/
*/

input @&strt_col record $varying200. len ;


/* If the line begins with carriage control, */
/* read the page number and replace it
*/
/* with blanks.
*/
if substr(record,2,10) eq
"&cc&cc&cc&cc&cc&cc&cc&cc&cc&cc" then
do;
/* Page eject detected. */
/* If the line is a carriage control
*/
/* line, read in the next (blank) line. */
input;
/* Read a line of output.
input @&strt_col record $varying200. len ;

*/

/* Scan for the current page number.

*/

pagenum=reverse(scan(reverse(record),1));
/*
/*
/*
/*
/*
/*
/*
/*
/*

Replace the original page number with*/


blanks because the page number will */
be printed in a different place.
*/
To do this, use the SUBSTR function */
on the left side of the equal sign. */
In this case SUBSTR works as a text */
replacement function. So, replace the*/
text from the first character of the */
page number to the end of the line. */

substr(record,
length(trim(record)) - length(pagenum) +1,
length(pagenum)) = ' ';
/*
/*
/*
/*

If user requests page number text at


top of page and requests to increase
page size, then add &PSADD blank
lines to the top of each page.

*/
*/
*/
*/

if (&psadd gt 0) and
("%upcase(%substr(&topbot,1,1))" eq "T")
then
do; /* Add blank lines to top of page. */
do line_num = 1 to %eval(&psadd);
put #line_num @1 ' ';
end;
end; /* Add blank lines to top of page. */
end;

/* Page eject detected. */

/* Write the record back to the file.

*/

if _n_ gt 1 then
do;
/* Write regular record back to file.*/
put @1 record $varying200. len @;
if cur_line lt &pagesize then put;
end;
/*
/*
/*
/*

/* Write regular record back to file.*/

Look ahead to the next input line to


determine if it has a carriage control
character. If it does, write the page
number on the current page.

*/
*/
*/
*/

input @2 next_cc $10. @@;


/* If look-ahead detects a page eject, write */
/* page number text.
*/

if next_cc eq "&cc&cc&cc&cc&cc&cc&cc&cc&cc&cc"
and pagenum ge 1 then
do;
/* Write page number text. */
/* Use macro logic to set the line and
*/
/* column placement for the page-numbering */
/* text.
*/
/* Place text at top or bottom of the page.*/
/* If T, place text on line 1.
*/
%if %substr(%upcase(&topbot),1,1) eq T %then
%let line=1;
/* Otherwise place text on last line
/* (same as page size).

*/
*/

%else
%let line=&pagesize;
/* Place text at left, center, or right.

*/

%if %substr(%upcase(&just),1,1) eq L %then


%let col=1;
%else
%if %substr(%upcase(&just),1,1) eq C %then
%let col=(floor((&linesize-length(text))/2));
%else
%if %substr(%upcase(&just),1,1) eq R %then
%let col=(&linesize-length(text)-1);
/* Concatenate text for page numbering.

*/

text=%unquote(&maketext);
put #&line @&col text;
put _page_;
end;
return;

/* Write page number text. */


/* End of main part of DATA step */

/* To avoid a lost card problem, jump to end */


/* of data when eof is read in input file.
*/
eof:
/* Concatenate text for page numbering.

*/

text=%unquote(&maketext);
put #&line @&col text;
run;

/* End of entire DATA step */

/* Delete temporary system files.


%if &sysscp=HP 800 %then

*/

%do;
X 'rm potemp1.txt potemp2.txt';
%end;
%else %if &sysscp=OS2 or &sysscp=WIN %then
%do;
X 'del potemp1.txt';
X 'del potemp2.txt';
%end;
%else %if &sysscp=VMS %then
%do;
X 'del potemp1.txt;*';
X 'del potemp2.txt;*';
%end;
%else %if &sysscp=CMS %then
%do;
X 'erase potemp1 txt a';
X 'erase potemp2 txt a';
%end;
/* No action is needed for &SYSSCP=OS. Files are */
/* deleted automatically when the SAS session
*/
/* ends.
*/
/* Set the page size and page number to the
/* original settings.
options ps=%eval(&pagesize-&psadd)
pageno=%eval(&lastpage+1);
%mend pageof;

*/
*/

S-ar putea să vă placă și