Connecting to SQL Server from Excel using ADO (Active X Data Objects) First of all to use ADO you have to add a reference to its Object Library. Go to the VB Editor, click Tools, then References. Type an M to see the entries beginning with M, scroll down till you find Microsoft ActiveX Data Objects 2.8. Click in the adjacent checkbox, and then click the OK button. This should add the references. Use Tools References again to check that the library for ADO has been added and close the window. Connecting to a SQL Server Database The trickiest aspect of all is to establish a working connection string. This could be put into a string variable, but for a little more convenience here it is typed into a public constant and so can be used by any of the subs in the workbook. For example, Public Const gstrCONNcompany As String = _ "Provider = SQLOLEDB;" & _ "Data Source=localhost;" & _ "Initial Catalog=Company;" & _ "User ID=sa;Password=niceday;" & _ "Network Library=dbmssocn" The parameters are as follows: Provider = SQLOLEDB always this for SQLServer Data Source = servername usually the NetBIOS name of the computer where SQL Server is installed, with the syntax NetBIOS name\SQL Server name For example, Data Source=Dell500\Dell500 (for me it is set to localhost because I am running an installation of Ms SQL Server Express Edition 2005 on the same laptop as the spreadsheet) Initial Catalog=database name one instance of SQL server can contain many databases; here I connect to a database called Company User ID=username;Password=password for SQL server authentication Network Library= here I am using TCP/IP protocol for which the setting is the name of the TCP/IP network library, which is dbmssocn 1 Integrated Security=SSPI you would use this if you were using Windows integrated security rather than SQL server authentication and the named pipes connection protocol. No need to supply the User ID and Password as it would be ignored It’s all rather technical and can take a while to sort out, but once it’s done it’s done. Find a local guru for further advice. Connect to a database with a plain text SQL query If you get this far you can try some examples. The first is the simplest, it just uses an SQL query in a string variable. You need to be familiar with SQL basics to understand it. Sub Dim Set Dim Set Dim ConnectCompany1() cn As ADODB.Connection cn = New ADODB.Connection rs As ADODB.Recordset rs = New ADODB.Recordset strSQL As String cn.Open gstrCONNcompany 'uses the connection string from above strSQL = "Select * FROM SalesOrder " & _ "WHERE CustomerID = 'ELIT01' " & _ "ORDER BY OrderDate" rs.Open strSQL, cn, , , adCmdText Range("A1").CurrentRegion.Clear ActiveSheet.Range("A1").CopyFromRecordset rs ActiveSheet.UsedRange.EntireColumn.AutoFit rs.Close Set rs = Nothing Set cn = Nothing End Sub The ADO components in the above example are the use of Connection and Recordset objects (which are beyond a simple explanation); however the good news is that the code is the same every time, and can be pasted into any sub you create. Finally there are three Excel VBA lines; the significant line is the CopyFromRecordset method of a range, and just provide the name of the recordset variable. This dumps all the data to the worksheet without the need for a loop. Using Stored Procedures Stored procedures are saved SQL statements that are stored on the database. You can connect to them from Excel VBA and copy the data. First, another connection string to use a database called Books Public Const gstrCONNbooks As String = _ "Provider = SQLOLEDB;" & _ "Data Source=localhost;" & _ "Initial Catalog=Books;" & _ "User ID=sa;Password=niceday;" & _ "Network Library=dbmssocn" 2 The stored procedure in the Books database is called GetTitles and is as follows: CREATE PROC GetTitles AS SELECT ISBN, Title FROM Book ORDER BY Title and the code: Sub Dim Dim Set Dim Set ConnectBooks() cn As ADODB.Connection cmd As ADODB.Command cn = New ADODB.Connection rs As ADODB.Recordset rs = New ADODB.Recordset cn.Open gstrCONNbooks Set cmd = New ADODB.Command Set cmd.ActiveConnection = cn cmd.CommandText = "GetTitles" cmd.CommandType = adCmdStoredProc Set rs = cmd.Execute Range("A1").CurrentRegion.Clear ActiveSheet.Range("A1").CopyFromRecordset rs ActiveSheet.UsedRange.EntireColumn.AutoFit rs.Close Set Set Set End rs = Nothing cn = Nothing cmd = Nothing Sub The ADO code uses a third type of object, the Command object. The interaction between the Connection, Recordset and Command is now more complicated, but again it follows the same pattern every time so can be copied and reused – just ensure your variable names are consistent within any given sub. Using Stored Procedures with parameters Finally, we go back to the Company database for an example of how to send a parameter to a stored procedure. The procedure is called spGetCustomerNames and uses a table called Customer. The parameter, City, will be supplied from the VBA code. CREATE PROC spGetCustomerNames @City nvarchar(25) AS SELECT CustomerID, CustomerName, Address1, City FROM Customer WHERE City = @City ORDER BY CustomerName Finally the VBA code: Sub ConnectCompanywithStoredProcedure() Dim cn As ADODB.Connection Set cn = New ADODB.Connection 3 Dim rs As ADODB.Recordset Set rs = New ADODB.Recordset Dim cmd As ADODB.Command cn.Open gstrCONNcompany Set cmd = New ADODB.Command Set cmd.ActiveConnection = cn cmd.CommandText = "spGetCustomerNames" cmd.CommandType = adCmdStoredProc Set rs = cmd.Execute(, "London") Range("A1").CurrentRegion.Clear ActiveSheet.Range("A1").CopyFromRecordset rs ActiveSheet.UsedRange.EntireColumn.AutoFit rs.Close Set rs = Nothing Set cn = Nothing Set cmd = Nothing End Sub The parameter ("London") is supplied in the second argument of the cmd.Execute method. Just change the parameter to another City for a different recordset (or better still, concatenate in a reference to a List Box which has the cities as values.) 4