Using Microsoft Excel for Data Presentation Peter Godard and Cyndi Williamson, SRI International, Menlo Park, CA



Similar documents
Choosing the Best Method to Create an Excel Report Romain Miralles, Clinovo, Sunnyvale, CA

Create an Excel report using SAS : A comparison of the different techniques

THE HELLO WORLD PROJECT

Importing Excel Files Into SAS Using DDE Curtis A. Smith, Defense Contract Audit Agency, La Mirada, CA

ABSTRACT INTRODUCTION SAS AND EXCEL CAPABILITIES SAS AND EXCEL STRUCTURES

AN ANIMATED GUIDE: SENDING SAS FILE TO EXCEL

Customized Excel Output Using the Excel Libname Harry Droogendyk, Stratia Consulting Inc., Lynden, ON

Data Presentation. Paper Using SAS Macros to Create Automated Excel Reports Containing Tables, Charts and Graphs

Access Queries (Office 2003)

Using SAS Output Delivery System (ODS) Markup to Generate Custom PivotTable and PivotChart Reports Chevell Parker, SAS Institute

Importing Excel File using Microsoft Access in SAS Ajay Gupta, PPD Inc, Morrisville, NC

Integrating SAS and Excel: an Overview and Comparison of Three Methods for Using SAS to Create and Access Data in Excel

Release 2.1 of SAS Add-In for Microsoft Office Bringing Microsoft PowerPoint into the Mix ABSTRACT INTRODUCTION Data Access

Methodologies for Converting Microsoft Excel Spreadsheets to SAS datasets

Creating Dynamic Reports Using Data Exchange to Excel

Using DDE and SAS/Macro for Automated Excel Report Consolidation and Generation

Microsoft' Excel & Access Integration

Introduction to Microsoft Access 2003

Applications Development

Using Excel as a Management Reporting Tool with your Minotaur Data. Exercise 1 Customer Item Profitability Reporting Tool for Management

ACCESS Importing and Exporting Data Files. Information Technology. MS Access 2007 Users Guide. IT Training & Development (818)

Combining SAS LIBNAME and VBA Macro to Import Excel file in an Intriguing, Efficient way Ajay Gupta, PPD Inc, Morrisville, NC

SPSS for Windows importing and exporting data

Flat Pack Data: Converting and ZIPping SAS Data for Delivery

Search and Replace in SAS Data Sets thru GUI

EXCEL PIVOT TABLE David Geffen School of Medicine, UCLA Dean s Office Oct 2002

Tips and Tricks for Creating Multi-Sheet Microsoft Excel Workbooks the Easy Way with SAS. Vincent DelGobbo, SAS Institute Inc.

ABSTRACT INTRODUCTION CLINICAL PROJECT TRACKER OF SAS TASKS. Paper PH

SAS ODS HTML + PROC Report = Fantastic Output Girish K. Narayandas, OptumInsight, Eden Prairie, MN

Moving Data Between Access and Excel

It s not the Yellow Brick Road but the SAS PC FILES SERVER will take you Down the LIBNAME PATH= to Using the 64-Bit Excel Workbooks.

Monthly Payroll to Finance Reconciliation Report: Access and Instructions

Excel Reporting with 1010data

Microsoft Office Word 2010: Level 1

Managing Tables in Microsoft SQL Server using SAS

Data Warehousing With Microsoft Access

How To Create A Report In Excel

Microsoft Access 2010 Part 1: Introduction to Access

Macros allow you to integrate existing Excel reports with a new information system

Database Concepts (3 rd Edition) APPENDIX D Getting Started with Microsoft Access 2007

Search help. More on Office.com: images templates

SPSS: Getting Started. For Windows

A Comparison of SAS versus Microsoft Excel and Access s Inbuilt VBA Functionality Jozef Tarrant, Amadeus Software Ltd., Oxford, UK

Explore commands on the ribbon Each ribbon tab has groups, and each group has a set of related commands.

Microsoft Office 2010: Access 2010, Excel 2010, Lync 2010 learning assets

Excel with SAS and Microsoft Excel

Producing Listings and Reports Using SAS and Crystal Reports Krishna (Balakrishna) Dandamudi, PharmaNet - SPS, Kennett Square, PA

Toad for Data Analysts, Tips n Tricks

Ohio University Computer Services Center August, 2002 Crystal Reports Introduction Quick Reference Guide

