Access 2010 - Dynamically Set Combo Control Source and Row Source - vba

I am limited in that I have to stick with the old (messy) table design. On this one interface I am developing, there is a combo drop down that is a fixed values list. The options are Group1, Group2, and Group 3. Based on that, a dependent combo needs to be set to the correct row source and control source.
The form is locked, and the user can navigate the records (first, last, next previous, and an unbound combo to jump to a record). During those operations, I just want to refresh which list the dependent combo should pull from, and what value it should bind to, to show the correct value.
When the user clicks to make a "new" record, I won't show the dependent drop down (or make it enabled. haven't decided yet) until they choose a value in the first combo, telling us which group it is.
In order to control this, I created a function for use on this form. This is that function:
Private Function MyGroup()
'Mybitval is a table value that is a bit data type. It means group1
If Me.Mybitval = True Then
Me.cboGroupType.Value = "Group1"
ElseIf Me.Mybitval = False And Nz(Me.MyID1, 0) <> 0 Then
Me.cboGroupType.Value = "Group2"
ElseIf Me.Mybitval = False And Nz(Me.MyID1, 0) = 0 Then
Me.cboGroupType.Value = "Group3"
End If
Select Case Me.cboGroupType
Case "Group1"
Me.cboGroupName.RowSource = "SELECT Group1.ID, Group1.G1Name FROM Group1 ORDER BY Group1.G1Name;"
Me.cboGroupName.ControlSource = me.FKID1
Case "Group2"
Me.cboGroupName.RowSource = "SELECT Group2.ID, Group2.G2Name FROM Group2 ORDER BY Group2.G2Name;"
Me.cboGroupName.ControlSource = Me.FKID2
Case "Group3"
Me.cboGroupName.RowSource = "SELECT Group3.G3ID, Group3.G3Name FROM Group3 ORDER BY Group3.G3Name;"
Me.cboGroupName.ControlSource = me.FKID1
End Select
Debug.Print Me.cboGroupName.RowSource
Debug.Print Me.cboGroupName.ControlSource
Debug.Print Me.cboGroupName.Value
End Function
The idea is that I call this function on load, after I go to the first record, and then on any navigation button click or after update of the go to combo.
The problem is, that the cbogroupname never shows the value it has in the control source. When I try to load the form, my debug rowsource shows the correct sql, and the control source shows the value of the correct table field for the current record it's on, but 2 things don't seem to work. If I don't do the 3rd debug on the value, the form loads fine, but the combo doesn't show the right value, even though it's bound to a table column that has a value. If do debug the value, I get a run-time error '2424': "The expression you entered has a field, control, or property name that [my application] can't find."
When I hit debug, it goes to the last line of the function:
Debug.Print Me.cboGroupName.Value
When I go to save a new record, I run through validation, and having this 1 combo, instead of 3 different ones with alternating the visibility, seems way easier. Is there a reason this isn't working the way I am wanting it to?
Thanks!

And just like that, I figured it out. Of course it takes me all day, and posting this question to get it.
Here is the function, with the right syntax:
Private Function MyGroup()
If Me.Mybitval = True Then
Me.cboGroupType.Value = "Group1"
ElseIf Me.Mybitval = False And Nz(Me.MyID1, 0) <> 0 Then
Me.cboGroupType.Value = "Group2"
ElseIf Me.Mybitval = False And Nz(Me.MyID1, 0) = 0 Then
Me.cboGroupType.Value = "Group3"
End If
Select Case Me.cboGroupType
Case "Group1"
Me.cboGroupName.RowSource = "SELECT Group1.ID, Group1.G1Name FROM Group1 ORDER BY Group1.G1Name;"
Me.cboGroupName.ControlSource = "FKID1"
Case "Group2"
Me.cboGroupName.RowSource = "SELECT Group2.ID, Group2.G2Name FROM Group2 ORDER BY Group2.G2Name;"
Me.cboGroupName.ControlSource = "FKID2"
Case "Group3"
Me.cboGroupName.RowSource = "SELECT Group3.G3ID, Group3.G3Name FROM Group3 ORDER BY Group3.G3Name;"
Me.cboGroupName.ControlSource = "FKID1"
End Select
Debug.Print Me.cboGroupName.RowSource
Debug.Print Me.cboGroupName.ControlSource
Debug.Print Me.cboGroupName.Value
End Function
Provided your form is bound to a table, such as mine is, the control source needs to = "fieldname" . It needs to be the field name in double quotes. Not me.fieldname as that ends up making the controlsource the value of that field name. It also can't be [table1]![field1] I tried that and that doesn't work either.
The above works beautifully. Now to test the rest of the form!

Related

Why can't I get the current record ID from a multi-instance form in VBA

