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) .
-
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 _
-
("C:\Integration\IntegrationDatabase.accdb")
-
Set MyQueryDef = MyDatabase.QueryDefs("MyParameterQuery")
-
-
'Step 3: Define the Parameters
-
With MyQueryDef
-
.Parameters("[Enter Segment]") = Range("D3").Value
-
.Parameters("[Enter Region]") = Range("D4").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
-
ActiveSheet.Cells(6, i).Value = MyRecordset.Fields(i - 1).Name
-
Next i
-
-
MsgBox "Your Query has been Run"
-
-
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.


Thanks for this. My inability to make parameter queries work from Excel has been a major annoyance.
I only got this to work, though when I had changed the references to:
Microsoft Office 12.0 Access Database Engine Object Library, and
Microsoft Access 12.0 Object library (which should probably have been set before).
Now it works (mostly - sometimes fails on an
ODBC call, but I get the feeling that most of these Microsoft ODBC calls are not that robust, and anyway the Access database is linking to a series of tables in VFP format).
Hi Mike,
Yes good tip, I had some fun doing somthing not unlike this a while back, in the end the solution was a right hack!
http://www.blog.methodsinexcel.co.uk/2009/04/28/parameters-in-ado-getting-good-with-access-%E2%80%93-not/#comments
Thanks
Ross
In the book ‘Excel 2007 Advanced Report Development’, Timothy Zapawa talks about how to execute parameter queries in Excel without using VBA.
Some points of note include:
• Parameters are not really intended to be used with pivottable reports (but Zapawa provides a work around)
• Parameters can be used in an Excel query, although if the query cannot be displayed graphically then you’ll need to transform it into a stored procedure or view.
• Parameters can be integrated with web queries, but otly by creating an .isql file outside of Excel
There’s some supporting documents and videos posted at http://www.wiley.com/go/excelreporting/2007 that might be of interest – check out the files on offer under chapter 15: there’s a sample spreadsheet (which I can’t use on my PC because I don’t have the sample database loaded) and a video (which I cant view on my PC for some reason).
I personally find this book almost impossible to follow. Either I’m dumb, or the book is not written for beginners, or both.
Thanks for this great article. Parameter queries can be tricky but this is an easy to follow walk through. You should consider sharing your knowledge and expertise with the Office community on Facebook. Check it out at http://www.facebook.com/office
Cheers,
Andy
MSFT Office Outreach Team
Thanks for this, it helped me a lot with a project.
I have just one question, how can I close the connection with the DB without closing the Excel file?
Thanks
Roger
Roger: You could set the object variables to nothing.
Set MyRecordset = Nothing
Set MyQueryDef = Nothing
Set MyDatabase = Nothing
It would be simpler, I would think, to create the query without parameters and then add the parameters to the resulting derived table. I might be missing something here...
Colin,
I thought of the same thing... Why build the parameters in Access if your Reporting is going to take place in Excel...Easier to build the parameters in Excel
This is one of the more broken down explanations I have found. I am still some what of a beginner when it comes to macros, specially when it comes to db stuff. But I have a question. What if I have a whole range of parameters to query under one field? I would still like to use the wildcard.
Matt: You can set up your Access queries so that wildcards are part of the query.
For example, you can use this as the criteria:
LIKE "*" & [Enter Region & "*"
When you pass the parameter from Excel, the wild cards will automatically wrap your parameter.
The wildcards are not the issue. I do have that set up. Its querying the multiple parameters for the one field. I just mentioned the wildcard in case the solution was to combine the parameters.
I have an Access report that uses a parameter query. Is it possible to use a vba procedure to pass the parameter values and open the report without prompts?
Russ: Just use the code here and replace the Range parameters in Step 3 with the hard-coded values you need.
Hi i was wondering how much you would to set your blog design up on my internet site for me, because i really like the look of your internet site but i don't know how to set such a hot design.
Hey thanks for the code, it was really helpful with what I'm working on. I'm trying to do the same thing now, but the parameter query I want to run is a query of 2 other queries. It asks for 2 parameters just like the others, but it does not return the data I need, just the column headers. This query works in Access. Any suggestions? Thank you.
Hi there,
Thank you very much for the code provided, it was proven to be the best step forward I've had with these parameter queries from access to excel!
It's great that the data is being transfered over, but my solution goes a bit further than this. Due to the amount of rows that I'm sending over from Access I require this data to be put in a pivot table, instead of just manually transfered into Excel.
Any further help would be very much appreciated!
Lee: Can you not build your pivot table on top of the query results?
If you do, you can add a line of code to refresh the pivot table every time the query updates.
I am new to VBA, but I've followed this so far and i am producing an error and don't know where to go from here:
the error is at the .parameters..."item in the collection could not be found".
What have I done wrong? Thanks
Jessie: Sounds like you're pointing to a query or table that doesn't exist.
Probably in the line
MyDatabase.QueryDefs("MyParameterQuery")
Be sure to replace MyParameterQuery with your query name.
Thanks datapig,
but no, i did add my query name.
I believe that I am not connecting to my database. When I run a debug from the beginning it says (1) "set MyDatabase = nothing"
(2) "set myqueryDef = nothing"
(3) it halts at ".parameter = "nothing in collection"
'Step 2: Identify the database and query
Set MyDatabase = DBEngine.OpenDatabase _
("\\hous0205\bps_data2\25257\Reports\BPSInventoryReports.Mdb")
Set MyQueryDef = MyDatabase.QueryDefs("qryDailyReceivingLog - Duke - Revised")
1) Also my query prompts for a date between a certain date. I am not sure how to set step 3 correctly for the parameter.
Example: I need it to bring up data between [this date] and [that date] and it suppose to display the data for me.
2) Also, for the run Paramater query button, did you add the code to it's property? I don't know how to make that button work.
here is my code after I changed the information:
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 _
("\\hous0205\bps_data2\25257\Reports\BPSInventoryReports.Mdb")
Set MyQueryDef = MyDatabase.QueryDefs("qryDailyReceivingLog - Duke - Revised")
'Step 3: Define the Parameters
With MyQueryDef
.Parameters("[ENTER start DATE] and [Enter end date]") = Range("B7").Value
End With
'Step 4: Open the query
Set MyRecordset = MyQueryDef.OpenRecordset
'Step 5: Clear previous contents
Sheets("Main").Select
ActiveSheet.Range("A7: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(11, i).Value = MyRecordset.Fields(i - 1).Name
Next i
MsgBox "Your Query has been Run"
End Sub
Jessie: In your code, step three looks like
With MyQueryDef
.Parameters("[ENTER start DATE] and [Enter end date]") = Range("B7").Value
End With
You can't have start date and end date coming from the same cell. Try this.
With MyQueryDef
.Parameters("[ENTER start DATE]") = Range("B6").Value
.Parameters("[Enter end DATE]") = Range("B7").Value
End With
Make the start date come from cell B6 and end date come from cell B7,
As far as connecting to your databae, be sure you have access to the database.
Why attempt to update a pivot table from the data returned from the parameterize query, when a parameterize pivot table is really what you want?
thanks, dadapig. this is exactly what i needed. works perfectly!!!
Can you please tell me how to to this?
Note: You will need to add a reference to the Microsoft DAO XX Object Library (where XX represents the latest version you have) .
Is it another line of code?I keep getting complie error -user defined type not defined on this line: (MyDatabase As DAO.Database)
thanks
here is my code
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 _
("\\lm-file-dfs-01\central\Commkt\Production\LMG-Property\File-Cabinet\LM Equipment Breakdown\Middle Market Tracking\Database\Middle Market Tracking System_be")
Set MyQueryDef = MyDatabase.QueryDefs("SearchPades")
'Step 3: Define the Parameters
With MyQueryDef
.Parameters("[Enter Policy]") = Range("D3").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
ActiveSheet.Cells(6, i).Value = MyRecordset.Fields(i - 1).Name
Next i
MsgBox "Your Query has been Run"
End Sub
Dave: In the Visual Basic Editor,
Go up to the toolbar and select Tools ->References.
This will bring up the references dialog box.
Go down the list and find the Microsoft DAO XX Object Library (where XX represents the latest version you have).
When you find it, place a check next to it then press OK.
This will added the needed reference.
thanks works great
Can you help with this one?
How would I plug this parameter into the format you provided? I am getting runtime 13 -mismatch
Like "*" & [] & "*" -error
.Parameters("[Enter Policy Number]") = Range("b3").Value
.Parameters("[Like "*" & [] & "*"]") = Range("b3").Value
here is what I am trying to do
Dave: Don't feed the LIKE operator through VBA. Build the like operator into your query.
For example, put this into the query criteria: Like "*" & [Param1] & "*"
Then just use .Parameters("[Param1]") Range("D3").Value
The LIKE operator will be applied on the Query side.
Just dropping a note to thank you. This code worked and completley saved a huge workaround for me.
I am stuck on a VB code I have that worked in 32 bit excel but does not work in 64 bit excel. I remove the soap client i was using at it is no longer supported and replaced it with MSXML
when I try to run the code I receive the following error
when I run the start client I get the attached error message
Compile Error: User Defined Type Not Defined
and then it goes to the Dim objHttp As MSXML.XMLHTTPRequest
(Note I also tried the MSXML.ServerXMLHTTPRequest and received the same error).
Any help would be greatly appreciated!
NOTE: I have tried adding the Microsoft XML 3.0, 4.0 and 6.0 reference library all resulting in the same error.
Below is my code:
Darrel: Wow...you've got alot going on here.
You'd have to give me a much simpler example than this.
Hello
Will this work using a runtime version of access?
I have it working on full verison of access but im having trouble with the runtime version.
thanks
Dave: Make sure you're referencing the database as an accdr.
Set MyDatabase = DBEngine.OpenDatabase _
("C:\Integration\IntegrationDatabase.accdr")
Thanks, you made my day. Works a treat.
I guess I am slow.. I get "Compile error: User-defined type not defined" on the first line "Dim MyDatabase As DAO.Database". And I don't really know what it means when you say "You will need to add a reference to the Microsoft DAO 12.0 [in my case] Object Library". Help & Thanks!
I am trying to run this code but get a 3343 run-time error message - unrecognizable database format? Help!
Trish: Make sure you're referencing the correct version of Access.
If you're using Access 2003, you'll ned to use this:
Set MyDatabase = DBEngine.OpenDatabase _
("C:\Integration\IntegrationDatabase.mdb")
Thanks for that but its Access 2007
Could it be something to do with References?
I am getting the following error:
'Run-time error '3112':
Record(s) cannot be read; no read permission on 'tblRequest'
'tblRequest' is one of the table in my query.
I am running Access and Office 2007. I have had to add a reference to: 'Microsoft Office 12.0 Access database engine object library' instead of 'Microsoft DAO 3.6 Object Library'
Is there anything else I should be doing?
Here is the top part of my query:
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 _
("\\lotus\data\Projects\Projects\Project Database\TaskManagerC.accde")
Set Db = OpenDatabase("\\lotus\data\Projects\Projects\Project Database\TaskManagerC.accde")
'Create a workspace with the correct login information
Set MyQueryDef = MyDatabase.QueryDefs("kbQryTaskTimeTotalsByRequest")
'Step 3: Define the Parameters
With MyQueryDef
.Parameters("[Enter Request]") = Range("C2").Value
End With
Hi,
I just found a funny solution to this, which allows to avoid coding, and remains sufficiently clean if the reporting is stable and not too complicated.
1. Create a XL sheet with your parameters (why not in the same workbook)
1bis. If you want to enter data in the main dashboard sheet, put a formula into the parameter sheet that points to the dashboard sheet
2. Go to access and make this sheet a linked table, with external data feature
3. Then you can use this table in the parameter fields or formulas with a subquery.
Works very nicely.
Regards,
Stevan
Thanks, saved a lot of time and added much to an ongoing project.
Hi there ,
Thanks for the code. I've been trying to run this but I keep getting a "Run time error '3219' Invalid operation' whenever I try to run it. My code is below. Please help !
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
Ok so I actually figured it out. My original query was a make-table query so I just changed it to a Select query and it worked.
However, the data that I really want to return is based on another query run based on the results of the new Select Parameter query.
How can I do that ? Do I run a macro where I'm manually running the other query? Do you think that would work or is there another way?
Thanks!
I actually will need to keep the query as a make-table because otherwise the next query will not work since it references the table made by the parameter query. How can I make this work ?
Basically I need to run two additional queries based on the results of the parameter query and then return the results to the user.
Thanks
Ghh: You should be able to use this before running the parameter query.
MyDatabase.Execute "MakeTableQuery1", dbFailOnError
MyDatabase.Execute "MakeTableQuery2", dbFailOnError