Create a New Database in Access 2010

SAS og Excel. Kender du fem forskellige måder at overføre data mellem SAS og Excel? Gert Nissen, seniorkonsulent

Using SAS Enterprise Business Intelligence to Automate a Manual Process: A Case Study Erik S. Larsen, Independent Consultant, Charleston, SC

Power Users Series: Excel Databases

DATA 301 Introduction to Data Analytics Microsoft Excel VBA. Dr. Ramon Lawrence University of British Columbia Okanagan

Chapter 4 Displaying and Describing Categorical Data

Excel 2003, MS Access 2003, FileMaker Pro 8. Which One Should I Use?

Advanced Excel Charts : Tables : Pivots : Macros

Tommy B. Harrington 104 Azalea Drive Greenville, NC

CDW DATA QUALITY INITIATIVE

VISUAL GUIDE to. RX Scripting. for Roulette Xtreme - System Designer 2.0

A Basic introduction to Microsoft Access

Microsoft Office Access 2007 which I refer to as Access throughout this book

MS Access Lab 2. Topic: Tables

Simply Accounting Intelligence Tips and Tricks Booklet Vol. 1

Importing and Exporting With SPSS for Windows 17 TUT 117

Getting Started Guide

Using SAS DDE to Control Excel

Pastel Evolution BIC. Getting Started Guide

SAS UNIX-Space Analyzer A handy tool for UNIX SAS Administrators Airaha Chelvakkanthan Manickam, Cognizant Technology Solutions, Teaneck, NJ

How To Write A Clinical Trial In Sas

Excel & Visual Basic for Applications (VBA)

Getting Started Guide SAGE ACCPAC INTELLIGENCE

Excel 2010: Create your first spreadsheet

Excel 2003 Tutorial I

Microsoft Excel 2007 Consolidate Data & Analyze with Pivot Table Windows XP

Writing Data with Excel Libname Engine

Web Reporting by Combining the Best of HTML and SAS

Switching from PC SAS to SAS Enterprise Guide Zhengxin (Cindy) Yang, inventiv Health Clinical, Princeton, NJ

Anyone Can Learn PROC TABULATE

Microsoft Excel 2007 Mini Skills Overview of Tables

Sample- for evaluation purposes only! Advanced Excel. TeachUcomp, Inc. A Presentation of TeachUcomp Incorporated. Copyright TeachUcomp, Inc.

Excel: Introduction to Formulas

USC Marshall School of Business Marshall Information Services

Excel & Visual Basic for Applications (VBA)

MAS 500 Intelligence Tips and Tricks Booklet Vol. 1

ReportBy Notification Examples

PivotTable and PivotChart Reports, & Macros in Microsoft Excel

IENG2004 Industrial Database and Systems Design. Microsoft Access I. What is Microsoft Access? Architecture of Microsoft Access

Computer Skills: Levels of Proficiency

Unit 10: Microsoft Access Queries

Introduction to Visual Basic and Visual C++ Database Foundation. Types of Databases. Data Access Application Models. Introduction to Database System

Introduction. Why Use ODBC? Setting Up an ODBC Data Source. Stat/Math - Getting Started Using ODBC with SAS and SPSS

Using SAS With a SQL Server Database. M. Rita Thissen, Yan Chen Tang, Elizabeth Heath RTI International, RTP, NC

Report Customization Using PROC REPORT Procedure Shruthi Amruthnath, EPITEC, INC., Southfield, MI

Transcription:

