I have a continuous form (MasterForm) for data entry based on one table. Some records need additional data, which I want to enter in a separate popup form (which has another table behind). This popup form (SlaveForm) opens by means of a click event in the MasterForm which triggers the DoCmd.OpenForm (vba instruction).
How can I “force” the popup form (SlaveForm) to be “in line” with the last current record of the MasterForm, by VBA code, exactly as I can do in a form/subform format (but here access has explicit tools to do that)?
Edit: See uploaded example
https://gofile.io/?c=VvMfiv (I am using an external link, since I was not able to find how I can do that in stackOverflow)
In the example, let us supose that we want to add Wagner's Parsifal Opera. After entering the name Parsifal you choose "Have Characters". It will open the SlaveForm (characters), where you want to write "Parsifal" and "Amfortas". However, I am not able to configure the synchronization between the MasterForm and the SlaveForm.
Any suggestion?
After some more digging, I manage to solve the problem. The BeforeInsert event in the slave form is the key. See uploaded file: https://gofile.io/?c=UxRdM8
In the MasterForm there is a text box (which can be set to be invisible) with the primary key (txtIDWork). After the Slave Form has been loaded, and before inserting a new register in the SlaveForm/Table, the BeforeInsert event (of the SlaveForm) assures that the primary key of the MasterForm (of the current register) is set to the foreign key of the SlaveForm:
Private Sub Form_BeforeInsert(Cancel As Integer)
Me.txtWorkNumber = Forms.frmMaster.txtIDWork
End Sub
where txtWorkNumber is the text box where the foreign key is written (which can be set to be invisible).
have you tried using a subform that is invisible until you need it, then making it visible when you want to enter data, then hide it again once you have filled it in?
Related
I have a form frmDetail that contains several locked fields I want populated only when another form has been filled out, in the name of having some kind of standardization in my data. This other form frmSignOut is used to enter in a date and location that will populate the fields on frmDetail. frmSignOut also contains a subform subULookup that looks up users from a different table using an identifier number. The resulting last name, first name and phone # should also be passed to frmDetail. I also hope to combine first and last name somehow into a Last,First format.
My approach so far has been to open frmSignOut modally with acDialog and I inserted Visible=False into the On_Click event on frmSignOut. Then I try to reference my subform fields and set them to the desired fields on frmDetail. I finish by refreshing and then closing the dialog form.
Private Sub CmdSignOut_Click()
DoCmd.OpenForm("frmSignOut"),,,,,acDialog
If CurrentProject.AllForms("frmSignOut").isLoaded=True Then
Set Forms!frmSignOut!SubULookup.PhoneNbrTxt=Me.ContactNbrTxt
DoCmd.Close (acForm), ("frmSignOut")
Me.Refresh
End If
End Sub
I have only been able to get this far, trying to pull the first field PhoneNbrTxt. I can get frmSignOut to open, I put in data and when I click my 'close' command button I get run-time error 438: Object doesn't support this property or method.
The line highlighted is where I try to reference my subform field. I also have a 'Cancel' button added to frmSignOut that just closes the form, I have no errors there.
Again I'm completely new to Access without much prior experience in anything related, I'd appreciate any knowledge you guys can throw at me.
EDIT: I've been able to successfully pull the value to Me.ContactNbrTxt by adjusting my code to the below.
Me.ContactNbrTxt = Forms!FrmSignOut!SubULookup.Form!PhoneNbrTxt
It looks like the missing part was the Form! right before the control name, along with formatting this correctly and dropping Set.
Im still trying to work out how to combine first and last name before also pulling those to frmDetail, if anyone can help there.
Please help me explain, why this happens, after that the solution should be easy :)
I have two forms, showing different data.
Form_1: there is a combo box (with names in it), where you can choose which company you wanna see, and an after-update macro searches the record (an [ID] field), and shows the information. (To be more complicated, this [ID] field is hidden, and used for subforms, where the actual infos appear.)
Form_2: this is a continuous form, each record is in connection with the companies shown in Form_1, but several record can belong to one company. There is a button for every record to open Form_1 with the information connected to it. The vba code of the button is:
Private Sub Button_Click()
DoCmd.OpenForm "Form_1", , , "[ID] = " & Me![ID]
End Sub
In the code, the same [ID] field is used, as described above: hidden and used for subforms.
Both forms are working as needed, I am happy with them.
But after Form_1 is opened from Form_2 with the button, the combo box remains empty (actually I don't need it to be filled), and if I wanna use it to search for other items, it doesn't work, as if the macro wasn't loaded. The list of names appear, I can click on any of them, but the [ID] field is not refreshed (and of course neither the subforms). I have to close the form, and open it again from the side-list.
Why does the macro stop working?
What should I change, to make it work?
Thanks for your help!
Form1 has the filter turned on to a specific key value, so attempts to find and reposition the form's current record will fail without explicitly resetting the filter.
The Where condition of the OpenForm command does not change the form's Record Source property, nor does it perform a simple search/reposition. Rather, it applies a form filter:
DoCmd.OpenForm "Form_1", , , "[ID] = " & Me![ID]
This state is indicated in several ways
On the Home ribbon (i.e. toolbar): The Toggle Filter button is active... is highlighted by a different color.
The form's navigation bar at the bottom of the form show "Filtered" highlighted with a little funnel icon.
The Access status bar shows "Filtered" on the right near other indicators.
Of course it's possible that all of those indicators are hidden, so you just need to be aware of what each command and parameter does.
Possible solutions:
Form1's ComboBox.AfterUpdate macro should turn off the filter before searching for a new ID value.
Form2's Button_Click event opens the form without applying a filter and instead runs code that does the same thing as the ComboBox.AfterUpdate method--searches and repositions the form's record rather than filtering it.
This can be achieved in multiple ways and is largely beyond the scope of this answer, but a hint is to make a Public method in the Form1 module that performs the search. Both the ComboBox.AfterUpdate method and the other button call that same public method so they have the same behavior.
I have a continuous form which displays a small amount of data from each record in my table ProjectT (i.e. project name, status) and a command button in the footer which I would like to open the selected record in its expanded single form (where all of the relevant info is displayed).
At first I set this button up using Access's wizard, but realized that Access opens a selected record by filtering the data on the form. The problem with this is that once the expanded form is opened, I want a user to be able to move to other records without having to select to unfilter the results. If I change the button on my continuous form to simply open the expanded single form, is there code I can run to make the form open to the selected record without putting a filter on?
Initially I thought to set the expanded form's (named ProjectF) default value to Forms!ProjectListF!ProjectID (where ProjectListF is the continuous form and ProjectID is the autonumber primary key for ProjectT), but this was not successful, I think because there is more than one ProjectID displayed on ProjectListF.
Another thing to consider is that I have another button on my Main Menu form which opens the ProjectF form in data entry mode to prevent the user inadvertently changing/deleting an existing record when they are trying to add a new one; I have no idea if this might be important when trying to find a solution to my issue.
I'm open to any suggestion--I have an okay handle on SQL, and have delved into a little VBA but am completely self taught. Any ideas? Thanks!
You can open the detailed form with this command:
DoCmd.OpenForm "ProjectF", , , "[ProjectID] = " & Me!ProjectID.Value & ""
I have a form with two subforms in it in the following format:
on Subform1, Element1 has Data1. Value of Data1 points to Data1 on Subform2 which has a value of Value1
Right now both subforms are showing all data in each table. What I want to do is filter Subform2 based on the row selected in Subform1.
In this example, Element3 is selected, so the pair Data3 Value3 shows in Subform2.
I've tried accomplishing this by altering the SQL on Subform2, but nothing I do seems to do the trick. I don't know if I'm looking in the right place, or if I should look somewhere else.
If there's anything else I should provide, please don't hesitate to point it out. I want to provide enough information to come to a solution.
You can do that by changing the recordsource of Subform2 on the OnCurrent event of subform1. The steps to do that are as follows:-
Open the form in design view
Go to the properties of subform1
Go to the event tab
Select eventprocedure from the oncurrent combo
double click on the button next to the event to go to the vba window
insert the following code
Private Sub Form_Current()
Me.Parent.Subform2.Form.RecordSource = "Select data,value From TableName Where data=" & Me.Data
End Sub
Open your query for subform2 in design view. Then set the criteria to =forms![mainform]![subform1].form![element].
then in VBA you need to requery subform2 when the selected record in subform 1 is changed. Go in to the on current event of subform1 and use the following:
private sub Form_Current()
forms![mainform]![subform2].requery
end sub
N.B. you may need to change the name of mainform, subform and the column name which I called element.
Results and explanation using methods in other answers
Okay, so I ended up coming to a solution for my specific problem, and hopefully by sharing here, it will help others in the future.
The other solutions to this question assume that your form hierarchy is as follows:
MainForm->Subform1->Subform2
As in, the second subform is in and owned by the first form. This will work for most applications, but not when both Subform1 and Subform2 are Datasheets.
The hierarchy in my case, and the hierarchy for the people I hope to help in the future is as follows:
MainForm->Subform1
MainForm->Subform2
As in, the second Subform is NOT owned by the first Subform.
With this hierarchy, the code in the other solutions doesn't work, unfortunately. However, there is a simple workaround:
Use hidden textbox control as a "link" between Subform1 and Subform2
(The following method uses the example names found in my original question)
From design view, create a Text Box in the MainForm, not in the Subform1 or Subform2.
On the Property Sheet for the newly created Text Box control, under the Data tab under Property "Control Source", put the following code:
=[Subform1].[Form]![Element1]
Obviously, replace Subform1 with your first subform, and typically Element1 will be Primary Key for that table.
Next, on the Property Sheet for the Text Box control, under the Format tab change Property "Visible" to No.
Next, we're going to change the "Link Master Fields" and "Link Child Fields" properties on Subform2, which can be found on the Data tab of the Property Sheet:
For the "Link Master Fields" property, put in the Name of the Text Box control you made. An example of a default name will be Text5. I renamed my Text Box to CurrentElementKey, but name it whatever you want. So in my "Link Master Fields" property, I put CurrentElementKey.
For the "Link Child Fields" property, since we put the Primary Key for Subform1 in the Text Box, we need to put the Foreign Key it relates to in Subform2. I can't tell you exactly what this will look like, because it will vary for your scenario. For example, you might have had Element1 be Element1PK on the first Subform, and it's Foreign Key on Subform2 as Element1FK. So you'd put Element1FK in "Link Child Fields".
If you have any questions, or require further explanation, please comment on this answer, and I'll do my best to help.
I have a database that was create in Access 2010. We recently updated our systems to Access 2013. In Access 2010 I have no errors accessing a form object with
Form_frmName.txtFieldName.Value
However, when using Access 2013 I get a runtime 2424 error stating that "The expression you entered has a field, control, or property name that Microsoft Access can't find. I am accessing from a module.
The module sets these fields visible using
With Form_frmName
.txtFieldName.Visible = True
End With
before attempting to access them.
Has there been any changes in the way form objects are accessed between 2010 and 2013? Is this an issue others have faced?
In Response to #WayneGDunn's questions below
QUOTE:
I need to know exactly what and how you are using this.
1. You have a bound textbox named 'txtFieldName' on a form. As #brad asked, is there a subform, and if so, is this field on the subform?
2. You said the code is in a module, but is the code in the form where the field is defined?
3. Please explain where/what form 'frmQAtab' is (you said your form name was 'frmName', so what is the other, how related?)
4. Is the code in an event? Can you share the entire subroutine?
5. Have you tried creating a dummy query and using the builder to reference the field?
RESPONSE:
1. I have a form (frmMain) with multiple tabbed pages. frmName is one of those tabs, containing the bound field txtFieldName.
2. The module is run from the form the field is in.
3. My apologies frmQAtab is frmName, I just neglected to make that generic in my copy-paste.
4. The event is a button click. The button click runs a sub from a module. That sub makes visible the fields, runs a query based on user input (two date fields), populates the bound fields with the returned record set, then attempts to access them for processing (another query is run to process a complete other set of fields). To post the entire subroutine would be a bit more than I would ask you to chew on. This is legacy code I'm trying to fix, and it's rather large.
5. I have not tried a dummy query. Access is not my field (I'm mainly a C#, scripting, guy.) Is there some suggestions in this area you could give?
One of the following references to your fields should work. I created a form (named 'frmMain'), then created a Tab Control with two tabs. On the first tab, I inserted another form (named 'frm3197'). I also created a text box on the tab control named 'txtFieldName' AND in form 'frm3197'. From a button click on 'frmMain', the following will reference each of those fields.
Private Sub cmdButton1_Click()
Forms![frmMain]![txtFieldName] = Now()
Forms![frmMain]![frm3197].Form![txtFieldName] = Now()
End Sub