Paper PO26 A Macro To Generate a Study Report Hany Aboutaleb, Biogen Idec, Cambridge, MA Abstract: Imagine that you are working on a study (project) and you would like to generate a report for the status of all or designated *.lst files in the input directory, and print number of pages designated of each table or listing in these directory. The SAS system and SAS/MACRO will help you process the studyrpt.sas macro to report the status of all designated *.lst files in the input directory, print one or more pages of each *.lst file, and create a batch file to run all the programs overnight. Introduction: This paper presents the studyrpt.sas macro, which is processed with the SAS system based upon the requirements of the macro as well as assignments defined by users. Overview: The studyrpt.sas macro will search all the *.lst files in specified directory to find the title or description of each *.lst file and count the output pages, and lines, find the creation date, last run date, and the file owner to produce a report file called studyrpt.lst. If the user set the macro variable prtpage=1 the studyrpt.sas macro will produce studydoc.lst file to include the first page of the *.lst files. This very useful option can be used by statisticians to produce table or listing shells for any new SAP that would include the location of the sample program for use by the statistical programmer. Finally the user can choose the creatbat parameter to optionally create a batch file that can be used to submit the entire program overnight or at the users leisure time. The macro program will create three optional reports in the directory specified by the OUTDIR parameter: Studtrpt.lst: A table including this is the output name, programmer name, creation date, last run date, maximum line per output, maximum page number, and the title (description). Studylst.lst: A file containing as many pages of each output document as specified by the user. Studylst.pdf: A file containing as many pages of each output document as specified by the user in Adobe Acrobat format. Method: Find a study you work on and need to have inventory or report about all the program files. Since any program will produce output with the extension *.lst, where * is the program file name then if we use *.lst files we will know a lot about our program files. Find the location of the original files and the location to store the studyrpt.sas macro output files. The user has the choice to add all the *.lst to one file for easy printing, or only the first page of each of *.lst to one file for use by statisticians to produce shells for any new SAP. The user has the choice to name the inventory or report output file. Macro inputs: The studyrpt.sas macro will need the following parameters: INDIR: Directory name, containing the *.lst files to be reported, where * is the files name. Example: indir=c:\iss\tabfig\dev OUTDIR: Directory name containing the reported files *.lst files are stored. Example: outdir=c:\iss\report INDEXF: Name of the *.lst files in the directory (default: blank). Example: indexf=eff_shft.lst ms_shft.lst cp_he.lst Or: indexf=cp*.lst (all the files beginning with cp) PRTPAGE: Number of pages to display for each file (default: 1)
Example: prtpage=1 to any integer Or: prtpage=no (No pages are printed. Only need report) Or: prtpage=all (All pages are printed) REPORT: If report file is requested (default: Yes) Example: report=no TITLE: The Report title Example: title= List Of All Output Files For Study XXX CREATBAT: If a batch file is requested to run all the program with one file Example: creatbat=no (default: YES) Helpful Hints: 1. Make sure your file have the extension *.lst. 2. Make sure the file you will report follows the standard output. If not do not worry the program will supply you with reports file. 3. Review out the report files in the outdir parameter (i.e. studyrpt.lst, studylst.lst, studylst.rtf). 4. Make sure you correct your *.lst files (i.e. all your format output files consistent with other output files) from the reports file. 5. Document your work for future reference (i.e. Working in two projects). 6. If you like to print all of your *.lst files choose prtpage=all so you have one file to send to the printer. 7. The macro assumes that there is a line between title and the body of output and another line between the body and the footnote. 8. You can use the debug parameter to debug the macro to check for error in the SAS output log file. 9. The macro will create a batch file to run all off SAS programs in the designated input directory. You can use Windows Scheduled tasks to schedule a task to run the batch file to run all the programs over night. 10. The macro will generate Acrobat Reader pdf format file to send it to others to review your outputworking project. CONCLUSION: A great deal of information and documentation can be gained by using this macro to report the status of working study in the input directory, inventory all the work done, and create a history of the study for future reference. TRADEMARKS: SAS is a registered trademark of the SAS Institute, Inc., in the USA and in other countries. Windows is a registered trademark of the Microsoft Corporation. Acknowledgment: The author would like to thank Ms. Tina Casteris for her review and valuable comments. REFERENCES: [1] SAS Institute, Inc., Cary, NC, SAS Guide to Macro Processing: Version 6, Second Edition. [2] SAS Institute, Inc., Cary, NC, SAS Procedures Guide: Version 6, Third Edition. [3] SAS Institute, Inc., Cary, NC, SAS Language Reference: Version 6, First Edition. CONTACT: Hany Aboutaleb Biogen Idec. 14 Cambridge Center Cambridge MA 02142 Tele. #: (617) 914-7125 Fax: (617) 679-3280 Internet: hany.aboutaleb@biogenidec.com
The Program: ----------------------------- Program ID: Studyrpt.sas Source pgm: None Description: Report the status of all or designated lst files in the input directory (studyrpt.lst) and print the number of pages designated in the parameter prtpage= of each table in these files (trialrpt.lst) Created: July 2003 Contact persons: Hany Aboutaleb (Biogen, 7125) Input parameters: indir = input directory where the lst files are located indexf= names of the lst files out of which pages are printed and reported (default: all lst files in the directory (blank)) example: fnames=eff3.lst eff4.lst lbrun.lst, or: fnames=eff*.lst, (all lst files beginning with eff) outdir= output directory for the output files, trialrpt.lst and trialrpt.doc prtpage= number of pages to display for each table (default: 1) options: 1 to any integer No (No pages are printed. Only need report) All (All pages are printed) report= if report file is requested (default: Yes) option: No creatbat= if a batch file is requested to run all the program with one file (default: YES) option: No debug= if the user request to debug the log (default: NO) option: Yes Note: Include formatprt.sas program to format the programmer name Modification log: ---------------- Date Reason Person ---- ------ ------ ------------------------------- %* Set SAS options; Options nodate nonumber nobyline nomprint fmterr ls=156 ps=52 nosource Nomlogic nosymbolgen nomprint nomlogic nomacrogen compress=no formchar= " + ---+= -/\<>*" ; %* To format the user names with fancy format; %include 'C:\bg12\formatprt.sas'; %macro Studyrpt(indir=, indexf=, outdir=, prtpage=1, title=, /* Report title */ report=yes, creatbat=yes, debug=no) ; %if %upcase(&debug)=yes %Then options macrogen symbolgen mlogic mprint; %local parmerr del dir; %put; %put <> BiogenIdec SYSTEM MACRO Studyrpt: Report the status of all or designated lst files in the input directory; %put; Determine the OS specific directory command %if %scan(&sysscp,1) = HP %then %let sep=/; %*let dir=%str(ls -x1); %*let del=rm; %*let username =%sysget(logname); %else options noxwait xsync; %let sep=\; %*let dir=%str(dir/b); %*let del=del;
Prepare macro variables ----------------------------------------------------------------------; %let indir=%upcase(&indir); %let outdir=%upcase(&outdir); %let creatbat=%upcase(&creatbat); %let report=%upcase(&report); %let linesize = %sysfunc(getoption(linesize)) ; %let parmerr=0; /** GET PHYSICAL DIRECTORY OF SAS WORK SPACE **/ %let workdir=%sysfunc(pathname(work)); Define the page break character ----------------------------------------------------------------------; %let cc=12; %let under = %qsysfunc(repeat(_,70)) ; %let underh= %str( )%qsysfunc(repeat(_,70)) ; %let empty = %qsysfunc(repeat(%str( ),70)) ; Break fnames parameter, if not empty %let nfnm=0; %***Number of list file in the input directory**; %if %upcase(&prtpage)=no %then %let hpage=no; %let prtpage=0; %else %if %upcase(&prtpage)=all %then %let hpage=all; %let prtpage=6868; %else %if %index(0123456789,%substr(&prtpage,1,1)) ne 0 %then %let hpage=&prtpage; Validate parameters %* Test if the &indir and &outdir exist and give warnings if not; %if %sysfunc(fileexist(&indir))=0 %then %put ERROR: Directory &indir does not exist ***; %let parmerr=1; %if %sysfunc(fileexist(&outdir))=0 %then %put ERROR: Directory &outdir does not exist ***; %let parmerr=1; %* Test if the prtpage= parameter is a positive integer; %do h=1 %to %length(&prtpage); %if %index(0123456789,%substr(&prtpage,&h,1))=0 %then %put ERROR: Check your prtpage= parameter. It must be a positive integer, a No or an All ***; %let parmerr=1; %* Test if the creatbat= parameter is filled out correctly; %if &creatbat^=yes and &creatbat^=no %then %put ERROR: Check your creatbat= parameter. It must be either Yes or No ***; %let parmerr=1; %* Test if the report= parameter is filled out correctly; %if &report^=yes and &report^=no %then %put ERROR: Check your report= parameter. It must be either Yes or No ***; %let parmerr=1; Quit the program if you have any wrong Input parameters - %if (&parmerr) %then %goto quit;
Delete the existing temporary and output files if there are any - %if %sysfunc(fileexist(&outdir&sep.studylst.lst)) %then filename delfil pipe "del &outdir&sep.studylst.lst" ; infile delfil lrecl=200 pad; input delf $200.; %if %sysfunc(fileexist(&outdir&sep.studylst.pdf)) %then filename delfil pipe "del &outdir&sep.studylst.pdf" ; infile delfil lrecl=200 pad; input delf $200.; %if %sysfunc(fileexist(&outdir&sep.studyrpt.lst)) %then filename delfil pipe "del &outdir&sep.studyrpt.lst" ; infile delfil lrecl=200 pad; input delf $200.; %if %sysfunc(fileexist(&outdir&sep.runprog.bat)) %then filename delfil pipe "del &outdir&sep.runprog.bat" ; infile delfil lrecl=200 pad; input delf $200.; Count the file and create macro variables for those files - %if %length(&indexf)>0 %then %let count=1; %let fnm&count=%scan(&fnames,&count,%str( )); %do %while(%length(&&fn&count)>0); %let count=%eval(&count+1); %let fnm&count=%scan(&fnames,&count,%str( )); %let nfnm=%eval(&count-1); %* Read input directory ; %else %if %length(&indexf)=<1 %then filename all_list pipe "dir &indir\*.lst/q/tc"; length text $200; infile all_list lrecl=200 pad missover; input text 1-200; text=lowcase(text); retain i 0; i=i+1; call symput('text' trim(left(put(i,8.))),trim(left(text))); call symput('ntext',trim(left(put(i,8.)))); %let j=0; %do i=1 %to &ntext; %if %index(%bquote(%upcase(&&text&i)),.lst)>0 %then %let j=%eval(&j+1); %let pro&j=%substr(%bquote(&&text&i), %index(%bquote(&&text&i),%scan(%bquote(&&text&i),4,%str( )))); %let pro&j=%substr(%bquote(&&pro&j),1,%index(%bquote(%upcase(&&pro&j)),%str( ))-1); %let pro&j=%scan(%bquote(&&pro&j),2,'\'); %let cdt&j=%substr(%bquote(&&text&i), %index(%bquote(&&text&i),%scan(%bquote(&&text&i),1,%str( )))); %let cdt&j=%substr(%bquote(&&cdt&j),1,%index(%bquote(%upcase(&&cdt&j)),%str( ))-1); %let fnm&j=%substr(%bquote(&&text&i), %index(%bquote(&&text&i),%scan(%bquote(&&text&i),5,%str( )))); %let fnm&j=%substr(%bquote(&&fnm&j),1,%index(%bquote(%upcase(&&fnm&j)),.lst)-1); %let nfnm=&j;
%if %upcase(&debug)=yes %Then %put NFNM=&nfnm; Read each file to determine report contained %if &nfnm>0 %then %do x=1 %to &nfnm; %let fname=%unquote(&&fnm&x); filename lists "&indir&sep&&fnm&x...lst"; Data _null_; infile lists truncover ; length line $25000; input line $char.; retain cnt 0; outf='f' trim(left(put(&x,8.))); call symput('outf' trim(left(put(&x,8.))),trim(left(outf))); if index(line,"&under") then stop; else if index(line,"&empty") then if index(trim(upcase(line)),'page') eq 0 then cnt=cnt+1; call symput( 'tit' left(cnt),trim(left(line))); call symput('ntit',trim(left(put(cnt,8.)))); %if %upcase(&debug)=yes %Then %put _user_; %let tlist=; %do i=1 %to %eval(&ntit); %if %length(&tlist)^=0 %then %if %index((%upcase(&tlist)),obs) %then %let tlist='check this program'; %else %let tlist=&tlist %bquote(&&tit&i); %else %let tlist=%bquote(&&tit&i); %if %upcase(&debug)=yes %Then %put tlist=&&tlist; data _null_ ; length buffer $200 ; infile lists lrecl=200 pad missover end=eof; input buffer $ 1-200; retain allpgno 0 line_num flag 1 progdate ; if _n_=1 then first=&cc; else first=input(substr(buffer,1,1),bits8.); if first=&cc then if flag then flag=0; allpgno=allpgno+1; line_num=_n_; if index(upcase(buffer),'date:') ne 0 then progdate=compress(substr(buffer,(index(upcase(buffer),'date:')+5),12)); if eof then call symput('progdt',trim(progdate)); call symput('linex',trim(left(put(line_num,8.)))); call symput('pagex',trim(left(put(allpgno,8.)))); data &&outf&x(keep=buffer); length buffer $25000; infile lists lrecl=200 pad missover length=len; input buffer $varying200. len; retain prtpage 0 flag 1 ;
if _n_=1 then first=&cc; else first=input(substr(buffer,1,1),bits8.);; if first=&cc then if flag then flag=0; prtpage=prtpage+1; if prtpage<=&pagex and prtpage<=&prtpage; data y&x; length filen $50 tit $25000; %if %length(&&fnm&x) ne 0 %then filen=compress("&&fnm&x");; program=put("&&pro&x",$prog.); creat=input("&&cdt&x",mmddyy10.); tit=trim(left("&&tlist")); linenum="&linex"; %if %length(&progdt) ne 0 %then progdate=left("&progdt");; pagemax="&pagex"; format creat date9.; This is where we loop thru to SET the data sets. data report; set %do x = 1 %to &nfnm; y&x ; data report; set report; retain lines 0 pagenum 0 ; where tit ne ''; if _n_=1 then lines = 0; pagenum + 1; lines + 1; if lines >=13 then lines = 1 ; pagenum + 1 ; end ; proc sql noprint; select left(put(max(pagenum),3.)) into: totpages from report; quit; Generate output inventory file filename outftb "&outdir&sep.studyrpt.lst"; proc printto print=outftb new; title1 ' '; title2 " &title on &sysdate &systime"; title3 " Directory: %upcase(&indir)"; title4 "Page #byval(pagenum) of &totpages"; footnote; proc report data=report split='\' center missing nowindows headline spacing=1 ls=158 ps=55; by pagenum ; where tit ne ''; columns filen program creat progdate linenum pagemax tit; define filen/order order=data flow width=20 "OUTPUT NAME"; define program/order order=data flow width=15 "PROGRAMMER NAME"; define creat/order order=data format=date9. width=9 'CREATION DATE'; define progdate/order order=data width=9 'LAST RUN DATE'; define linenum/order order=data width=4 'MAX LINE NO.'; define pagemax/order order=data width=4 'MAX PAGE NO.'; define tit/width=75 flow 'DESCRIPTION '; break after progdate/skip; compute after;* _page_; txt1="note 1: &nfnm LST FILES HAVE BEEN PROCESSED IN THE DIRECTORY."; %if &prtpage>0 %then txt2="note 2: &hpage PAGE OF EACH TABLE IS PRINTED INTO THE FILE STUDYRPT.LST.";; txt4="source: Studyrpt.sas"; line @1 &linesize*'_' ; line @1 txt1 $&linesize..; line @1 txt4 $50. ; endcomp;
proc printto; title1; title2; title3; title4; Generate output file to Print designated pages to the file studylst.lst %if &prtpage>0 %then %do x=1 %to &nfnm; set &&outf&x; file "&outdir&sep.studylst.lst" mod; len=200; if _n_=1 then buffer='0c'x buffer; put buffer $varying200. len; ------------ Generate PDF output format file to Print designated pages to the file studylst.pdf ------------ ods pdf close; %if &prtpage>0 %then ods pdf file="studylst.pdf" nopdfnote NOTOC; *ods printer printer="acrobat Distiller" file="&outdir&sep.studylst.pdf"; %do x=1 %to &nfnm; set &&outf&x; file print; len=200; if _n_=1 then buffer='0c'x buffer; put buffer $varying200. len; *ods printer close; ods pdf close; Generate batch file to run designated programs %if &creatbat=yes %then data x; file "&outdir&sep.runprog.bat"; put 'path=%path%;"c:\program Files\SAS Institute\SAS\V8"'; %do y=1 %to &nfnm; put 'sas ' "&indir\&&fnm&y...sas" ' -nostatuswin -nologo'; %if %upcase(&debug)=yes %Then %put _user_; ------------ Quit the program in case of any parameter erro ------------ %quit: %if (&parmerr) %then %put ERROR: Macro Studyrpt stopped because of error. **** ; %mend Studyrpt; ------------ Sample macro call ------------ %Studyrpt( indir=m:\bg12psoriasis\wp-1201\csr_2004\dev, indexf=, outdir=c:\personal\2004_paper\, prtpage=1, title=list Of All Output Files For Study XXX, report=yes, creatbat=yes, debug=no);
Sample output Files: Studylst.lst Listing of Adverse Events for Patients Who Discontinued Study Due to an Adverse Event Page 1 of 2 Onset Adverse Event Relationship Day of to Treatment Center- Event Day of Investigator Preferred Severity Study Drug Group Patient (a) Withdrawal Term (b) Term (MedDRA) (b) (b) (a) *=Adverse Event was serious. (b) Investigator assessment. SOURCE: \ISS\Study XXX\AEDISC_LIST.SAS DATE: 08NOV2004 Studylst.pdf Listing of Adverse Events for Patients Who Discontinued Study Due to an Adverse Event Page 1 of 2 Onset Adverse Event Relationship Day of to Treatment Center- Event Day of Investigator Preferred Severity Study Drug Group Patient (a) Withdrawal Term (b) Term (MedDRA) (b) (b) (a) *=Adverse Event was serious. (b) Investigator assessment. SOURCE: \ISS\Study XXX\AEDISC_LIST.SAS DATE: 08NOV2004
Studyrpt.lst List Of All Output Files For Study XXX on 16DEC04 11:50 Directory: c:\iss\study xxx Page 1 of 7 MAX MAX CREATION LAST RUN LINE PAGE OUTPUT NAME PROGRAMMER NAME DATE DATE NO. NO. DESCRIPTION aedisc_list Aboutaleb, Hany 16SEP2004 08NOV2004 76 2 Listing of Adverse Events for Patients Who Discontinued Study Due to an Adverse Event aeglossary Aboutaleb, Hany 16SEP2004 08NOV2004 38 1 Adverse Event Glossary aept8 Aboutaleb, Hany 16SEP2004 08NOV2004 56 1 Incidence of Treatment-Emergent Adverse Events by Preferred Term With an Incidence of 8% or More NOTE 1: 76 LST FILES HAVE BEEN PROCESSED IN THE DIRECTORY. Source: Studyrpt.sas Runprog.bat path=%path%;"c:\program Files\SAS Institute\SAS\V8" sas C:\ISS\Study xxx\aedisc_list.sas -nostatuswin -nologo sas C:\ISS\Study XXX\aeglossary.sas -nostatuswin -nologo