Running an Access Parameter Query from Excel

October 19, 2009 by datapig Leave a reply »

An Access parameter query is a kind of interactive query that prompts you for criteria before the query is run. Parameter queries are useful when you need to ask the query different questions using different criteria each time you run it.

Now we all know you can pull data from Access into Excel using MS Query. The problem is that MS Query doesn't let you pull in Parameter queries. There may be a technical reason for this, but I like to think it's just Microsoft's way of keeping things interesting. After all, technical roadblocks are the spice of life.
If you've had enough spice, I'll show you a VBA workaround that will enable you to run an Access parameter query from Excel.

 

The Problem:

I've built this parameter query in Accesss. This particular query will ask the user for a Region and a Business Segment. This works fine in Access.

I've named this query MyParameterQuery.

 

The problem is when I try to connect to this query via MS Query in Excel, I don't see it in the list. It turns out that Parameter queries are not available in list of connectable objects.

 

Even if I try to get cocky, brute forcing MS Query to look at the query, I get the dreaded "Too Few Parameters" error.

 

 

The Solution:

My solution is to use a bit of VBA to pull the data based on parameters you enter directly into Excel.

The first step is to set up a spreadsheet like the one shown here.  You'll notice that the needed parameters will be fed from Cells D3 and D4.

 

Once your spreadsheet is ready to go, switch over to VBA and enter this code into a standard module.

Note: You will need to add a reference to the Microsoft DAO XX Object Library (where XX represents the latest version you have) .

 

Visual Basic:
  1. Sub RunParameterQuery()
  2.  
  3. 'Step 1: Declare your variables
  4. Dim MyDatabase As DAO.Database
  5. Dim MyQueryDef As DAO.QueryDef
  6. Dim MyRecordset As DAO.Recordset
  7. Dim i As Integer
  8.  
  9. 'Step 2: Identify the database and query
  10. Set MyDatabase = DBEngine.OpenDatabase _
  11. ("C:\Integration\IntegrationDatabase.accdb")
  12. Set MyQueryDef = MyDatabase.QueryDefs("MyParameterQuery")
  13.  
  14. 'Step 3: Define the Parameters
  15. With MyQueryDef
  16. .Parameters("[Enter Segment]") = Range("D3").Value
  17. .Parameters("[Enter Region]") = Range("D4").Value
  18. End With
  19.  
  20. 'Step 4: Open the query
  21. Set MyRecordset = MyQueryDef.OpenRecordset
  22.  
  23. 'Step 5: Clear previous contents
  24. Sheets("Main").Select
  25. ActiveSheet.Range("A6:K10000").ClearContents
  26.  
  27. 'Step 6: Copy the recordset to Excel
  28. ActiveSheet.Range("A7").CopyFromRecordset MyRecordset
  29.  
  30. 'Step 7: Add column heading names to the spreadsheet
  31. For i = 1 To MyRecordset.Fields.Count
  32. ActiveSheet.Cells(6, i).Value = MyRecordset.Fields(i - 1).Name
  33. Next i
  34.  
  35. MsgBox "Your Query has been Run"
  36.  
  37. End Sub

 

After the code is ready, running it will make data magically appear based on your parameters!

Who needs MS Query?

 

This technique allows you to build some interesting reporting solutions with relatively little effort.

RELATED STUFF

  1. Using Access to Combine Multiple Excel Files: Method 1
  2. VBE Tips I Wish I Knew 5 Years Ago
  3. Sending Data to Excel using Access SQL
  4. Using Access to Combine Multiple Excel Files: Method 2
  5. Passing Multiple Values to One Parameter
  6. Using the Switch Function in Excel
  7. Special Characters are a Pain in the Asterisk
  8. Why is Excel so Negative about Hiding Subtotals
  9. Why Replace the DOM Interface
  10. Sending Variable Access Data To An Excel Range
Advertisement

