=========================================================================
Date: Fri, 19 Jul 2002 10:38:35 -0400
Reply-To: "Delaney, Kevin P." <khd8@CDC.GOV>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Delaney, Kevin P." <khd8@CDC.GOV>
Subject: FW: Tutorial: Using DDE to collate a number of RTF-files and/or W
ord documents
Content-Type: text/plain; charset="iso-8859-1"
Boy this Kilo Volt person, whoever s/he is, seems to know a lot about
DDE....
;-)
-----Original Message-----
From: Kilo Volt [mailto:dde_dude@HOTMAIL.COM]
Sent: Friday, July 19, 2002 10:01 AM
Subject: Tutorial: Using DDE to collate a number of RTF-files and/or
Word documents
LS,
In the ongoing series of cool DDE tricks, here's a tutorial on how to bundle
a bunch of MS Word documents and/or RTF files into a single Word document.
Why would one possibly want to do this? I've found it useful for the
following reason: some of my longer SAS programs generate various bits and
pieces of ODS RTF output. At the end of the day however, I'd like to have a
single output document rather than squillions of separate chunks.
The following assumes a local directory structure for in- and output files.
Should you wish to run the tutorial, make sure to mimic these on your pc:
c:\temp\append word docs\input
c:\temp\append word docs\output
The output directory is initially empty. In the input directory, some .doc
and/or .rtf files should be present. Just pick a few for testing purposes
... So here goes:
%* First we define some macro variables pointing to the input and *;
%* output directories, and one for the name of the output document.*;
%let indir=c:\temp\append word docs\input;
%let outdir=c:\temp\append word docs\output;
%let outdocname=All in One;
%* Furthermore, we reserve a macro variable for the number of eli- *;
%* gible files found in the input directory. This will be computed *;
%* later. *;
%let nfiles=0;
%* Then we scour the input directory for files of type .doc and *;
%* .rtf. Any such filenames are stored in a small SAS data set *;
%* WORK._FILENAMES *;
filename indir "&indir";
data _filenames(keep=filename);
length
filename $ 200
;
did=dopen('indir');
do i=1 to dnum(did);
filename=dread(did,i);
if substr(left(reverse(upcase(filename))),1,4) in ('COD.','FTR.')
then output; end; rcÜlose(did);
run;
filename indir clear;
%* We store the number of such files in a macro variable NFILES. *; data
_null_;
call symput('nfiles',trim(left(put(nobs,3.)))); stop; set _filenames
nobs=nobs;
run;
%* Start MS Word, and define a DDE doublet-style filename WORDSYS *;
%* through which to send WordBasic commands. *;
options noxsync noxwait xmin; filename wordsys dde 'winword|system'
lreclP00; data _null_;
length fid rc start stop time 8; fid=fopen('wordsys','s'); if (fid le 0)
then do; rc=system('start winword'); startÚtetime(); stop=start+10; do while
(fid le 0);
fid=fopen('wordsys','s'); timeÚtetime(); if (time ge stop) then fid=1; end;
end; rcülose(fid);
run;
%* Minimize the Word application. *; data
_null_;
file wordsys; put '[AppMinimize]';
run;
%* Set the default directory to the output directory and save a *;
%* new blank document there with the specified name. *;
data _null_;
file wordsys; put '[ChDefaultDir "' "&outdir" '",0]'; put
'[FileNewDefault]'; put '[FileSaveAs.Name="' "&outdocname" '",.Format=0]';
run;
%* A little macro to loop through the input documents and do stuff.*;
%macro docloop;
%local
curr_filename
file_num
;
%do file_num=1 %to &nfiles;
%let curr_filename=;
%* Dig up the name of the next input file from WORK._FILENAMES.*; data
_null_;
set _filenames; if _n_=&file_num then do; call
symput('curr_filename',trim(left(filename))); end;
run;
%* Open it up, select all, copy, and close the input doc again.*;
%* Then paste into the output document. *; data
_null_;
file wordsys; put '[ChDefaultDir "' "&indir" '",0]'; put '[FileOpen.Name="'
"&curr_filename" '"]'; put '[EditSelectAll]'; put '[EditCopy]'; put
'[FileClose 2]'; put '[EditPaste]';
run;
%* If this was not the last input file to process, introduce a *;
%* page break. *;
%if &file_num ne &nfiles %then %do;
data _null_; file wordsys; put '[InsertPara]'; put '[InsertPageBreak]'; run;
%end;
%end;
%mend docloop;
%docloop;
%* Save the output file and close it. *; data
_null_;
file wordsys; put '[FileClose 1]';
run;
To have the documents collated in a specific order, one might save various
bits of ODS RTF output with cleverly chosen filenames, and a mere proc sort
on the WORK._FILENAMES data set will do the trick.
All this developed and tested on a Win2Kpro box with Office97 and
SASv8.2 / SASv9.0
Kind Regards,
kV.
_________________________________________________________________
|