MS Access VBA: Fetch data from a query which corresponds to an ID field from a selected row in a subform table - vba

I'm completely new to VBA and MS Access!
I have a Subform within a form which contains data about items which all have an "Equipment ID" field.
Using data from a different table, I have a query to count the number of "faults" associated with each item. This Query also has the "Equipment ID" field.
I have a second form which contains text boxes, and can be accessed by a button. On the button click, the form opens up and data from the selected current row in the subform are passed into the text boxes. I have assigned the original data table to the form control source.
What I want to do:
I'm having trouble with the query. I have been trying to link the subform and the query, so that when the row on the sub form is selected, the "Equipment ID" is grabbed from that, and the "number of faults" in the Query can be found from its corresponding "Equipment ID".
Here is the code so far (and what I want to happen in comments):
Private Sub Button_Click()
Dim db As Database
Dim rs As DAO.Recordset
Dim EqIDfrm As String 'Equipment ID from the subform
'Open up the Faults Query
Set db = CurrentDb
Set rs = db.OpenRecordset("qryFaultTotal")
'open up the second form
DoCmd.OpenForm "SecondForm"
'Grab the "Year" from the selected row in the sub form and assign it to SelectYear. The text
'box value in the second form then becomes the SelectYear value.
SelectYear = [Forms]![Form1]![tblAsset Subform].[Form]![Year]
[Forms]![Form2]![txtYear] = SelectYear
' etc. for other fields
'grab the equipment ID from the subform and from the Query
EqIDfrm = [Forms]![Form1]![tblAsset Subform].[Form]![Equipment_ID]
EqIDqry = rs![Equipment_ID]
'<--- this seems to be part of the problem
'Lookup the Total number of faults from the FaultTotal Query, where the Equipment ID in the Query is
the same as the equipment ID on the subform from the selected row.
Fault = DLookup("[TotalFault]", "[FaultTotal]", "[EqIDqry] = " & [EqIDfrm] & "")
End Sub
When I use lookup I keep getting an error of some sort (type mismatch, run-time error), and I just can't figure it out. It doesn't seem to like the EqIDqry but I don't know why despite Googling. I feel like it should be very simple, but I understand I may have to do something totally different! Any advice would be appreciated :)

Related

MS Access 2019: Can't populate a form field using SQL query in VBA

I want to auto-populate a field in my form based on the results of an SQL query. I'm just not sure of the proper syntax to get it to properly read the query. This is what I've got, but it's not returning the value of the query, it's actually just returning the text of the query itself.
Private Sub PurchBatchNo_Enter()
Dim MostRecentPurchBatch As String
MostRecentPurchBatch = "SELECT Max(PurchaseBatchNo) FROM purchases"
Me.PurchBatchNo.Value = MostRecentPurchBatch
End Sub
I'm sure the issue has to do with the quotation marks, but it doesn't work without them either, and I'm not sure how to write it properly.
Thanks for being here for beginners like me!
All your code does is set a variable to a string of characters then attempts to set value of field with that string.
But why would you want to populate field with a value already used in a record? Most likely you need to increment by 1.
To use an SQL statement, would have to open a recordset object then reference field of recordset.
Private Sub PurchBatchNo_Enter()
Dim MostRecentPurchBatch As DAO.Recordset
If IsNull(Me.PurchBatchNo) Then
Set MostRecentPurchBatch = CurrentDb.OpenRecordset("SELECT Max(PurchaseBatchNo) AS MaxBatch FROM purchases")
Me.PurchBatchNo = MostRecentPurchBatch!MaxBatch + 1
End If
End Sub
However, pulling a single value from table is what domain aggregate functions are good for.
Private Sub PurchBatchNo_Enter()
If IsNull(Me.PurchBatchNo) Then Me.PurchBatchNo = DMax("PurchaseBatchNo", "purchases") + 1
End Sub
Instead of using VBA procedure, consider just setting DefaultValue property of textbox bound to PurchBatchNo field with the DMax() expression. As soon as record is initiated by input to another textbox, the PurchBatchNo will populate.
If user should not be able to edit this value, set textbox as Locked Yes and TabStop No and use a different event for the VBA code if you go with VBA.

Showing table records in a report with different textboxes