Using Microsoft Excel for Data Presentation Peter Godard and Cyndi Williamson, SRI International, Menlo Park, CA ABSTRACT A common problem: You want to use SAS to manipulate and summarize your data, but you need to present the results in Excel. In this talk, suitable for both beginning and experienced programmers, we ll explore several solutions to this problem some common, some not so common. To start, we ll look at the export procedure the simplest way to move data between SAS and Excel. Next, we ll explore ways to trick ODS into creating an Excel file from any SAS procedure and to format this output using the template procedure. We ll also look at ways to turn DATA _NULL_ reports into Excel spreadsheets. Lastly, we ll talk about Visual Basic for Applications (VBA), which can be used to format Excel output, construct a multiple sheet workbook, and even produce charts from your SAS reports. INTRODUCTION SAS allows you to manipulate a wealth of data and spew out countless results. There are many ways to transform SAS output into a more readable, non-programmer-friendly, and shareable format. We are going to focus on four dynamic methods to transform your SAS results into slick reports by utilizing DATA _NULL_, PROC EXPORT, ODS HTML, and DDE. We will also cover some quick VBA coding to enhance your final product. Please note: The examples used in this paper were written using SAS Version 9.1 for personal computers. To facilitate understanding of the main points, we have relied on the familiar Northwind database distributed with Microsoft Access and Microsoft SQL Server databases. This database is an inventory/ordering system consisting of less than a dozen tables. Although the focus of this paper is moving data from SAS to Excel, we have also provided several examples of Visual Basic for Applications (VBA) code, which we used only to format the data. VBA is an interpreted language that interacts with Microsoft Office Applications. It s object based, which means that everything in the realm of a particular application is an object. In Excel, for example, workbooks, worksheets, ranges, and charts are all objects. Just like objects in the real world, they have properties or characteristics and they have actions that they can do. In writing VBA code, you most often are doing things like setting the properties of a range (e.g., making a cell shaded and setting its text to bold) or performing an action (e.g., inserting a chart or deleting a row). The good news for SAS programmers is that VBA has control structures that are very similar to SAS (such as IF THEN statements and DO loops). Almost all VBA code resides in a subroutine or a function that can be referred to as a macro. Macros are stored either in a particular workbook or in a user s personal macro workbook. If it s in a particular workbook, the macro is more portable. If it s in a personal macro workbook, it s always available to you when you open Excel. In Excel, you can record a macro, execute steps that you want to be able to repeat, and then turn recording off. This will write VBA code for you. You can rerun the code or you can modify it. This is a great place to start learning some of the simpler VBA code. Readers may have differing levels of knowledge about VBA. Experienced VBA programmers may be interested in the specific techniques used to format the output. Inexperienced VBA programmers may just be interested in what VBA is capable of. To learn more about VBA, you may want to refer to some of the following: http://www.excel-vba.com http://msdn.microsoft.com http://www.ozgrid.com/vba http://www.exceltip.com Stephen Bullen, et al., Excel 2002 VBA, Indianapolis, IN: Wrox (2003). Online Consulting, Excel 2000 Programming: Using Visual Basic for Applications, Wilmington, DE: Online Consulting (1999). John Walkenbach and Brian Underdahl, Excel 2002 Bible, New York, NY: Wiley Publishing, Inc. (2001). John Walkenbach, Excel 2002 Power Programming with VBA, New York, NY: M&T Books ( 2001). 1

DATA _NULL_ The most primitive method for presenting SAS data and reports in Excel is all-too-familiar to most SAS programmers. You can write lines of data to a text file by using the PUT statement in a _NULL_ data step. You can then use Excel to import the text file and create an Excel worksheet. The main difference between a DATA _NULL_ report that is meant to live its life as a text file and one destined for greater things in Excel is that there must be some way to parse the report into columns in Excel. This means you must use either fixed column locations or insert delimiters when you write out the data. These can be any sentinel value you choose, but tabs are often a favorite choice since a column of data would rarely (if ever) contain a valid tab character. SYNTAX data _null_; set datasettowritefrom; file nameoftextfiletowriteto.txt ; Conditional expressions and put statements <file nameofadditionaltextfiletowriteto.txt ;> <More conditional expressions and put statements> run; EXAMPLE In the example below, we used PROC SQL and SAS/Access to ODBC to pull data together from the Northwind database housed on our local instance of SQL Server. Combining data from tables related to employees, customers, and orders, we constructed a table that shows the total sales made by each salesperson to each customer. In this instance, we have limited the sales data to the third quarter of 1996. The output of our first procedure is a temporary SAS dataset called customersales_q3_1996. Next, we used the DATA _NULL_ to produce a tab-delimited text file called customersales_q3_1996.tab. We made use of several basic features of DATA _NULL_. We put out titles and column headings before writing any data by specifying if _n_ = 1 then. Most important, for the purposes of getting our output into Excel, we used the hexadecimal representation of the tab character (i.e., 09 x) to specify the delimiters between the columns. libname north odbc dsn=local; * Get the total sales by each person to each customer from Northwind database; proc sql; create table customersales_q3_1996 as select trim(e.firstname) ' ' trim(e.lastname) as Salesperson, c.companyname as Customer, sum(cost) as Sales from (select orderid, sum(unitprice * Quantity) as cost from north.orderdetails group by orderid) od inner join north.orders o on o.orderid = od.orderid inner join north.employees e on o.employeeid = e.employeeid inner join north.customers c on o.customerid = c.customerid where '01Jul1996:00:00:00.00'dt <= o.orderdate < '01Oct1996:00:00:00.00'dt group by trim(e.firstname) ' ' trim(e.lastname), c.companyname order by trim(e.firstname) ' ' trim(e.lastname), c.companyname; quit; * Create a tab-delimited text file; data _null_; set customersales_q3_1996; file "c:\reports\customersales_q3_1996.tab"; if _N_ = 1 then put 'Customer Sales Report' / '3rd Quater, 1996' // 'Sales Person' '09'x 'Customer' '09'x 'Sales Q3'; put Salesperson '09'x Customer '09'x Sales; run; 2

