/*============================================================================== | PROGRAM NAME: PAGENUMS.SAS | | PROGRAMMER: Lara Guttadauro | | SOFTWARE AND VERSION#: SAS 8.02 | | PURPOSE: Create macro that will determine page breaks. | ==============================================================================*/ ** NOTE: A character needs to be included in the variables that will wrap that will identify **; ** when the text will wrap to the next line. **; %macro PAGENUMS (INDATA=, /* Name of input data set */ OUTDATA=, /* Name of output data set */ UNIQUE=, /* Identifies unique observations */ WRAPVARS=, /* Variables that can potentially have wrapped text */ IDWRAP=, /* Identifier for text going to next line */ KEEPONPG=, /* Var that ids what is trying to be kept together on 1 page */ KEEPID=, /* Variables needed to merge by the KEEPONPG variable */ XTRFIRST=, /* # of additional lines needed for first obs for KEEPONPG var */ SKIPLINE=, /* # of lines to be skipped between unique observations */ LINESAVL=, /* # of lines available per page - excluding header & footer */ FORCEBRK= /* Var that needs to be forced to break on a new page */ ); %** Sort the incoming data set **; proc sort data=&INDATA out=MDATA1; by &UNIQUE; run; %** Count the maximum number of lines per observation **; data MDATA2; set MDATA1; by &UNIQUE; %** Count the number of wraps per line **; %if &WRAPVARS ne %then %do; array WRAP{*} &WRAPVARS; MAXLINES=0; do i=1 to dim(WRAP); MAXLINES=max(MAXLINES, length(compress(WRAP{i}))-length(compress(WRAP{i}," &IDWRAP"))+1); end; %end; %else %do; MAXLINES=1; %end; %** Add the line skips and the additional lines for the first KEEPONPG variable **; if first.&KEEPONPG then MAXLINES=MAXLINES+&SKIPLINE+&XTRFIRST; else MAXLINES=MAXLINES+&SKIPLINE; run; %** Count the number of lines needed for each KEEPONPG variable **; data MDATA3 (keep=&KEEPID KEEPLINE); set MDATA2; by &UNIQUE; retain KEEPLINE 0; if first.&KEEPONPG then KEEPLINE=MAXLINES; else KEEPLINE=KEEPLINE+MAXLINES; if last.&KEEPONPG; run; %** Merge the maximum number of lines per KEEPONPG variable onto rest of data **; data &OUTDATA (drop=LINEONPG CHECKFIT KEEPLINE MAXLINES PAGENEED); merge MDATA2 MDATA3; by &KEEPID; PAGENEED=ceil(KEEPLINE/&LINESAVL); %** Identify the page breaks **; retain PAGENO 1 LINEONPG 0 CHECKFIT; %if &FORCEBRK ne %then %do; ** If it is a FORCED BREAK (and not the first one), then go to next page **; if first.&FORCEBRK and _n_ ne 1 then do; PAGENO=PAGENO+1; LINEONPG=0; end; %end; %** Deal with KEEPONPG variable that only need one page **; if PAGENEED=1 then do; %** Check to see if KEEPONPG variable will fit on the page **; if first.&KEEPONPG then CHECKFIT=LINEONPG+KEEPLINE; %** YES - Whole KEEPONPG variable fits **; if CHECKFIT<=&LINESAVL then LINEONPG=LINEONPG+MAXLINES; %** NO - KEEPONPG variable will not fit **; if CHECKFIT>&LINESAVL then do; PAGENO=PAGENO+1; LINEONPG=MAXLINES; CHECKFIT=KEEPLINE; end; end; %** Deal with KEEPONPG variable that need more than one page **; if PAGENEED>1 then do; %** Check to see if UNIQUE variable will fit on the page **; CHECKFIT=LINEONPG+MAXLINES; %** YES - UNIQUE variable fits **; if CHECKFIT<=&LINESAVL then LINEONPG=LINEONPG+MAXLINES; %** NO - UNIQUE variable does not fit **; if CHECKFIT>&LINESAVL then do; PAGENO=PAGENO+1; LINEONPG=&XTRFIRST+MAXLINES; CHECKFIT=&XTRFIRST+MAXLINES; end; end; run; %mend PAGENUMS;