I have a database I'm working on with a number of forms, some of them have to be updated when something in a different form is changed. I've set it up so that they're multi-instance forms, which works something like this:
Set frm = New Form_Name
frm.RecordSource = "select * from Table_Name where id = " & ID
colForms.Add Item:=frm, Key:=frm.hwnd & ""
mintForm = mintForm + 1
frm.SetFocus
frm.Visible = True
colForms is a collection.
To refresh a form, I've added a function that refreshes the form that matches the name and ID passed:
Function RefreshForm(RForm As String, ID As Integer)
If Developer = False Then On Error GoTo Fehler
Dim F As Form
On Error Resume Next
For i = 1 To mintForm
Set F = colForms(i)
If F.CurrentRecord = ID And F.Name = RForm Then F.Refresh
Next i
'Error handling logic
Done:
Exit Function
Fehler:
RuntimeError "MultiInstance: RefreshForm", Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext, Err.LastDllError
Err.Raise 1000, , "Folgefehler"
End Function
Problem is, F.CurrentRecord is always 1 for some reason, even though the ID of the record in the form is definitely not 1. Any idea what I'm doing wrong, or how I could properly get the record ID (primary key) from the form? The form is definitely bound (at least the ones where I'm trying to get the ID).
CurrentRecord is not pulling record's ID from unique identifier field. CurrentRecord is a sequential number assigned by the form and has no relationship to the record unique identifier saved in field.
If focus is on fifth record then it is record 5 and if that record has a unique ID field value of 5 then they are equivalent. Doing this comparison seldom makes sense. A form always sequentially numbers records starting with 1 regardless of filtering/sorting yet the form could be filtered to display a subset of records and/or records could be sorted so ID's are not sequential nor start with 1.
If you want to know ID of record that has focus then reference field name holding that data.
If F!fieldname = ID And F.Name = RForm Then F.Refresh

Why is my WHERE clause not working in my combo box

I have a combo box called NameFilt. I wish the row source to be as follows:
SELECT DISTINCT VoucherListTbl.BuyerName
FROM VoucherListTbl
WHERE (((VoucherListTbl.BuyerName) Is Not Null)) OR (((VoucherListTbl.BuyerName)<>""));
i.e show all the unique BuyerNames from my table and dont include any blanks
The above SQL is generated in the query bulider by clicking on the 3 dots in combo box's row source in the property sheet, then selecting the BuyerName field and then entering Is Not Null Or <>" in the criteria. Clicking run in the query builder displays the exact result I expect.
On closing and saving the query builder and then clicking in the combo box on the form I get a different result - All the DISTINCT names are there, but there is a blank at the start of the list.
When I attempt to use this SQL in my VBA code I get another result. The code is:
Private Sub NameFilt_GotFocus()
Me.AllowEdits = True
Me.NameFilt.RowSource = "SELECT DISTINCT VoucherListTbl.BuyerName
FROM VoucherListTbl WHERE (((VoucherListTbl.BuyerName) Is Not Null))
OR (((VoucherListTbl.BuyerName)<>""));"
Me.NameFilt.Dropdown
End Sub
This results in the combo box's dropdown showing only one option - a blank! There are no names listed.
Moreover, If the WHERE clause is removed i.e. the code is:
Private Sub NameFilt_GotFocus()
Me.AllowEdits = True
Me.NameFilt.RowSource = "SELECT DISTINCT VoucherListTbl.BuyerName FROM VoucherListTbl;"
Me.NameFilt.Dropdown
End Sub
Then the DISTINCT names are shown, with a blank option at the top of the list which is what one would expect
Please could you help by explaining why the WHERE clause will not work for me when entered into the VBA code
Many thanks
If you use "" within "" it will break the string and that's the reason of non-working WHERE condition. Encode quotes with "" i.e. end of your original string should look like <>""""));" or replace "" with '' and try again.
Note, same query can be written as
SELECT DISTINCT BuyerName
FROM VoucherListTbl
WHERE IsNull(BuyerName,'')<>''

In VB.NET Query on what to do when field is empty

What I have is a form behind a login and I want to pull in a value from our database for the NameField IF that value exists, otherwise leave it blank for the user to fill in.
So I have the following if statement which works IF there is a value in our database for AliasName:
If _NameID <> Guid.Empty Then
Name.Text = (From c In _Data.CONSTITUENTs
Where c.ID = _NameID
Select c.KEYNAME).FirstOrDefault().ToString()
NameField.Text = (From atc In _Data.CODEs
Join a In _Data.AliasName On atc.ID Equals a.CODEID
Where atc.DESCRIPTION = "Default Name" AndAlso a.CONSTITUENTID = _NameID
Select a.NAME).FirstOrDefault().ToString()
End If
What I now need to know is how to add an if statement to read if there is a value that exists in the AliasName field and the description matches "Default Name", and if so, use that value, otherwise, allow the user to enter their own value.
Right now it is pulling in the value when it exists, but erroring out the page when it does not.

How to use a query as a control source for a textbox on a form?

