BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Semie
Fluorite | Level 6

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);

1 ACCEPTED SOLUTION

Accepted Solutions
jsbyxws
Obsidian | Level 7

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?

View solution in original post

5 REPLIES 5
ballardw
Super User

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.

Semie
Fluorite | Level 6
Thank you so much for the suggestion.

One of the files had image which caused the file to be corrupted and now working great.
Semie
Fluorite | Level 6

One more question on the combining RTF files.

 

Is there an option to create TOC from the RTF files?

SASKiwi
PROC Star

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.

 

jsbyxws
Obsidian | Level 7

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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 5 replies
  • 4102 views
  • 1 like
  • 4 in conversation