BookmarkSubscribeRSS Feed
Obsidian | Level 7

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

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

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.




Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.


Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 3 in conversation