2005 David Woods


Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • This is a very basic introduction. Most of these features are far more powerful than what I’m showing, and there are often better ways of doing things that I’m not aware of. These are all simple methods that even beginners can understand. I’ve included all the code samples necessary to reproduce the effects, but we won’t dwell too much on the code, so don’t worry if it looks a bit daunting.
  • The problem with this approach is that the output is UGLY! It’s unformatted… so either the analyst has to spend valuable time formatting it (every time the report is generated), or use the formatting exactly as it is, perhaps pasted into a word document. A better approach would be to let SAS do all the layout and the formatting.
  • This is the form of how you submit commands to Excel. Use a data _null_ statement and set the sas2xl reference. Then ‘put’ the commands. Commands can all be put in the same data step, or broken up into separate steps, with other processing or conditionals between.
  • Several different ways, this is just one of them. The ‘notab’ is to stop it moving to the next stage when it gets to a space… we force it to move with the tab character.
  • Easy to imagine how we could separate the data entry and formatting into sections and throw some if then statements around it to create conditional formatting, or even conditional output.
  • The same thing can be done for Word, but you need to keep track of where the “cursor” is in the document at any given point, since the convenient cell references aren’t available.
  • This piece of code goes within the data step, and there is one like it for each piece of text. Items which remain the same don’t need to be repeated, for example ‘”Ariel”’…
  • Again, this code goes within the data step. Building the PDF is just a matter of assembling elements. Can be combined with loops and data sets to fill in multiple items.
  • Can also use proc tabulate.
  • Can redefine any fonts you choose.
  • Just a quick overview…
  • EG if index(htmlline,’string’) = 0 then delete else do…
  • 2005 David Woods

    1. 1. David Woods SUNZ Conference 14 th December 2005 Real-World Inputs and Outputs
    2. 2. Overview <ul><li>Reading and writing to Excel </li></ul><ul><li>Making controlled PDFs </li></ul><ul><li>Submitting commands to Windows </li></ul><ul><li>Sending email </li></ul><ul><li>Inputs from the Web </li></ul>
    3. 3. Outputting to Excel <ul><li>Typical Scenario: </li></ul><ul><li>Need to design a report from SAS datasets to be read by regular analysts in Excel. </li></ul><ul><li>Typical Solution: </li></ul><ul><li>SAS dataset is ‘Exported’ either as an Excel file, or as a comma delimited file. </li></ul>
    4. 4. Outputting to Excel <ul><li>Problem: </li></ul><ul><ul><li>PROC EXPORT </li></ul></ul><ul><ul><li>DATA = SASHELP.Tourism </li></ul></ul><ul><ul><li>OUTFILE = &quot;C:output.xls&quot; </li></ul></ul><ul><ul><li>DBMS =EXCEL REPLACE ; </li></ul></ul><ul><ul><li>SHEET = &quot;sheet1&quot; ; </li></ul></ul><ul><ul><li>RUN; </li></ul></ul><ul><ul><li>UGLY! </li></ul></ul>
    5. 5. Dynamic Data Exchange <ul><li>We can use Dynamic Data Exchange (DDE) to read and write directly to Excel. </li></ul><ul><li>Uses X4ML to instruct Excel </li></ul><ul><li>Can read/write to individual cells or ranges </li></ul><ul><li>Can apply formatting to cells </li></ul><ul><li>Can use conditional formatting and output </li></ul>
    6. 6. Desired Excel Output
    7. 7. Some code for starting DDE <ul><li>Open Excel for writing: </li></ul><ul><ul><li>options noxsync noxwait xmin; </li></ul></ul><ul><ul><li>filename sas2xl dde 'excel|system' ; </li></ul></ul><ul><ul><li>data _null_ ; </li></ul></ul><ul><ul><li>length fid rc start stop time 8 ; </li></ul></ul><ul><ul><li>fid=fopen('sas2xl','s'); </li></ul></ul><ul><ul><li>if (fid le 0 ) then do ; </li></ul></ul><ul><ul><li> rc=system('start excel'); </li></ul></ul><ul><ul><li> start=datetime(); </li></ul></ul><ul><ul><li> stop=start+ 10 ; </li></ul></ul><ul><ul><li> do while (fid le 0 ); </li></ul></ul><ul><ul><li> fid=fopen('sas2xl','s'); </li></ul></ul><ul><ul><li> time=datetime(); </li></ul></ul><ul><ul><li> if (time ge stop) then fid= 1 ; </li></ul></ul><ul><ul><li> end ; </li></ul></ul><ul><ul><li>end ; </li></ul></ul><ul><ul><li>rc=fclose(fid); </li></ul></ul><ul><ul><li>run ; </li></ul></ul><ul><li>Set up new workbook: </li></ul><ul><ul><li>/* Get rid of old workbook and */ </li></ul></ul><ul><ul><li>/* create new one. Save it. */ </li></ul></ul><ul><ul><li>%let path = C:SUNZ; </li></ul></ul><ul><ul><li>%let name = My workbook; </li></ul></ul><ul><ul><li>data _null_ ; </li></ul></ul><ul><ul><li>file sas2xl; </li></ul></ul><ul><ul><li>put '[file.close(false)]' ; </li></ul></ul><ul><ul><li>put '[new(1)]' ; </li></ul></ul><ul><ul><li>put '[error(false)]' ; </li></ul></ul><ul><ul><li>put &quot;[save.as(&quot;&quot;&path&name&quot;&quot;)]&quot; ; </li></ul></ul><ul><ul><li>run ; </li></ul></ul>
    8. 8. DDE – putting values in cells <ul><li>filename recrange dde </li></ul><ul><li>&quot;excel|[My workbook.xls]Sheet1!r2c2:r3c6&quot; notab ; </li></ul><ul><li>%let t = '09'x; </li></ul><ul><li>data _null_; </li></ul><ul><li>file recrange; </li></ul><ul><li>put &t &t </li></ul><ul><li> 'Holidays in Spain' &t </li></ul><ul><li> 'UK real personal' &t &t </li></ul><ul><li> 'The consumer price' ; </li></ul><ul><li>output ; </li></ul><ul><li>put 'Year' &t &t </li></ul><ul><li> 'by US residents' &t </li></ul><ul><li> 'disposable income' &t </li></ul><ul><li> 'The UK population' &t </li></ul><ul><li> 'index in Spain' ; </li></ul><ul><li>output ; </li></ul><ul><li>run ; </li></ul><ul><li>filename recrange clear ; </li></ul>Set a range Write values to The range Clear the range
    9. 9. DDE – putting values in cells <ul><li>filename recrange dde </li></ul><ul><li>&quot;excel|[My workbook.xls]Sheet1!r4c2:r13c7&quot; notab ; </li></ul><ul><li>data _null_ ; </li></ul><ul><li>set sashelp.tourism(obs= 10 ); </li></ul><ul><li>file recrange; </li></ul><ul><li>put year &t &t vsp &t pdi &t pop &t cpisp; </li></ul><ul><li>run ; </li></ul><ul><li>filename recrange clear ; </li></ul>Set a range Write values to The range Clear the range
    10. 10. DDE – formatting <ul><li>Submit commands in data steps calling ‘sas2xl’ </li></ul><ul><li>Zoom to 85% </li></ul><ul><ul><li>data _null_ ; </li></ul></ul><ul><ul><li>file sas2xl; </li></ul></ul><ul><ul><li>put '[zoom(85)]' ; </li></ul></ul><ul><ul><li>run ; </li></ul></ul>
    11. 11. DDE - formatting <ul><li>Make headings bold and purple: </li></ul><ul><ul><li>data _null_ ; </li></ul></ul><ul><ul><li>file sas2xl; </li></ul></ul><ul><ul><li>put '[select(&quot;r2:r3&quot;)]' ; </li></ul></ul><ul><ul><li>put '[format.font(&quot;Arial&quot;,10,true,false,false, </li></ul></ul><ul><ul><li>false,17,false,false)]' ; </li></ul></ul><ul><ul><li>run ; </li></ul></ul>Functions are X4ML functions Complete help can be found in MACROFUN.hlp… go to: http://www.microsoft.com/learning/ And search for MACROFUN.EXE Eg: FORMAT.FONT(name_text, size_num, bold, italic, underline, strike, color, outline, shadow)
    12. 12. DDE - formatting <ul><li>data _null_ ; </li></ul><ul><li>file sas2xl; </li></ul><ul><li>/* Set background colors */ </li></ul><ul><li>put &quot;[select(&quot;&quot;r2c2:r3c2,r2c4:r3c7&quot;&quot;)]&quot; ; </li></ul><ul><li>put &quot;[patterns(1,0,1)]&quot; ; </li></ul><ul><li>put &quot;[select(&quot;&quot;r4c2:r13c2&quot;&quot;)]&quot; ; </li></ul><ul><li>put &quot;[patterns(1,0,39)]&quot; ; </li></ul><ul><li>put &quot;[select(&quot;&quot;r4c4:r13c7&quot;&quot;)]&quot; ; </li></ul><ul><li>put &quot;[patterns(1,0,43)]&quot; ; </li></ul><ul><li>/* Set number formats */ </li></ul><ul><li>put '[select(&quot;c4,c6&quot;)]' ; </li></ul><ul><li>put '[format.number(&quot;0.00&quot;)]' ; </li></ul><ul><li>put '[select(&quot;c7&quot;)]' ; </li></ul><ul><li>put '[format.number(&quot;0.0000&quot;)]' ; </li></ul><ul><li>/* Center all cells */ </li></ul><ul><li>put '[select(&quot;c2:c7&quot;)]' ; </li></ul><ul><li>put '[alignment(3)]' ; </li></ul><ul><li>run ; </li></ul>data _null_; file sas2xl; /* Set column widths */ put '[column.width(7.14,&quot;c2&quot;,false)]' ; put '[column.width(2,&quot;c1,c3&quot;,false)]' ; put '[column.width(18.2,&quot;c4:c7&quot;,false)]' ; /* Set outlines borders */ put '[select(&quot;r2c2:r13c2,r2c4:r13c7&quot;)]' ; put '[border(2)]' ; /* Set internal borders */ put '[select(&quot;r2c4:r13c6&quot;)]' ; put '[border(,,1)]' ; /* Save and close the file */ put '[error(false)]' ; put '[save]' ; put '[file.close(false)]' ; put '[quit()]' ; run ;
    13. 13. Finished output
    14. 14. DDE – reading Excel sheets <ul><li>DDE can also be used to read </li></ul><ul><li>specified ranges from Excel sheets. </li></ul><ul><li>data _null_ ; </li></ul><ul><li>file sas2xl; </li></ul><ul><li>put '[file.close(false)]' ; </li></ul><ul><li>put '[open(&quot;C:My workbook&quot;)]' ; </li></ul><ul><li>put '[workbook.activate(&quot;Sheet1&quot;)]' ; </li></ul><ul><li>run ; </li></ul><ul><li>filename recrange dde </li></ul><ul><li>&quot;excel|[My workbook.xls]Sheet1!r6c4:r8c5&quot; notab ; </li></ul><ul><li>data workbook; </li></ul><ul><li>infile recrange delimiter = '09'x lrecl=1000 ; </li></ul><ul><li>input VAR1 $ VAR2 $; </li></ul><ul><li>run ; </li></ul><ul><li>filename recrange clear ; </li></ul>First open Excel as earlier, and close it again at the end.
    15. 15. Making PDFs <ul><li>Often, it’s necessary to make a document in PDF format that looks exactly like you want it to. </li></ul><ul><li>Example: </li></ul><ul><li>The invoice for the conference </li></ul>
    16. 16. Making PDFs – proc ganno <ul><li>Create a dataset with one observation for each item on the PDF. </li></ul><ul><li>Text entries: </li></ul><ul><li>function= 'label' ; </li></ul><ul><li>x= 5 ; y= 94.25 ; </li></ul><ul><li>style = '&quot;Arial&quot;' ; </li></ul><ul><li>position = '6' ; </li></ul><ul><li>size= 3 ; </li></ul><ul><li>text= 'SUNZ' ; </li></ul><ul><li>output ; </li></ul>
    17. 17. Making PDFs – proc ganno <ul><li>Drawing lines: </li></ul><ul><li>function= 'move' ; x= 1 ; y= 87 ; </li></ul><ul><li>output ; </li></ul><ul><li>function= 'draw' ; x= 95 ; y= 87 ; </li></ul><ul><li>color = 'black' ; line = 1 ; size= 8 ; </li></ul><ul><li>output ; </li></ul>Move cursor to start of line Draw line to finishing position
    18. 18. Making PDFs – proc ganno <ul><li>Finally, invoke the ODS PDF output destination. </li></ul><ul><li>ods listing close ; </li></ul><ul><li>ods pdf bookmarklist= none file = &quot;C:invoice.pdf&quot; ; </li></ul><ul><li>goptions hpos = 100 vpos = 100 ; </li></ul><ul><li>proc ganno annotate =annodata; </li></ul><ul><li>run ; quit ; </li></ul><ul><li>ods pdf close ; </li></ul><ul><li>PROC GANNO very powerful, used for assembling graphs one element at a time, or customising graphs </li></ul><ul><li>Requires SAS/GRAPH </li></ul>
    19. 19. Making PDFs – proc report <ul><li>No SAS/GRAPH… need to use PROC REPORT </li></ul><ul><li>Harder! </li></ul><ul><li>Approach: </li></ul><ul><li>Activate ODS PDF output destination </li></ul><ul><li>Call PROC REPORT to place elements on page </li></ul><ul><li>Problems: </li></ul><ul><li>PROC REPORT is hard to customise the appearance of </li></ul><ul><li>SAS help is almost useless </li></ul>
    20. 20. Making PDFs – proc report <ul><li>Biggest resource is the paper by Brian T. Schellenberger at SAS </li></ul><ul><li>This paper is written entirely using PROC REPORT and ODS </li></ul><ul><li>Found at http://support.sas.com/rnd/base/topics/odsprinter/qual.pdf </li></ul>
    21. 21. Making PDFs – proc report <ul><li>options </li></ul><ul><li>topmargin= 1.25 </li></ul><ul><li>bottommargin= 0.3 </li></ul><ul><li>leftmargin= 0.75 </li></ul><ul><li>rightmargin= 0.75 </li></ul><ul><li>papersize=a4; </li></ul><ul><li>ods path </li></ul><ul><li>work.templat(update) </li></ul><ul><li>sasusr.templat(update) </li></ul><ul><li>sashelp.tmplmst(read); </li></ul><ul><li>proc template ; </li></ul><ul><li>define Style styles.format; parent = styles.Printer; </li></ul><ul><li>replace fonts / </li></ul><ul><li>&quot;docFont&quot; = ( &quot;Arial&quot; , 10 pt) </li></ul><ul><li>&quot;headingFont&quot; = ( &quot;Arial&quot; , 10 pt,bold) </li></ul><ul><li>&quot;headingEmphasisFont&quot; = ( &quot;Arial&quot; , 10 pt,bold italic) </li></ul><ul><li>&quot;FixedFont&quot; = ( &quot;Courier New, Courier&quot; , 8 pt) </li></ul><ul><li>&quot;FixedHeadingFont&quot; = ( &quot;Courier New, Courier&quot; , 8 pt,bold) </li></ul><ul><li>&quot;FixedStrongFont&quot; = ( &quot;Courier New, Courier&quot; , 8 pt,bold) </li></ul><ul><li>&quot;FixedEmphasisFont&quot; = ( &quot;Courier New, Courier&quot; , 8 pt,italic) </li></ul><ul><li>&quot;EmphasisFont&quot; = ( &quot;Arial&quot; , 10 pt) </li></ul><ul><li>&quot;StrongFont&quot; = ( &quot;Arial&quot; , 8 pt, bold) </li></ul><ul><li>&quot;TitleFont&quot; = ( &quot;Arial&quot; , 8 pt) </li></ul><ul><li>&quot;TitleFont2&quot; = ( &quot;Arial&quot; , 8 pt) </li></ul><ul><li>; </li></ul><ul><li>end ; </li></ul><ul><li>run ; </li></ul>First steps: Set some options and define a new style template
    22. 22. Making PDFs – proc report <ul><li>Activate the ODS PDF destination: </li></ul><ul><li>ods listing close ; </li></ul><ul><li>ods printer style =format columns= 1 pdf notoc </li></ul><ul><li> file = &quot;C:sample.pdf&quot; ; </li></ul><ul><li>options cardimage nodate nonumber; </li></ul><ul><li>ods escapechar = '' ; </li></ul><ul><li>ods printer startpage=no; </li></ul><ul><li>title ; </li></ul><ul><li>footnote ; </li></ul>
    23. 23. Making PDFs – proc report <ul><li>Construct a dataset that contains the information you wish to output. Then call PROC REPORT. </li></ul><ul><li>data text ; </li></ul><ul><li>text = 'This is the line of text we wish to display.' ; </li></ul><ul><li>run ; </li></ul><ul><li>proc report data =text nowindows noheader </li></ul><ul><li>style ={rules=none frame=void just=l cellspacing= 0 cellpadding= 0 }; </li></ul><ul><li>define text / style =data; </li></ul><ul><li>run ; quit ; </li></ul><ul><li>This will output a normal looking line of text </li></ul>
    24. 24. Making PDFs – proc report <ul><li>Make macros! </li></ul><ul><li>%macro standardtext(text); </li></ul><ul><li> data text; </li></ul><ul><li> length text $ 9999 ; </li></ul><ul><li> text = resolve(&text); </li></ul><ul><li> run; </li></ul><ul><li> proc report data=text nowindows noheader </li></ul><ul><li> style={rules=none frame=void just=l cellspacing= 0 cellpadding= 0 }; </li></ul><ul><li> define text / style=data; </li></ul><ul><li> run; quit; </li></ul><ul><li>% mend standardtext; </li></ul><ul><li>%standardtext( &quot;This is the line of text we wish to display.&quot; ); </li></ul>
    25. 25. Making PDFs – proc report <ul><li>Changing appearance of output: </li></ul><ul><li>Use escape character ‘’ </li></ul><ul><li>To get This is italic </li></ul><ul><li>Use %standardtext( &quot;This is S={font_style=italic}italicS={}&quot; ); </li></ul><ul><li>Some style modifiers are: font_face, font_size, font_style, font_weight </li></ul><ul><li>Can also use shading and borders in the report table </li></ul>
    26. 26. Note on manipulating files <ul><li>Any commands you can execute from the command prompt you can execute with SAS: </li></ul><ul><li>Delete a file </li></ul><ul><li>systask command &quot;del C:sample.pdf&quot; taskname =del; </li></ul><ul><li>waitfor del; </li></ul><ul><li>Rename a file </li></ul><ul><li>systask command &quot;rename C:sample.pdf letter.pdf&quot; taskname =ren; </li></ul><ul><li>waitfor ren; </li></ul><ul><li>Run a Word macro </li></ul><ul><li>systask command &quot; start /wait /min winword.exe &quot;&quot;C:mydoc.doc&quot;&quot; /mymacro &quot; taskname =runmacro; </li></ul><ul><li>waitfor runmacro; </li></ul>
    27. 27. Sending Email using SAS <ul><li>Add the following lines to your SAS config file </li></ul><ul><li>(default - C:Program FilesSASSAS9.1 lsenSASV9.CFG) </li></ul><ul><li>-emailsys SMTP </li></ul><ul><li>-emailhost 'smtp.offlode.com' </li></ul><ul><li>-emailid 'david@offlode.com' </li></ul><ul><li>Then: </li></ul><ul><li>data _null_ ; </li></ul><ul><li>file myemail; </li></ul><ul><li>put 'Dear David' ; </li></ul><ul><li>put ' ' ; </li></ul><ul><li>put 'Thank you for your patience ' @; </li></ul><ul><li>put 'in sitting through these talks.' ; </li></ul><ul><li>put ' ' ; </li></ul><ul><li>put 'Please find attached a PDF' ; </li></ul><ul><li>put ' ' ; </li></ul><ul><li>put 'David Woods' ; </li></ul><ul><li>run ; </li></ul>filename myemail email to = ( &quot;info@sunz.net.nz&quot; ) from = &quot;David Woods <david@offlode.com>&quot; subject = &quot;Have a nice day&quot; attach = &quot;C:sample.pdf&quot; ;
    28. 28. Getting stuff from the web <ul><li>Define a webpage as a fileref </li></ul><ul><li>Load the HTML source code into a dataset </li></ul><ul><li>Search through the dataset to find the required info </li></ul><ul><li>filename webpage url &quot;http://www.nzx.com/&quot;; </li></ul><ul><li>data nzx; </li></ul><ul><li> infile webpage length =len lrecl = 4000 ; </li></ul><ul><li> input htmlline $varying4000. len; </li></ul><ul><li>run ; </li></ul>
    29. 29. NZX share prices Examine the source code to find some string which characterizes your target information, then extract the desired info into a new variable.
    30. 30. Google celebrity search <ul><li>%let firnam = David; </li></ul><ul><li>%let surnam = Woods; </li></ul><ul><li>filename webpage url &quot;http://www.google.co.nz/search?hl=en&q=%22&firnam+&surnam%22&btnG=Google+Search&meta=&quot; ; </li></ul><ul><li>data _null_ ; </li></ul><ul><li>infile webpage length =len lrecl= 4000 ; </li></ul><ul><li>input htmlline $varying4000. len; </li></ul><ul><li>if index(htmlline, 'table width' )> 0 AND index(htmlline, '</b> of about <b>' )> 0 then do ; </li></ul><ul><li> call symput( 'number' ,substr(substr(htmlline,index(htmlline, </li></ul><ul><li>'</b> of about <b>' )+ 17 ), 1 ,index(substr(htmlline,index(htmlline, </li></ul><ul><li>'</b> of about <b>' )+ 17 ), '<' )- 1 )); </li></ul><ul><li> stop ; </li></ul><ul><li>end ; </li></ul><ul><li>run ; </li></ul>
    31. 31. Google celebrity search
    32. 32. Google celebrity search <ul><li>Can rank people by celebrity status: </li></ul><ul><li>Application for detection of false names, if count is above a certain threshold they might be fake. </li></ul>
    33. 33. Useful References <ul><li>SAS help </li></ul><ul><li>SUGI papers </li></ul><ul><li>DDE: </li></ul><ul><ul><li>http://www.sas-consultant.com/professional/SUGI27-HOW-DDE.pdf </li></ul></ul><ul><ul><li>http://www.sas-consultant.com/professional/SUGI26-Against-All-ODS-1.pdf </li></ul></ul><ul><ul><li>http://www.nesug.org/html/Proceedings/nesug04/ap/ap06.pdf </li></ul></ul><ul><li>ODS PDF output </li></ul><ul><ul><li>http://support.sas.com/rnd/base/topics/odsprinter/qual.pdf </li></ul></ul><ul><ul><li>http:// support.sas.com/rnd/base/topics/odsprinter/usepaper.pdf </li></ul></ul>