| Date: | Wed, 31 May 2006 16:35:49 -0400 |
| Reply-To: | Joe Whitehurst <joewhitehurst@GMAIL.COM> |
| Sender: | "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU> |
| From: | Joe Whitehurst <joewhitehurst@GMAIL.COM> |
| Subject: | Re: Read/Write Microsoft Word document |
|
| In-Reply-To: | <8AD8F86B3312F24CB432CEDDA71889F201B5BBD9@ex06.GHCMASTER.GHC.ORG> |
| Content-Type: | text/plain; charset=ISO-8859-1; format=flowed |
Here is an ancient (pre dot notation) SAS Component Language Example with a
little VB and macro variables:
INIT:
/* Get macro-variable parameters */
cm_to_point=28.35;
margin_cm=2.54;
docname=left(SYMGET('lisname'));
IF INDEX(docname, "'") THEN docname=TRANSLATE(docname, '"', "'");
IF INDEX(docname, '"') EQ 0 THEN docname='"'||TRIMN(docname)||'"';
doc_orient=SYMGET('orient');
font_sz=SYMGET('fontsze');
caption_type=SYMGET('listype');
IF UPCASE(doc_orient) NE 'PORTRAIT' THEN DO;
wdOrientLandscape=1;
page_w=INT(29.7*cm_to_point);
page_h=INT(21*cm_to_point);
*page_w=INT(27.94*cm_to_point);
*page_h=INT(21.59*cm_to_point);
END; ELSE DO;
wdOrientLandscape=0;
page_h=INT(29.7*cm_to_point);
page_w=INT(21*cm_to_point);
*page_h=INT(27.94*cm_to_point);
*page_w=INT(21.59*cm_to_point);
END;
/*- Retrieve document name,
Define output name -*/
lisname=docname;
dirname=SUBSTR(docname, 1, INDEX(docname, '\')-1);
docname=SUBSTR(docname, INDEX(docname, '\')+1);
DO WHILE(INDEX(docname, '\'));
parentdir=dirname;
dirname=TRIMN(dirname)||'\'||SUBSTR(docname, 1, INDEX(docname, '\')-1);
docname=SUBSTR(docname, INDEX(docname, '\')+1);
END;
filename=SCAN(docname, 1, '.');
i=2;
DO WHILE(SCAN(docname, i+1, '.') NE '');
filename=TRIMN(filename)||'.'||SCAN(docname, i);
i=i+1;
END;
outdocname=TRIMN(parentdir)||'\Doc\'||TRIMN(filename)||'.doc"';
refname=TRIMN(filename);
CALL SYMPUT("outdocf", outdocname);
/*- Word Constants Definitions -*/
wdLine=5;
wdWord=2;
wdParagraph=4;
wdGoToPage=1;
wdExtend=1;
wdGoToNext=2;
wdContentText=-1;
wdActiveEndPageNumber=3;
wdNumberOfPagesInDocument=4;
wdFormatDocument=0;
wdOrganizerObjectStyles=0;
/*- Open a (new) MS-Word session -*/
hostcl=loadclass('sashelp.fsp.hauto');
CALL SEND (hostcl, '_NEW_', wordobj, 0, 'Word.Application');
CALL SEND (wordobj, '_SET_PROPERTY_', 'Visible', 'True');
CALL SEND (wordobj, '_GET_PROPERTY_', 'Documents', worddoc);
/*- Load VB macros from word template document -*/
CALL SEND (wordobj, '_GET_PROPERTY_', 'Addins', addins);
CALL SEND (addins, '_DO_', 'Add',
SYMGET('pgm_in')||"\Wdata\Source\Publish.DOT", 'True');
/*- Create New Document according to HouseStyle, A4 Portrait/Landscape -*/
IF UPCASE(doc_orient) NE 'PORTRAIT' THEN DO;
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.NewA4LandscHS");
END; ELSE DO;
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.NewA4PortraitHS");
END;
/*- Get a handle to active document and full name -*/
CALL SEND (wordobj, '_GET_PROPERTY_', 'ActiveDocument', actdoc);
actdocfname=''; /* needs to be pre-defined as string for
the following instruction to work */
CALL SEND (actdoc, '_GET_PROPERTY_', 'FullName', actdocfname);
/*- Copy defined styles from template to current documeny -*/
CALL SEND (wordobj, '_DO_', 'OrganizerCopy',
SYMGET('pgm_in')||"\Wdata\Source\Publish.DOT",
actdocfname, "Caption0", wdOrganizerObjectStyles);
CALL SEND (wordobj, '_DO_', 'OrganizerCopy',
SYMGET('pgm_in')||"\Wdata\Source\Publish.DOT",
actdocfname, "Caption1", wdOrganizerObjectStyles);
CALL SEND (wordobj, '_DO_', 'OrganizerCopy',
SYMGET('pgm_in')||"\Wdata\Source\Publish.DOT",
actdocfname, "PDFbookm", wdOrganizerObjectStyles);
CALL SEND (wordobj, '_DO_', 'OrganizerCopy',
SYMGET('pgm_in')||"\Wdata\Source\Publish.DOT",
actdocfname, "PDFbookmView", wdOrganizerObjectStyles);
/*-Insert .LIS file -*/
CALL SEND (wordobj, '_GET_PROPERTY_', 'Selection', wordsel);
CALL SEND (wordsel, '_DO_', 'InsertFile', lisname, "", 0,0, 0);
/*
*- Set Page Setup and Font - already done in NewA4LandscHS -*;
CALL SEND (wordobj, '_GET_PROPERTY_', 'Selection', wordsel);
CALL SEND (wordsel, '_DO_', 'WholeStory');
CALL SEND (wordsel, '_GET_PROPERTY_', 'Font', selfon);
CALL SEND (selfon, '_SET_PROPERTY_', 'Name', "Courier New");
CALL SEND (selfon, '_SET_PROPERTY_', 'Size', font_sz);
CALL SEND (wordobj, '_GET_PROPERTY_', 'ActiveDocument', actdoc);
CALL SEND (actdoc, '_GET_PROPERTY_', 'PageSetup', pgsetup);
CALL SEND (pgsetup, '_SET_PROPERTY_', 'Orientation',
wdOrientLandscape);
CALL SEND (pgsetup, '_SET_PROPERTY_', 'TopMargin',
margin_cm * cm_to_point);
CALL SEND (pgsetup, '_SET_PROPERTY_', 'BottomMargin',
margin_cm * cm_to_point);
CALL SEND (pgsetup, '_SET_PROPERTY_', 'LeftMargin',
margin_cm * cm_to_point);
CALL SEND (pgsetup, '_SET_PROPERTY_', 'RightMargin',
margin_cm * cm_to_point);
CALL SEND (pgsetup, '_SET_PROPERTY_', 'PageWidth', page_w);
CALL SEND (pgsetup, '_SET_PROPERTY_', 'PageHeight', page_h);
*/
/*- Remove Last line if it only contains a Carriage Return -*/
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.RemoveLstLF");
/*- Remove Page Break on 1st line -*/
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.Remove1stPgBrk");
/*- Insert caption (at top of 1st page) with specific text
and bookmark it with a specific name -*/
CALL SEND (wordsel, '_DO_', 'TypeParagraph');
CALL SEND (wordsel, '_DO_', 'MoveUp', wdLine, 1);
*- Make sure caption_type is defined -*;
IF caption_type NOT IN ('Figure' 'Table' 'Equation') THEN DO;
CALL SEND (wordobj, '_GET_PROPERTY_', 'CaptionLabels', captionlabels);
CALL SEND (captionlabels, '_DO_', 'Add', caption_type);
END;
*- type refname, select it, define its text as MyBookMarkName
(VB Global variable that will be used by VB macro SetMyBookMark)
then delete it -*;
CALL SEND (wordsel, '_DO_', 'TypeText', refname);
CALL SEND (wordsel, '_DO_', 'MoveUp', wdLine, 1, wdExtend);
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.NameMyBookMark");
CALL SEND (wordsel, '_DO_', 'Delete');
*- type caption_type, select it, define its text as MyCaptionType
(VB Global variable that will be used by VB macro InsertCaptionRef)
then delete it -*;
CALL SEND (wordsel, '_DO_', 'TypeText', caption_type);
CALL SEND (wordsel, '_DO_', 'MoveUp', wdLine, 1, wdExtend);
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.NameMyCaptionType");
CALL SEND (wordsel, '_DO_', 'Delete');
*- Insert caption text and select it -*;
_cap0=INPUT(SYMGET('_cap0'), 8.); *- number of caption parts -*;
lastchar='';
IF _cap0 THEN DO i=1 TO _cap0;
*- concatenate caption parts into a single paragraph -*;
cap=TRIM(SYMGET('_cap'||TRIM(LEFT(PUT(i, 8.)))));
IF lastchar NE '' THEN DO;
IF lastchar=: '.' THEN cap=' '||cap;
ELSE IF lastchar=: '-' THEN cap=' '||cap;
ELSE cap=' '||cap;
END;
CALL SEND (wordsel, '_DO_', 'TypeText', cap);
lastchar=REVERSE(TRIM(cap));
END;
ELSE CALL SEND (wordsel, '_DO_', 'TypeText',
"NOTICE: no caption is defined for "
||TRIMN(caption_type)||" "||TRIMN(lisname));
CALL SEND (wordsel, '_DO_', 'TypeParagraph');
CALL SEND (wordsel, '_DO_', 'MoveUp', wdParagraph, 1);
CALL SEND (wordsel, '_DO_', 'Extend'); * zero-character selection *;
CALL SEND (wordsel, '_DO_', 'Extend'); * word *;
CALL SEND (wordsel, '_DO_', 'Extend'); * sentence *;
CALL SEND (wordsel, '_DO_', 'Extend'); * paragraph *;
*- Make Caption from selection and re-select the caption -*;
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.MakeCaption");
* CALL SEND (wordsel, '_DO_', 'InsertCaption', caption_type, caption);
* Above statement would be limited to the length of caption variable *;
CALL SEND (wordsel, '_DO_', 'MoveUp', wdParagraph, 1);
CALL SEND (wordsel, '_DO_', 'Extend'); * zero-character selection *;
CALL SEND (wordsel, '_DO_', 'Extend'); * word *;
CALL SEND (wordsel, '_DO_', 'Extend'); * sentence *;
CALL SEND (wordsel, '_DO_', 'Extend'); * paragraph *;
CALL SEND (wordsel, '_GET_PROPERTY_', 'End',
select_end);
CALL SEND (wordsel, '_SET_PROPERTY_', 'End',
select_end-1);
*- Bookmark the selection -*;
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.SetMyBookMark");
*- Insert white text that PDFMaker will use to create
a bookmark to this page -*;
*CALL SEND (wordsel, '_DO_', 'MoveDown', wdParagraph, 1);
*CALL SEND (wordsel, '_DO_', 'TypeParagraph');
*CALL SEND (wordsel, '_DO_', 'MoveLeft', wdCharacter, 1);
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.SetPDFbookmViewStyle");
CALL SEND (wordsel, '_DO_', 'TypeText', SYMGET('_bookm'));
*- Insert reference to Caption on top of following pages -*;
CALL SEND (wordobj, '_DO_', 'Run', "Publish.Module1.InsertCaptionRef");
/*- Add Filename + path to header of document to help identify
printed output (will be removed afterwards) -*/
CALL SEND (wordobj, '_DO_', 'Run',
"Publish.Module1.HeaderFilePath");
/*- Save as Word document and close MS-Word session -*/
CALL SEND (actdoc, '_DO_', 'SaveAs', outdocname, wdFormatDocument);
CALL SEND (worddoc, '_DO_', 'Close', 0);
CALL SEND (wordobj, '_DO_', 'Quit', 0);
CALL SEND (wordobj, '_TERM_');
RETURN;
MAIN:
RETURN;
TERM:
RETURN;
On 5/31/06, Pardee, Roy <pardee.r@ghc.org> wrote:
>
> We had a guy here come up w/a fairly Rube-Goldbergian thing using
> winword's mail merge feature. He defined merge fields in a word
> document that referred to a text file, and then changed the contents of
> the text file w/sas to "update" the word doc.
>
> It worked well for the time his group needed it AFAIK...
>
> -----Original Message-----
> From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of
> data _null_;
> Sent: Wednesday, May 31, 2006 12:30 PM
> To: SAS-L@LISTSERV.UGA.EDU
> Subject: Re: Read/Write Microsoft Word document
>
> I think your method will "break" your WORD document. You my be able to
> accomplish this using SAS via DDE. I don't have an example but there
> are many SUGI papers and other SAS-L related discussions that should be
> helpful.
>
> You should be able to use SAS to execute a find/change etc. through DDE,
> I do this with SAS DDE to EXCEL but have not tried it with WORD.
>
> I suspect there are more modern methods, that would be rather simple.
> Others will be more helpful. Search the archives while you wait.
>
> On 5/31/06, compilsys <pmaradan@compilsys.com> wrote:
> > Hi,
> > Does anyone knows how to read a Microsoft Word document (not RTF) and
> > write into a new one with some string modified...
> >
> > I tried :
> >
> > data _null_;
> > infile 'c:\mydocument.doc' recfm=n length=len _infile_=tmp;
> > input;
> > if index(tmp,'stringtomodify') > 0 then
> > tmp=tranwrd(tmp,'stringtomodify','stringmodified');
> > put tmp $varying32767. len;
> > run;
> >
> > ...but does'nt work.
> > I choose WORD document because same RTF document is ~20MB instead of
> > ~350K...
> > thanks folks
> > Pascal
> >
>
|