In an ms access 2010 database, I have a listbox whose afterupdate procedure needs (among other things) to navigate to a specific tab in a navigation subform. I can get it to change the SourceObject property of the navigation subform, but the selected tab does not get changed, so the user ends up seeing the right source object with the wrong tab selected. This looks unprofessional. How can I change both the selected tab and the source object?
I uploaded a simplified database that recreates the problem to this file sharing site.
The list box that needs its afterupdate method changed is called lstbxClients. Here is my current draft of its afterupdate method, which is currently throwing an error:
Private Sub lstbxClients_AfterUpdate()
Dim rst
Set rst = Me.RecordsetClone
rst.FindFirst "ClientNumber = " & lstbxClients.Column(0)
Me.Bookmark = rst.Bookmark
'Forms!Main!NavigationSubform.Form!NavigationSubform.SourceObject = "qryListCommunicationForms"
DoCmd.BrowseTo acBrowseToForm, "qryListCommunicationForms", "Forms!Main!NavigationSubform.Form!NavigationSubform"
Form.NavigationSubform " "
'Forms!Main!NavigationSubform.Form!NavigationSubform.SelectedTab = "CommFormsNavBtn"
Set rst = Nothing
End Sub
How do I change the code above so that it changes both the selected tab AND the source object of the navigation subform when the user clicks on a different record in the listbox?
Access gave a relatively decent explanation of what the proper syntax of the path is.
So your BrowseTo command should look like this:
DoCmd.BrowseTo acBrowseToForm, "qryListCommunicationForms", "Main.NavigationSubform>FindClientsNavigation.NavigationSubform"
Use the syntax below
DoCmd.BrowseTo acBrowseToForm, "qryListCommunicationForms", "Main.NavigationSubform>findClientsNavigation.NavigationSubform", "ClientNumber = " & lstbxClients.Column(0)
and
DoCmd.BrowseTo acBrowseToForm, "ListAddresses", "Main.NavigationSubform>findClientsNavigation.NavigationSubform", "ClientNumber = " & lstbxClients.Column(0)
The only change is the second parameter syntax , use
"Main.NavigationSubform>findClientsNavigation.NavigationSubform"
Hope this helps
The easiest way to do it :
Form_NavFormName.NavigationSubform.SourceObject = "FormName"
Related
I have a Project to be done in MS Access 2016, and stubled across an Issue, that should be easy to resolve, however, I have no clue on how to do it.
The Database I am developing is based on a huge, unfiltered datasheet exported by another database. I have a main form headview in which I placed two subforms listview an detailview. The listviewis sorted by a combobox.
Now to what "should" happen: If you click on an entry of said listview, the detailview shows additional information of the clicked entry.
Both subforms are based on the same datasheet. So I went ahead and tried to match them via primary key entries. However, that didnt work. The detailview subform is still empty. I also tried to write a vba macro for the listview with listview.click() that didnt work either.
Is there a way to connect those two subforms within a main form? If so, how do I do that?
I am greatfull for any response,
Have a nice day
-Ninsa
Ok, finally I got the reason for error 2455, it's a timing problem.
When the procedure Form_Current of the listview form is called the first time, the detail subform is not yet bound to the detail subform control, which causes the error.
Possible solutions
Option1: Ignore error 2455
Either add On Error Resume Next in the top of the Form_Current procedure or rewrite it to handle that specific error 2455:
Private Sub Form_Current()
On Error GoTo Catch
With Me.Parent.DetailSubformControl.Form
.Filter = "[ID] = '" & Me.ID.Value & "'"
.FilterOn = True
End With
Finally:
Exit Sub
Catch:
If Err.Number = 2455 Then Resume Finally
MsgBox Err.Number & "(" & Err.Description & ") occured.", vbExclamation, "Attention"
Resume Finally
End Sub
Option2: Control the source objects of the subform controls
Clear the Source Object property of the subform controls in the head form and set them explicit when loading the head form.
That prevents the unlucky timing at all.
So in the head forms load event procedure add this:
Private Sub Form_Load()
Me.DetailSubformControl.SourceObject = "Table1Detail"
Me.DatasheetSubformControl.SourceObject = "Table1Datasheet"
End Sub
Option3: Use Link Master/Child Fields
You could use the properties Link Master Fields and Link Child Fields of the detail subform control.
Therefor you have to create a textbox control named ID on the head form and for cosmetic aspects hide it by setting its property Visible to False.
This new control will be bound to the detail subform control:
Set the property Link Master Fields and Link Child Fields of the detail subform control on the head form both to ID.
The Form_Current procedure of the listview form then only contains this:
Private Sub Form_Current()
' Set the value of the hidden control 'ID' on the head form,
' which is bound to the detail subform control, to the selected ID.
Me.Parent.ID.Value = Me.ID.Value
End Sub
You should handle filtering of the detailview on the Listview_Current event. That event fires as soon as Listview changes records.
You can either set up an event handler for the Listview_Current event on the listview's form module, or use WithEvents in the parent form to listen to that specific event.
If you choose the latter, note that it's required that Listview has a form module, else the events won't fire.
Given that your ID field of the datasource is ID and the detail subform control is named DetailSubformControl, this example works.
Place this code to the Form_Current event of the listview subform (which is fired on every record you move to):
Private Sub Form_Current()
' Set a reference to the detail subform control
With Me.Parent.DetailSubformControl
' Set the filter of its contained form to the current ID of the listview.
' The "'" are only necessary if it is a text and not a numeric field.
.Form.Filter = "[ID] = '" & Me.ID.Value & "'"
.Form.FilterOn = True
End With
End Sub
I got query to make some modification that enable user to open multiple instances of the form when they do search data. I got manage to create a new module following Allen Browne guide and now I can open multiple instances of the spreadsheet which is good step forward but I cannot find solution how I can open that specific form.
In module I have got following code:
Public clnClient As New Collection 'Instances of frmClient.
Function OpenAClient()
'Purpose: Open an independent instance of form frmClient.
Dim frm As Form
'Open a new instance, show it, and set a caption.
Set frm = New Form_SurgeriesForm
frm.Visible = True
frm.Caption = frm.Hwnd & ", opened " & Now()
'Append it to our collection.
clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)
Set frm = Nothing
End Function
And under my button I replaced bit:
DoCmd.OpenForm "SurgeriesForm", acNormal
Forms!SurgeriesForm.Requery
.. and usef following code:
ModuleInstances.OpenAClient
I recon I need to add / change somehow the code below to be able to open multiple instances but do not have idea how to do it.
DoCmd.OpenForm "SurgeriesForm", acNormal
Forms!SurgeriesForm.Requery
I appreciate for any help with this as i got stuck and do not know how I can achieve this.
I think this is what you want?...
With the button on your SurgeriesForm add this code to the On Click event to open a new instance of the form:
Private Sub Command8_Click()
OpenAClient
End Sub
This will create a new instance of the form each time you click the button.
Next, add a blank combo-box to the form and change it's Row Source Type to Value List.
Add this code to the form:
Private Sub Combo9_GotFocus()
Dim frm As Variant
Combo9.RowSource = ""
For Each frm In clnClient
Combo9.AddItem frm.Caption
Next frm
End Sub
Now, when you click the drop-down it will list each form that you have created an instance of.
Finally, add this code to the form:
Private Sub Combo9_AfterUpdate()
clnClient(Combo9.Value).SetFocus
End Sub
Now, selecting a form name from the combo-box will move the focus to that form.
NB: You'll need to update the name of the controls to match yours.
NB2: Remember to open the first form using OpenAClient or it won't get listed in the combobox (as it's not in the collection).
I have a form in MS Access with a Tab Control (called TabCtrl). This control has several pages, each with a subform.
On Form_Open, I want to query the subforms for the total number of records and put that number in the tab's name. For example, the tab named MyTab should become MyTab (2):
Private Sub SetTabName_MyTab()
Dim i As Integer
i = CurrentDb.OpenRecordset("Select count(*) from [MyQry];").Fields(0).Value
TabCtrl.Pages("MyTab").Name = "MyTab (" & i & ")"
End Sub
However, when I run this, the last line returns Run-time error 2136 "To set this property, open the form or report in Design view". Does this mean I can't do this in code? Should I use another Event?
You are trying to change the internal name of the control, rather than caption on the tab page control.
Try:
ATabcontrol.Pages("MyTab").Caption = "MyTab(" & i & ")"
Note: I have done this before and found issues with the text not changing till the tabcontrol was manipulated.
Try:
Dim s as string
'To Get current Tab Caption
s = Me.TabCtl.Pages(Me.TabCtl.Value).Caption
'To Set current Tab Caption
s = "TabName"
Me.TabCtl.Pages(Me.TabCtl.Value).Caption = s
StackOverflow. I have an issue I've been grappling with for too long. Currently, I have a form that displays consortium data, with a button that says "Create new consortium." When I click it, it shows a pop up window that allows you to enter the name, as displayed in the image below. Almost everything works fine, except I can't get it to display the new record after I create it. See my code below--you'll get a sense of what I'm trying to do.
By the way, if it matters, the "Consortium name" combo box allows you to select records. I don't see how it could throw my update off, but I thought I should include that information.
Here's the form:
Here's the code:
Interestingly, StackOverflow doesn't seem to indent the code properly after making an edit--I was able to do it successfully with a new test post. Oh well. I'm a noob to this as well:
Private Sub CreateConsortiumButton_Click()
If IsNull(Me.ConsortiumNameText) Or Me.ConsortiumNameText = "" Then ''insert better validation here
MsgBox "Please enter a valid consortium name."
Else
'' Create a new Consortium record with the ConsortiumNameText field on the popup window
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("Consortium")
rst.AddNew
rst("Consortium name").Value = Me.ConsortiumNameText
ConsortiumID = rst("ConsortiumID").Value
rst.Update
'' Now, create a corresponding record in the ResearchContributions table
Set rst = CurrentDb.OpenRecordset("ResearchContributions")
rst.AddNew
rst("ConsortiumID").Value = ConsortiumID
rst.Update
MsgBox "Consortium " & Me.ConsortiumNameText & " successfully created."
'' Change the form's combo box to reflect the new record
Forms!Main!NavigationSubform!ConsortiumNameCombobox = Me.ConsortiumNameText
'' Close popup
DoCmd.Close
'' Attempt to set the record on the main form to the newly created one - NOT WORKING!
DoCmd.OpenForm "Main", acNormal, , "[ConsortiumID] = " & ConsortiumID
End If
End Sub
I think part of the issue may have to do with the fact that I've placed the "Consortium Form" form, which is based around a tab control, into the "Main" form. Perhaps because I'm trying to open the Main form with a certain ConsortiumID, that ConsortiumID doesn't apply to Consortium Form. It appears as though I can't link the master with its child, but this hasn't been necessary in the past. Please forgive me if the concepts sound vague in confused, for it is only because the concepts are vague and confused as of yet in my mind--this is my first Access project. Anyone have any tips?
Okay, I think I figured it out. I've added the following code:
DoCmd.OpenForm "Main"
DoCmd.Requery
DoCmd.SearchForRecord , , acFirst, "[ConsortiumID] = " & ConsortiumID
First, open the form, then requery in able to register the fact that the new item is in the database, then use SearchForRecord to open it up. Neato. Thanks, everyone.
I'm pretty new to MS Access. I'm trying to create a simple form that will basically search for a particular record using a textbox, rather than a drop down box. Essentially a user would be able to enter an ID number and retrieve some other related Info. However, I do not want the user to be able to add any new records to the database. I've been able to get the forms to look the way I want them, but I'm not sure where to place the code (do I create a macro, insert the code into the properties of the button?) Any help is greatly appreciated!
I assume that you have bound your form to a table or a query and that you want to be able to enter the ID manually in a textbox, then press ENTER and load that record's data or display an error message if there is no such record.
As dsteele said, make sure that the form's Data property Allow Addtions is set to No to disallow users from adding records.
Then, from the AfterUpdate event of the textbox, add the following code (assuming that your textbox is named txtGoTo):
Private Sub txtGoTo_AfterUpdate()
If (txtGoTo & vbNullString) = vbNullString Then Exit Sub
Dim rs As DAO.RecordSet
Set rs = Me.RecordsetClone
rs.FindFirst "[ID]=" & txtGoTo
If rs.NoMatch Then
MsgBox "Sorry, no such record '" & txtGoTo & "' was found.", _
vbOKOnly + vbInformation
Else
Me.RecordSet.Bookmark = rs.Bookmark
End If
rs.Close
txtGoTo = Null
End Sub
Note that you will have to change the line rs.FindFirst "[ID]=" & txtGoTo to something that is adequate for your data:
"[ID]=" should be replaced by the field you want to search (it could be "[POReference]=" or something else.
if you are searching by a numeric ID, for instance because the field is an autonumber column, then the code is fine.
Otherwise, if the field you are searching on is a string (say PN12-G) then you have to change the code to:
rs.FindFirst "[ID]=""" & txtGoTo & """"
Failing to use the proper quoting (or quoting where not necessary) will result in errors of the kind Data type mismatch....
As a new user, I would recommend that you have a look at the sample NorthWind project database that is either shiped with older versions of Access or available as a template for download from Access 2007.
There a lots of techniques to learn from as a new Access developer, including other ways to implement record navigation.
Set the form property Data/'Allow Additions' to No.
Either in the AfterUpdate event of the textbox, or in the Click event of a button, you can write code or assign a macro to look up and display the record you want.