I have an entry form with a sub. I have three combo boxes that work together. combo 1 sets up with vba and an after event combo 2 and on into three. They work fine independently of the main form, but when I sue the form as a sub the cascade stops working.
Forms
Main Form Name "1A-Event Entry"
SubForm Name "1B-Event sub"
ComboBox 1 (After Update)
Private Sub Category_AfterUpdate()
Me.Type = Null
Me.Type.Requery
Me.Type = Me.Type.ItemData(0)
End Sub
ComboBox 2 (SQL)
SELECT Type.ID, Type.Type, Type.Category
FROM Type
WHERE (((Type.Category)=[Forms]![1B-Event sub]![Category]))
ORDER BY Type.Type;
CombBox2 (After Update)
Private Sub Type_AfterUpdate()
Me.Detail1 = Null
Me.Detail1.Requery
Me.Detail1 = Me.Detail1.ItemData(0)
End Sub
ComboBox3 (SQL)
SELECT Detail.ID, Detail.Detail, Detail.Type
FROM Detail
WHERE (((Detail.Type)=[Forms]![1B-Event sub]![Type]))
ORDER BY Detail.Detail;
I am sure is has something to do with the Form/ Subform scripting in the SQL, but it escapes me.
As a subform, you need a different reference:
WHERE Type.Category=[Forms]![1A-Event Entry]![Subform Control Name Here].Form![Category]
When a form is run as a subform of another form, you must refer to the subform control.
Related
I am trying to build a code where previous records in a certain form are locked for editing. This would be to allow users to create and edit new forms, but not change data from previous forms. I want to be able to allow users to access and edit the previous 5 forms, but lock the data in all forms previous to that.
I've tried several things, but as a novice VBA user, nothing has worked. I tried:
Private Sub Form_Load()
If Me.ID < 22 Then
Me.AllowEdits = False
Else
Me.AllowEdits = True
End If
End Sub
I used a dummy "22" to see if the code would work, but it just ended up locking all of the records, not just numbers 1-21, like I was trying to do.
I would like the "22" to be the value of the ID field in the most recent record. I would also like it to be: If Me.ID < (ID of most current record)-5
Is this possible?
Form_Loadis wrong event, as only raised once on startup withMe.IDbeing the first record. You have to check current selected record withForm_Currentevent.
Don't rely onIDbeing consecutive (e.g. caused by deletions). Select Top 5 IDs (sort decending) and get minimum.
Create as saved query (e.g. name it FormNameTop5ID, where FormName is name of form, TableName is table/query bound to form )
SELECT TOP 5 ID FROM TableName ORDER BY ID DESC
In the form create aForm_Currentevent
Private Sub Form_Current()
If Me.ID.Value < DMin("ID", "FormNameTop5ID") Then
Me.AllowEdits = False
Else
Me.AllowEdits = True
End If
End Sub
Two tables in my MSAccess database: MainT, and SubT which is linked to MainT via a one-to-many join.
I use a listbox (Listbox1) on a form (Form1) which opens a new form (Form2) on double-click. On that second form (Form2) there is also a second listbox (Listbox2).
The issue I am having is that Form2 displays the correct record from MainT as selected from Listbox1 on Form1 - but the Listbox2 on Form2 is supposed to show only records from SubT which match the record from MainT.
Instead Lisbox2 is displaying all the records in SubT and is not filtering based on those records in SubT that match the record from MainT being displayed in the form (Form2)
The double-click command from Listbox1 to open Form2:
DoCmd.OpenForm "Form2", , , "TrackerPTID =" & Me.ListBox1, , acDialog
So my question is how I can take the value from Form1/Listbox1 that gets Form2 to open to the correct record and pass that to the Listbox2 so that it uses that same value to filter Listbox2 to the records on SubT that match the record on MainT
Thanks in advance!
R
If you are using Access 2007 or later I would suggest using TempVars.
Set a Tempvar in Form1 before opening Form2
Tempvar("TrackerPTID") = Me.Listbox1
DoCmd.OpenForm "Form2", , , "TrackerPTID =" & Me.ListBox1, , acDialog
Then define the Listbox2.RowSource like:
Select * from SubT where TrackerPTID = [Tempvars]![TrackerPTID]
As you have the ID on Form2, all you need is to filter the listbox. Use the OnCurrent event of Form2 to filter on Form2's ID:
Private Sub Form_Current()
Me!Listbox2.RowSource = "Select * From Table2 Where ID = " & Me!ID.Value & ""
End Sub
I have a main form and a continuous subform which is connected to main form using invoice id, customer name and invoice date. When I add a new invoice, I select customer in main form and enter data in subform because I allow edits in my subform.
Now if I change customer in main form, customer should also change in subform for the data which I already added. But my subform turns to blank, when I select previous customer it shows the entered data.
I want my subform customer update to newly selected customer in main form. I used some vba code but its not working. The below code I got from a tutorial.
Private Sub Customer_Name_AfterUpdate()
With Me.[Sales_Invoice_Detail(its my subform].Form.RecordsetClone
Do Until .EOF
.Edit
!Customer_Name = Me.Customer_Name (This is the Field which i want to update in my subform)
!Invoice_Id = Me.Invoice_Id( it has one to many relationship between forms)
.Update
.MoveNext
Loop
'MsgBox "You Change Customer To " & Customer_Name & "!"
End With
Me.Refresh
End Sub
a continuous subform which is connected to main form using invoice id,
customer name and invoice date
Remove customer name and invoice date from the connection (MasterLinkFields/ChildLinkFields). These can be pulled either directly from the parent form or - using a query - from the source of the subform.
My question concerns situations where custom code is required to auto-increment fields in MS Access, specifically with issues that arise from using such code in the OnActivate event.
I have a field [Group_ID] that auto-increments each time a new record is made using custom code in the OnCurrent and OnActivate events. Sometimes I need Group_ID to be incremented OnActivate, but sometimes I do not. In some cases users will actually use a "duplicate record" button to use the same Group_ID (along with most other fields) for a subsequent record. In situations like these, I'd like to set a condition for the OnActivate event that allows users to reference other forms or tables without re-querying Group_ID upon returning to the form to finish a record. Here is my code:
'increments Group_ID when a new record is made
Private Sub Form_Current()
If Me.NewRecord = True Then
Me.Group_ID = Nz(DMax("Group_ID", "All_sightings"), 1) + 1
End If
End Sub
'increments Group_ID when the form becomes active IF the value is no
longer max value + 1
Private Sub Form_Activate()
If Me.Group_ID = Nz(DMax("Group_ID", "All_sightings")) + 1 Then
Else
Me.Requery
End If
End Sub
What I would like to do is add an additional condition to the Form_Activate sub that checks whether a different field is already filled out (e.g. if the "duplicate" button was used) when the form re-activates after a user returns to a partially completed record. This field will not require any input from the user because it will be automatically filled when a user clicks the duplicate button. The field I have chosen is [UTM_x].
I have tried:
=IIF(Me.Group_ID = Nz(DMax("Group_ID", "All_sightings")) + 1 And Not IsNull(Me.UTM_x), "", Me.Requery)
And various other combinations of nested IIF() and IfThenElse statements, but have not had any luck. The form continues to requery every time on the OnActivate event when Group_ID is not more than (max+1). Any suggestions?
I played around with iif statements and more if-then-else statements, eventually finding a solution to my problem. Here it is:
Private Sub Form_Activate()
If Me.Group_ID = Nz(DMax("Group_ID", "All_sightings")) + 1 Then
'blank/do nothing because Group_ID is already max+1
ElseIf IsNull(UTM_x) Then
Me.Requery 'makes Group_ID max+1 because null UTM_x means it's a new record
Else
'blank/do nothing because Group_ID = max and this is a duplicated record
End If
End Sub
I have a simple MS Access database with shows details about complaints received. I have 4 tables which are as follows:
1st Table is called "tbl_Data" which shows generic info like Complaint Detail etc,
2nd Table is called "tbl_Tools" which lists all Tool numbers and descriptions,
3rd Table is called "tbl_Products" which lists all Product numbers and descriptions,
4th Table is called "tbl_Material" which lists all Material numbers and descriptions.
I want to have 2 Combo Boxes in the frm_Complaints which gets the PartNumber from the correct table depending on the data in the 1st Combo Box.
For example: The 1st Combo Box will list "Tool", "Product", and "Material" depending on what the complaint refers to, and if I select "Tool", the 2nd Combo Box will lookup "PartNo" in "tbl_Tools" only. I have tried Union Queries to merge all 3 tables, but then the data cannot be edited. Is there a simple way in VBA to make the 2nd Combo Box only lookup Part Numbers from the correct table, and then have a 3rd field which shows the corresponding description?
See screenshot link:
As my comment, you can set 2nd ComboBox.List trigger by ComboBox1_Change event.
Private Sub ComboBox1_Change()
Select Case ComboBox1.ListIndex
Case 0
ComboBox2.List = ArrayTool
Case 1
ComboBox2.List = ArrayProducts
Case 2
ComboBox2.List = ArrayMaterial
End Select
End Sub
Or something like this:
Private Sub ComboBox1_Change()
Select Case ComboBox1.Value
Case "Tool"
ComboBox2.List = ArrayTool
Case "Products"
ComboBox2.List = ArrayProducts
Case "Material"
ComboBox2.List = ArrayMaterial
End Select
End Sub
You can definitely change the table you select using the method outlined above
- not just pick different arrays -use select case in VBA, and put the SQL into VBA, exactly as you would write it in Access, but within speech marks. In the below, the case changes, on the basis of a change in value of a text box (Me.Poltxt)(not a combo box), and this code sits within a longer sub routine that is triggered by the update of a combo box not mentioned here - but the principle is just the same.
Elements 1 and Elements 2 are the 2 different tables.
Select Case Me.Poltxt.Value
Case "Pol1"
Me.Polcbo.RowSource = "SELECT [Elements 1].[ElemName] FROM [Elements
1] ORDER BY [Elements 1].[ElemName];"
Case "Pol2"
Me.Polcbo.RowSource = "SELECT [Elements 2].[ElemName] FROM [Elements 2] ORDER
BY [Elements 2].[ElemName];"
Case Else: Me.Polcbo.Value = "N/A"
End Select