Proper syntax for activating record selectors - ms-access

I would like to know the proper syntax to write a string which will activate and de-activate the record selectors on subform 'frmEffortImpact' located on the main form 'frmProjectCharter01'. Unfortunately I continue to get an error message "properties or methods not supported by object". This is the code i am currently using:
Private Sub cmdAddImpacts_Click()
If Me.AllowAdditions = True Then
Forms![frmprojectcharter01]![frmEffortImpact].RecordSelectors = False
ElseIf Me.AllowAdditions = False Then
Forms![frmprojectcharter01]![frmEffortImpact].RecordSelectors = True
End If

With Forms![frmprojectcharter01]![frmEffortImpact] you are reaching the subform control (which has properties like SourceObject and LinkMasterFields). To get the normal Form properties of the form being used as a subform, you need to access the .Form property of the subform control.
Forms![frmprojectcharter01]![frmEffortImpact].Form.RecordSelectors = False
Then you can reach .RecordSelectors and others.

Related

How to return the name of a form's highest parent

I have subform and sometimes it is opend with a parent form, and sometimes it is opened with a parent and a grandparent forms.
How can I find the name of the highest current parent of the subform?
I recommend using events and not relying on a string of object hierarchies. So subform decides it needs to be closed and raises a CloseRequested event. Then whatever form opened subform can act on that. That action could either be to attempt to close itself (if it succeeds then great, it was the parent) or pass it along the chain.
This example below doesn't use events but will work to close the parent-est form when a button is clicked on the subform.
'command button on your subform
Private Sub Command0_Click()
Dim frm As Form
Set frm = FindHighestAncestor(Me)
DoCmd.Close acForm, frm.Name
End Sub
Public Function FindHighestAncestor(frm As Form)
If IsHighestLevelForm(frm) Then
Set FindHighestAncestor = frm
Else
If TypeOf frm.Parent Is Form Then
Set FindHighestAncestor = FindHighestAncestor(frm.Parent)
Else
Set FindHighestAncestor = frm
End If
End If
End Function
Public Function IsHighestLevelForm(frm As Form) As Boolean
Dim f As Form
For Each f In Application.Forms
If f.Name = frm.Name Then
IsHighestLevelForm = True
Exit Function
End If
Next
IsHighestLevelForm = False
End Function
If that is your only two scenarios you can do two things. Check if Mainform is open or check the Parent property of Subform1.

MS Access subform not displaying records and not navigating

I have a one-to-one relationship between an SLD table and an ORDER table. The SLD table is the main form, ORDER table is the subform. The main form's table has more records than the subform table. Master and child links are set. I have decompiled and have done compact and repair. I suspect my application is malfunctioning. In that case it is not the first time (I have fixed it before). Nothing seems to be working this time. I have also imported into a new database.
On form-load both forms and fields are working fine. I continue to the next records using a ['NEXT'] button and reach the end of the sub-forms records therefore having blanks fields. I try to navigate to the previous records (also using a button) but the subform does not move/navigate. Nothing happens to the subform.
It seems like it has gotten worse because first it was navigating but it was not obeying code saying when text box is filled disable checkbox and vise versa.
From the sounds of it the issue is in your Next button rather than it being a subform issue. As you stated in the comments the default navigation allows the form to work as expected.
Is this logic out in your Previous button OnClick Event? Also to be safe i would add in the OR statement in the below code to be extra sure that its catching nulls or blanks
If (IsNull(Forms!Order!OrderSubform.Form!txtDate_Of_Order.Value‌​)) OR Forms!Order!OrderSubform.Form!txtDate_Of_Order.Value‌​ <> "" Then
Forms!Order!OrderSubform.Form!txtDate_Of_Order.Enabled = False
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Enabled = True
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Value = True
Else
Forms!Order!OrderSubform.Form!txtDate_Of_Order.Enabled = True
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Enabled = False
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Value = False
End If
I found out that the If statement belonged in Form_Current event. I am not experiencing the problem anymore after this code:
Private Sub Form_Current()
If (IsNull(Forms!Order!OrderSubform.Form!txtOrder_Number.Value) Or _
Forms!Order!OrderSubform.Form!txtOrder_Number.Value = "") Then
Forms!Order!OrderSubform.Form!txtDate_Of_Order.Enabled = True
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Enabled = True
ElseIf (IsNull(Forms!Order!OrderSubform.Form!txtDate_Of_Order.Value) Or _
Forms!Order!OrderSubform.Form!txtDate_Of_Order.Value = "") Then
Forms!Order!OrderSubform.Form!txtDate_Of_Order.Enabled = False
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Enabled = True
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Value = True
Else
Forms!Order!OrderSubform.Form!txtDate_Of_Order.Enabled = True
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Enabled = False
Forms!Order!OrderSubform.Form!chkbxOrder_Cancelled.Value = False
End If
End Sub

How best to call a public sub routine declared in a form used as the source object a subform control from the main form?