70 Responses

  1. Ghh says:

    datapig: Thanks for the reply. It's not working though, I think I made a mistake here. This is the new code. It's returning the error "Compile error: Invalid outside procedure"

    Defects_Master.Execute "qry_FPY_CustomDates", dbFailOnError
    Defects_Master.Execute "qry_FPY_CustomeDates", dbFailOnError
    Sub RunParameterQuery()
    'Step 1: Declare your variables
    Dim Defects_Master As DAO.Database
    Dim MyQueryDef As DAO.QueryDef
    Dim MyRecordset As DAO.Recordset
    Dim i As Integer
    'Step 2: Identify the database and query
    Set Defects_Master = DBEngine.OpenDatabase _
    ("D:\Documents and Settings\e479196\Desktop\FPY & TPY\Defects_Master.mdb")
    Set MyQueryDef = Defects_Master.QueryDefs("qry_FPY_CustomDates")
    'Step 3: Define the Parameters
    With MyQueryDef
    .Parameters("[Enter Start Date]") = Range("C2").Value
    .Parameters("[Enter End Date]") = Range("C4").Value
    .Parameters("[Enter Cell Name]") = Range("C6").Value
    .Parameters("[Enter Material Number]") = Range("C8").Value
    End With
    'Step 4: Open the query
    Set MyRecordset = MyQueryDef.OpenRecordset
    'Step 5: Clear previous contents
    Sheets("Main").Select
    ActiveSheet.Range("A14:K10000").ClearContents
    'Step 6: Copy the recordset to Excel
    ActiveSheet.Range("A15").CopyFromRecordset MyRecordset
    'Step 7: Add column heading names to the spreadsheet
    For i = 1 To MyRecordset.Fields.Count
    ActiveSheet.Cells(14, i).Value = MyRecordset.Fields(i - 1).Name
    Next i
    MsgBox "Your Query has been Run"
    End Sub

  2. FranckF @ STE says:

    Hi all,

    You do not need VBA code to perform this.
    - create an ODBC Data Set using your Access 2003 DB.
    - Then create a simple query without parameters inside.
    - In excel 2007 do a "Data" / "From Other Sources" / "From MS Query"
    - Select the ODBC data set created before
    - Select the access query and make a "Return data to excel"
    - Make a "Connection Properties" in excel and "Edit".
    - At this stage you will see "Edit Query" in properties
    - MS Query opens and now add you parameters
    - Make a "return data to excle"

    And you are done...

    FranckF

  3. Fran Schadler says:

    Hi Frank, I am so desperate here. Both ideas sound great, but I can't get it to work. I've never done VBA before and I tried to do exactly what you have above but with my database and query names. You mention adding a reference to the MS DAO xx object Library. I don't know how to do that. Is that what I'm missing?

    'Step 1: Declare your variables
    Dim MyDatabase As DAO.Database
    Dim MyQueryDef As DAO.QueryDef
    Dim MyRecordset As DAO.Recordset
    Dim i As Integer

    'Step 2: Identify the database and query
    Set MyDatabase = DBEngine.OpenDatabase _
    ("C:\Documents and Settings\schadlfr\My Documents\SusanT.mdb")
    Set MyQueryDef = MyDatabase.QueryDefs("Query1")

    I do NOT have MS Query and don't think my company will allow it but I will try. But does the machine that will be using this need to have it also or just the developer?

    Sorry for the questions, but i'm new and would love to do this.

    Thank you

    p.s. I tried the 10/6 option but couldn't figure out the connection properties and edit part...

  4. Patrick says:

    Thank you! I had been trying to run a LIKE query from Excel to Access and it was NOT WORKING. I tried * and % and nothing worked. This worked the first try, and it seems to be faster then by connected through ADO. Wow. Awesome. I also set the variables to nothing at the end.

    Sub RunParameterQuery(BondName As String)
    'Step 1: Declare your variables
    Dim MyDatabase As DAO.Database
    Dim MyQueryDef As DAO.QueryDef
    Dim MyRecordset As DAO.Recordset
    Dim i As Integer

    'Step 2: Identify the database and query
    Set MyDatabase = DBEngine.OpenDatabase _
    (BABsDatabaseFilePath)
    Set MyQueryDef = MyDatabase.QueryDefs("Bond_Name_Query")

    'Step 3: Define the Parameters
    With MyQueryDef
    .Parameters("[Enter Bond Name]") = BondName

    End With

    'Step 4: Open the query
    Set MyRecordset = MyQueryDef.OpenRecordset
    If MyRecordset.RecordCount = 0 Then frmBondNames.FrameNameBox.Visible = False: GoTo End_With_No_Records:
    MyRecordset.MoveFirst
    frmBondNames.lvBondNames.ListItems.Clear
    frmBondNames.lvBondNames.Sorted = False
    If Not MyRecordset.BOF And Not MyRecordset.EOF Then
    frmBondNames.FrameNameBox.Visible = True
    'frmBondNames.FrameNameBox.Top = frmBondNames.txtCUSIP.Top
    MyRecordset.MoveFirst
    While Not MyRecordset.EOF
    With frmBondNames.lvBondNames
    Set li = .ListItems.Add(, , MyRecordset("Bond_Name").value)

    li.SubItems(1) = MyRecordset("Bond_Type").value

    End With
    MyRecordset.MoveNext
    Wend
    Else
    frmBondNames.FrameNameBox.Visible = False
    End If

    End_With_No_Records:
    'MsgBox "Your Query has been Run"
    Set MyDatabase = Nothing
    Set MyQueryDef = Nothing
    Set MyRecordset = Nothing
    End Sub

  5. Bill Wilson says:

    you are a freaking genius!
    I have been mucking with this stupid problem all day.
    you rock

  6. Stacey says:

    THANK YOU! This worked like a charm! I am so grateful for this quick and easy macro. So many other help sites and message boards had complicated solutions or told you to create a parameterless version of the query in the DB, which 1. I couldn't do, since I don't have that kind of access to the DB, and 2. didn't help me, since I needed the parameters in my query.

    Thank you so much once again!

  7. Adrian Brown says:

    "Now we all know you can pull data from Access into Excel using MS Query. The problem is that MS Query doesn't let you pull in Parameter queries."

    Just for the record, this comment is wrong. You can in fact run parameter queries using MS Query from Excel on an Access database. In fact, it's pretty cool because you can house the parameters in spreadsheet cells. I do it all the time, and it works great. The Access DB then just becomes a backend for Excel storing and retrieving data.

  8. Brilliant. I have hated MS Query for many years. Running the query natively in Access is so much better. Thanks very much for showing how easy it is to set up VBA

  9. Philip says:

    Wow! Really worked like a charm! I need to get deeper into VB because this just rocks.

    If you need to "add a reference to the Microsoft DAO XX Object Library", then in the VB editor, go to "Tools" and "References" and select the "Microsoft DAO X.X Object Library" that appears on your list (where X.X = the version on your system).

  10. Lincoln says:

    how do I make an ms query use a range of cells though? Can get it to refer to a cell for the parameter but wondering how to make it use the values in a range of cells

  11. Mr B says:

    Hey Adrian Brown. I too used to integrate Excel into Access parameter queries, but now can't figure out how to do it in Office 2007. WHich version are you using and how are managing it?

  12. Steve says:

    Any ideas how to implement this in a secure database?

  13. Peter says:

    Please help! This stuff is great but I am experiencing a an error.

    It runs fine returning all data in the query without the .parameter code but when I insert that code it kicks back an error Run-Time error '3265' Item not found in collection.

    I set everything up as specified above and double checked all the spelling etc.

    'Step 3: Define the Parameters
    With MyQueryDef
    .Parameters("[Acct]") = Range("k2").Value
    .Parameters("[Gender]") = Range("D3").Value
    .Parameters("[Age]") = Range("D4").Value
    End With

  14. Mark says:

    I have done all the code and set the DAO in my preferences but I get a Runtime error "3343". Unrecognised database format 'S:\IRRSD_DATA|Participation\NQ\NQ Participation_Finalised.accdb'.

    My code is:

    Sub RunParameterQuery()

    'Step 1: Declare your variables
    Dim MyDatabase As DAO.Database
    Dim MyQueryDef As DAO.QueryDef
    Dim MyRecordset As DAO.Recordset
    Dim i As Integer

    'Step 2: Identify the database and query
    Set MyDatabase = DBEngine.OpenDatabase _
    ("S:\IRRSD_DATA\Participation\NQ\NQ Participation_Finalised.accdb")
    Set MyQueryDef = MyDatabase.QueryDefs("Report1")

    'Step 3: Define the Parameters
    With MyQueryDef
    .Parameters("[Enter Hub Name]") = Range("C2").Value
    End With

    'Step 4: Open the query
    Set MyRecordset = MyQueryDef.OpenRecordset

    'Step 5: Clear previous contents
    Sheet1.Select
    ActiveSheet.Range("A6:K10000").ClearContents

    'Step 6: Copy the recordset to Excel
    ActiveSheet.Range("A7").CopyFromRecordset MyRecordset

    'Step 7: Add column heading names to the spreadsheet
    For i = 1 To MyRecordset.Fields.Count
    ActiveSheet.Cells(6, i).Value = MyRecordset.Fields(i - 1).Name
    Next i

    MsgBox "Your Query has been Run"

    End Sub

  15. Lori says:

    I have the same problem as Mark on July 13th. Has anyone found a solution to his problem?

  16. datapig says:

    Mark,
    Lori,

    It looks like you're trying to hit a network directory that has been mapped to your Windows Explorer as a relative drive. In this case, you'll have to use the full absolute network path.

    For Example:

    Instead of
    B:\SalesOps\AccessDatabase.accdb

    I would use
    \\skuspldc03\data\SalesOps\AccessDatabase.accdb

  17. Glen Powers says:

    Michael,

    I have transcribed your code verbatim except for the name of my DB and query.

    I am getting the dreaded error 3343: Unrecognized Database Format.

    here are two screen shots: 1) My references and 2) the code.

    Can you tell me what I need to to do to fix this problem. I am using Excel 2007 and Access 2007.

    thanks

    glen

    references:

    MS Excel 12.0 Object Library
    MS DAO 3.6 Object Library

    Code:

    'Step 1: Declare your variables

    Dim MyDatabase As DAO.Database
    Dim MyQueryDef As DAO.QueryDef
    Dim MyRecordSet As DAO.Recordset
    Dim i As Integer

    'Step 2: Identify the database and query
    Set MyDatabase = DBEngine.OpenDatabase _
    ("C:\My Documents\TRHDR1.accdb")
    Set MyQueryDef = MyDatabase.QueryDefs("PARAMETERQUERY")

    'Step 3: Define the Parameters
    With MyQueryDef
    .Parameters("[Enter Name]") = Range("C1").Value
    End With

    'Step 4: Open the Query
    Set MyRecordSet = MyQueryDef.OpenRecordSet

    'Step 5: Clear Previous contents
    Sheets("Main").Select
    ActiveSheet.Range("A6:K10000").ClearContents

    'Step 6: Copy the recordset to Excel
    ActiveSheet.Range("A7").CopyFromRecordset MyRecordSet

    'Step 7: Add column heading names to the spreadsheet
    For i = 1 To MyRecordSet.Fields.Count
    Actovesheet.Cells(6, i).Value = MyRecordSet.Fields(i - 1).Name
    Next i

    MsgBox "Your Query has been run"

    End Sub

  18. Kyle says:

    After having the '3343 - Unrecognized Database Format' error I changed my references in excel to "Microsoft 12.0 Access Database Engine Object Library". This appears to have cleared up the problem, even though references are declared as DAO they're apparently very compatible.

  19. Laurent says:

    I'm having error 3265 "Item not found in collection". My Query has the following cirteria:

    Field: WORK ORDER: Trim([WO_HDR.WO_NUM])

    Cirteria: Like [Enter WO Number and include "*" at end of WO Number to include NCR WO]

    It seems like the trim function is messing it up. any ideas how to get around it?

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

*

* Copy this password:

* Type or paste password here:

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>