Update Combo Box Value - ms-access

In Access VBA I'm attempting to update a combo box's value based on a query.
Code:
Function updateComboBox()
Dim db As Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Dim user as string
user = environ("username")
strSQL = "SELECT [Name] FROM myQuery WHERE [UserName] = '" & user & "'"
Set rs = db.OpenRecordset(strSQL)
If rs.RecordCount > 0 Then
Me.MyComboBox = rs.Fields(0)
End If
End Function
The error I get:
You can't assign a value to this object.
How can I change the current value of the combo box?
It may be important to note that the combo box is a list of values populated from a query. It happens to be the same query strSQL is using. It is important that users can still choose other names, but it defaults to their own.
EDIT:
I ended up doing the following work around to make this work:
I set the default property of MyComboBox to be =[myTextBox].
Form_OnOpen --> Update myTextBox's value based on query. Refresh form so combobox displays myTextBox's value.

use this
for single data Me.MyComboBox.AddItem(***)
for collection
Me.MyComboBox.List = rs.Fields(0)

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

Microsoft Access 2010 interdependencies in Forms (fill out one cell, automatically fill another)

In excel, I know this is the VLOOKUP function, however, being a beginner at Access, I have no clue how to do this.
I have halls (from A to H), who all have their own teamleader (eg A-->Ben, B-->Michael, C-->Dave, etc). I would like to select just the hall, and the teamleader will automatically show up in the next field on the form. At the end, all will be registered in a table.
I have currently build this equation to fill out a specific value in a cell (dependent on the value of another cell), but it is giving an error message. What am I doing wrong?
Option Compare Database
Dim db As DAO.Database
Dim rst As DAO.Recordset
Private Sub Hal_AfterUpdate()
Set db = CurrentDb
'SELECT Voormannen.Voorman, Voormannen.Hal
'FROM Voormannen
'WHERE (((Voormannen.Hal)=[Formulieren]![DSM formulier]![Hal]));
strSQL = "SELECT Voormannen.Voorman, Voormannen.Hal FROM Voormannen WHERE [Voormannen]![Hal]=[Forms]![DSM formulier]![Hal]"
Set rst = db.OpenRecordset(strSQL)
rst.MoveFirst
Me.Tekst304 = rst![Voorman]
rst.Close
Set rst = Nothing
Me.Refresh
End Sub
Assuming your SQL string returns a correct dataset, try replacing this:
Me.Tekst304 = rst![Voorman]
with this:
Me.Tekst304.Text = rst("Voorman")
If your SQL string does not return a correct dataset, try changing it to this:
strSQL = "SELECT Voorman, Hal FROM Voormannen " & _
"WHERE Hal = '" & Forms![DSM formulier]!Hal.Text & "'"
You need to surround your control reference with ampersands (&) otherwise VBA doesn't know you're referencing a control.

Get Record based on form textbox value

I am trying to get a record based on the value contain within the textbox on a form. i.e i type in the information into the textbox and other values associated with that value are returned to other textbox on the form.
I thought this would be easy but can't seem to get it to work.
Currently I was trying
Dim rst As DAO.Recordset
Dim SQL As String
Dim SQL2 As String
SQL = "SELECT tblmytbl.[IDCODE]"
"FROM tblmytbl " & _
"WHERE (((tblmytbl.[IDCODE]) = forms!myform!mybox.value "
Set db = CurrentDb
Set rst = db.OpenRecordset(SQL)
If Not ((rst.BOF = True) And (rst.EOF = True)) Then
Forms!myform!Text102 = rst.Fields("[Name]")
Forms!myform!Text103 = rst.Fields("[Surname]")enter code here
Note: The search information is alphanumeric and i have tried without the .value
Any help would be appreciated.
Thanks
The SQL you send to the server can't access the form. However, you can concatenate the value into the string that you send like:
" WHERE (((mytable.myfield) = '" & FixQuotes(Forms!myform!mybox.value) & "') " & _
Note, you may need to defend yourself against SQL injection, a simple (but not complete) defense would be something like:
Public Function FixQuotes(input as string) As String
FixQuotes = Replace(input,"'","''")
End Function
EDIT:
Based on your updated code, there's quite a number of changes you need to make. Beyond my statement above, the .OpenRecordset only applies to full tables, you can't use it with a SELECT statement. Instead, you have to instantiate a QueryDef. On top of that, you try to reference fields you didn't include in the query. Also, you can simplify the expression Forms!myform! to Me (which could help if you want to reuse the code somewhere else) So your code should look something like this:
Dim db as Database 'always dim everything, you should use Option Explicit'
Dim rst as Recordset 'DAO is the default anyway'
Dim qdf as QueryDef 'this object is required for queries'
Set db = CurrentDb
'prepare single-use query, to return the values you're going to use
'as mentioned before, the query doesn't have access to the form
'we can use Me since it references the form'
' use TOP 1 since you only expect 1 record'
Set qdf = db.CreateQueryDef("","SELECT TOP 1 Name,Surname FROM tblmytbl " & _
"WHERE IDCODE = '" & FixQuotes(Me.mybox.value) & "';")
Set rst = qdf.OpenRecordset(DbOpenForwardOnly)
'forwardonly since you only care about the first record'
If Not rst.EOF Then 'ForwardOnly has to start at the first record'
Me.Text102.Value = rst!Name
Me.Text103.Value = rst!Surname
'I highly suggest giving these boxes better names'
Else
'no record found'
End if
rst.Close
qdf.Close
db.Close 'close these objects, it can sometimes cause memory leaks otherwise'

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.