SAS Tip of the Month
I received a question from a reader on how to concatenate many individual outputs into a single file. This is a very interesting question and is not as simple as it may seem.
The first question that must be asked is whether the page numbers on the individual outputs should remain on the combined document, e.g. for the first file it may have page 1 of 4, on the second file it may have page 1 of 876. The reason for asking this question first is that the output file does not have a concept of "pages" and sets the count after the entire document is loaded into word (ever have the situation where when you open a file and it says Page 1 of 3 but you know there are over 100 pages?).
If it is the case that each documents Page x of y values be preserved then the best approach is to create PDF files of each individual output and use a free tool such as PDFTK to combine the individual PDFs into one document.
If however you want to create a "master document" with a unique page number for each page, you have a couple of ways of doing this.
If you use the same font and color palette and the pages all have the same margins, it is possible to use the following SAS macro:
%let rptdir=%str(G:\TEMP); *Change this to the directory you are dealing with; *Bring in every RTF file; data _allouts0; attrib _txt length=$1024 informat=$char1024. format=$char1024. _fn length=$1024 _myinfile length=$1024 _ln length=8 _myinline length=8; infile "&rptdir.\*.rtf" lrecl=1024 filename=_myinfile line=_myinline length=len; input _txt $varying1024. len; _fn=scan(strip(_myinfile),-1,'\'); _ln=_n_; run; *Sort by file name and line number; proc sort data=_allouts0; by _fn _ln; run; *Do some manipulation; data _allouts1 _printlist0 (keep=_fn); length _flg 8; *1=Use in combined file; retain _flg; set _alllogs0 end=eof; by _fn _ln; if first._fn then do; output _printlist0; *List of files read; if _ln=1 then _flg=1; *Knows it is a RTF; else _flg=0; end; else if _txt=:'\widowctrl\' then _flg=1; if last._fn then do; if eof then _txt='\pard}'; *Close file; else _txt='\pard\sect\sectd\sbkpage'; *Add page break and ready for another file; end; output _alllogs1; *Output to combined file; run; *Create COMBINED.RTF document; data _null_; file “&rptdir.\combined.rtf” lrecl=1024; set _allouts1; where _flg=1; *Select only lines we need; put _txt; run; *Print list of outputs created; proc print data=_printlist0; var _fn; label _fn='Output Name'; run;
There is one other dependency - this code will only work with files created using ODS RTF in SAS 9.2, all of them using a single template (however the code can be adapted for 9.3 and above if needed) as it exploits the structured way SAS creates the RTF file with ODS. Note also that the output file created is in the same directory as the individual files and is called COMBINED.RTF.
Another way that you can combine the documents into one is to create a Master document in word (you only have to create this once) and it will update as documents are updated. This has the advantage of storing documents with different fonts, i.e. some containing Times Roman, some containing Arial and others containing Courier New. SAS is not required and Word is very good at handling Master documents. Unfortunately I have not found a way to combine the documents using a Visual Basic macro that can be imbedded in Microsoft Word.
Hope this was useful.
Updated February 2, 2015