DATA Step, Macro, Functions and more

How to combine multiple rtf files in to one single file

Occasional Contributor
Posts: 7

How to combine multiple rtf files in to one single file

Hi Folks,


Recently I have came across a situation where I need to combine multiple .rft reports in a single rtf report. I have tried various papers on the internet but they are not relevant to some or other way.

Here are the challenges I'm facing -

1) the rtf reports are of different orientations like few of them are portrait and some are landscape. I need to maintain the orientation of each file in final report.

2) each report has page numbers in it so when they gets combined final reports should show new page numbers like Page 1 of XXX to and not older once.

3) when all rtf files should retain their titles and footnotes similar to that of individual report.


4) Page brake should work properly after each page/report.

Attaching code that I'm working on currently, hope I have explained it correctly.


options mprint mlogic symbolgen;
%macro m_combrtf(inpath= ,outpath= ,outfile= );
*Get rtf file names from a folder;
data rtffiles(keep=fileloc fnm);
length fref $8 fnm $80 fileloc $400;

rc = filename(fref, "&inpath");
if rc = 0 then did = dopen(fref);

dnum = dnum(did);

do i = 1 to dnum;
fnm = dread(did, i);
fid = mopen(did, fnm);
if fid > 0 and index(fnm,'rtf') then do;
fnm = strip(tranwrd(fnm,".rtf",""));
rc = dclose(did);

*Sort rtf files by tfl number;
data rtffiles(keep= fileloc ord tflno);
length tflno $200 ;
set rtffiles;

/* if index(fnm,"_t_") then ord = 1; */
/* else if index(fnm,"_f_") then ord = 2; */
/* else if index(fnm,"_l_") then ord = 3; */


tflno = strip(tranwrd(fnm,".rtf",""));

proc sort data = rtffiles; by ord tflno; run;

*Create macro variable which contains all rtf files;
proc sql noprint;
select quote(strip(fileloc)) into :rtffiles separated by ', '
from rtffiles;
filename rtffiles (&rtffiles); * create filename rtffiles ###;

proc sql noprint;
select fileloc into :fileloc from rtffiles(obs = 1);
data start;
length rtfcode $32767;
infile "&fileloc" lrecl = 32767 end = eof;
input ;
rtfcode = _infile_;

retain kpfl strfl;

if substr(rtfcode,1,6)='\sectd' then kpfl=1;
if index(rtfcode, "\paperw") and index(rtfcode,"\paperh") then delete;
if kpfl = . then output start;

*data rtf;
data rtf(keep = rtfcode);
length rtfcode $32767 tflnam $1000;
set rtffiles end=last;
retain kpfl ;

do until (eof);
infile rtffiles lrecl=32767 end=eof filevar=fileloc;

*Remove RTF header section and replce \sectd with \pard\sect\sectd;
if sof then kpfl=.;

if substr(rtfcode,1,6)='\sectd' then do;
if num = 1 then rtfcode=compress(tranwrd(rtfcode,'\pgnrestart\pgnstarts1'," "));
else rtfcode='\pard\sect'||compress(tranwrd(rtfcode,'\pgnrestart\pgnstarts1'," "));
/* if index(rtfcode,"Page ") then rtfcode="\trowd\trkeep\trqc\trgaph0"; */

/* if index(rtfcode,"\pard\sect\sectd\linex0\endnhere\sbknone") then rtfcode="\page\pard\sect\sectd\linex0\endnhere\sbknone"; */

*Remove RTF closing } except for last file;
if eof and not last then delete;

*output concatenated rtf;
if kpfl=1 then output rtf;


data _null_;
file "&outpath/&outfile..rtf" lrecl=32767 nopad;
set start rtf; *concatenate rtf header,document info, all rtf files;
put rtfcode;

%mend m_combrtf;

%let inpath=I:\temp\Summary;
%let outpath =I:\temp\output;
%let outfile = sample;

%m_combrtf(inpath = &inpath,
outpath = &outpath,
outfile = &outfile);

looking forward to get some help.

Thanks in advance.

- Nikhil

Super User
Posts: 23,771

Re: How to combine multiple rtf files in to one single file

Posted in reply to nikhilwagh

I don't believe SAS has the functionality to do this, but you can likely do it with a VBS script and then call or generate the VBS script from SAS.

Super User
Posts: 13,583

Re: How to combine multiple rtf files in to one single file

Posted in reply to nikhilwagh

If all the rtf files were created by SAS programs you might be able to combine the programs so that all the output is generated within one single ODS RTF "sandwich" changing options such as orientation with options statements as needed.

Otherwise there is so much stuff to wade through to find the bits you need to maintain or change (section break identifiers for page numbers for example) I think this would be an exercise in masochistic programming.



Ask a Question
Discussion stats
  • 2 replies
  • 3 in conversation