I have a form MyForm1 with a module having the method.
Public Sub CreateSQL(ProductID as variant)
Me.Recordsource = " SELECT * FROM ProductOrders " _
" WHERE ProductID = " & Nz(ProductID ,0)
Me.Requery
End Sub
I use this as a subform to a form named MyMainForm.
When I change the value of a control on MyMainForm it successfully executes the following line:
Me.Subform1.Form.CreateSQL ProductID:=Me.cboProductID
My Questions:
Why are the members not listed on the intellisense list that appears after I type Me.Subform1.Form.?
Is there a way of getting them to be listed?
Is there a property that will let me access the "Form_MyForm1" class of the form referenced in the subform control "Source object property" (ie the Me.Subform1.form ) ?
It's like I need to be able to write:
Me.Subform1.Form_MyForm1.CreateSQL ProductID:=Me.cboProductID
Does such a property already exist? If so how do I access it? Is it in the properties collection?
PS: If you need more information please see the same questions posted in a long Stack overflow question here
Harvey
Don't know.
Not that I know of.
Make the subfunction Public.
But it looks like you could save yourself a lot of trouble by using the Master/Child link option of a form and its subform control.
Instead to the mainform calling the method Me.Subform1.Form.CreateSQL
You should create an object variable in the subform that points to the main form and responds to events eg:
Dim WithEvents cvMyParentForm As Form
Property Set MyParentForm(MyParentForm As Form)
Set cvMyParentForm = MyParentForm
End Property
Property Get MyParentForm() As Form
Set MyParentForm = cvMyParentForm
End Property
When the main form opens use the Form_Open event to "initialise" the subforms
Private Sub Form_Open(Cancel As Integer)
If Me.Subform1.Form.MyParentForm Is Nothing Then
Set Me.Subform1.Form.MyParentForm = Me
End If
End Sub
then you can get the subform to respond to the FORM events that are raised by the mainform.
If you need to have the subform respond to any events that you declare in the main form you will need to chnaeg the above code to use the Form_MyMainFormname type
Dim WithEvents cvMyParentForm As Form_MyMainFormName
Property Set MyParentForm(MyParentForm As Form_MyMainFormName)
Set cvMyParentForm = MyParentForm
End Property
Property Get MyParentForm() As Form_MyMainFormName
Set MyParentForm = cvMyParentForm
End Property
Private Sub cvMyParentForm_Current()
'MsgBox "Sub form current event - does syncing"
Me.Form.Recordset.FindFirst "ID = " & Nz(cvMyParentForm.ID, 0)
If Me.Form.Recordset.NoMatch Then
MsgBox "Humph"
Else
End If
End Sub
Private Sub cvMyParentForm_MyEvent()
MsgBox "A user define event 'MyEvent' was fired on the main form"
End Sub

Access VBA: How to control element when it has focus

I'm trying to disable a button when it is clicked:
Private Sub submitButton_Click()
Me.submitButton.Enabled = False
If dataPath = "" Or skuPath = "" Then
MsgBox "Please enter spreadsheet locations."
Else
Call importExcelData(dataPath, "data")
Call importExcelData(skuPath, "skus")
If validate = True Then
Call generateReports
End If
End If
End Sub
I'm getting a runtime error: "You can't disable a control while it has the focus".
Do you know a way around this?
Thanks!
You must first set the focus to a different control.
That said, if you really have no other control to send the focus to (which I'd find hard to believe), there is a "workaround." You can add a command button and set its TabStop property to False and its Transparent property to True and set the focus to that control.

Determine whether a Access checkbox is checked or not

Such a simple question, but I cannot find the answer (Google, MS help, SO):
How can I check by VBA whether an unbound checkbox on an Access form is checked by the user or not? Can't find the right property.
UPDATE:
I used this code after the suggestions of #HansUp and #RC:
Private Sub CmdTest_Click()
MsgBox "Check1.Value = " & Me.Check1.Value
MsgBox "Check2.Value = " & Me.Check2.Value
End Sub
Private Sub Form_Load()
Me.Check1.Value = 25
Me.Check2.Value = 50
End Sub
2nd UPDATE:
The code should be this (thanks to #David-W-Fenton):
Private Sub CmdTest_Click()
If Me.Check1 = True Then
MsgBox "Check1 IS CHECKED"
Else
MsgBox "Check1 IS NOT CHECKED"
End If
If Me.Check2 = True Then
MsgBox "Check2 IS CHECKED"
Else
MsgBox "Check2 IS NOT CHECKED"
End If
End Sub
Private Sub Form_Load()
' set first checkbox default checked
Me.Check1.Value = True
' set second checkbox default unchecked
Me.Check2.Value = False
End Sub
Checkboxes are a control type designed for one purpose: to ensure valid entry of Boolean values.
In Access, there are two types:
2-state -- can be checked or unchecked, but not Null. Values are True (checked) or False (unchecked). In Access and VBA, the value of True is -1 and the value of False is 0. For portability with environments that use 1 for True, you can always test for False or Not False, since False is the value 0 for all environments I know of.
3-state -- like the 2-state, but can be Null. Clicking it cycles through True/False/Null. This is for binding to an integer field that allows Nulls. It is of no use with a Boolean field, since it can never be Null.
Minor quibble with the answers:
There is almost never a need to use the .Value property of an Access control, as it's the default property. These two are equivalent:
?Me!MyCheckBox.Value
?Me!MyCheckBox
The only gotcha here is that it's important to be careful that you don't create implicit references when testing the value of a checkbox. Instead of this:
If Me!MyCheckBox Then
...write one of these options:
If (Me!MyCheckBox) Then ' forces evaluation of the control
If Me!MyCheckBox = True Then
If (Me!MyCheckBox = True) Then
If (Me!MyCheckBox = Not False) Then
Likewise, when writing subroutines or functions that get values from a Boolean control, always declare your Boolean parameters as ByVal unless you actually want to manipulate the control. In that case, your parameter's data type should be an Access control and not a Boolean value. Anything else runs the risk of implicit references.
Last of all, if you set the value of a checkbox in code, you can actually set it to any number, not just 0 and -1, but any number other than 0 is treated as True (because it's Not False). While you might use that kind of thing in an HTML form, it's not proper UI design for an Access app, as there's no way for the user to be able to see what value is actually be stored in the control, which defeats the purpose of choosing it for editing your data.
Check on yourCheckBox.Value ?