Access: passing value to a parameter query using VBA? - ms-access

I have a an Access form with a parameter query (pink color). Here is my form:
When the user selects a species, Access uses the number generated by the option group (called "speciesSelection") to lookup the species name in a table, and it works. However, I would like to pass the species name to a parameter query, so that a record set can be the data source for the highlighted combo box (Combo12). However, when I select a species, the combo box is blank. Here is my code:
Private Sub speciesSelection_AfterUpdate()
Dim dbs As Database
Dim qdf As QueryDef
Dim rst As Recordset
Set dbs = CurrentDb
'Get species name of the current Cases instance'
Dim speciesChosen As String
speciesChosen = DLookup("Species", "tblSpeciesList", "ID=" & speciesSelection)
'Get the parameter query
Set qdf = dbs.QueryDefs("qryClinicalObservations")
'Supply the parameter value
qdf.Parameters("enterSpecies") = speciesChosen
'Open a Recordset based on the parameter query
Forms!inputForm.Controls!Combo12.RowSource = qdf.OpenRecordset()
End Sub
I created my query using the wizard. Here is a snapshot:
In the criteria section, I can manually enter a species when prompted (e.g. "cat"), and it works. But not with my VBA code...
Is there an obvious mistake? It seems that Combo12 is not recognized.
EDIT:
Here is my new code. Actually, Combo12 is in a subform called observationsSubform. Here is my code and new form. As you can see, the drop-down menu, but the options aren't visible:
Private Sub speciesSelection_AfterUpdate()
Dim dbs As Database
Dim qdf As QueryDef
Dim rst As Recordset
Set dbs = CurrentDb
'Get species name of the current Cases instance'
Dim speciesChosen As String
speciesChosen = DLookup("Species", "tblSpeciesList", "ID=" & speciesSelection)
MsgBox (speciesChosen)
'Get the parameter query
Set qdf = dbs.QueryDefs("qryClinicalObservations")
'Supply the parameter value
qdf!enterSpecies = speciesChosen
Set Me!observationsSubform!Combo12.Recordset = qdf.OpenRecordset()

A combo box's RowSource is a string property, so you can't assign a Recordset object to it. Assign your Recordset to the combo's Recordset property instead.
Since that is an object assignment, use the Set keyword.
Set Forms!inputForm!Combo12.Recordset = qdf.OpenRecordset()
If Combo12 and speciesSelection are both contained in the same form (inputForm), you can use this instead ...
Set Me!Combo12.Recordset = qdf.OpenRecordset()

Related

VBA Access Object Type Returned For Combobox Field

How can I iterate a record set that returns a field of type field2?
Is there a way to tell how many objects are in the field2 type?
Let me describe the relevant aspects of my table:
The table fields has field NMR which contains a list of possible options a user can select in another table. In the Experiments table, the field NMR is a combobox with populates the options from the other table.
The way I do this is in the Experiments table design, I have set the field this way:
Now in one of my forms, I need to read the value in Experiments!NMR which can be a multiple selections allowed combobox. The recordset rs!NMR is of type Field2.
To get the values, you iterate using an integer (i.e. rs!NMR(0) would return the first selected option). The problem is I don't know how to get the field count and calling !NMR(i) where i is greater than the number of elements will invoke a Run time error '3265', Object doesn't exist in this collection.
Their exist a size method only returns the field width size (4?) and the documentation states this is the size of the data type within the field2 object.
There doesn't seem to be a count method associated with field2 as using !NMR.Count invokes runtime error 438, Object doesn't support this method.
Code:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim qry As String
qry = "SELECT * FROM Experiments"
Set db = CurrentDb
Set rs = db.OpenRecordset(qry, dbOpenSnapshot)
With rs
Do While Not .EOF
Dim i As Integer
For i = 0 to !NMR.Count ' or SOMETHING - this is the problem
' this is irrelevant, I need to know how to iterate the list
Next i
.MoveNext
Loop
End With
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
I've also tried logic control such as
Do While(!NMR(i) <> vbNullString) since the individual components are strings, but no luck. This issues the same 3265: Item isn't found error. Same for a loop with this check Do While Not IsNull(!NMR(i))
Is there a way to tell how many objects are in the Field !NMR?
You need to assign the complex Field2 to a Recordset2 object and loop through it.
Sub Whatever()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rsComplex As DAO.Recordset2
Dim qry As String
qry = "SELECT * FROM Experiments"
Set db = CurrentDb
Set rs = db.OpenRecordset(qry, dbOpenSnapshot)
Do While Not rs.EOF
Set rsComplex = rs("NMR").Value
rsComplex.MoveLast
rsComplex.MoveFirst
Dim i As Integer
For i = 0 To rsComplex.RecordCount - 1 ' Asker modified
Debug.Print rsComplex(0)
rsComplex.MoveNext
Next i
rsComplex.Close
Set rsComplex = Nothing
rs.MoveNext
Loop
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Sub

