Access query parameter from control - ms-access

Fish out of water looking for direction/advice not necessarily code (Although that would be helpful). I am an ME that designs machines for a living and I am trying to automate an existing 2010 Access database used for engineering part numbers. I want the user to select the project number and have the next available part number automatically appear in the part number field.
I have tried unsuccessfully using ADO and DAO examples from the various sources to pass a parameter that is based on the value of a form control to a select query. My latest attempt is as follows:
Private Sub ctlProject_AfterUpdate()
Dim dblProject As Double
dblProject = Me.ctlProject.Value
MsgBox "The curret project number is " & dblProject, vbOKOnly, "Project Number"
Const cstrQueryName As String = "qryDetails"
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set dbs = CurrentDb()
Set qdf = dbs.QueryDefs(cstrQueryName)
qdf.Parameters("Project") = dblProject
' Open recordset on the query
Set rst = qdf.OpenRecordset()
rst.MoveLast
Debug.Print ("Project ID: " & rst!Project)
rst.Close
qdf.Close
dbs.Close
End Sub
Code produces a "Run-Time Error '3265'. Item not found in this collection" that stems from this line of code:
qdf.Parameters("Project") = dblProject
Original Source code here
I have had similar failures using the ADO Command object. I would greatly appreciate any help or recommendations for references/resources. I have been using "Access 2003 vba programmers's manual" by WROX and "Access 2010: the missing manual" as hardcopy references.
Here is the code from the SQL view of qryDetails:
SELECT tblDetails.Project, tblDetails.Number, tblDetails.Title, tblDetails.Initials,
tblDetails.IssuedOn
FROM tblDetails
WHERE (((tblDetails.Project)=[Project]));

I'm skeptical about Project as the parameter name because there is a field with the same name. It's also a reserved word, but I'm unsure whether that is an extra challenge here.
Revise qryDetails to use a different name for the parameter.
SELECT tblDetails.Project, tblDetails.Number, tblDetails.Title, tblDetails.Initials,
tblDetails.IssuedOn
FROM tblDetails
WHERE (((tblDetails.Project)=[pProject]));
And don't forget to revise the VBA to use that new name ...
qdf.Parameters("pProject") = dblProject
If you still have trouble after those changes, see what Access thinks about your query parameter(s).
Const cstrQueryName As String = "qryDetails"
Dim dbs As DAO.Database
Dim prm As DAO.Parameter
Dim qdf As DAO.QueryDef
Set dbs = CurrentDb()
Set qdf = dbs.QueryDefs(cstrQueryName)
MsgBox "Parameters.Count: " & qdf.Parameters.Count
For Each prm In qdf.Parameters
MsgBox "Parameter Name: " & prm.Name
Next

Related

Trying to pass parameters to an MS Access query