I have a table name is Table1 with 2 fields which are Name and Married_Status.
For Name includes Names of the employees and for the Married_Status includes Yes or No.
The Question is: Can I show them in a report by 2 ways? first when the status is Yes 2 textboxes appear but if the status in No 1 textboxes appears?
I use Access 2016
If I am understanding you correctly you want to hide the Married_Status column if it is no. However this answer covers hiding other columns if I am misunderstanding. In short, this is called conditional formatting and is done by highlighting the control-clicking the format tab- then clicking conditional formatting. However, access can only conditionally format the text color, font, and background of a control. Further the default control for a yes/no variable is a checkbox and the checkbox allows no conditional formatting.
There are two work-arounds. First you can make the Married_Status text box invisible in all cases:
base the report on a query and replace Married_Status with a Calculated variable like:
Married_Status: IIf([Table1].[Married_Status]=True,"Married",Null)
If we use a text box for Married_Status and make it transparent we get:
When Married_Status is Null and the Married_Status textbox is transparent nothing shows. Unfortunately a checkbox shows even when the value is null.
The second work-around requires you know a lot about the data in advance and should only be done if the boss insists. You can build the report using VBA. For my sample data I know I have one page of 4 cases so I can avoid the detail section which limits me to one control for every instance of Married_Status and put as many controls as I need in the Header:
Then in the load event use vba to set the controls:
Private Sub Report_Load()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("Table1")
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
For i = 1 To 4
Me.Controls("Text" & i) = rs("EmployeeName")
If rs("Married_Status") = True Then
Me.Controls("Check" & i) = True
Else
Me.Controls("Check" & i).Visible = False
End If
rs.MoveNext
Next i
End If
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub

Combo Box selecting First Record and not the defined record

