PUT, DBLOAD AND ODE: Three Ways to Export Data to Excel and Why To Use Them Doug Felton, Trilogy Consulting Corporation, Englewood, CO Frank Ferriola, Trilogy Consulting Corporation, Englewood, CO ABSTRACT No matter how good we think SAS is, in many situations, the end user needs to take the data from SAS and use it in another format, frequently Microsoft Excel. This paper will present three ways to get the data to the user for use in Microsoft Excel and the advantage/disadvantages of each of them. Using FILEIPUf, PROC DBLOAD and Dynamic Data Exchange (ODE), you can successfully output the data and avoid the frustrations that we encountered trying to get data to our clients. INTRODUCTION Recently, we were both on assignment at Kaiser Permanente. Both of our projects involved getting data from SAS into Excel in various forms. One project required over 40,000 records and IS variables to be placed into Excel. The other project required placing data in more than one place within a workbook. In this presentation, we are using Sample Data for the fictional D&F Children's Store, which has locations in 14 states in the US. We are examining their revenue and expenses for 1999 by Division and State. The data resides in a SAS Data Set with a filename of SASDATA.SAMPLE. (Table 1) Table 1 Sample Data for D&F Children's Store (Total Records 5,475) PROCDBLOAD Probably the easiest way to export data programmatically to Excel is to use PROC DBLOAD. PROC DBLOAD is a SAS procedure that comes with the SAS/Access for PC File Fortnats module. In version 6.12 it has a limit of 16,384 rows, so if you have more than that many observations to export, you'll need to use a DATA step with the Pur command (described above). PROC DBLOAD basically accomplishes the same thing as the SAS Export wizard, except it can be put into code (automated vs. manual). We'll just discuss the major features here. For a more complete description of the procedure, see the guide for SAS/Access for PC File Formats. PROC OBLOAD DBMS EXCEL DATA SASDATA.SAMPLE; PATH="C:\DATA\EXCEL \SAMPLE.XLS"; PUTNAMES YES; LIMIT=O; LOAD; NOTE: Load completed. Examine statistics below. NOTE: Inserted (5475) obs into SAMPLE.XLS. NOTE: Rejected {0) insert attempts see the log for deta1ls. When called up in Excel the file will look like Table 3 Table 2- Excel File Result of DB LOAD p;z co ID CA ID co CA ID co p;z r Stroller 9/27/99 4558.67 5292.38 Stroller 6/25/99 3350.18 4602.81 Stroller 2/3/99 4210.57 3509.02 stroller 4/29/99 3333.5 2986.89 Stroller 1/18/99 3547.03 5091.28 clothing 3/30/99 4896.01 4820.16 Stroller 5/1/99 4248.08 3273.2 clothing 2/17/99 4776.39 2814.75 clothing 1/27/99 5276.33 4838.22 Toys 3/12/99 4196.16 5378.48 C+ron11aro 7/')1; /00 1;.111 A:~ ~&;;.17 ')1 69
The PUTNAMES command tells SAS whether or not to export a header row. The LIMIT command tells SAS how many observations to export. However, to export all the observations, set LIMIT=O. We've written a simple SAS macro (OUTEXCEL) that uses PROC DBLOAD, and stored it in a SAS macro autocalllibrary. This enables us to easily call up the macro from any of our SAS programs any time that we need to dump data to Excel. The macro requires two input parameters: 1. The name of the SAS data set that you would like to export to Excel 2. The name of the Excel file that you would like SAS to write %MACRO OUTEXCEL(DSN,FN); PROC DBLOAD DBMS=EXCEL DATA= &DSN; PATH= 11 &FN"; PUTNAMES=YES; LIMIT~O; LOAD; %MEND; The SAS macro autocalllibrary is defined in by: OPTIONS SASAUTOS=path to autocalllibrary (e.g.- OPTIONS SASAUTOS c:/sas/macrolib) Your AUTOEXEC.SAS file is probably to best place to put this OPTIONS statement so that it will be executed every time you invoke a SAS session. Then, when you want to write out an Excel file from any of your SAS programs, just submit the macro: For Example: %0UTEXCEL(SASDATA.SAMPLE, C:\SAS\SAMPLE.xls); This will create the same log and Excel file as running the DBLOAD directly. A word of caution here: You cannot overwrite an existing file with PROC DBLOAD. If the file already exists, PROC DBLOAD will not execute. You can either manually move/delete the file first, or you could modify the OUTEXCEL macro to remove the file for you. DELIMITED OR FIXED FILES USING PUT The first way we are going to export data is using the PUT Statement to send the data out to a delimited file. First of all, we need to answer some questions to decide what kind of file we need to create. The first question we need to ask is which type of file do we need to create? We have two choices: Fixed or delimited. Fixed data would Create a file where the data would be columnar with each variable in the same place in each record. If we choose Delimited we would have to make some other decisions. A CSV (Comma Separated Variables) file automatically uses the comma (,) as a delimiter. You can set other delimiters, but every comma.will create a separate field. You need to be careful if you have commas in your data, or you may have unwanted variables or splits created. Another way we can delimit is to write out to a TXT file, in which we can choose the delimiting character. You can use a number of special. characters, but whatever you use, be careful if that character occurs in the data. It will cause a new variable to be made everytime it sees that character. Regardless of which file we choose, we also need to decide whether we want to include headers. Headers will place names for each of your columns in the first row of each column. The easiest file to create from a programming view would be the CSV file. This automatically places commas (,)between variables in the output data set. This is easily accomplished in SAS in the PUT Statement. If you choose a different delimiter, then the output should be sent out to a TXT file. If you choose a fixed file, you need to design the layout of the data by determining what is the maximum length of each variable. Otherwise you could lose parts of the data when you output. In our example we are going to create a CSV file: 70
LIBNAME SASDATA "C:\SAS"; FILENAME SALESCSV "C:\SAS\OUTSALES.CSV"; DATA _NULL_ ; SET SASDATA.SAMPLE; FILE SALESCSV; IF _NL=1 THEN PUT 'STATE,DIVISION,DATA,REVENUE,COST'; PUT STATE (DIVISION DATE REVENUE COST) (', '); Note that the first variable listed is before the parentheses and the delimiter is listed at the end (','). SAS will put the delimiter BEFORE each of the variables listed in the parentheses. The header is created with the IF _N_ =1 Statement. This will put the labels listed as the first record of the file. Each label is separated by the delimiter, in this case a comma and the entire record is put in single quotes. When executed the log will look like this: NOTE: The file SALESCSV is: FILENAME=C:\SAS\SALESCSV.CSV, RECFM=V,LRECL=256 NOTE: 5476 records were written to the file SALESCSV. The minimum record length was 30. The maximum record length was 40. NOTE: The DATA statement used 0.82 And the output file will look like Table 2. This table will contain 5,276 records with the flfst record being the header. After this file is created we can import it directly into Excel. First launch Excel and then click on FILE OPEN. At the bottom of the dialogue box that appears, click on the drop down box for ''Files of Type". Select "Text Files (*.pm; *.txt *.csv)". The file SALESCSV.CSV should now appear in your file list. If not, move to the directory that contains SALESCSV.CSV, select and open. The file will then load into the proper cells on the spreadsheet. If you saved to a.txt or.prn file there will be an intermediate step in which you have to tell Excel how to import the data, by using the delimiter or fixed width. An import wizard will appear to walk you through the steps. If it doesn't look right you can always import it again. 'l'able 3 CSV OtJ'l'PtJ'l' I'J:Ll!: State,Division,Date,Revenue,Cost AZ,Toys 01/01/1999,3695.63,4522.81 AZ,Stroilers,01/01/1999,3186.17,4578.66 AZ,Clothing,01/01/1999,4262.34,4459.95 AZ,Clothing,01/02/1999 6 3356.92 6 2868.06 AZ,Toys 01/02/1999,565.21,263.95 AZ,Stroilers,01/02/1999,5637.36,5200.23 AZ,Strollers 6 01/03/1999,4571.54,3984.67 AZ,Clothing, 1/03/1999,5334.17,2851.77 AZ,Toys,01/03/1999,4894.48,4128.88 AZ,Toys 01/04/1999,3505.65,2932.53 AZ,Stroilers 6 01/04/1999,3363.18,5247.66 AZ,clothing, l/04/1999,4815.92,2624.75 AZ,Clothing 6 01/05/1999t3573.01,4651.10 AZ,Toys 01/ 5/1999,478j.48,2763.43 AZ,Stroilers,Ol/05/1999,5663.34,3516.80 AZ,Strollers 6 01/06/1999,4760.45,3195.36 AZ,Clothing, 1/06/1999,3488.14,4629.40 AZ,Toys,01/06/1999,3510.89,3627.16 AZ,Toys 01/07/1999,3207.46,3658.90 AZ,Stroilers,01/07/1999,4673.41,4819.52 AZ,Clothing,Ol/07/1999,3423.86,5292.26 DDE <Dynamic Data Exchange) DDE provides a method for passing data and Excel macro commands from SAS into Excel. PUT and PROC DBLOAD are better alternatives for dumping large amounts of data into Excel, but DDE is great for populating particular ranges of cells in a spreadsheet. This makes DDE very powerful for reporting purposes. You can have SAS do all of the data manipulation, Excel do all the data manipulation, or any combination of the two. This also gives access to all of the formatting features available within Excel. The basic steps for passing data from SAS to Excel using DDE are: 1. Get your SAS data into it's final format (complete all data steps, proc summary steps, merges, etc.) 2. Execute the command that instructs SAS to open an Excel session 3. Pass any data/macro instructions from SAS to Excel Get your data into final format: Example We are going to choose the data for one state of our data, in this case Arizona. *DDE_EX. SAS; *Sums revenue and cost information for Toy Department for state of users choice; *Select state to report on; %LET STATE=AZ; PROC SUMMARY DATA=TOYS; VAR REVENUE COST; WHERE STATE="&sTATE"; 71
OUTPUT OUT=SUMTOYS SUM=; The execution log is: NOTE: The data set SASOATA.SUMTOYS has 1 observations and 4 variables. NOTE: compressing data set SASDATA.SUMTOYS decreased size by D.OO percent. Compressed is 1 pages; uncompressed would require 1 pages. NOTE: The PROCEDURE SUMMARY used 0.66 Instruct SAS to open a session in Excel Once your SAS data is ready to pass to Excel, you can instruct SAS to open Excel with the. following commands: OPTIONS NOXSYNC; X "&xlpath - pat:h and ri1ename or t:emp1at:e ri1e"; (e.g. - X "C:/MSOFFICE/EXCEL/EXCEL.EXE - C:/DATA/REPORTS/TEMPLATE.XLS";) It is probably best to set XLP A TH in your AUTOEXEC.SAS because upgrades to Excel may be installed to a different directory or the program could be run on a different machine where Excel is stored in a different path. This would prevent you from having to change multiple programs, instead you can modify one line in the AUTOEXEC.SAS file: %LET XLPATH- C:\MSOFFICE\EXCEL\EXCEL.EXE; SAS will only let you use 8 characters for a directory, while Windows 95 and above seemingly allows larger directory names. But in reality Windows only uses 8 characters with.a label that's longer. To find the 8 character equivalent to use in SAS Programs, open up the DOS Shell and use the DIR command to find the truncated name for files and directories. For example, the template file may have the name: C:\MyDocuments\Excel\template.xls However, if you open a DOS shell, this filename will appear as: C:\MYDOCU-1 \EXCEL\TEMPLATE.XLS You can now take this truncated name into your SAS program. The OPTIONS NOXSYNC statement tells SAS to run asynchronously with Excel. Otherwise, SAS will "sleep" until the Excel session is terminated. Next we execute a DATA _NULL_ step, which instructs SAS to "sleep" for a period of 7 seconds while the Excel session is getting started. If you do not do this step, SAS may try to pass data to Excel before Excel is open, causing an error. DATA _NULL X.,SLEEP(7); NOTE: The DATA statement used 7.08 Pass data/macro instructions to Excel Generally, there are two steps involved here; One, clearing any residual data in the template from previous executions. Two, exchanging actual data from SAS to Excel. Clearing residual data We recommend that before passing data through to Excel, that you use SAS to instruct Excel to execute a "CLEAR" macro. This macro should go through and clear all the cells that will be populated with data from SAS. Consider this example: A managed care organization provides coverage for an extremely large group and an extremely small group. The MCO runs a report to summarize costs group by group. If they run a report for the large group first, they may get several occurances of relatively rare medical procedures, for example a liver transplant. The data passed to Excel for this group may look like this: Group # 1000 Hospital Inpatient Hospital Outpatient Transplants $5,000,000 $2,000,000 $500,000 If this data is passed to Excel, and tbe template is saved with this data, the next time the report is run, with a group with no transplants, the report would look like this: Group#! Hospital Inpatient Hospital Outpatient Transplants $50,000 $20,000 $500,000 Because of this, it is recommended that you clear out all cells that could be populated with data from SAS before passing any data through. The 72
most simple method to do this is to use the Macro record function in Excel to create an Excel macro to clear all of these cells, and then issue a SAS command to execute this Excel macro. The command to execute in SAS would look like this: *Set the filename that will tell Excel to execute a system command FILENAME CMDS DDE 'EXCELISYSTEM'; DATA _NULL_; FILE CMDS; put '[RUN("TEMPLATE.XLS!CLEAR", FALSE)]'; run; In this example, the Excel Macro CLEAR is:. SUb CLEAR() ' CLEAR Macro ' Macro recorded 4/11/00 End sub Range("A1:A2").Select selection.clearcontents Range("B5:c7").select selection.clearcontents Range("A1"). Select The PUT statement in the SAS code above is actually an Excel4.0 style macro command. SAS 6.12 and below does not support passing Visual Basic style macro code. Here, we just use the PUT statement to call in a macro that is stored within TEMPLA TE.XLS. The '09'x is the method that SAS uses to "tab" to the next cell. This should be placed after all variables in your PUT statement except the last one. Note that the data in the DOE example is formatted with commas and decimal places. This is done in the Excel template and the settings are held when SAS sends the data to the file. When saving the Excel file, you should utilize the Save As command rather than a straight save. That way if you make changes to the spreadsheet, you won't alter the original template. Passing data from SAS to Excel We take the data that has been prepared in previous steps, and do a DATA _NULL_ step with a PUT statement. DATA _NULL_; SET SUMTOYS; FILENAME DATA DDE 'EXCELISheetl!R7C2:R7C3' NOTAB; FILE DATA; PUT REVENUE '09'x COST; You will see the following in the log: NOTE: The file DATA is: FILENAME EXCELISheet11R7C2:R7C4, RECFM-V,LRECL 256 NOTE: 1 record was written to the file DATA. The minimum record length was 22. The maximum record length was 22. NOTE: The DATA Statement used 1.1 73
CONCLUSION There are several methods for exporting data from SAS to Excel. Depending on your particular requirements, any one of these may be more appropriate than the others. All methods have advantages and disadvantages as shown in the Table below. Version 8 of SAS may alter the utility of some of these processes. For instance, an export wizard that can be implemented through code may make PROC DBLOAD useless. The Output Delivery System (ODS) may be sufficient, in some instances, so that using DDE to place data in an Excel template may no longer be necessary. However, using DDE to place data in Excel gives access to end-users to do their own custom formatting. Regardless of the capabilities of version 8, moving data from SAS to Excel using these methods will continue to work. BIOGRAPHY Doug Felton and Frank Ferriola have both been consultants at Trilogy Consulting Corporation since 1997. Doug has specialized in health care and cost/benefit analysis, while Frank has spent 16 years using SAS In health care financial systems. Email: Doug Felton: felton@mho.net Frank Ferriola: faferriola@yahoo.com Address for Both: Trilogy Consulting Corp. 9800 Mt. Pyramid Rd. Suite 400 Englewood, CO 80112 (J Additional step of importing data in Excel 0 Raw data dump only rows 0 Exports directly to.xls file Need SAS/Access for PC File (J DOE Data Exchange) o place in specific sheets, rows, and columns o Can place into existing workbooks (temolates) Can be tedious to code 0 Poorly suited to exporting large amounts of data REFERENCES SAS is a registered trademark of SAS Institute, Inc in the USA and other countries. SAS/Access to PC File Formats, Version 6, SAS Institute, Inc. SAS Language, Version 6, SAS Institute, Inc. SAS Guide to Macro Processing, Version 6, SAS Institute, Inc. Importing and Exporting Data with Excel using DOE, Beth Worrall, Kaiser Permanente SAS Users Group, 12199 74