Here is the result once it has been opened and imported in Excel: The worksheet above needs a few tweaks to make the output presentable. At a minimum, we want to adjust the column widths and set the sales column to currency format. If this report is only run once, this is easy enough to accomplish manually. If, on the other hand, we plan to run the report regularly, we will want to automate that formatting. This can be easily done by recording a very simple VBA macro. Below is the code we recorded: Sub formatcustomersales() Columns("A:C").EntireColumn.AutoFit Columns("C:C").Style = "Currency" End Sub 3

Here is the prettier output: ADVANTAGES If you ve ever used the PUT statement in BASE SAS, there is no new syntax to learn. You have a lot of control. You can append data to the text file you create. You can put out multiple text files in a single DATA STEP. You can put out highly formatted reports (e.g., blank rows, different types of data on rows or columns). DISADVANTAGES This would be labor intensive (or you would need to write VBA code) if you wanted to automate reading lots and lots of tab-delimited text files into Excel. You can only write to one worksheets in the Excel workbook. You probably have to do more manual formatting than the other options presented in this paper. You can t control the formatting (such as bold text, centering, shading) from SAS. WHEN TO USE If you already have a DATA _NULL_ report set up and you want to get it into Excel. When procedure output or a vanilla data set export just won t do the trick. 4

PROC EXPORT PROC EXPORT is by far the easiest way to produce an Excel worksheet from SAS. This procedure is included in the SAS/Access to PC File Formats product. In fact, there is a handy wizard to import data to and export data from SAS. If you use the wizard, we recommend that you use the option to save the code so you can modify (as necessary) and rerun the export. SYNTAX proc export data=sas-data-set outfile=excel-file-name DBMS=Excel2000 Excel97 Excel5 Excel4 Excel <REPLACE>; EXAMPLE Pulling from the two orders tables in the Northwind database, we can construct a simple quarterly sales report that will show the total sales and number of units sold by country. This can be done by first constructing a SAS dataset and then using PROC EXPORT to construct the Excel file. libname north odbc dsn=local; * Get the total sales and number of units sold by country from Northwind database; proc sql; create table QuarterlySales_Q3_1996 as select a.shipcountry, sum(b.unitprice) as Sales, sum(b.quantity) as Units from north.orders a inner join north.orderdetails b on a.orderid = b.orderid where '01Jul1996:00:00:00.00'dt <= a.orderdate < '01Oct1996:00:00:00.00'dt group by a.shipcountry; quit; * Export the data to Excel; proc export data = QuarterlySales_Q3_1996 file = "c:\reports\quarterlysales_q3_1996.xls" DBMS=Excel2000 replace; run; 5

This code will produce an Excel workbook named QUARTERLYSALES_Q3_1996 with a single worksheet with the same name. The sample output is below: Looking at the output above, there is some formatting work to be done before the report can be sent out. There are no titles, some of the columns are too narrow, and there is little formatting. In addition, we might want to provide a chart to display the quarterly sales in a graphical format. Here we went a bit further with the macro we recorded for the DATA _NULL_ example. We have cleaned up the code produced by the Excel macro recorder so that it is easier to read, but everything it does could be recorded without knowledge of VBA. 6

