Using RecordSource to change form contents - forms

I am trying to create a method that displays a selected table in a DS view form. The form will be used repeatedly to view different tables, so I figured the easiest way would be to create a form and dynamically change the RecordSource based on the user selection.
I created a form called "frmDisplay" to be used to display the contents of a table to the users. I am trying to use this code to update the form.
Private Sub btnViewEntries_Click()
Dim frmDisplay As Form
Dim selection As String
Me.cmboSelection.SetFocus
selection = "tbl" & Me.cmboSelection.Text
Set frmDisplay.RecordSource = selection
DoCmd.OpenForm "frmDisplay", acFormDS
End Sub
Currently, the code is throwing an "Improper use of property" error when I try to set the RecordSource to the selection made in the combo box.
Set frmDisplay.RecordSource = selection
I have looked around for a while now, but I cannot seem to find any definitive answer that applies to this example. Most posts that I found were missing the Set keyword...
Does anyone recognize the problem? More importantly, is this even the best way to make this
work?
Thanks
_____ EDIT _____
I figured it out, see code below.
Dim selection As String
Me.cmboSelection.SetFocus
selection = "SELECT * from tbl" & Me.cmboSelection.Text
DoCmd.OpenForm "frmDisplay", acDesign
Forms!frmDisplay.Form.RecordSource = selection
DoCmd.Close acForm, "frmDisplay", acSaveYes
DoCmd.OpenForm "frmDisplay", acFormDS

I note you've already provided your answer, but you may find the following helpful.
If you have a main form with the controls cmboSelection and btnViewEntries then add a subform control and call it fsbDisplay. Don't put anything in this subform, leave it unbound.
Now try the following one-liner:
Private Sub btnViewEntries_Click()
fsbDisplay.SourceObject = "Table.tbl" & cmboSelection.Value
End Sub
The advantage of this method is that you can use it to call up any table or query (prefix with Query. instead of Table.) and the fields shown are dynamically created.

Related

Open Form to a value selected on ComboBox - Ms Acces