first time asking here because i'm stumped!
I have a MS Access Form with 2 combo boxes:
First combo box (cboPub) selects a Publisher which then filters the second combo box (cboTitle), this works fine however the pulled record is the first record and not the one that meets the criteria.
Code below:
Private Sub cboPub_AfterUpdate()
cboTitle = Null
cboTitle.Requery
End Sub
Sub cboTitle_AfterUpdate()
' Find the record that matches the control.
Me.RecordsetClone.FindFirst "[Supplier] = """ & Me![cboTitle] & """"
Me.Bookmark = Me.RecordsetClone.Bookmark
End Sub
I suspect it is because of the line here:
Me.RecordsetClone.FindFirst "[Supplier] = """ & Me![cboTitle] & """"
but i dont know what to change to have it select the correct record.
A common task is to filter the data in a form's details section from unbound combo boxes in the form header section. (don't set the comboboxs' data sources) I assume that is what you are trying to do because me in the afterupdate event refers to the form. If so set the forms filter rather than messing with the forms record source. Your second problem is cboTitle's afterupdate event doesn't fire when cbotitle's value is changed through vba code. So put all the code in cboPub.
Private Sub cboPub_AfterUpdate()
'cboTitle = dlookup("Title", "SomeTable", "SupplierID = " & cboPub.value) 'how I filtered cboTitle
Me.Filter = "SupplierID = " & cboPub.Value
Me.FilterOn = True
End Sub
Private Sub cboTitle_AfterUpdate()
Debug.Print "check the immediate window for how cboTitle's after update event does not fire when cboTitle is updated with VBA"
End Sub
warning: treat this as pseudo code; the exact filter depends on how Supplier, Publisher, and Title are related in your tables and combo boxes.
Explanation: I think the programmers behind access intentionally forced us to set up our forms entirely at design time. No matter what I have tried Access does not display runtime changes to it's record source in any acceptable fashion. It is the access way or the high way. Linking up your record source and form variables at design time then filtering is the only approach I have found that works. I assume the reasons behind why you cannot trigger an afterupdate event through code are similar.

combobox.column property returns invalid use of null in vba

I am a database//Access noob, so bear with me. I have a database set up to keep track of Consultants and their Vendors for a tech consulting company. Some consultants are their own vendors, and some have third-party vendors that handle their contracting. In the case where a consultant is also their own vendor, the contact information is the same for both. Contact Info is stored in a separate table, with primary key ContactID and foreign key fields for ConsultantID (primary key in ConsultantT) and VendorID (primary key in VendorT).
In the case that the relevant Contact Info has already been entered on one of the forms, I want to be able to select the already existing Contact Info record and tell the database to add the other foreign key ID field to the existing record based on the record on the main form. So, for example, if I have already entered Contact Info for Consultant A via the Consultant form, when I open the Vendor form to add Consultant A's vendor I want the option to select "Consultant A" from a combo box and have their info populate VendorsF's Contact Info form while adding the VendorID to the already existing Contact Info record for Consultant A.
I think I've almost worked it out, but am stuck on one last thing. Right now I have a popup form (ChooseConsultantInfoF) for selecting an existing ContactInfo record. On that form I have a search combobox (SelectConsultantCombo) to select the existing record, and a command button (SaveConsultantbtn) which I've tried to code to Update the ContactInfoT and add the VendorID from the current record on the VendorsF to the existing record in ContactInfoT. Here is the all of the code for the popup form:
Option Compare Database
Option Explicit
Private Sub SaveConsultantbtn_Click()
Dim stupid As Long
stupid = SelectConsultantCombo.Column(0)
DoCmd.RunSQL "UPDATE ContactInfoT SET VendorID = (Forms!VendorsF!VendorID) Where ContactInfoID = " & stupid & ";"
End Sub
Private Sub SelectConsultantCombo_AfterUpdate()
Dim rst As DAO.Recordset
Set rst = Me.RecordsetClone
rst.FindFirst "ContactInfoID = " & Me!SelectConsultantCombo
Me.Bookmark = rst.Bookmark
leave:
Me!SelectConsultantCombo = Null
If Not rst Is Nothing Then Set rst = Nothing
Exit Sub
End Sub
When I try to put it into action, I get Error 94: Invalid use of Null and it pulls up
stupid = SelectConsultantCombo.Column(0)
I know the code block works apart from that--I tried the Click event once with a numeric value instead of the variable:
Private Sub SaveConsultantbtn_Click()
DoCmd.RunSQL "UPDATE ContactInfoT SET VendorID = (Forms!VendorsF!VendorID) Where ContactInfoID = 1 ;"
End Sub
without any trouble, so the issue must be in calling the combobox's column.
I also tried defining the variable with Nz to allow Null:
stupid = Nz(Me.SelectConsultantCombo.Column(0), 0)
and that gets the code working also, but still doesn't save my VendorID to the record in ContactInfoT. None of the columns in the combobox contain Null values (none that I can find, anyway). Dunno if this is useful, but the Row Source of the combobox is:
SELECT ContactInfoT.ContactInfoID, ConsultantT.ConsultantID, ConsultantT.FirstName, ConsultantT.LastName FROM ConsultantT INNER JOIN ContactInfoT ON ConsultantT.ConsultantID = ContactInfoT.ConsultantID ORDER BY ConsultantT.[LastName], ConsultantT.[FirstName];
Does anyone know why Access doesn't recognize my combobox.column property? Or is there another way to write this up in VBA to avoid this error?
First try stupid = Me.SelectConsultantCombo.Column(0) (you are missing the Me. part).
But what you should really do is make sure your bound column on the combo box is set correctly and just use stupid = Me.SelectConsultantCombo
I took Me!SelectConsultantCombo = Null out of the combo's afterupdate and it works perfectly now! Of course if I have the combo set to null somewhere in the code it's going to pull up null somewhere else, d'oh!

Access Calculate Next Value (lookup value}?

I need to get a value from a textbox in a report's detail section which will give me multiple values. I need to get each of those values into VB to do some calculations... I can pull a value from forms with ChildID = Forms!FRM_Child!ChildID.Value, but when I put
Private Sub Report_Open(Cancel As Integer)
Dim ChildID as Integer
ChildID = Reports!RPT_Due_Date!ChildID.Value
End Sub
it crashes and says "Run-time error '2424': The expression you entered has a field, control, or property name that Microsoft Access can't find."
I've checked and double checked the names. The thing I figure is that somehow because it's in the detail section with multiple values it crashes. Any ideas?
ChildID Last_Asmt_Type Last_Asmt_Date Next_Asmt_Type Next_Asmt_Date
1 Initial Evaluation 1/5/15 Periodic Review 5/5/15
2 Periodic Review 2/5/15 Annual Review 6/1/15
3 Annual Review 3/5/15 Periodic Review 7/1/15
What I want to do is get the Last_Asmt_Type and then with if/then rules select the Next_Asmt_Type ie If Last_Asmt_Type is Periodic Then Next_Asmt_Type is Annual....
How would I do this with a lookup value?
In Report_Open(), the textbox exists as control, but it has no value yet.
Your code would work in Report_Load(), but as you already know, it would be pointless because you would only get the first value.
If you want to read all values, don't try to read them from the report textbox, open a recordset on the report's data source. Like this:
Dim RS As Recordset
Set RS = CurrentDb.OpenRecordset(Me.RecordSource)
Do While Not RS.EOF
Debug.Print RS!MMI
RS.MoveNext
Loop
RS.Close
But:
Most probably there is an entirely different and better way to do what you want. What kind of calculations are you doing?