Below is the VBA code we ran: Public Sub FormatQuarterlySales() 'Excel VBA Macro to format Quarterly Sales Report 'Recorded and lightly edited by Peter Godard 'Set column widths Columns("A:A").ColumnWidth = 15 Columns("B:B").ColumnWidth = 10 Columns("C:C").ColumnWidth = 10 'Center columns Columns("A:C").HorizontalAlignment = xlcenter 'Edit column titles Cells(1, 1).Value = "Country" Cells(1, 2).Value = "Total Sales" Cells(1, 3).Value = "Units Sold" 'Set column header properties to make text: 'bold, wrapped, highlighted, and underlined Range("A1:C1").Select With Selection.Font.Bold = True.WrapText = True.Borders(xlEdgeBottom).LineStyle = xlcontinuous.borders(xledgebottom).weight = xlthin.borders(xledgebottom).colorindex = xlautomatic.interior.colorindex = 15.Interior.Pattern = xlsolid End With 'Add rows for the report title Rows("1:2").Select Selection.Insert Shift:=xlDown Selection.Insert Shift:=xlDown 'Add the first title With Range("A1").Value = "Quarterly Sales Report".Font.Bold = True.HorizontalAlignment = xlleft End With 'Add the second title (asking user for input) Dim reportdate As String reportdate = InputBox("Enter the reporting period.", "Reporting period") With Range("A2").Value = reportdate.font.bold = True.HorizontalAlignment = xlleft End With End Sub 7

Below is the newly formatted report in Excel: Now we want to create a graphical display of the data. We ll use the VBA macro below to generate a chart showing the total sales for each country. Again, you could record the macro in Excel to generate the VBA code; we just cleaned it up a little bit for readability. Public Sub QuarterlySalesChart() 'Excel VBA Macro to create a quarterly sales chart 'Recorded and lightly edited by Peter Godard 'Get name of current worksheet so chart can be added there Dim actsheet As String actsheet = ActiveSheet.Name 'Add the chart and specify options Charts.Add ActiveChart.ChartType = xlcolumnclustered ActiveChart.SetSourceData Source:=Sheets(actSheet).Range("A5:B20"), PlotBy:=xlColumns ActiveChart.HasTitle = True ActiveChart.ChartTitle.Characters.Text = "Total Sales, by Country" ActiveChart.HasLegend = False ActiveChart.Location Where:=xlLocationAsObject, Name:=actSheet End Sub 8

After running the macro, you get the chart shown below: ADVANTAGES The syntax is quite easy. If you didn t care about the format of the data, you could be done with one simple PROC EXPORT. DISADVANTAGES You can t do this if you don t have the SAS/Access to PC File Formats product. In addition, you have to work in a PC environment for this to work. You can t write to discontinuous ranges (which would be important for highly formatted reports with variable data in columns and/or rows). You can t write to more than one worksheet at a time. You can t control the formatting (such as bold text, centering, shading) from SAS. WHEN TO USE When you have a simple tabular report on a single worksheet. When you don t have much time and you need quick results. 9

ODS HTML Sometimes, the result you need can be produced directly from a SAS procedure, but you d like to present the data in Excel so that other people can manipulate or chart the data themselves. It would be nice to be able to produce an Excel file using the Output Delivery System (ODS). While this isn t exactly possible, we can trick SAS into doing what we want. By using ODS HTML and specifying a filename with a.xls extension, we can produce a file that is readable by Excel. SYNTAX ods html file= your_file_name.xls ; SAS-Procedure-Calls ods html close; EXAMPLE In demonstrating the ODS to Excel functionality, we ll create a report that displays the number of packages, total shipping weight, and total shipping charges sent to each destination by each shipping agent. The SAS code below first pulls data from the database (Northwind, in case you ve forgotten) and then uses the MEANS procedure to produce the data. By wrapping the ODS open and close lines around the MEANS procedure, the output is sent to an HTML file with a.xls extension. * Get the shipping agent, ship date, ship weight, shipping charge, and destination from Northwind database; proc sql; create table shipping as select b.companyname label='shipping Agent', a.shippeddate, a.freight label = 'Total Shipping Weight', case ShipperID when 1 then freight * 5 when 2 then freight * 3.50 when 3 then freight * 3.15 end as shippingcharge label = 'Total Shipping Charges', a.shipcountry label = 'Destination' from north.orders a inner join north.shippers b on a.shipvia = b.shipperid where '01Jul1996:00:00:00.00'dt <= a.shippeddate <= '01Oct1996:00:00:00.00'dt; quit; proc sort data=shipping; by shipcountry; run; * Put out the data to an HTML file with a.xls extension; ods html file="c:\reports\quarterlyshipping_q3_1996.xls"; title "Shipping Report: 3rd Quarter, 1996"; proc means data=shipping sum; class companyname; by shipcountry; var freight shippingcharge; run; ods html close; 10

