LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (May 2006, week 5)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
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
Comments:   To: "Pardee, Roy" <pardee.r@ghc.org>
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 > > >


Back to: Top of message | Previous page | Main SAS-L page