0% found this document useful (0 votes)
118 views

SAS PGM File Processing

This macro takes a program file and output file as input, executes the program to generate output, and post-processes the output to insert page numbers. It handles operating system specific file handling, reads the output to determine the current page, inserts the page text, and writes the output back with page numbers.

Uploaded by

Rammurthy
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
118 views

SAS PGM File Processing

This macro takes a program file and output file as input, executes the program to generate output, and post-processes the output to insert page numbers. It handles operating system specific file handling, reads the output to determine the current page, inserts the page text, and writes the output back with page numbers.

Uploaded by

Rammurthy
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 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;

*/
*/

You might also like