If you opened the HTML file in Excel, you would see the following: The output above is something clients would be able to work with, but we might want to clean it up a bit before delivery. As in the previous examples, we can write a simple VBA macro to accomplish that result. Unlike the previous examples, we have written this code rather than recording it because we wanted to use a loop structure to apply the same logic to multiple tables. The VBA code below deletes unnecessary information, relabels items, and cleans up the display. Public Sub FormatQuarterlyShipping() 'Delete unneeded rows and columns Rows("3:4").Select Selection.Delete Shift:=xlUp Columns("C:C").Select Selection.Delete Shift:=xlToLeft 'Reset column widths Columns("A:A").ColumnWidth = 20 Columns("B:B").ColumnWidth = 15 Columns("C:C").ColumnWidth = 25 'Format report title Range("A1").WrapText = False Range("A1").Font.Bold = True 'Declare pointer/counter vars to navigate sheet Dim rowpointer As Integer Dim blankrowcount As Integer rowpointer = 3 blankrowcount = 0 11

'Traverse spreadsheet until five blank rows are found Do While blankrowcount < 5 If Cells(rowPointer, 1).Value = "" Then blankrowcount = blankrowcount + 1 Else 'If text is found, reset blank counter blankrowcount = 0 'If a new destination is found, format that table If Left(Cells(rowPointer, 1).Value, 11) = "Destination" Then 'General formatting Cells(rowPointer, 1).Select Rows(rowPointer + 1).Delete ActiveCell.Offset(1, 1).Value = "No. Packages" ActiveCell.Offset(1, 2).Value = "Statistic" ActiveCell.Offset(1, 3).Value = "Value" 'Figure out if this table has 1, 2 or 3 shippers Dim shippers As Integer If ActiveCell.Offset(4, 0) = "" Then shippers = 1 ElseIf ActiveCell.Offset(6, 0) = "" Then shippers = 2 ElseIf ActiveCell.Offset(8, 0) = "" Then shippers = 3 Else shippers = 0 End If 'Format data rows If shippers > 0 Then Range(ActiveCell.Offset(2, 0), ActiveCell.Offset(1 + (2 *_ shippers), 0)).HorizontalAlignment = xlleft Range(ActiveCell.Offset(2, 2), ActiveCell.Offset(1 + (2 *_ shippers), 2)).HorizontalAlignment = xlleft 'Set number formats for each shipper For i = 0 To shippers 1 ActiveCell.Offset(2 + (i * 2), 3).NumberFormat = "#,##0.00" ActiveCell.Offset(3 + (i * 2), 3).NumberFormat = "$#,##0.00" Next i End If 'Format table header Range(ActiveCell, ActiveCell.Offset(0, 3)).Select Selection.MergeCells = True Selection.HorizontalAlignment = xlcenter Selection.Borders(xlEdgeLeft).LineStyle = xlcontinuous Selection.Borders(xlEdgeLeft).Weight = xlmedium Selection.Borders(xlEdgeLeft).ColorIndex = 1 Selection.Borders(xlEdgeTop).LineStyle = xlcontinuous Selection.Borders(xlEdgeTop).Weight = xlmedium Selection.Borders(xlEdgeTop).ColorIndex = 1 Selection.Borders(xlEdgeBottom).LineStyle = xlcontinuous Selection.Borders(xlEdgeBottom).Weight = xlmedium Selection.Borders(xlEdgeLeft).ColorIndex = 1 Selection.Borders(xlEdgeRight).Weight = xlmedium Selection.Borders(xlEdgeRight).ColorIndex = 1 Selection.Borders(xlEdgeRight).LineStyle = xlcontinuous Selection.Interior.ColorIndex = 15 Selection.Interior.PatternColorIndex = xlautomatic End If End If rowpointer = rowpointer + 1 Loop End Sub 12

