43

I have a query that's rather large, joining over a dozen tables, and I want to pull back records based on an id field (e.g.: between nStartID and nEndID).

I created two parameters and tested them as criteria and they work fine.

The issue is, I need to run an insert query from this main query, and need the parameters where they are, in the main query. So, I need to pass parameters to it programmatically.

Anyone have a clue as to how this can be done?

Thanks.

Gord Thompson
  • 116,920
  • 32
  • 215
  • 418
Jav
  • 543
  • 1
  • 4
  • 10
  • 1
    I have a solution for my need, but not sure if it's the best. I've created global variables for the nStartID and nEndID, then just create a function for each, as in getStartID() and getEndID() which read those values. Then I just use those functions in the original query's where clause. Not the most elegant of solutions, but it works. I'm leaving this open in the event that anyone else has experience they'd like to share, for the benefit of others. Thanks for your helpful input. – Jav May 15 '13 at 15:23

5 Answers5

68

I just tested this and it works in Access 2010.

Say you have a SELECT query with parameters:

PARAMETERS startID Long, endID Long;
SELECT Members.*
FROM Members
WHERE (((Members.memberID) Between [startID] And [endID]));

You run that query interactively and it prompts you for [startID] and [endID]. That works, so you save that query as [MemberSubset].

Now you create an UPDATE query based on that query:

UPDATE Members SET Members.age = [age]+1
WHERE (((Members.memberID) In (SELECT memberID FROM [MemberSubset])));

You run that query interactively and again you are prompted for [startID] and [endID] and it works well, so you save it as [MemberSubsetUpdate].

You can run [MemberSubsetUpdate] from VBA code by specifying [startID] and [endID] values as parameters to [MemberSubsetUpdate], even though they are actually parameters of [MemberSubset]. Those parameter values "trickle down" to where they are needed, and the query does work without human intervention:

Sub paramTest()
    Dim qdf As DAO.QueryDef
    Set qdf = CurrentDb.QueryDefs("MemberSubsetUpdate")
    qdf!startID = 1  ' specify
    qdf!endID = 2    '     parameters
    qdf.Execute
    Set qdf = Nothing
End Sub
Gord Thompson
  • 116,920
  • 32
  • 215
  • 418
  • Thanks for sharing, I have found similar code, but nothing as well explained. – Jav May 29 '13 at 17:31
  • 2
    This also works if you create a query in VBA; e.g. `Dim qdf As DAO.QueryDef; Set qdf = db.CreateQueryDef("", "UPDATE Members SET Members.age = [age]+1")` – Nat Jul 19 '18 at 00:00
24

Try using the QueryDefs. Create the query with parameters. Then use something like this:

Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef

Set dbs = CurrentDb
Set qdf = dbs.QueryDefs("Your Query Name")

qdf.Parameters("Parameter 1").Value = "Parameter Value"
qdf.Parameters("Parameter 2").Value = "Parameter Value"
qdf.Execute
qdf.Close

Set qdf = Nothing
Set dbs = Nothing
Jessica
  • 241
  • 2
  • 2
  • 3
    I think you also can refer to `.Parameters` by number, like `qdf.Parameters(1).Value = "Parameter Value"`. Not sure if it's zero based. – iDevlop Feb 05 '16 at 09:27
4

Many thanks for the information about using the QueryDefs collection! I have been wondering about this for a while.

I did it a different way, without using VBA, by using a table containing the query parameters.

E.g:

SELECT a_table.a_field 
FROM QueryParameters, a_table 
WHERE a_table.a_field BETWEEN QueryParameters.a_field_min 
AND QueryParameters.a_field_max

Where QueryParameters is a table with two fields, a_field_min and a_field_max

It can even be used with GROUP BY, if you include the query parameter fields in the GROUP BY clause, and the FIRST operator on the parameter fields in the HAVING clause.

FreeMan
  • 5,660
  • 1
  • 27
  • 53
Nigel
  • 41
  • 2
3

You can also use TempVars - note '!' syntax is essential You can also use TempVars - note '!' syntax is essential

loki
  • 9,816
  • 7
  • 56
  • 82
Dougie
  • 49
  • 3
0

Plenty of responses already, but you can use this:

Sub runQry(qDefName)
    Dim db As DAO.Database, qd As QueryDef, par As Parameter

    Set db = CurrentDb
    Set qd = db.QueryDefs(qDefName)

    On Error Resume Next
    For Each par In qd.Parameters
        Err.Clear
        par.Value = Eval(par.Name)          'try evaluating param
        If Err.Number <> 0 Then             'failed ?
            par.Value = InputBox(par.Name)  'ask for value
        End If
    Next par
    On Error GoTo 0

    qd.Execute dbFailOnError
End Sub

Sub runQry_test()
    runQry "test"  'qryDef name
End Sub
iDevlop
  • 24,841
  • 11
  • 90
  • 149