Those who work with Excel like having their data right there, at their fingertips, where they can edit, format, and analyze the information--you know, give it a good scrub.
Ever notice how accountants feel about their desktop spreadsheet application? Insistent, aren't they? That's because they can be much more productive when they have their familiar software at hand. So what can you do when your users' desktop application and the data they want to access are not at all near one another? This article shows how to bring your Excel users and their data together.
Microsoft Excel is the standard among desktop spreadsheet applications, and it enjoys a very high acceptance rating and degree of loyalty from its millions of users. Excel is so ubiquitous now that everyone who works with numbers knows what an .xls or .xlsx file is. You can feel confident that if you send an Excel spreadsheet as an email attachment to someone, the recipient would be capable of working with it. The challenge, then, is to bring information from a database like Oracle, MS Access, MySQL, or DB2 on the System i into an Excel spreadsheet. Turns out, it's not all that hard.
Two Ways to Get External Data into Excel
There are two approaches to importing external data into an Excel spreadsheet:
- You can use Excel's built-in feature for importing external data. It's very easy to use and provides generally satisfactory service. You can create a Microsoft Query specification that will join distinct files together by specified relationships, filter data records by content, or place records in some sorted order. In short, the query can specify anything that SQL is capable of. The query is then used during the data transfer process to determine what records to transfer and how they are ordered.
- When a higher degree of control is required, one must turn to Excel's built-in macro language: Visual Basic for Applications (VBA). VBA gives you fine-grained programming instructions, allowing you to perform complex data manipulation, calculations, and formatting. Pretty much anything you can do manually in Excel, you can do with a VBA macro (indeed, Excel includes a Macro Recorder that monitors manual operations in a spreadsheet and generates the corresponding VBA instructions). When accessing external data with an Excel macro, however, you must code the connectivity specifications yourself.
Both methods of accessing external data from within Excel depend on a database-specific connectivity driver called a data provider.
Data Providers: ODBC and OLE DB/ADO
Getting database information into an Excel spreadsheet relies on a data provider. A data provider is a driver that can form a bridge between a database and an enabled external application like Excel. Two dominant technologies are currently in use for data providers: Open Database Connectivity (ODBC) and Object Linking and Embedding Database (OLE DB). Note Microsoft's technology for implementing OLE DB is called ActiveX Data Objects (ADO).
Each database will have a matching ODBC or OLE DB data provider (or both) that will form the conduit linking a database and Excel. Therefore, before you can transfer records from a database to Excel, you must acquire the matching data connectivity provider.
Most databases will install the matching ODBC and/or OLE DB driver(s) automatically as part of the installed package. Occasionally, though, you may have to augment the database setup process by downloading the driver separately and installing it.
Using Excel's Built-In Features to Import External Data
When setting up Excel's built-in services for accessing external data, you'll be interacting with a series of screens that help you establish the connection and transfer the data. This method of accessing external data enlists the services of a little-hailed sub-feature of Microsoft Office: MS Query. MS Query is used by Office applications but is not known to be a standalone application; however, it can be used independently of mainstream Office applications.
To access external data from within Excel, start a new spreadsheet or workbook and select Data > Get External Data > From Other Sources. Then select From Microsoft Query, which will use the external database's ODBC driver to link to the database.
(Note these instructions apply to Excel 2007; different versions of Excel will vary slightly. Also note that even though there's an option button labeled From Access, these instructions apply to Access as well. The button is just a shortcut.)
On the dialog box that comes up, select New Data Source. The ensuing screen will ask you for a name to apply to this data source and an ODBC driver that should be associated with it. You may open a list of the available drivers that are installed on your computer and select from there (this is a good way to see what you've got installed as well). Select the appropriate driver and click OK. The screens that appear next will depend on the database you're connecting to, asking perhaps for a URL, user ID, and password (as is the case when connecting to a System i) or for a local folder and database. When you complete the connection screens, select the data source you just created and click OK. You'll see a list of the available tables/files in the database (Figure 1). From these tables, select the columns/fields of interest.
Figure 1: Select files and columns with the Query Wizard.
The next screens prompt you for specifications as to how to filter and sort your data and then finally for a location within your spreadsheet where the imported records will be inserted.
Note that importing records from a database into Excel in this manner is a one-way transfer. That is, the data is copied from the database into your spreadsheet, but the spreadsheet and the database are not linked. Any changes made to the imported data in the spreadsheet will not be reflected in the original database.
Accessing a Database from an Excel Macro
Often, Excel's built-in support for importing external data doesn't give you enough control. For example, you might want to specify a System i physical file member other than *FIRST, or you might want to place imported data into specific spreadsheet cell locations. For these situations, you can enlist the services of an Excel macro and its scripting language, VBA.
Included with Excel is a version of Microsoft's IDE for VBA. The VBA editor in Excel allows you to create a script that can establish a connection to a database, import data, manipulate the data within the spreadsheet, and even perform updates to live data in the database.
I'll present two example Excel macros: one for accessing a MySQL database with ODBC and one for accessing System i data with OLE DB/ADO.
Accessing a MySQL Database with an Excel Macro and ODBC
Again, you must have the correct ODBC driver for the database you're accessing. In the case of MySQL, you have to download and install the mySQL connector that matches your version (see
mySQL connector for ODBC for more information). Once the driver is installed, you must create a Data Source Name (DSN), which is just a configuration object that details the connection to the database (ODBC driver to use, database to access, user ID and password, plus other options). To create a DSN, go to Control Panel > Administrative Tools > Data Sources (ODBC). Click the System DSN tab and then the Add... button. Scroll to MySQL ODBC x.x Driver, select that driver, and click Finish. Fill in the next screen's login panel with a name for your DSN and a server name (specify a URL or use localhost for a database on this same PC). See Figure 2.
Figure 2: Set up a Data Source Name (DSN).
On the Connect Options tab, enter a value of 3306 for Port (the default) and click OK to finish. Any entries that you don't fill in here (like User and Password) must be supplied to MySQL when you run your Excel macro.
Now you're ready to create an Excel macro inside of a spreadsheet. Start Excel and create a new workbook. Click the Developer tab and then Macros. Type a name for your macro into the top of the next dialog box (mySQL_macro is used in this example) and click Create. This will open the VBA script editor that lurks within Excel (Figure 3).
Figure 3: Use Excel's VBA script editor.
You must tell VBA that you will be using additional tools for accessing data, so click on the Tools menu and select References.... Put a checkmark next to Microsoft DAO 3.xx Object Library and click OK.
Click inside of the editing panel and insert the following statements between the Sub and End Sub statements. Then substitute your own values for the placeholders (TABLENAME, DATABASENAME, USERID, PASSWORD, FIELD1, and FIELD2).
' Example macro for accessing MySQL data with the ODBC driver...
Dim dbmySQLData As Database
Dim rsmySQLData As Recordset
Dim sQry As String
Dim sWork As String
Dim lWork As Long
' Example SQL statement. Change for your file...
sQry = "SELECT * FROM TABLENAME"
' Specify your ODBC data source name on the next line plus any values
' that weren't included in the DSN configuration (like user ID and password)...
Set dbmySQLData = OpenDatabase("", False, False, _
Set rsmySQLData = dbmySQLData.OpenRecordset(sQry, dbOpenDynaset)
' Load a couple of MySQL fields into non-contiguous cells...
Do While Not rsmySQLData.EOF
lWork = lWork + 2
Range("A" & CStr(lWork)).Select
ActiveCell.FormulaR1C1 = rsmySQLData!FIELD1 ' Change FIELD1 to your field name
Range("B" & CStr(lWork)).Select
ActiveCell.FormulaR1C1 = rsmySQLData!FIELD2 ' Change FIELD2 to your field name
' Release object resources...
Set rsmySQLData = Nothing
Set dbmySQLData = Nothing
The macro will establish a connection to a MySQL database, issue an SQL statement to the server to request a recordset, and then iterate through the records, loading them into non-contiguous cells in the Excel spreadsheet.
From the File menu, select Close And Return To Microsoft Excel. Click Macro, select your macro, and click Run. If all is well, data should come into your spreadsheet, occupying every other cell.
Accessing System i Data with an Excel Macro and OLE DB/ADO
Sometimes, it's easier to deploy a database application that's based on OLE DB/ADO because ADO doesn't depend on a DSN configuration. This second example is very similar to the first one; only the data access technology is different--this time with ADO. In this case, OLE DB/ADO is used to connect to a System i and submit an SQL command. As with ODBC, a recordset is returned that can be read under your explicit control.
Accessing data through ADO requires an object similar to an ODBC driver called an ADO Data Access Provider, and the System i database is no different. Normally, the ADO provider for the System i (named IBMDA400) is automatically installed with the System i Express Client package.
To put this example into practice, start a new Excel workbook. Click the Developer tab and then the Macro button. Type a name for your macro (ADOMacro is used in this example), and click Create.... Again, you'll have to set a reference to a library of data-handling routines, but a different library this time. Click Tools and then References... Find Microsoft ActiveX Data Objects x.x Library and put a check next to it. Then click into the editor and insert the following statements between Sub and End Sub. Finally, change the code for the placeholders (HOSTURL, USERID, PASSWORD, LIBRARY, FILENAME, FIELD1, and FIELD2), substituting your own values.
'This macro show how to use the System i OLE DB /ADO
' data access provider...
'NOTE: You must have Microsoft OLE DB support and
' IBM's OLE DB/ADO data access provider
' (IBMDA400) installed on your PC.
'NOTE: You also have to set a reference to
' "Microsoft ActiveX Data Objects x.x Library"
' ("Tools" menu, "References")
' Define objects...
Dim objConnection As ADODB.Connection
Dim objCommand As ADODB.Command
Dim objRecordSet As ADODB.Recordset
Dim lWork As Long
' Create objects...
Set objConnection = New ADODB.Connection
Set objCommand = New ADODB.Command
Set objRecordSet = New ADODB.Recordset
' Change the following line for your System i' host name or URL, userid and password
objConnection.Open "Provider=IBMDA400;Data Source=HOSTURL;", "USERID", "PASSWORD"
Set objCommand.ActiveConnection = objConnection
' Put your System i file name in next line...
objCommand.CommandText = "LIBRARY/FILENAME(*FIRST, *FIRST, *NONE)"
objCommand.CreateParameter("P1", adChar, adParamInput, 1)
' Execute the request for a cursor...
Set objRecordSet = objCommand.Execute(varRcds, varParms, adCmdTable)
Do While Not .EOF
' Put some System i fields in Excel cells...
lWork = lWork + 2
Range("A" & CStr(lWork)).Select
ActiveCell.FormulaR1C1 = lWork
Range("B" & CStr(lWork)).Select
ActiveCell.FormulaR1C1 = .Fields("FIELD1") ' Substitute your field name here...
Range("C" & CStr(lWork)).Select
ActiveCell.FormulaR1C1 = .Fields("FIELD2") ' Substitute your field name here...
' Be sure to release the object's resources...
Set objRecordSet = Nothing
Set objCommand = Nothing
Set objConnection = Nothing
This macro also returns a set of records from the System i and populates every other row of a spreadsheet.
Writing your own macro also has the advantage of being capable of sending data changes back to the database through SQL's UPDATE statement. Similarly, you can execute other SQL commands to create a new table, add records, delete records, etc.