I am trying to write a MS Access report based on a query that I can programically put the a date range in using VBA. I set up the query with Between [StartDate] and [EndDate] as the criteria. Then I have the following code on a form:
Private Sub AutoReport1_Click()
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set qdf = CurrentDb.QueryDefs("MixByRangeA")
qdf.Parameters("StartDate").Value = #10/2/2014#
qdf.Parameters("EndDate").Value = #11/2/2014#
Set rst = qdf.OpenRecordset()
End Sub
Nothing seems to happen. Should the query open and show on the screen? I have tried a few code variations of the above based on my internet searches but nothing works.
Nothing is happening because you're not doing anything with qdf and rst after you set them. I'm not entirely sure what you're trying to accomplish, but:
1. If you want to open a Report whose RecordSource is the results of the Query (with parameters dynamically set), try placing the following in the Report's code module:
Private Sub Report_Open(Cancel As Integer)
Dim db As DAO.Database: Set db = CurrentDb
Dim qdf As DAO.QueryDef
Dim sql As String
Set qdf = db.QueryDefs("MixByRangeA")
sql = qdf.sql
sql = Replace(sql, "[StartDate]", "#10/2/2014#")
sql = Replace(sql, "[EndDate]", "#11/2/2014#")
Me.RecordSource = sql
On Error Resume Next
qdf.Close: Set qdf = Nothing
db.Close: Set db = Nothing
End Sub
And in the Form, use this to open the Report:
Private Sub AutoReport1_Click()
DoCmd.OpenReport "Report1", acViewReport
End Sub
2. If instead you just want to open the Query (with parameters dynamically set), try the following:
Public Sub AutoReport1_Click()
Dim db As DAO.Database: Set db = CurrentDb
Dim qdf As DAO.QueryDef
Dim sql As String
Set qdf = db.QueryDefs("MixByRangeA")
sql = qdf.sql
sql = Replace(sql, "[StartDate]", "#10/2/2014#")
sql = Replace(sql, "[EndDate]", "#11/2/2014#")
qdf.sql = sql
DoCmd.OpenQuery (qdf.Name)
On Error Resume Next
qdf.Close: Set qdf = Nothing
db.Close: Set db = Nothing
End Sub
I don't think it can be done the way simple way you want.
This seems a shame because you've followed what could be considered 'best practise' by using a stored procedure with parameters parameters, rather than constructing dynamic SQL.
The truth is, even if it is good practise generally, you are guilty of going against the natural flow of how the Access Team want you use its software! Looks like you are compelled to dynamically construct a WHERE clause to squirt into the provided method :(
The easy method is to remove the parameters from the query and apply a filter to the report:
Dim StartDate As Date
Dim EndDate As Date
StartDate = #10/2/2014#
EndDate = #11/2/2014#
DoCmd.OpenReport "YourReport", , , "[YourDateField] Between #" & Format(StartDate, "yyyy\/mm\/dd") & "# And #" & Format(EndDate, "yyyy\/mm\/dd") & "#"

MS Access 2013 objects (tables, queries) display created or modified date

Is there any way I can make Access 2013 display created and modified date? Access 2003 used to display those features and can't seem to find any solution to Access 2013?
You can right-click the object list header, and do View -> Details. But that's still not a very good overview.
(Oh how I miss the Access 2003 database window...)
A better way is to query the MSysObjects table, e.g.:
SELECT MSysObjects.Type, MSysObjects.Name, MSysObjects.DateUpdate, MSysObjects.DateCreate
FROM MSysObjects
WHERE (((MSysObjects.Type)<>2 And (MSysObjects.Type)<>3 And (MSysObjects.Type)<>-32757)
AND ((Left([Name],1))<>'~') AND ((Left([Name],4))<>'Msys'))
ORDER BY MSysObjects.Type, MSysObjects.Name;
See here for the object type constants:
Meaning of MsysObjects values -32758, -32757 and 3 (Microsoft Access)
You may also be interested in this free "Database window replacement" add-in:
http://www.avenius.de/index.php?Produkte:DBC2007
If Access hasn't got a baked-in solution and you have a lot of objects to look at, you could always create your own with a table set up something like this:
And then write some VBA to loop through the object collections and write the properties you're interested in to the above table. The example below loops through the Tables and Queries collections, but you could write additional loops for Forms, Reports, etc. (There may even be a simpler way to just loop through all Access objects).
Public Sub CreatedModified()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim tdf As DAO.TableDef
Dim qdf As DAO.QueryDef
Dim strSql As String
strSql = "DELETE * FROM tblCreatedModified"
Set db = CurrentDb
db.Execute strSql
Set rs = db.OpenRecordset("tblCreatedModified")
With rs
' tables
For Each tdf In db.TableDefs
If Not (tdf.Name Like "*MSys*" Or tdf.Name Like "~*") Then
.AddNew
!ObjectType = "Table"
!ObjectName = tdf.Name
!DateCreated = tdf.DateCreated
!DateModified = tdf.LastUpdated
.Update
End If
Next
' queries
For Each qdf In db.QueryDefs
If Not (qdf.Name Like "*MSys*" Or qdf.Name Like "~*") Then
.AddNew
!ObjectType = "Query"
!ObjectName = qdf.Name
!DateCreated = qdf.DateCreated
!DateModified = qdf.LastUpdated
.Update
End If
Next
End With
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub

Using SQL and VBA in combination

Okay I'm new here and will be my first question, I'm getting stuck with my code that I'm busy with.
I keep bumping same error which is related to the Runtime error: 3129 in Access Visual Basic
Now it is an importing button function set in a Public Sub check below my code:
Public Sub ImportDataTablebtn_Click()
Dim strSQL As String
Dim db As DAO.Database
Dim tbl1 As DAO.TableDef
Dim tbl2 As DAO.TableDef
Dim fld1tbl1 As DAO.Field
Dim fld2tbl1 As DAO.Field
Dim fld3tbl1 As DAO.Field
Dim fld1tbl2 As DAO.Field
Dim fld2tbl2 As DAO.Field
Dim fld3tbl2 As DAO.Field
Set db = CurrentDb
Set tbl1 = db.TableDefs("Clicks Returns")
Set tbl2 = db.TableDefs("Oct 2015 Clicks Returns")
Set fld1tbl1 = tbl1.Fields("SKU")
Set fld2tbl1 = tbl1.Fields("Item Description")
Set fld3tbl1 = tbl1.Fields("Oct 2015 FIN YTD TY % Returns")
Set fld1tbl2 = tbl2.Fields("Sku")
Set fld2tbl2 = tbl2.Fields("Item Description")
Set fld3tbl2 = tbl2.Fields("F21")
DoCmd.RunSQL strSQL
strSQL = "INSERT INTO tbl1 (fld1tbl1, fld2tbl1, fld3tbl1)" & _
"SELECT fld1tbl2, fld2tbl2 fld3tbl2 FROM tbl2;"
Set db = Nothing
End Sub
Now I know some of my lines like the table rename and field might not really be required, though I thought that it would just make it easier with the code...
Please let me know where I'm making my error as I feel like going crazy by keep looking at it over and over.
In the database is the tables that I'm referring towards and I want to move the certain fields from the one table to the other table as it is imported excel sheets, I'm busy making it an automated system where someone would just click on buttons on a form and it will sort out the data.
Thank you for taking the time to read this essay and also answering it
There are a couple of mistakes in your code.
First the code will not substitute your variables for the table/field names. So the string SELECT fld1tbl2 is not converted to SELECT [Item Description].
Second you are trying to run your query before you have built it.
Finally Access uses VBA and not VBScript. It's a different language. While they have much in common there are some important differences. Stick to the the VBA tag and you will be more likely to get the answers you need.
I've refactored your code. This version builds and then runs the query.
Public Sub ImportDataTablebtn_Click()
Dim strSQL As String
' Build Query.
strSQL = "INSERT INTO [Clicks Returns] " & _
"(SKU, [Item Description], [Oct 2015 FIN YTD TY % Returns]) " & _
"SELECT Sku, [Item Description], F21 FROM [Oct 2015 Clicks Returns];"
' Run Query.
DoCmd.RunSQL strSQL
End Sub

3061 VBA Error - SQL Query "Too few parameters. Expected 1." Simple query

I have the following code:
Private Sub lst1Model_Operation_Click()
Dim db As Database
Dim sSQL As String
Dim rst As Recordset
Set db = CurrentDb
sSQL = "SELECT * FROM qryOrder_Model_Operation_Value WHERE Model_Operation_ID = " & CInt(Me![lst1Model_Operation].Value)
Debug.Print sSQL 'when pasted this into a query SQL, it works flawlessly.
Set rst = db.OpenRecordset(sSQL) 'error line
'some code here
rst.Close
Set db = Nothing
End Sub
I'm at loss at what to do. The Debug.Print looks like:
SELECT * FROM qryOrder_Model_Operation_Value WHERE Model_Operation_ID = 748
And as I said, if I paste that Debug.Print into a Query in the Access itself, it produces the desired results.
I have tried adding ' ' around the value, but using CInt() I already made sure it is parsed as integer. The Model_Operation_ID also expects to get an integer (otherwise it wouldn't work in a separate query either).
Edit:
The qryOder_Model_Operation_Value is as follows:
SELECT tbl1Model_Operation.Model_Operation_ID, tbl1Model_Operation.Model_ID, tbl1Model_Operation.Operation_Value_ID, tbl2Operation_Value.Operation_Name_ID, tbl3OperationsList.Operation_Name, tbl1Order_Model.Quantity AS [Počet párov], tbl1Order_Model.Order_ID
FROM tbl3OperationsList INNER JOIN (tbl2Operation_Value INNER JOIN (tbl1Model_Operation INNER JOIN tbl1Order_Model ON tbl1Model_Operation.Model_ID = tbl1Order_Model.Model_ID) ON tbl2Operation_Value.Operation_Value_ID = tbl1Model_Operation.Operation_Value_ID) ON tbl3OperationsList.Operation_ID = tbl2Operation_Value.Operation_Name_ID;
Make sure Access understands you want rst to be a DAO.Recordset instead of an ADODB.Recordset:
'Dim rst As Recordset
Dim rst As DAO.Recordset
Both the ADO and DAO object models include Recordset objects. Although similar in some respects, they can not be used interchangeably.
When your Access VBA project references include a version of ADO (ActiveX Data Objects) and that reference has a higher priority than the DAO reference, Dim rst As Recordset will give you an ADODB.Recordset. Avoid unwelcome surprises by always qualifying your Recordset declarations with DAO or ADODB as appropriate.
Try this way:
Set rst = db.OpenRecordset(sSQL,dbOpenTable)
or
Set rst = db.OpenRecordset(sSQL,dbOpenSnapshot)

how to fill a recordset in vba in a module behind a db

I have tried many ways to get the job done. I am inexperienced with the
Access VBA.
I think the problem is how to set the current database. The code is in a module from another db as the current db. I have paste the code here in a module behind the
currentdb that also gives the same error. I have looked after very much questions.
It must be simple. But I don't see the answer.
Private Sub project()
Dim projectnamen As DAO.Database
Dim strSQL As String
Dim rs As DAO.Recordset
Dim strdbName As String
Dim strMyPath As String
Dim strdb As String
Dim accapp As Object
Path = "c:\GedeeldeMappen\programma en bestanden stiko"
strdbName="projektnamen.accdb"
strMyPath = Path
strdb = strMyPath & "\" & strdbName
'make the db "projectnamen"current. Perhaps this is possible with set??
Set accapp = CreateObject("Access.Application")
accapp.OpenCurrentDatabase (strdb)
'fieldname is naam_van_het_project
'tablename is projectnaam
strSQL = "SELECT All naam_van_het_project FROM projectnaam;"
'here i get an error "can't find the object Select All naam_van_het_project
'FROM projectnaam" error 3011
Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenTable)
rs.MoveFirst
Do While Not rs.EOF
MsgBox (rs)
rs.MoveNext
Loop
End Sub
I think you want to run that query against the db which you opened in the new Access session, accapp.
The CurrentDb method is a member of Application. So qualify CurrentDb with the object variable name of that other application session.
'Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenTable)
Set rs = accapp.CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)
Note OpenRecordset won't let you use dbOpenTable with a query. So I arbitrarily chose dbOpenSnapshot instead. If that's not what you want, substitute a different constant from the RecordsetTypeEnum Enumeration (see Access help topic for details).