Using an Input Box to assign value to a parameter

I have the following code
command_Click()
rDate = InputBox("MM/YYYY")
end sub
When I click the command the input box appears and I input my value. But then I get another pop up asking for the parameter value for rDate.
Any thoughts?
I assume you have a query that's like
Select *
From SomeTable
Where acolumn = rDate
The rDate defined in your command_click() sub is not the same thing. That rDate is a local variable which has nothing to do with your query.
You likely want to pass your parameter to a query. Let's say your query is called vikesQuery. Your command button click code would look like this
Dim qdef As DAO.QueryDef
Set qdef = CurrentDb.QueryDefs("vikesQuery")
If qdef Is Nothing Then
Exit Sub
End If
qdef.Parameters("rDate") = InputBox("MM/YYYY") 'though there are much better ways of getting your parameter like a textbox on a form
Dim rs As DAO.Recordset
Set rs = qdef.OpenRecordset
Now your query is in a recordset where you can do lots with it. Typically you would show this on a form.
Dim frm As Form
DoCmd.OpenForm "vikesForm", acNormal
Set frm = Forms("vikesForm")
Set frm.Recordset = rs 'sets the recordset of the form to the recordset you generated from your query.
This last step assumes you have a form set up to accept the structure of this recordset. i.e. textboxes bound to the right columns.

Access 2010 VBA to put one field from a query in a variable

