open a field after allowedits in access - ms-access

I have a huge form in access which needs to prevent users from editing the details in it.. I have done that by setting Me.Allowedits to false. But there is one field which I need to keep as open to editing. To do this I have jus placed the code to open the field after the allowedits part in two places where the allowedit code occurs. the flow on debugging was like this
Load
Me.allowedits =false
if condition=true
field.locked=false
field.enalble=true
The same thing I have replicated in current event of the form.Basically I have just kept the code wherever the allowedits was set to fasle.
But my field is still locked and cannot edit it.Is this because once we set allowedits=false the fields in the page cannot be made editable again.
Is there any other alternative?
Appreciate the help.

Then you can't use a form-level setting.
If this is constant (the fields are always locked), simply set all other controls to Locked = True.
If it's dynamic, use a procedure like this:
Private Sub SetEditable(EnableEdit As Boolean)
Dim ctl As Control
For Each ctl In Me.Controls
' The main editable control types (add more if they occur on your form)
If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Or _
ctl.ControlType = acCheckBox Or ctl.ControlType = acSubform Then
If ctl.Name = "MySpecialDateField" Then
' Always editable
ctl.Locked = False
Else
ctl.Locked = Not EnableEdit
' If you want to provide a visual feedback:
' 0 = Flat (locked), 2 = Sunken (editable)
ctl.SpecialEffect = IIf(EnableEdit, 2, 0)
End If
End If
End If
Next ctl
End Sub

Related

If control is not visible, set value to null (access VBA)

