I am trying to combine multiple RTF files to one RTF file using the macro below. I ran the code below and creates blank RTF file and it is corrupted which could not be opened.
I found the macro on this link:
http://pharma-sas.com/a-sas-macro-to-combine-portrait-and-landscape-rtf-files-into-one-single-file/
Could anyone take the code below if any issue?
Or will be appreciated if any other macro is available.
Any help will be appreciated!
%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,'docx') then do;
fileloc="&inpath\"||left(trim(fnm));
fnm = strip(tranwrd(fnm,".docx",""));
output;
end;
end;
rc = dclose(did);
run;
*Sort rtf files by tfl number;
data rtffiles(keep= fileloc ord tflno);
length tflno $200 ;
set rtffiles;
if upcase(fnm)^="TOC" then do;
if substr(upcase(fnm),1,1)="T" then ord = 1;
else if substr(upcase(fnm),1,1)="F" then ord = 2;
else if substr(upcase(fnm),1,1)="L" then ord = 3;
end;
tflno = strip(tranwrd(fnm,".docx",""));
run;
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;
quit;
filename rtffiles (&rtffiles); * create filename rtffiles ###;
*Start;
proc sql noprint;
select fileloc into :fileloc from rtffiles(obs = 1);
quit;
/*%put &fileloc;*/
/*%put &rtffiles;*/
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;
run;
*data rtf;
data rtf(keep = rtfcode);
length rtfcode $32767 tflnam $1000;
set rtffiles end=last;
sof+1;
retain kpfl ;
do until (eof);
infile rtffiles lrecl=32767 end=eof filevar=fileloc;
input;
rtfcode=_infile_;
*Remove RTF header section and replce \sectd with \pard\sect\sectd;
if sof then kpfl=.;
if substr(rtfcode,1,6)='\sectd' then do;
num+1;
kpfl=1;
if num = 1 then rtfcode=compress(tranwrd(rtfcode,'\pgnrestart\pgnstarts1',''));
else rtfcode='\pard\sect'||compress(tranwrd(rtfcode,'\pgnrestart\pgnstarts1',''));
end;
*Remove RTF closing } except for last file;
if eof and not last then delete;
*output concatenated rtf;
if kpfl=1 then output rtf;
sof=0;
end;
run;
data _null_;
file "&outpath\&outfile..docx" lrecl=32767 nopad;
set start rtf; *concatenate rtf header,document info, all rtf files;
put rtfcode;
run;
%mend m_combrtf;
%m_combrtf(inpath = C:\Users\mh\Desktop\Macros\rtf files,
outpath = C:\Users\mh\Desktop\Macros\rtf files,
outfile = sample);
Hello,
I used the macro on one scenario and found the page number did not keep the original one. Instead pages is from 1 to N where N is the number of total pages of combined RTF file. The reason I suspect is that RTF code when opened in NotePad++ contains page information like this
\fldinst { PAGE }}}{ of }{\field{\*\fldinst { NUMPAGES }}}
. And this is probably due to fact that RTF code "^{pageof}" in used in proc report in SAS program to create the RTF file.
Can someone help?
I would suggest reading some of those files one-at-a-time into a data set and then looking at them. There is that pesky Length limit on the variable you are using RTFCODE. A long paragraph could well exceed that, which means that you have the "start paragraph" RTF information but miss the "end paragraph".
If you have images in the file that is another issue that you may not have an object fit completely into a single variable.
Personally I would use a word processing program to do such.
If you are creating the RTF output then place all of in a single ODS RTF/ODS RTF close; statement OR look into Proc Document as a way to combine things created by SAS in a single session.
One more question on the combining RTF files.
Is there an option to create TOC from the RTF files?
If you open your RTF in a word processing application like MS Word then the answer is yes. SAS ODS can't post-process existing RTFs but can create TOCs if creating an RTF from scratch. Here's an example.
Hello,
I used the macro on one scenario and found the page number did not keep the original one. Instead pages is from 1 to N where N is the number of total pages of combined RTF file. The reason I suspect is that RTF code when opened in NotePad++ contains page information like this
\fldinst { PAGE }}}{ of }{\field{\*\fldinst { NUMPAGES }}}
. And this is probably due to fact that RTF code "^{pageof}" in used in proc report in SAS program to create the RTF file.
Can someone help?
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.