I want to open a form to a specific record based on the value is selected on a comboBox. I have written a code and its working, but before opening the form it shows a dialogue box with input field asking for the parameter i want for the form which i dont want the VB code to ask.
DoCmd.OpenForm "Final_Exam", acNormal, , "[admclass] = " & Me.Combo4.Value & ""
This is the code i have written and the requirement is that on clicking the button the form opens without any dialogue box asking for parameter. thanksa
What I've found is the best way to open one form from another is to use OpenArgs. When opening Form 2 from Form 1's button, use code like this:
Private Sub cmdOpenOtherForm_Click()
DoCmd.OpenForm FormName:="frmOtherForm", OpenArgs:=Me.Combo4.Value
End Sub
Then, in the Load event of Form 2, use the openargs to set up your filter:
Private Sub Form_Load()
If Not IsNull(Me.OpenArgs) Then
Me.Filter="[admclass]=""" & Me.OpenArgs & """"
Me.FilterOn = True
End If
End Sub
If the field you're filtering on is a text field, make sure to properly escape double quotes (as is done above).

How to navigate from a form to a subform in a different form?

I'm working on a Access-Database that is split into multiple parts. Each has a Main-Form with Subforms in nested Tabs.
Walkthrough
We have a starting-Area that is separated into different Themes. Those theme-forms have buttons that represent Subthemes.
When I hit Button A i want to navigate from Mainform 1 to Mainform 2 Subtheme A (easy as it is the default).
When I hit Button B I want to navigate from Mainform 1 to Mainform 2 Subtheme B. (I can't get this to work)
What i know
I can easily get from Mainform 1 to Mainform 2 landing per default on Theme 1
Private Sub buttonB_Click()
DoCmd.openForm "Mainform2", _
End Sub
I don't know how to navigate to Mainform2->Sub Theme B. I can open the right subform using the OpenArgs but i cant do it with the Tabs. I tried to use the DoCmd.browseTo in onLoad() of mainform2 but that breaks the process.
If i am not mistaken there should be a way to use DoCmd.browseTo in the buttonB_click() but i cant get the path right.
DoCmd.OpenForm Method (Access)
DoCmd.BrowseTo Method (Access)
I tried to describe the problem as general as possible so answers can be helpful for others as well. I hope you can help me!
So I managed to resolve it:
First we navigate to the Main-Form of Theme2 and tell it which topic we want with the help of OpenArgs:
Private Sub buttonThemeB_Click()
DoCmd.openForm "Mainform2", _
OpenArgs:="Theme B"
End Sub
In the FormLoad() of Mainform2 we check the OpenArgs and navigate the Subform-Controle:
Private Sub Form_Load()
Dim strSubFormToken As String
' If OpenArgs property contains a subform name, open corresponding subform
If Me.OpenArgs <> 0 Then strSubFormToken = Me.OpenArgs
Select Case strSubFormToken
Case "Theme A"
strSubForm = "form_themeA"
Case "Theme B"
strSubForm = "form_themeB"
End Select
strSubForm =
If Len(strSubForm) > 0 Then
DoCmd.BrowseTo acBrowseToForm, strSubForm, "frmTheme2.Navigationsunterformular" 'Your Navigationtarget
End If
End Sub
The Mainproblem in all this is that if you use the DoCmd.BrowseTo Path to Subform Control you have to know some rules that aren't documented:
the “>” character seems unusual, that’s because it has been introduced specifically for the Path parameter of BrowseTo. Its meaning is this: The form to the right of the “>” character is loaded into the subform control specified to its left.
The path must specify a series of Form.SubFormControl pairs. Each subform control specified must be a control in the form that precedes it in the path.
The pairs must be separated by the “>” character.
and most important:
The first form in the path must be the form that is currently loaded directly in the Access window (or browser window if the application is running on the web.) This means that the Path parameter only allows you to change the contents of a currently-visible subform control.
So we have to first open the new main-form before navigating the navigation-subcontrol.
Seems to be the best way to handle this.
Thanks for the suggestions!

Open Subform in Access in New Window

I have a form in access ("F_Filter") where I indicate parameters to filter a datable. Form F_Filter also contains a subform which shows the filtered datatable results on the same screen. This subform with the filtered results is named "Child400." Its Source Object is "F_FilterResults".
I would like to be able to 1) open the subform in a new window so all I see are the filtered results and 2) export the results to Excel.
Normally I would be able to open a form in a new window by creating a button and creating an on click event with the following code
DoCmd.OpenForm "NameOfForm", acFormDS
However, this code does not work when I put in "Child400" as the NameOfForm. I think this is because Child400 is a subform and is not recognized by Access.
I also tried DoCmd.OpenForm "[F_Filter]![Child400]", acFormDS to no avail. Note that I have also tried DoCmd.OpenForm "F_FilterResults", acFormDS which works fine but this table only contains the prefiltered results.
DoCmd.OpenForm "F_FilterResults"
is the correct form to open. "Child400" is (I assume) the name of the subform control. That is not a form that you can open.
Then you need to apply the same filter as you did to the subform instance. The same method you use now for the subform can be used for the separate form.
If you have trouble with that, please add the existing filter code to your question.
Edit
There is no magic behind what records a form shows. It is controlled by a couple of properties. The easiest way is probably to simply take them over to the new form.
Something like:
Sub OpenResults()
Dim fSub As Form, fNew As Form
Set fSub = Me!Child400.Form
DoCmd.OpenForm "F_FilterResults", acFormDS
Set fNew = Forms!F_FilterResults
fNew.RecordSource = fSub.RecordSource ' if you change the RecordSource in your code
fNew.Filter = fSub.Filter
fNew.FilterOn = fSub.FilterOn
fNew.OrderBy = fSub.OrderBy
fNew.OrderByOn = fSub.OrderByOn
End Sub

LibreOffice Basic get Elements from form

I'm trying to get value from textfield on the form.
sub Test(oEv)
oForm = oEv.Source.Model.Parent
textBox = oForm.getByName("Description")
MsgBox textBox.Text
end sub
There is an Exception: "Type: com.sun.star.container.NoSuchElementException" on the line "textBox = oForm.getByName". I have a text field with the name "Description" on the same form, where is the button I press to run this macro. What is wrong here?
Check that the name is the same case, not description.
Also, use the Form Navigator to determine whether the control is under the form in the hierarchy.
Have you tried using an introspection tool such as MRI or XrayTool to view the properties of oForm? With the tool, expand the form to see if it contains the Description control.
Often in Base, it is better to deal with the form as a recordset rather than reading the controls. Here is some sample code:
Sub ButtonClickHandler(oEvent as Object)
'com.sun.star.comp.forms.ODatabaseForm
oForm = oEvent.Source.Model.Parent
lDescriptionCol = oForm.findColumn("DESCRIPTION") ' from underlying query or table
Print(oForm.getString(lDescriptionCol))
BasicLibraries.LoadLibrary("XrayTool")
xray(oForm)
End Sub
For more ideas, see https://forum.openoffice.org/en/forum/viewtopic.php?f=39&t=38725.

How do you edit records from a VBA form that you want to interactively select?

I have a set of ComboBox's in an MS Access 2003 DB that are all bound to fields in a single table. However, the data that they allow you to select doesn't come from that table and instead comes from various other tables. This works fine for the record creation story but now I want to be able to edit the record retroactively. The problem is that I can't figure out how to refill the form elements without writing a bunch of custom code.
My initial inclination is to provide a combo box that limits your choices to record IDs and then do a custom query and use that to set the selected values in all of different form elements. However, I feel like I should be able to do something as simple as DoCmd.GoToRecord , , , ID and the form should repopulate just fine. I'm not opposed to doing the busy work but I'm sure I'm just missing something in my relatively puny knowledge of VBA and Access.
Just to add to the mix, I would offer two approaches, one recommended, the other not.
Approach 1: If you've bound your form to the whole data table (this is the non-recommended approach), you can use the combo box wizard to navigate to the requested record, but I wouldn't recommend it in recent versions of Access:
a. it doesn't allow you to properly name the combo box before it creates code.
b. the code is just WRONG.
Here's the code I just produced in my test database:
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[InventoryID] = " & Str(Nz(Me![Combo2], 0))
If Not rs.EOF Then Me.Bookmark = rs.Bookmark
This is wrong in so many ways it's just remarkable. This is what the code should be:
With Me.RecordsetClone
.FindFirst "[ID]=" & Me!cmbMyComboBox
If Not .NoMatch Then
If Me.Dirty Then Me.Dirty = False
Me.Bookmark = .Bookmark
Else
MsgBox "Not Found!"
End If
End With
There is no need to clone the form's recordset when the RecordsetClone already exists.
There is no reason to use an object variable when you can just directly use the pre-existing object.
There needs to be a check for a dirty record before departing the record because if you don't force the save, errors in the save process can lead to lost data.
But the better approach is this:
Approach 2: Use the combo box to change the form's underlying recordsource.
The AfterUpdate event of your combo box would look something like this:
If Not IsNull(Me!cmbMyComboBox) Then
Me.Recordsource = Me.Recordsource & " WHERE [ID]=" & Me!cmbMyComboBox
End If
Now, this only works the first time, as on the second resetting of the Recordsource, you end up with two WHERE clauses, which is not good. There are two approaches:
a. assuming that the form opens without a WHERE clause, store the opening recordsource value in a module-level variable in the form's OnLoad event:
Private Sub Form_Load()
strRecordsource = Left(Me.Recordsource,Len(Me.Recordsource)-1)
End Sub
And at the module level, define strRecordsource accordingly:
Dim strRecordsource As String
Then in the combo box's AfterUpdate event, you have this instead:
Me.Recordsource = strRecordsource & " WHERE [ID]=" & Me!cmbMyComboBox
Now, if your form opens with a WHERE clause already defined, it gets more complicated, but I'll not go into that and leave it as an exercise to the reader what the best approach might be.
I presume that you've already set up the row sources for each combo box. So long as you haven't limited the combo box to that list; it should display what you have stored in that column.
However, if your Combo Box changes its list for each row you can do something like this in the record's OnCurrent event or the field's GotFocus event:
Me.combo_box_name.Requery
After re-reading your question, I think I see what you are trying to achieve. You're on the right track with GotoRecord, although I would probably use OpenForm in this case, because it has a WhereCondition property that allows you to use SQL to specify exactly what record to open. It sounds like you want to implement a "jump to record" type functionality in your form, where the user selects a record ID from a list and the form changes to display the selected record.
One possibility is to switch to the new record each time the user selects an item in the ComboBox. You can handle this in the ComboBox's Click event.
I'll use a simple example: suppose you have a Students table, and a StudentForm for viewing/editing records in the Students table. The StudentForm has a ComboBox cboStudentID that is bound to the Students.ID column via it's RowSource property. When you select a student ID in the ComboBox, the StudentsForm will switch to display the corresponding student record.
In the Click event handler for the ComboBox, you can code this "jump to record" functionality with something like the following:
Private Sub cboStudentID_Click()
Dim recordID As Long
'The ItemData property will return the value of the bound'
'column at the specified index.'
recordID = cboStudentID.ItemData(cboStudentID.ListIndex)
'Jump to the record. This assumes we want to use the same form.'
'You can change the form name if you want to open a different form when'
'the user selects an ID from the ComboBox.'
DoCmd.OpenForm "StudentForm", WhereCondition:="Student.ID=" & recordID
End Sub
As David W. Fenton points out in the comments, you can shorten the following line:
recordID = cboStudentID.ItemData(cboStudentID.ListIndex)
to this:
recordID = Me!cboStudentID
or just:
recordID = cboStudentID
since the default value of the ComboBox in this case will be the value of the bound column at the current ListIndex. In this case, you could just remove recordID altogether and code the Click event as follows:
Private Sub cboStudentID_Click()
DoCmd.OpenForm "StudentForm", WhereCondition:="Student.ID=" & cboStudentID
End Sub