I have a form myForm that's binded to a table tbl in my database. (I don't know if binded is the correct term, but It shows records from tbl on by one.)
In the form:
contact: textbox, binded to tbl.contact.
dailyCount: textbox, should show the amount of contacts entered today.
In the table:
contact
dateEntry
The query I want to use is:
SELECT count(*)
FROM tbl
WHERE contact = currentContact
AND month(dateEntry) = month(now)
AND day(dateEntry) = day(now)
AND ear (dateEntry) = year(now)
Where currentContact is the contact that is showing on the form now.
I tried putting the query in the dailyCount dataSource, but It's not working. When I click on the three dots on datasource to access the wizard, I get a window to build functions and not queries.
How do I get the currentContact showing on the form into the query?
There are multiple ways to do this. For a couple of reasons, I don't like to hardcode queries in the datasource of a specific field, and I mostly build/assign all my queries in VBA. So here's how I would do it.
In the load event of you form :
Private Sub Form_Load()
Dim SQL As String
Dim RST As Recordset
dim theCOntact as string ' Change accordingly
theCOntact = Me.currentContact ' I don't know how your fields are named, so change accordingly
SQL = "SELECT count(*) AS cnt FROM tbl WHERE contact = " & theContact & "' AND month(dateEntry) = month(now) AND day(dateEntry) = day(now) AND Year(dateEntry) = year(now)"
Set RST = CurrentDb.OpenRecordset(RST)
If RST.BOF Then
dailyCount.Value = RST!cnt
Else
dailyCount.Value = 0
End If
End Sub
Assuming your contact field is string, if its a number remove the quotes in the SQL
Probably the simplest approach is to use the DLookup function with an associated query:
Create and save a named query with your SQL code or equivalent. Let's call it "qryDailyCount". Note that it should be modified to look something like this (in particular, name the column and change the record reference to a GROUP BY for now):
SELECT count(*) as DailyCount
FROM tbl
WHERE month(dateEntry) = month(now)
AND day(dateEntry) = day(now)
AND year (dateEntry) = year(now)
GROUP BY contact
In the dailyCount textbox, set the Control Source to something like this:
=DLookUp("Count";"qryDailyCount";"contact = [contact]")
(Note that if the contact field is a text field, you must enclose it with single quotes.)

inputing query with data from combobox in parentform to listbox in subform

I have an ms-access db that has a form (FormA) with two sub forms (subFormB and subFormC). I am trying to use the value of a combobox (combo2) in FormA to get values (from a table) which will be input into subFormB and subFormC. i.e whatever values the user selects from combo2 will be used as a filter to query a table in the db and the values will be input into listboxs in either subFormB or subFormC
My code runs well with FormB but i cant seem to get it to work for FormC
The values that are displayed in combo2 depend on the value of another combo box (combo1).
If combo1 is "staff name" then the values in combo2 are string (names) and results are input into subFormB
If combo1 is "project name" then the values in combo2 are numeric (numbers)and results are input into subFormC
an example of my code is below
Private Sub Combo2_AfterUpdate()
If Combo1 = "Staff Name" Then
subFormB.Visible = True
ltemp = "SELECT Staff.department"
ltemp = ltemp & " FROM Staff "
ltemp = ltemp & " WHERE Staff.staff_name = '" & combo2 & "' "
Me!subFormB.Form.List3.RowSource = ltemp
If Combo1 = "Project Number" Then
subFormC.visible = True
TID = "SELECT Contracts.TargetIssueDate"
TID = TID & " FROM Contracts "
TID = TID & " WHERE Contracts.cms = combo2 "
Me!subFormC.Form.List25.RowSource = TID
End Sub
In other words the first part of my code works but the second part (starting from the second if statement) doesnt. i feel it is because the value of combo2 at this instance is numeric, and the problem is from the query but i dont know how to rewrite the query so that it would work.
In the first query, the value of combo2 is included in the WHERE clause.
But the second query includes the combo's name instead of its value. In other words, this is the WHERE clause built by the code ...
WHERE Contracts.cms = combo2
In that situation, I would expect Access to treat combo2 as a parameter and ask you to supply a value for it. But you didn't mention that, so something more may be going on.
The code includes ...
If Combo1 = "Staff Name" Then
... but there is no closing End If later. Perhaps, you've shown us an abbreviated version of your actual code, and the actual version does include End If?
Rather than sorting out those details, I'll suggest a different approach. Make a backup copy of your db file. Use this query as the RowSource for List3 on subFormB.
SELECT Staff.department
FROM Staff
WHERE Staff.staff_name = Forms!FormA!combo2;
Then, in Combo2_AfterUpdate of FormA, just Requery the subform's listbox, or even the entire subform, instead of altering the listbox RowSource ... one of these two ...
Me!subFormB!List3.Requery
Me!subFormB.Requery
If that approach is satisfactory, apply the same strategy to the other subform . And if it fails completely, revert back to your backup db.