In Access 2010 I need to be able to click a command button that will run a query that returns a small two field recordset. Then put the second field in that recordset into a string variable.
This string variable is a link to a word document on the network. the second part of the code will then open the word document.
Any help is GREATLY appreciated.
I am getting the Error: "Object variable or With block variable not set"
My Code looks like this:
`Option Compare Database
Private Sub cmdCESpec_Click()
On Error GoTo Err_cmdCESpec_Click
Dim db As Database
Dim rs As DAO.Recordset
Dim s As String
Dim specSheet As String
s = "SELECT p.PartNum, p.CE_SpecSheet FROM tblParts p WHERE p.PartNum = '" & [Forms]![frmSpecSheet]![cboPartNum] & "'" 'Chooses the correct Spec Sheet.
Set rs = db.OpenRecordset(s)
specSheet = rs.Fields("CE_SpecSheet") 'Chooses the Spec Sheet Field
rs.Close
Dim oApp As Object
Set oApp = CreateObject("Word.Application")
oApp.Visible = True
With oApp
.Documents.Open (specSheet)
End With
Exit_cmdCESpec_Click:
Exit Sub
Err_cmdCESpec_Click:
MsgBox Err.Description
Resume Exit_cmdCESpec_Click
End Sub
After dissecting your code.. this:
"..WHERE (((tblParts.PartNum)=[Forms]![frmSpecSheet]![cboPartNum]));"
embeds the words Forms!etc into your sql-statement, it doesn't insert the combo-box value into the statement.
You need to take the form reference out of the string:
Dim db As Database
Dim rs As Recordset
Dim s As String
Dim specSheet As String
s = "SELECT tblParts.PartNum, tblParts.CE_SpecSheet FROM tblParts WHERE " _
& "tblParts.PartNum=" & [Forms]![frmSpecSheet]![cboPartNum]
'Chooses the Correct Spec Sheet
Set db = CurrentDb
Set rs = db.OpenRecordset(s)
specSheet = rs.Fields("CE_SpecSheet")
'Chooses the Spec Sheet Field
rs.Close
Dim oApp As Object
Set oApp = CreateObject("Word.Application")
oApp.Visible = True
With oApp
.Documents.Open ("specSheet")
End With
If the combobox's value is text then you'll need to also surround this with apostrophes.
You also don't need to SELECT the field tblParts.PartNum, you can just refer to it in the WHERE clause.
You haven't posted much information but what I gather you're looking for is Recordset
Dim db As Database
Dim rs As Recordset
Dim s As String
Dim myString As String
s = "SELECT * FROM myTable1;" 'Replace with the SQL you need
Set db = CurrentDb
Set rs = db.OpenRecordset(s)
myString = rs.Fields("myFieldName1") 'Replace myFieldName with the appropriate field name
rs.Close

Add query to child form

I have been looking for some time now, but I can't see the problem here:
Option Compare Database
Option Explicit
Private Sub cmd_Refresh_Click()
Dim sSQL_Select As String
Dim Qdb As Database
Dim Qry As QueryDef
sSQL_Select = "SELECT * FROM T_TIME_SCHEDULE"
Set Qdb = CurrentDb
Set Qry = Qdb.CreateQueryDef("QTS", sSQL_Select)
DoCmd.OpenQuery "QTS", acViewNormal
Me.F_Child_Result.Form.RecordSource = "QTS"
Me.F_Child_Result.Requery
Qdb.QueryDefs.Delete ("QTS")
Set Qdb = Nothing
End Sub
This line:
Me.F_Child_Result.Form.RecordSource = "QTS"
results in the following error:
Run-Time error '2467': The expression you entered refers to an object that is closed or doesn't exist.
The syntax should be correctly constructed, and I double checked the name of the subform.
Desipte, the error remains.
Do not set the record source to a query, just the SQL string.
sSQL_Select = "SELECT * FROM T_TIME_SCHEDULE"
''Set Qdb = CurrentDb
''Set Qry = Qdb.CreateQueryDef("QTS", sSQL_Select)
''DoCmd.OpenQuery "QTS", acViewNormal
Me.F_Child_Result.Form.RecordSource = sSQL
''Me.F_Child_Result.Requery
There is no need to requery, the form will be requeried when the record source is changed.
Note that even if you could set the record source to a query (which you can't), it would not be quoted.
FROM Chat
It appears that there are two mixed strands in the question. What is required is a means to set the Source Object of the subform control to a query, not the Record Source of a form contained by the subform control.
The source object can be set like so:
Me.F_Child_Result.SourceObject="Query." & sQueryName
If the Source Object is already set to the name of a saved query that is used only for this form, there is no need to reset it, you can just modify the sql of the query:
Set qdf = CurrentDB.QueryDefs("JunkQuery")
qdf.SQL = sSQL

VBA - Accessing a collection of values

I have two access forms. frm_Main and frm_Sub which has data conditionally displayed depending on the selections of the main form. I need to write a select all function for items displayed in frm_Sub. In VBA is there a way that I can get a list of the id's currently being displayed in frm_Sub?
for example, if I do this
me.controls("Svc_Tag_Dim_Tag_Num").value
I get the value for one of rows in the frm_Sub, is there a way to get all of the values?
Maybe I can ask a different way. I have a form that is displayed as a listview, in VBA, is there a way to get all the values from a specific column?
Another option is to write a function that concatenates the PKs of the recordset that the subform displays. Say your main form is Company and your subform lists Employees. You'd have a LinkMasterFields and LinkChildFields properties of the subform control would be CompanyID (PK of the Company table, FK of the Employees table).
Thus, to get the same set of records as is displayed in the subform when the parent is on a particular Company record:
Dim db As DAO.Database
Dim strSQL As String
Dim rst As DAO.Recordset
Dim strEmployeeIDList As String
Set db = CurrentDB
strSQL = "SELECT Employees.* FROM Employees WHERE CompanyID="
strSQL = strSQL & Me!CompanyID & ";"
Set rs = db.OpenRecordset(strSQL)
If rs.RecordCount > 0 Then
With rs
.MoveFirst
Do Until .EOF
strEmployeeIDList = strEmployeeIDList & ", " & !CompanyID
.MoveNext
Loop
End With
strEmployeeIDList = Mid(strEmployeeIDList, 3)
End If
rs.Close
Set rs = Nothing
Set db = Nothing
Now, why would you do this instead of walking through an already-opened recordset (i.e., the subform's RecordsetClone)? I don't know -- it's just that there may be cases where you don't want your lookup to be tied to a particular form/subform. You could fix that by making your function that concatenates accept a recordset, and pass it a recordset declared as I did above, or pass it the subform's RecordsetClone. In that case, you could use the concatenation function either way, without being tied to the form/subform.
If I understand your question you should be able to access the ID value in the control using Column(x) where x indicates the control's row source column starting from 0. For example, if ID is in column 0 with width 0 in. it will be hidden from view but VBA can "see" it as me.controls.["Svc_Tag_Dim_Tag_Num"].column(0).
To get at the sub-form's record source directly from outside the form's class module you could create a function something like:
Public Function test_get_sub_form_record_set() As String
Dim dbs As Database
Dim rst As Recordset
Dim xcat As String
Set dbs = CurrentDb()
Set rst = [Forms]![Your Main Form Name]![Your Sub-form Name].[Form].RecordsetClone
If rst.RecordCount > 0 Then
rst.MoveFirst
xcat = rst!ID
rst.MoveNext
Do While Not rst.EOF
xcat = xcat & ", " & rst!ID
Loop
Else
xcat = ""
End If
test_get_sub_form_record_set = xcat
rst.Close
Set dbs = Nothing
End Function
This would be included in a separate module and when called would return a concatenated, comma separated list of ID's.