AD006 A Microsoft Access Based System, Using SAS as a Background Number Cruncher David Kiasi, Applications Alternatives, Upper Marlboro, MD ABSTRACT In Access based systems, using Visual Basic for Applications (VBA) to perform intensive number crunching is cumbersome and slow. Using ODBC, I have managed to use SAS as a background processing tool to perform these intricate calculations quickly. Also, the development time with SAS is far less than it would be with VBA for this use. In this application SAS works in the background and never interfaces directly with the user. REASONS FOR USING THE MICROSOFT ACCESS / SAS HYBRID What are some of the reasons why one would use this setup? SAS is superior to most software packages with regard to number crunching. Talk to any statistician and many will say that SAS is the application development environment of choice when it comes to performing statistical calculations. You already have a Microsoft Access system and want to add complex reports. Your organization is made up of SAS specialists, not VBA specialists. Because the algorithms that the reporting is based on are complex in nature, it would be better to have this high level of code be in a language that can be maintained by other staff. Your organization has not invested, staff and software wise, significantly in SAS A/F. Microsoft Access, however, is a user friendly tool that allows users to quickly develop an interactive form dialog that can handle many typical functions. Also, it is much more affordable. In the labor market, unlike Visual Basic, there are a number of casual Microsoft Access users. WHAT STEPS THE USER MUST GO THROUGH TO PROCESS OUTPUT USING THIS SET-UP So what do you need to do to get this to work? First and foremost, your SAS installation must be able to support ODBC. SAS Learning Edition does not support ODBC. A Microsoft Access Form must be developed that invokes the Microsoft Access Macro that produces the report. A Microsoft Access Macro must be developed to execute each step that is used to process the report. Microsoft Access modules must be created to ensure that each step in the process is done in order. A Microsoft Access Report object must be created to produce the report from a Microsoft Access table created from the SAS file. The SAS code must use a LIBNAME statement to link to the Access data base. EXAMPLE SYSTEM The example used in this paper is Applications Alternatives own Customer Satisfaction Survey System. Within Microsoft Access, we run a SAS program that uses parameters from the Microsoft Access form. This program uses PROC MEANS to compute the Standard Error, so that a significant difference of the percent satisfied over time periods can be calculated. The output dataset produced will be imported back into Microsoft Access, enabling the user to have instant access to his/her results. SAS Version 8.2 and Microsoft Access XP (2002) is used. 1
CREATING THE FORM The following is the Microsoft Access Form used to process the report: When we click, Event Procedure, on the window, the following VBA code is shown: Private Sub Command24_Click() On Error GoTo Err_Command19_Click DoCmd.RunMacro "Custsat" Exit_Command24_Click: Exit Sub Err_Command24_Click: MsgBox Err.Description Resume Exit_Command24_Click End Sub This simple code, which simply runs one Macro, can be generated using a Microsoft Access Wizard, where the error processing code, shown above, is automatically generated. DEVELOPING THE MICROSOFT ACCESS MACRO The button, Create the Report, is the one used to produce the report in our example. In Microsoft Access, we must get into design mode and click this button. Then, we choose the Properties window and, within it, display the Event window. We are running the Macro with a click to the button on the Form, so we are using the, On Click, action on the Event Window. The following is the Microsoft Access Macro that processes the report. Details will be explained as I go through the specific steps, below: 2
NO NEED TO CREATE A MICROSOFT ACCESS DATA SOURCE Using a SAS LIBNAME statement that links to the Microsoft Access database in the SAS version 8 program eliminates the need to create a Microsoft Access Data Source. However, you may find that your Microsoft Access ODBC driver is not working correctly. At your work site, you may find that on one PC, your application works fine but on another one that looks as if its configured the same on the surface, does not. You will need help with your system support staff to solve this problem if it comes up. DELETING THE EXISTING REPORT TABLE WITH THE MICROSOFT ACCESS MACRO The Microsoft Access report object reads a Microsoft Access table that is created by the SAS program. It permanently resides in the Microsoft Access database. The table is replaced each time a report is processed. If, however, there is a problem that prevents this table from being replaced, the report may use the previous table, which shows outdated information. To prevent this, the Microsoft Access Macro deletes this table before anything else is done. This way, the user never inadvertently produces a report from old results. This is the first step in the Microsoft Access Macro used in the example. THE SAS PROGRAM The way to run a SAS program from Microsoft Access is to run it in batch mode. To do this, make a copy of the sasv8.cfg file calling it csrun.cfg with lines added that run the program. The lines added to the end of the configuration file are as follows: -sysin c:\marketing\custsat.sas -log C:\marketing\custsat.log This new configuration file will be executed by a, Run App, action from the Microsoft Access Macro. In the command line field, the following has been entered: C:\program files\sas institute\sasv8\sas.exe -config c:\marketing\csrun.cfg One can get around the use of the CFG file but the universality of your application may be jeopardized. MICROSOFT ACCESS MODULES TO CONTROL EXECUTION One of the problems that one encounters developing such an application is how to prevent the Microsoft Access Macro from continuing to execute while the batch SAS program is running. The solution is to develop one or more Microsoft Access Modules that force the Macro to wait until the SAS program is finished. Using the, Run Code, statement, the first module is shown below: Public Function Waiting() As Boolean Dim Start As Variant Dim dif As Variant Start = Time Do DoEvents dif = DateDiff("s", Start, Time) Loop Until dif > 10 Waiting = True End Function It halts the Macro for 10 seconds to give the batch SAS program enough time to be loaded. The second Module reads the display, waiting for the batch SAS window to disappear from the screen before allowing the Macro to continue to execute: Option Compare Database Option Explicit Declare Function FindWindowEx& Lib "user32" Alias "FindWindowExA" (ByVal hwndparent As Long, ByVal hwndchildafter As Long, ByVal lpclassname As String, ByVal lpwindowname As String) Public Function WaitUntil() As Boolean Dim lresult As Long Do DoEvents lresult = FindWindowEx(0, 0, vbnullstring, "BATCH SAS") Loop Until lresult = 0 WaitUntil = True End Function 3
An additional call to functon Waiting is necessary to allow the software to complete the creation of the Access table by the SAS program after the batch SAS session has completed. THE SAS CODE THAT READS AND WRITES TO THE MICROSOFT ACCESS TABLE In SAS Version 8 all one has to do is have the Microsoft Access ODBC driver installed on the PC and the use of the following LIBNAME statement to read and write Microsoft Access tables from SAS: libname OUT odbc complete="dsn=msacccess; dbq=c:\marketing\cs_stat.mdb; UID=Admin"; The SAS program performs the calculations and enters them directly into the Access table that will be used by the Access Report object. The user now can print the report, save it as a file, or delete it, within the default controls that exist within Microsoft Access. THE REPORT OBJECT The final step in the Macro, is to open our Microsoft Access report object. The design window for this object is as follows: OTHER APPROACHES There are other approaches to creating a Microsoft Access/SAS hybrid system. First, if one does not have ODBC available, one could generate a text file with Microsoft Access and read that into SAS. Then, SAS would generate another text file that would be imported into Microsoft Access. The downside is that the application would be slowed down by doing two text to binary conversions. Second, one could execute a SAS program from Microsoft Access and generate a SAS report, saved in RTF format. Then, Access could open a Word session that would import the RTF file. The upside to this is that the end user may prefer his report to be in Word. This is much easier than writing Microsoft Access data into Word using bookmarks. CONCLUSION The report, when produced, looks as follows: Users can effectively combine SAS with Microsoft Access to create an application that is superior to either 4
one by itself in terms of development time, speed, and cost. ACKNOWLEDGEMENTS SAS is a registered trademark of the SAS Institute, Inc., Cary, NC, USA Access is a registered trademark of the Microsoft Corporation, Redmond, WA, USA AUTHOR CONTACT David Kiasi Applications Alternatives P.O. Box 4238 Upper Marlboro, Md., 20775 (301) 350-4752 Fax: (301) 350-4752 Email: david.kiasi@appalt.com Web page: www.appalt.com 5