Running Access Queries From Excel Using VBA

Share this

October 6, 2013

Running Access Queries From Excel Using VBA


Introduction


Two weeks ago, I published a VBA code for retrieving values from DBF (database) files. Some days after that post, I received some e-mail requests about doing the same, but for Access databases. More precisely, two readers (Josh and Maria) asked me to write two different VBA codes for running Access queries directly from Excel. I decided to “answer” both requests by writing this post since both are related to the same subject: Access queries.

In the next section, you will find two Excel VBA code snippets that show you how to retrieve data from an Access database. The idea behind both macros is the same:

  • Create and open a connection to the Access database.
  • Create a recordset that will contain the query results.
  • Create the necessary SQL select statement or set the query name.
  • Open the recordset.
  • If the recordset has data, write them into Excel.
  • Finally, close the recordset and the connection.

Both codes have many similarities and share a lot of code lines. Their main difference, however, is in the query part. The first code (CreateAndRunQuery) creates the query on the fly, while the second one (RunExistingQuery) uses an existing database query.

 


VBA code for running access queries


Both macros below use the Sample.accdb database, located in the same folder as the workbook. First, the CreateAndRunQuery macro is presented, which runs a query on the Customers table of the database, retrieving information (names, addresses, etc.) from all the customers from Canada.

Create and run Access queries on the fly

Option Explicit

Sub CreateAndRunQuery()
    
    '------------------------------------------------------------------------------------------
    'This macro opens the Sample.accdb database, creates and runs a SQL query (filtering
    'all the customers from Canada). Then, it copies selected fields back in the Excel sheet.
    'The code uses late binding, so no reference to an external library is required.
    
    'Written By:    Christos Samaras
    'Date:          05/10/2013
    'Last Updated:  29/11/2014
    'E-mail:        [email protected]
    'Site:          https://www.myengineeringworld.net
    '------------------------------------------------------------------------------------------

    'Declaring the necessary variables.
    Dim con         As Object
    Dim rs          As Object
    Dim AccessFile  As String
    Dim strTable    As String
    Dim SQL         As String
    Dim i           As Integer
            
    'Disable screen flickering.
    Application.ScreenUpdating = False
    
    'Specify the file path of the accdb file. You can also use the full path of the file like:
    'AccessFile = "C:\Users\Christos\Desktop\Sample.accdb"
    AccessFile = ThisWorkbook.Path & "\" & "Sample.accdb"
    
    'Set the name of the table you want to retrieve the data.
    strTable = "Customers"
    
    On Error Resume Next
    'Create the ADODB connection object.
    Set con = CreateObject("ADODB.connection")
    'Check if the object was created.
    If Err.Number <> 0 Then
        MsgBox "Connection was not created!", vbCritical, "Connection Error"
        Exit Sub
    End If
    On Error GoTo 0
    
    'Open the connection.
    con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & AccessFile
    
    'Create the SQL statement to retrieve the data from the table.
    'Get the necessary information (first name etc.) for all the Canadian customers.
    SQL = "SELECT FirstName, LastName, Address, City, Phone FROM " & strTable & " WHERE COUNTRY='Canada'"
    
    On Error Resume Next
    'Create the ADODB recordset object.
    Set rs = CreateObject("ADODB.Recordset")
    'Check if the object was created.
    If Err.Number <> 0 Then
        'Error! Release the objects and exit.
        Set rs = Nothing
        Set con = Nothing
        'Display an error message to the user.
        MsgBox "Recordset was not created!", vbCritical, "Recordset Error"
        Exit Sub
    End If
    On Error GoTo 0
         
    'Set thee cursor location.
    rs.CursorLocation = 3 'adUseClient on early  binding
    rs.CursorType = 1 'adOpenKeyset on early  binding
    
    'Open the recordset.
    rs.Open SQL, con
    
    'Check if the recordset is empty.
    If rs.EOF And rs.BOF Then
        'Close the recordset and the connection.
        rs.Close
        con.Close
        'Release the objects.
        Set rs = Nothing
        Set con = Nothing
        'Enable the screen.
        Application.ScreenUpdating = True
        'In case of an empty recordset display an error.
        MsgBox "There are no records in the recordset!", vbCritical, "No Records"
        Exit Sub
    End If
    
    'Copy the recordset headers.
    For i = 0 To rs.Fields.Count - 1
        Sheets("New Query").Cells(1, i + 1) = rs.Fields(i).Name
    Next i
    
    'Write the query values in the sheet.
    Sheets("New Query").Range("A2").CopyFromRecordset rs
    
    'Close the recordset and the connection.
    rs.Close
    con.Close
    
    'Release the objects.
    Set rs = Nothing
    Set con = Nothing
    
    'Adjust the columns' width.
    Sheets("New Query").Columns("A:E").AutoFit
    
    'Enable the screen.
    Application.ScreenUpdating = True

    'Inform the user that the macro was executed successfully.
    MsgBox "The Canadian customers were successfully retrieved from the '" & strTable & "' table!", vbInformation, "Done"