I have a form with a number of controls on it. However, if the user marks an option button as "Not Due", many of these fields are set to not be visible. Ultimately I don't want these hidden fields to store any value, but I don't want the values to disappear until the form is saved (that way if someone accidentally hits "not due", it doesn't erase all of the information). This is the code I have-- set to run on all controls before the form updates.
It's telling me that the "Object doesn't support this property or method" and highlights ctl.Value = null when I debug. Any idea what I can do to make this work?
Dim ctl As Control
If Me.optPayDue = 2 Then
For Each ctl In Me.Controls
If ctl.Visible = False Then ctl.Value = Null
Next ctl
End If
The reason you're getting this error is because things included in the Controls collections are like Subforms, Labels, EmptyCells, etc. which do not have a Value property.
You want to check that the thing for which you are setting the value has a Value property before acting on it.
Dim ValueControls As New Dictionary
ValueControls.Add "TextBox", "TextBox"
ValueControls.Add "CheckBox", "CheckBox"
ValueControls.Add "ComboBox", "ComboBox"
ValueControls.Add "ListBox", "ListBox"
ValueControls.Add "OptionButton", "OptionButton"
Dim ctl As Control
If Me.optPayDue = 2 Then
For Each ctl In Me.Controls
If Not ctl.Visible and ValueControls.Exists(TypeName(ctl)) Then
ctl.Value = Null
End If
Next ctl
End If
To use the Dictionary class you need to add a reference to Microsoft Scripting Runtime (C:\Windows\SysWOW64\scrrun.dll)
Another way to do this is to weed out any controls that don't have a .Value in your for loop. Assuming it is just textboxes you can do the following
Dim ctl As Control
If Me.optPayDue = 2 Then
For Each ctl In Me.Controls
If ctl.ControlType = acTextBox and ctl.Visible = False Then
ctl.Value = Null
Next ctl
End If
For something like a checkbox the control type will be acCheckBox and the value would be set to 0.

Controls not changing color in the first page of a report

I have a sub that opens a report "eBouchTest". I loop through controls and change the controls' backcolors. I'm simplifying my question, eventually this will only happen based on a condition but for now I want every combobox, listbox or textbox colored grey.
When running the following piece of code, page 1 of my report does not have it's control's colors changed, but all the other pages do. Why is that so and how can I fix it? Clicking a button launches the following sub with no errors:
Sub ViewReport()
Dim formname As String
Dim ctl As Control
Dim frm As Report
formname = "eBouchTest"
Set frm = Application.Reports(formname)
DoCmd.openreport formname, acViewPreview
For Each ctl In frm.Controls
If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Or ctl.ControlType = acListBox Then
ctl.BackColor = RGB(200, 200, 200)
Debug.Print ctl.Name & " " & ctl.BackColor
End If
Next ctl
Set ctl = Nothing
End Sub
Page 1 of the report (partial picture only for size purpose):
following pages:
How can I make page 1 change colors as well?
Use the code of formatting control in the detail_format event of report.
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim formname As String
Dim ctl As Control
Dim frm As Report
formname = "eBouchTest"
Set frm = Application.Reports(formname)
For Each ctl In frm.Controls
If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Or ctl.ControlType = acListBox Then
ctl.BackColor = RGB(200, 200, 200)
Debug.Print ctl.Name & " " & ctl.BackColor
End If
Next ctl
Set ctl = Nothing
End Sub
Also use a global variable to set the formatting of control dynamically.
AFIK, only way to effectively control dynamic appearance of controls on report with VBA is code in Format event of section the controls are in. Format events run only for Normal and Preview not Report view.
Can use custom Global variable or intrinsic OpenArgs to pass conditional value to the report. DoCmd.openreport formname, acViewPreview, , , , "some value"
Maybe Conditional Formatting would work for you. This will allow display in Report view. A CF rule can reference the OpenArgs parameter passed to report. Ex:
Can simultaneously select all controls desire to have this rule and set the condition for all in one action.
CF is really the only way to change control appearance between records because VBA code sets property for ALL instances of the control. So if the condition depends on data in each record, use CF.
The first page will also be coloured if I refresh it in one way or another. In my case, the reports are displayed in Landscape mode in print preview, so at the end of the code, I just add
frm.Printer.Orientation = acPRORLandscape
which really doesn't change anything, but for some reason it colors the fields in without adding or changing anything else to the code.

How to cycle through Textbox Controls Access VBA

I wanted a code that would cycle thru the names of text box controls on a form whose Visible = true. I know this code is constructed incorrectly, but I need to ask if anyone can point me in the right direction.
Public Sub TxtBoxNamevisible(ByRef pfrm As Form)
Dim ctl As Control
Dim txtbx As TextBox
For Each txtbx In pfrm.Controls.visible = true
MsgBox txtbx.Name
Next txtbx
End Sub
pfrm.Controls.visible does not compile because Controls is a collection. Visible is a supported property for members of that collection, but not supported on the collection itself.
Loop through pfrm.Controls, check whether each of them is a Visible text box, and MsgBox the names of those which are ...
Dim ctl As Control
For Each ctl In pfrm.Controls
If ctl.ControlType = acTextBox And ctl.Visible = True Then
MsgBox ctl.Name
End If
Next ctl

Access 2013 vba - clear a form's controls, bypassing calculated controls

I would like to clear all the controls in an Access 2013 form. I found the following script on this site by Johan Godfried and it works very well.
Private Sub resetForm()
Dim ctl As Control
For Each ctl In Me.Controls
Select Case TypeName(ctl)
Case "TextBox"
ctl.value = ""
Case "CheckBox", "ToggleButton"
ctl.value = False
Case "OptionGroup"
ctl = Null
Case "OptionButton"
' Do not reset an optionbutton if it is part of an OptionGroup
If TypeName(ctl.Parent) <> "OptionGroup" Then ctl.value = False
Case "ComboBox", "ListBox"
ctl.RowSource = vbNullString
End Select
Next ctl
End Sub
Except that when the iteration selects a calculated control I receive the following error:
You can't assign a value to this object.
Is there a property that can be used to by-pass calculated controls?
try Me.myControl.controlsource="" to unbound that control
and then call resetForm()

Start at the beginning of control, not the middle

When a mask is applied to a control like ...
Me.item_name.InputMask = ">!CCCCCCCCCCCCCCCCCCC"
and user clicks in that control the cursor is where they clicked, not at the beginning.
Me.item_name.SelStart = 0
fixes that. I am trying to loop thru all controls with.
For Each ctl In Me.Controls
ctl.SelStart = 0
Next ctl
Ya ... not working.
I have also tried ...
For Each Ctl In Me.Controls
Select Case Ctl.ControlType
Case acTextBox
Debug.Print Ctl.Name
Ctl.SelStart = 0
Case Else
'nothing to do
End Select
Next
Get a RunTime error 2185 on the Ctl.SelStart = 0
This will fail for any controls that don't have a .SelStart property, such as CommandButtons.
The .Properties collection of the control will tell you if it has a .SelStart property, i.e.
Sub ResetControls(f As Form)
Dim c As Control
For Each c In f.Controls
Dim p As Property
For Each p In c.Properties
If p.Name = "SelStart" Then
c.SelStart = 0
End If
Next p
Next c
End Sub
You can also use the text control's OnGotFocus event (which occurs when the user clicks or tabs into the control), and set SelStart there instead. The drawback is that you need to write the event for each control, so you can't do it in a loop. The advantage is that it's extremely simple to do, and you can add other functionality to the event for a specific control if needed (like updating from the content of another control).