Here s the prettier output. ADVANTAGES The syntax is quite easy. If you don t care about the format of the data, you only need to wrap ODS open/close statements around your procedure calls. You can run more than one SAS PROC and have the results appear on the same worksheet. You can run this from BASE SAS (i.e., you don t need the SAS/Access to PC File Formats product). Your TITLE statements appear on the Excel worksheet. You have more control over the formatting of your Excel worksheet. For example, you can use the STYLE= option on the ODS statement to change the look of your output. Alternatively, you can create your own template using PROC TEMPLATE. DISADVANTAGES You can t write to discontinuous ranges (which would be important for highly formatted reports with variable data in columns and/or rows). You can t write to more than one worksheet at a time. You ll have to open the workbook in Excel and save the HTML file as an Excel file (if you care about that). WHEN TO USE When you have results from any PROCs that you want in Excel. When you want something quick and dirty, PROC EXPORT will do the trick. When you want something quick, dirty, and pretty, ODS HTML is for you. Note: If you want even more control over your ODS output to Excel, you will want to investigate ODS XML. A good place to start is Vincent DelGobbo s paper titled From SAS to Excel via XML (http://support.sas.com/rnd/papers/sugi29/excelxml.pdf). 13

DDE Dynamic Data Exchange (DDE) is an interprocess communication tool developed by Microsoft and first implemented in Windows Version 3.1. Although DDE is an older technology, it continues to be supported in Windows and Macintosh operating systems. DDE works by allowing two or more applications to exchange data with each other. For the purpose of producing Excel workbooks from SAS, we can have SAS open up a DDE conversation with Excel and pass data and commands to it. Here are a couple of good places to get started if you want to learn more about DDE: Ted Conway, Another Shot at the Holy Grail: Using SAS to Create Highly-Customized Excel Workbooks, SUGI 28 John He, ODS or DDE for Data Presentation A Preliminary Comparison of Output from Different Sources, SUGI 28 Lawrence Helbers and Alex Vinokurov, SAS Output to Excel: DDE and Beyond, NESUG 15 Christopher A. Roper, Using SAS and DDE to Execute VBA Macros in Microsoft Excel, SUGI 25 SYNTAX Opening a DDE Conversation: x templateworksheetname.xls ; x excelprogramfile.exe ; DDE filename statement to write to a worksheet region: filename <filename> DDE excel <worksheet>! <range> "; DDE filename to pass commands to Excel: filename <filename> DDE excel system ; Note: The SAS Institute has a sample program titled DDE Sample 3 that is a great resource for getting started with this syntax (http://ftp.sas.com/techsup/download/sample/samp_lib/hostsampdde_example_3 Sending_ Commands_.html). EXAMPLE In this example, we will use DDE to write the quarterly sales report developed in the DATA _NULL_ section above. Rather than producing the report for a single quarter, we ll show how DDE can write a report for each quarter to a different worksheet within the workbook. *Open up the template file in Excel; options noxwait noxsync; x "c:\reports\template.xls"; *Put SAS to sleep so that the operating system has time to do its business; data _null_; rc = sleep(1.5); run; * Define output ranges for exporting fiscal data; FILENAME Qtr1 DDE "excel Q1!r1c1:r250c4" notab; FILENAME Qtr2 DDE "excel Q2!r1c1:r250c4" notab; FILENAME Qtr3 DDE "excel Q3!r1c1:r250c4" notab; FILENAME Qtr4 DDE "excel Q4!r1c1:r250c4" notab; * Define DDE topic "system" in order to send commands to excel; FILENAME ddecmds DDE "excel system"; %macro makerpt(startdate, enddate, outfile, title); *This macro constructs a table of customer sales for the period between the start and end dates and writes the table out to the worksheet specified by outfile. The filename is declared as type dde, so the result will be printed in Excel; 14

proc sql; create table temp as select trim(e.firstname) ' ' trim(e.lastname) as Salesperson, c.companyname as Customer, sum(cost) as Sales from (select orderid, sum(unitprice * Quantity) as cost from north.orderdetails group by orderid) od inner join north.orders o on od.orderid = o.orderid inner join north.employees e on o.employeeid = e.employeeid inner join north.customers c on o.customerid = c.customerid where &startdate <= o.orderdate < &enddate group by trim(e.firstname) ' ' trim(e.lastname), c.companyname order by trim(e.firstname) ' ' trim(e.lastname), c.companyname; quit; data _null_; set temp; file &outfile; if _N_ = 1 then put 'Customer Sales Report' / &title // 'Sales Person' '09'x 'Customer' '09'x 'Sales Q3'; put Salesperson '09'x Customer '09'x Sales; run; %mend makerpt; %makerpt('01jan1997:00:00:00.00'dt, '01Apr1997:00:00:00.00'dt, Qtr1, '1st Quarter, 1997'); %makerpt('01apr1997:00:00:00.00'dt, '01Jul1997:00:00:00.00'dt, Qtr2, '2nd Quarter, 1997'); %makerpt('01jul1997:00:00:00.00'dt, '01Oct1997:00:00:00.00'dt, Qtr3, '3rd Quarter, 1997'); %makerpt('01oct1997:00:00:00.00'dt, '01Dec1997:00:00:00.00'dt, Qtr4, '4th Quarter, 1997'); data _null_; file ddecmds; *DDE is passing commands to Excel here; *Run a macro to format the workbook; put '[run("personal.xls!formatcustomersalesworkbook")]'; *Save the filled in template with a new file name; PUT '[save.as("c:\reports\quaterlycustomersales_1997.xls")]'; *End the connection by closing Excel; PUT '[quit()]'; run; 15

Here is one worksheet of the resulting workbook; the other worksheets are remarkably similar: To format all four sheets, we used VBA code slightly modified from the original DATA _NULL_ example. Public Sub formatcustomersales(sheetname) Sheets(sheetName).Select Columns("A:C").EntireColumn.AutoFit Columns("C:C").Style = "Currency" End Sub Public Sub formatcustomersalesworkbook() formatcustomersales ("Q1") formatcustomersales ("Q2") formatcustomersales ("Q3") formatcustomersales ("Q4") End Sub ADVANTAGES You can write to discontinuous ranges (which would be important for highly formatted reports with variable data in columns and/or rows). In other words, you have all the same advantages as DATA _NULL_ but none of the disadvantages. You can write to more than one worksheet in a workbook. DDE works by passing commands to Excel. If you happen to know the Excel 4 macro language, you can pass all those same commands to Excel. If you don t know the Excel 4 macro language, you might want to learn the basics (e.g., save as and quit), but everything else can be handled by calling VBA macros. You can run this from BASE SAS (i.e., you don t need the SAS/Access to PC File Formats product). 16

DISADVANTAGES There is a learning curve when you first set up DDE. In addition, there might be a few vexing things that you ll run across. The syntax is a little more challenging than using other methods. If Microsoft significantly changes how Excel or DDE works, you may have to rewrite or rework a lot of your code. WHEN TO USE When you have a report that needs to be done repetitively (e.g., one report for each subgroup or something that needs to be run daily). CONCLUSION In this paper, we have reviewed the four main methods available for moving data from SAS to Excel. The advantages and disadvantages of each method are summarized below: Difficulty of syntax Amount of code needed to create file to be read by Excel Multiple worksheets in a workbook DATA _NULL_ PROC EXPORT ODS HTML DDE Easy (if you know the PUT statement) Moderate to High Easy Low Easy Low Moderate to Hard Moderate to High Yes Discontinuous ranges Yes Yes PROC output directly Write multiple times to the same worksheet Ability to produce highly formatted reports Format from SAS Ability to call VBA macros from SAS Yes (and multiple PROCs as well) Yes Yes Yes High Low High Yes (PROC TEMPLATE, STYLE=) Yes Output is in Excel format Yes Yes Part of BASE SAS Yes Yes Yes REFERENCES Ted Conway, Another Shot at the Holy Grail: Using SAS to Create Highly-Customized Excel Workbooks, SUGI 28 Vincent DelGobbo, From SAS to Excel via XML, NESUG 2004 John He, ODS or DDE for Data Presentation A Preliminary Comparison of Output from Different Sources, SUGI 28 Lawrence Helbers and Alex Vinokurov, SAS Output to Excel: DDE and Beyond, NESUG 15 Christopher A. Roper, Using SAS and DDE to Execute VBA Macros in Microsoft Excel, SUGI 25 ACKNOWLEDGEMENTS We appreciate the little package known as Mary McCracken, who carefully read our paper and wrote our introduction. 17

CONTACT INFORMATION Your comments and questions are valued and encouraged. Contact the author at: Peter Godard SRI International 333 Ravenswood Ave Menlo Park CA 94025 Work Phone: (650) 859-5583 Email: peter.godard@sri.com Cyndi Williamson SRI International 333 Ravenswood Ave Menlo Park CA 94025 Work Phone: (650) 859-4912 Email: cyndi.williamson@sri.com SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other cou ntries. indicates USA registration. Other brand and product names are trademarks of their respective companies. 18