End Sub 

Here is the RunExistingQuery macro, which runs the existing qrRegions query. The particular query counts the number of customers from each region on the Customers table.

Run existing Access queries

Option Explicit

Sub RunExistingQuery()
    
    '------------------------------------------------------------------------------------
    'This macro opens the Sample.accdb database and runs the (existing) qrRegions query
    '(counting the number of customers from each region, based on table Customers).
    'Then, it copies all the query results back in the Excel sheet.
    'The code uses late binding, so no reference to an external library is required.
    
    'Written By:    Christos Samaras
    'Date:          05/10/2013
    'Last Updated:  29/11/2014
    'E-mail:        [email protected]
    'Site:          https://www.myengineeringworld.net
    '------------------------------------------------------------------------------------

    'Declaring the necessary variables.
    Dim con         As Object
    Dim rs          As Object
    Dim AccessFile  As String
    Dim strQuery    As String
    Dim i           As Integer
            
    'Disable screen flickering.
    Application.ScreenUpdating = False
    
    'Specify the file path of the accdb file. You can also use the full path of the file like:
    'AccessFile = "C:\Users\Christos\Desktop\Sample.accdb"
    AccessFile = ThisWorkbook.Path & "\" & "Sample.accdb"
    
    'Set the name of the query you want to run and retrieve the data.
    strQuery = "qrRegions"
    
    On Error Resume Next
    'Create the ADODB connection object.
    Set con = CreateObject("ADODB.connection")
    'Check if the object was created.
    If Err.Number <> 0 Then
        MsgBox "Connection was not created!", vbCritical, "Connection Error"
        Exit Sub
    End If
    On Error GoTo 0
    
    'Open the connection.
    con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & AccessFile
    
    On Error Resume Next
    'Create the ADODB recordset object.
    Set rs = CreateObject("ADODB.Recordset")
    'Check if the object was created.
    If Err.Number <> 0 Then
        'Error! Release the objects and exit.
        Set rs = Nothing
        Set con = Nothing
        'Display an error message to the user.
        MsgBox "Recordset was not created!", vbCritical, "Recordset Error"
        Exit Sub
    End If
    On Error GoTo 0
         
    'Set thee cursor location.
    rs.CursorLocation = 3 'adUseClient on early  binding
    rs.CursorType = 1 'adOpenKeyset on early  binding
    
    'Open the recordset.
    rs.Open strQuery, con
    
    'Check if the recordset is empty.
    If rs.EOF And rs.BOF Then
        'Close the recordset and the connection.
        rs.Close
        con.Close
        'Release the objects.
        Set rs = Nothing
        Set con = Nothing
        'Enable the screen.
        Application.ScreenUpdating = True
        'In case of an empty recordset display an error.
        MsgBox "There are no records in the recordset!", vbCritical, "No Records"
        Exit Sub
    End If
    
    'Copy the recordset headers.
    For i = 0 To rs.Fields.Count - 1
        Sheets("Existing Access Query").Cells(1, i + 1) = rs.Fields(i).Name
    Next i
    
    'Write the query values in the sheet.
     Sheets("Existing Access Query").Range("A2").CopyFromRecordset rs
    
    'Close the recordset and the connection.
    rs.Close
    con.Close
    
    'Release the objects.
    Set rs = Nothing
    Set con = Nothing
    
    'Adjust the columns' width.
    Columns("A:B").AutoFit
    
    'Enable the screen.
    Application.ScreenUpdating = True

    'Inform the user that the macro was executed successfully.
    MsgBox "All data were  successfully retrieved from the '" & strQuery & "' query!", vbInformation, "Done"

End Sub 

Both codes use late binding, so no reference to an external library is required. The Access queries that were used here were relatively simple to demonstrate the macros. Of course, you can use more complicated ones.

 


Downloads


Download

The zip file contains an Excel workbook containing the two macros presented above and a sample Access database. The workbook can be opened with Excel 2007 or newer.

 


Read also 


Read DBF Files Using VBA
Export A Large Access Table/Query To Excel
Add Records Into Existing Access Table From Excel Using VBA

Page last modified: May 16, 2021

Christos Samaras

Hi, I am Christos, a Mechanical Engineer by profession (Ph.D.) and a Software Developer by obsession (10+ years of experience)! I founded this site back in 2011 intending to provide solutions to various engineering and programming problems.

  • You are great. I used this code with my Access Database Name and path with My Query name, It work fine. I am happy to say Thanks.

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
    Add Content Block
    >