I have a single form which can be accessed from multiple places in my Access 2013 app - depending on where the form is opened from, the recordsource should be different - for example if opening the form to search for a record, the form recordsource is a parameter query where the user enters the record id as the parameter - but if opening the form from elsewhere the recordsource is a select query and the record id is passed using VBA.
I want to avoid having twin forms if possible - I just want a single form and be able to set the recordsource when the form opens... is it possible to set the form recordsource upon opening the form (rather than after the form is opened)?
Have a bit of VBA that rewrites the query that your form reads from. Try this:
Set db = CurrentDb()
DoCmd.DeleteObject acQuery, "myFormQuery"
Set q = db.CreateQueryDef("myFormQuery")
q.Sql = "SELECT * FROM mytable WHERE 1=1;"
DoCmd.OpenForm "myForm", acNormal
Related
I'm using a sub-form to assign multiple tasks at the same time. This sub-form is placed on a form that has common details applicable to all the tasks there. For instance: Customer, Product Code, Part Code etc., Both the form and the sub-form feed the data to the same table. These forms are linked with one of the keys - Line Item, which is present on both the form and the sub-form. The other two keys are Task Title - placed on the sub-form, and Stage ID placed on the main form. Line Item is configured in a way that it populates the value from another open form for both the main form and the sub-form.
But Access isn't allowing me to add any details whatsoever to the sub-form. It gives me the error "You must enter a value for 'TableName.LineItem' field.
Kindly advise.
Two Approaches:
Select Table A and hit create form on the ribbon. Then do the usual prettification like deleting id columns, setting the forms format to continuous forms, and replacing textboxes with combo- boxes where appropriate.
First Approach is put unbound controls and a button in the header. Then insert the values from the controls in the button click event
Private Sub cmbAddRecord_Click()
Dim db As Database
Set db = CurrentDb
Dim rs As DAO.Recordset
Set rs = db.OpenRecordset("TableA")
rs.AddNew
rs!A = Me.txtA
rs!B = Me.txtB
rs!C = Me.txtC
rs.Update
Me.Requery 'show changes
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Sub
You can also insert values while actively entering the data for instance
Private Sub A_AfterUpdate() 'A is the TextBox in the detail section that is bound to A in TableA and so forth
Me.B = B.Parent!txtB
Me.C = C.Parent!txtC 'Tip use Me.MyControlName.SetFocus to select a control
Me.Refresh 'show changes
'tip you can also put this code in hotkeys https://learn.microsoft.com/en-us/office/vba/api/access.form.keydown
End Sub
'
Is there some sort of work-around that could make this possible? Or could anyone offer just some general advice on my situation below? I tried to set the record source through VBA but had no luck.
My situation:
I have a main form with a subform contained within, and I want the subform to be purely for data entry (Data Entry = Yes). Upon clicking a button, the user is sent from the main form to a report (print preview only). I want the source for this report to be the subform the users are entering data into, but I don't have this option from the report's property sheet itself (no forms), and I also was unable to set it through VBA. Here's my code, it's one line so I highly doubt it's the problem.
Private Sub Report_Load()
Reports![P18003 SDR Report].RecordSource = "P18003 SDR Subform"
End Sub
Previously, to work-around this I had a parameter query that waited for the user to enter data into an unbound textbox from the main form, and an after update trigger on that textbox would load any data relevant to that parameter (my employer and I miscommunicated the requirements).
It turns out though that I don't need to load any older data, and I run into problems with my current parameter query in the event that the user does input a parameter which loads old data - that old data is transferred to the report in addition to the new data they've just entered. This is the main problem with the method I am currently using, and it trashes almost all functionality with this form and report. The events that a user would need to enter a parameter which queries older data are few and far between, but it's not a functional product unless I can get the subform to be connected to the report directly. There's likely something obvious I'm missing here (or at least, I hope there is).
Thanks in advance for taking the time to read this and for any help you may offer.
you can either send the recordsource to the report itself in the OpenArgs by the open report event, after the click event in the subform
Private Sub btnSubform_Click()
Dim strSQL as String
strSQL = "SELECT * FROM SubformQuery WHERE ID = " & CurrentSubfromRecordID
Docmd.OpenReport, acViewReport, , , , strSQL
End Sub
and then in the Report.
Private Sub Report_Open(Cancel As Integer)
Me.recordsource = Me.OpenArgs
End Sub
Or you can make a paramter Query and set this Query criteria as record source for the report. So the parameter in the query is pointing to the current selected row in the subform. Like this:
--- At the Criteria in the Query designer:
--- RecordSource for the Report:
Forms![FormMain]![YourSubform]![ID]
Now every time the reports obens he gets the ID from the current selected record of your subform.
Hope you're enjoying your Friday afternoon!
I've got a form on MS Access which searches a linked table for a barcode (which is entered by the user)
If the barcode exists in the table I'd like to show the user the record which contains the matched barcode, if not the code moves on elsewhere.
Here is what I have so far:
DoCmd.DeleteObject acQuery, "Query2"
Set qdef = CurrentDb.CreateQueryDef("Query2", s)
Me.sbfMatchedRec.SourceObject = "Query2"
I get an error when trying to change the SourceObject to Query2.
If I open Query2 it has the exact information I need in it. I can also go via the form properties and change the SourceObject to Query2 which then displays what I need, but I just need to know how to change this in VBA as above.
Thanks!
You could requery the subform with the barcode passed in from the form's textbox as the WHERE criteria in the subform's .RecordSource property.
For example, say this table (tblProducts) has your list of barcoded records:
You could then add a subform to your form that will show records from tblProducts. Also add a textbox to the form for the user to supply a barcode and a command button for the user to initiate a search:
Before hooking-up the search button with the VBA, take a look at the .RecordSource property for the subform...
...switch the query builder to SQL View:
Copy the sql as you can use this as the basis to filter the records in the subform using VBA.
Go back to the form in design view and go in to the search button's On Click event:
The SQL you've copied can then be used to create an SQL string that takes the value entered in the form's barcode textbox (I've called the text box on the form txtBarcode) as part of the WHERE clause. This sql string can then be applied to the subform's .RecordSource property and then the subform can be requeried to show the result set of the new SQL definition in the subform:
Private Sub cmdSearch_Click()
Dim strSql As String
strSql = "SELECT tblProducts.Barcode, tblProducts.ProductName" _
& " FROM tblProducts"
If _
Me.txtBarcode > "" _
Then
strSql = strSql & " WHERE tblProducts.Barcode=" & Me.txtBarcode
End If
Me.tblProducts_sub.Form.RecordSource = strSql
Me.tblProducts_sub.Form.Requery
End Sub
So if we put 1001 in the text box on the form, and click the search button, the subfom only shows that matching record:
I have a tabbed navigation. I have a bound form a user double clicks on a single user out of a long list. I want to go to an unbound form, and pre-load the form with details about that user (edit the user). I'm specifically using an unbound form because I want to show a save/cancel button. I can't find any way to pass the id of the user into the load_form call. Am I missing something? Must I use some sort of global (this seems bad to me)?
You can use OpenArgs when opening the form:-
DoCmd.OpenForm "MyForm", acNormal,,,,,Args
And whatever Args is can be referenced in "MyForm" as Me.OpenArgs
e.g. if you pass a numeric PK then you could use something like:
dim db as dao.database
set db = currentdb
dim rs as dao.recordset
set rs = db.openrecordset ("select * from MyTable where PK=" & me.openargs", dbopendynaset, dbfailonerror)
if rs.eof then
'didn't find record with PK...
else
'then populate the unbound controls on your form with the fields from the recordset
...
Note that you don't need to have an unbound form just to offer a save/cancel. if you write an event handler for the form's Before Update event, you can cancel changes or commit them as you please.
So I recently have been trying to incorporate more sub forms to make the UI more friendly. So I have a pre developed form that runs some VB, so for examples sake lets just say that it runs SQL statement, returns the recordset, and fills text boxes with the data (because this is sort of an interactive dashboard concept:
dim db as database
dim rs as recordset
dim sql as string
set db = current db
sql = "SELECT * FROM tblMain;"
set rs = db.OpenRecordSet(sql)
rs.movefirst
[forms]![DashboardSubName].txtValue1 = rs!Value1
rs.close
set rs = nothing
set db = nothing
with error handling that returns a error "DashboardSubName" not found. So orginally this form was its own form, and opening it by itself it works fine, but once I use it within the parent form i get this error.
im sure it is simply something i am not aware of, but what gives?
thanks guys
justin
When a Form is loaded as a sub-form, it is referenced as if it were just another control on the Main Form - it is no longer part of the global Forms collection.
So the correct reference should be:
Me!DashboardSubName.Form.txtValue1
where DashboardSubName is the name of your sub-form control.
Assuming the code you showed us is part of the subform, rather than the parent form, replace
[forms]![DashboardSubName].txtValue1 = rs!Value1
with
Me.txtValue1 = rs!Value1
The reason for the syntax here is that the subform control is distinct from the subform embedded inside it. The subform control has properties of its own (limited in comparison to the subform itself), and to get to the properties/methods of the subform embedded in it you have to specify that you want the form that the subform embeds.
Me!MySubformControl
...is the subform control.
Me!MySubformControl.Form
...is the form embedded in the subform control.
Last of all, I really wonder why you're walking a recordset to update data in a subform. This is not normal practice, though it's tangential to your actual question.