disable certain fields in a form (1 Viewer)

azhar2006

Registered User.
Local time
Today, 06:19
Joined
Feb 8, 2012
Messages
202
Good evening to all
I found this code for dear friend(@arnelgp ) and made use of it for an existing field on the form. My question is how can I make this code a public function that works on all or some of the form fields. Thank you so much....
Code:
Private Sub textfield_GotFocus()
Dim ctl As Control
Set ctl = Screen.PreviousControl
    MsgBox "arnelgp"
    With ctl
        .SetFocus
        .SelStart = Len(.Text)
        .SelLength = 0
    End With
    Me!txt.Enabled = False
End Sub
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 08:19
Joined
Feb 28, 2001
Messages
27,001
To make this more general, you could pass in the name of the control or a control object to a subroutine. If this routine would be used ONLY on a single form, it can be declared as private - but then can only be called from the form's class module. If you want to use it on multiple forms, it has to be public and in a general module. I'm going to show only the public variant. First how to declare it, then how to use it.

Code:
Public ModifyField( ByRef ctl as Access.Control )

    With ctl
        .SetFocus
        .SelStart = len( .Text )
        .SelLength = 0
        <<<other effects can be done here on the selected control>>>
    End With

End Sub

To use it:

Code:
    ModifyField Me.SomeControlName

But now, some warnings. The code you showed us has issues worthy of discussion.

(1) You used a reference to Me!txt.enabled - but that syntax implies that you have a control named "txt" AND that the routine is located in the class module for the form that has that name. If you don't have a form field named [txt] then that line will fail. Further, since you used "!" rather than "." you will get a run-time error complaining about a non-existent object because the "!" defers object resolution to run-time.

(2) Your title suggests you want to disable the control - which you surely can do. But you can't do it while that control has focus. Therefore, watch out for the use of the .SetFocus method. And of course, if you wanted to put the text cursor after the last character in the text field, you NEED the .SetFocus since .Text as a property is only valid when the control has focus. Therefore, to put the text cursor inside a control's text input area and then disable the control is self-contradictory.

(3) Using Screen.PreviousControl does have some limits on when you can call it. For example, you can't call it until there IS a "previous control" for it to reference. I.e. it would fail if you called it immediately after a Form_Load event or the first Form_Current after the _Load event. Admittedly, this is a minor concern - but if the routine is called from the first control to gain focus after the form has been launched will give you the implied error immediately.

(4) It is unclear from the on-line documentation of .PreviousControl as to what happens if a sub-form exists and the previous focus was in the sub-form, but you then use the .PreviousControl from the sub-form's parent.

(5) If this DOES go into a generic module, you cannot EVER use "Me." or "Me!" syntax in it. Everything will have to either be a local variable or must be passed in as a call parameter. In a general module, there IS no "Me." Only class modules have a "Me" shortcut.
 

azhar2006

Registered User.
Local time
Today, 06:19
Joined
Feb 8, 2012
Messages
202
To make this more general, you could pass in the name of the control or a control object to a subroutine. If this routine would be used ONLY on a single form, it can be declared as private - but then can only be called from the form's class module. If you want to use it on multiple forms, it has to be public and in a general module. I'm going to show only the public variant. First how to declare it, then how to use it.

Code:
Public ModifyField( ByRef ctl as Access.Control )

    With ctl
        .SetFocus
        .SelStart = len( .Text )
        .SelLength = 0
        <<<other effects can be done here on the selected control>>>
    End With

End Sub

To use it:

Code:
    ModifyField Me.SomeControlName

But now, some warnings. The code you showed us has issues worthy of discussion.

(1) You used a reference to Me!txt.enabled - but that syntax implies that you have a control named "txt" AND that the routine is located in the class module for the form that has that name. If you don't have a form field named [txt] then that line will fail. Further, since you used "!" rather than "." you will get a run-time error complaining about a non-existent object because the "!" defers object resolution to run-time.

(2) Your title suggests you want to disable the control - which you surely can do. But you can't do it while that control has focus. Therefore, watch out for the use of the .SetFocus method. And of course, if you wanted to put the text cursor after the last character in the text field, you NEED the .SetFocus since .Text as a property is only valid when the control has focus. Therefore, to put the text cursor inside a control's text input area and then disable the control is self-contradictory.

(3) Using Screen.PreviousControl does have some limits on when you can call it. For example, you can't call it until there IS a "previous control" for it to reference. I.e. it would fail if you called it immediately after a Form_Load event or the first Form_Current after the _Load event. Admittedly, this is a minor concern - but if the routine is called from the first control to gain focus after the form has been launched will give you the implied error immediately.

(4) It is unclear from the on-line documentation of .PreviousControl as to what happens if a sub-form exists and the previous focus was in the sub-form, but you then use the .PreviousControl from the sub-form's parent.

(5) If this DOES go into a generic module, you cannot EVER use "Me." or "Me!" syntax in it. Everything will have to either be a local variable or must be passed in as a call parameter. In a general module, there IS no "Me." Only class modules have a "Me" shortcut.
To make this more general, you can pass the name of the control or control object to a subroutine.
Speech in the utmost magnificence. Thank you very much for this valuable information. Yes, what I want is to use it for one model only. Not a general function. Now I understand after reading what you have mentioned what is the difference between a subroutine and a general function. Thanks again . I also found this code. But it locks all the controls. My question regarding this code is how to exclude some text fields.
Code:
Private Sub Form_Current()
    Dim ctrl As Control
For Each ctrl In Detail.Controls
    If (TypeOf ctrl Is TextBox) Then
        ctrl.Locked = True
'        ctrl.Enabled = False
    End If
Next
End Sub
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 09:19
Joined
Feb 19, 2002
Messages
42,981
This is code I use to lock controls on a form. It toggles based on the value of bLock. If bLock is true the controls are locked, otherwise they are unlocked. Only controls that will deviate have tags. So, if some controls should always be locked, then they have a tag of "LOCK" if a control should never be locked, then the tag is "NoLock". It uses the control type since buttons can't be locked. they have to be disabled.

Code:
Public Sub LockControls(frm As Form, bLock As Boolean)
    Dim ctl As Control
    For Each ctl In frm.Controls
    Select Case ctl.ControlType
        Case acTextBox, acComboBox, acListBox, acCheckBox
            Select Case ctl.Tag
                Case "NoLock"
                    ctl.Locked = False
                Case "Lock"
                    ctl.Locked = True
                Case Else
                    ctl.Locked = bLock         'toggle locks
            End Select
        Case acOptionGroup, acOptionButton, acCheckBox      ''not working
             Select Case ctl.Tag
                Case "NoLock"
                    ctl.Locked = False
                Case "Lock"
                    ctl.Locked = True
                Case Else
                    ctl.Locked = bLock         'toggle locks
            End Select
        Case acCommandButton
            Select Case ctl.Tag
                Case "NoLock"
                    ctl.Enabled = True
                Case "Lock"
                    ctl.Enabled = False
                Case Else
                    ctl.Enabled = Not bLock         'toggle locks
            End Select
    End Select
Next ctl
Set ctl = Nothing
End Sub
 

azhar2006

Registered User.
Local time
Today, 06:19
Joined
Feb 8, 2012
Messages
202
This is code I use to lock controls on a form. It toggles based on the value of bLock. If bLock is true the controls are locked, otherwise they are unlocked. Only controls that will deviate have tags. So, if some controls should always be locked, then they have a tag of "LOCK" if a control should never be locked, then the tag is "NoLock". It uses the control type since buttons can't be locked. they have to be disabled.

Code:
Public Sub LockControls(frm As Form, bLock As Boolean)
    Dim ctl As Control
    For Each ctl In frm.Controls
    Select Case ctl.ControlType
        Case acTextBox, acComboBox, acListBox, acCheckBox
            Select Case ctl.Tag
                Case "NoLock"
                    ctl.Locked = False
                Case "Lock"
                    ctl.Locked = True
                Case Else
                    ctl.Locked = bLock         'toggle locks
            End Select
        Case acOptionGroup, acOptionButton, acCheckBox      ''not working
             Select Case ctl.Tag
                Case "NoLock"
                    ctl.Locked = False
                Case "Lock"
                    ctl.Locked = True
                Case Else
                    ctl.Locked = bLock         'toggle locks
            End Select
        Case acCommandButton
            Select Case ctl.Tag
                Case "NoLock"
                    ctl.Enabled = True
                Case "Lock"
                    ctl.Enabled = False
                Case Else
                    ctl.Enabled = Not bLock         'toggle locks
            End Select
    End Select
Next ctl
Set ctl = Nothing
End Sub
Thank you very much (Pat Hartman) but where do I put the (NoLock) and (Lock) and (bLock) in the text properties?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 09:19
Joined
Feb 19, 2002
Messages
42,981
You put Lock or NoLock in the tag property of the "special" controls on the form. Any control without a Lock or NoLock tag will be locked or unlocked depending on the value you pass in the bLock argument. If you pass true, you are telling the code to lock all controls. If you pass false, you are telling the code to unlock all the controls. The "Lock" and "NoLock" tags specify EXCEPTIONS. So, if the tag is LOCK, the control is locked regardless of the value of bLock and if the tag is "UnLock", the control is unlocked regardless of the value of bLock.

There are some similar code suggestions floating around but they tag all fields. My method only tags "special" fields which makes it more flexible and less likely to cause a problem if you forget the form uses it since all untagged controls will automatically be subject to the value of bLock.
 

azhar2006

Registered User.
Local time
Today, 06:19
Joined
Feb 8, 2012
Messages
202
You put Lock or NoLock in the tag property of the "special" controls on the form. Any control without a Lock or NoLock tag will be locked or unlocked depending on the value you pass in the bLock argument. If you pass true, you are telling the code to lock all controls. If you pass false, you are telling the code to unlock all the controls. The "Lock" and "NoLock" tags specify EXCEPTIONS. So, if the tag is LOCK, the control is locked regardless of the value of bLock and if the tag is "UnLock", the control is unlocked regardless of the value of bLock.

There are some similar code suggestions floating around but they tag all fields. My method only tags "special" fields which makes it more flexible and less likely to cause a problem if you forget the form uses it since all untagged controls will automatically be subject to the value of bLock.
Thank you my friend did not work with me. Thanks for your time 🌷
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 08:19
Joined
Feb 28, 2001
Messages
27,001
If I may step in on Pat's code, I'll first say she usually gives very good advice. So when you say "did not work for me" there is an open question remaining. For future reference for this - or any other problem, we welcome questions but need to know the symptoms of the failure if we are to help you. Can you be more specific about "did not work" ??
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 09:19
Joined
Feb 19, 2002
Messages
42,981
The code was copied directly out of an application so I know it works. I explained it when I posted it. I explained it a second time. As Doc said, you need to show us YOUR version of the code and preferably post the db with the form so I can be sure that you implemented it correctly.
 

azhar2006

Registered User.
Local time
Today, 06:19
Joined
Feb 8, 2012
Messages
202
If I may step in on Pat's code, I'll first say she usually gives very good advice. So when you say "did not work for me" there is an open question remaining. For future reference for this - or any other problem, we welcome questions but need to know the symptoms of the failure if we are to help you. Can you be more specific about "did not work" ??

The code was copied directly out of an application so I know it works. I explained it when I posted it. I explained it a second time. As Doc said, you need to show us YOUR version of the code and preferably post the db with the form so I can be sure that you implemented it correctly.
Note, dear sir, the example attached
 

Attachments

  • Lock.accdb
    496 KB · Views: 316

Pat Hartman

Super Moderator
Staff member
Local time
Today, 09:19
Joined
Feb 19, 2002
Messages
42,981
1. You did NOT set the tag property of any control.
2. You did NOT call the code
3. You put the code into the form's class module. Since the code takes a form object property, I thought I didn't need to tell you that the code itself belongs in a standard module so you can call it from any form that is open. So you have to move the code
3. You do not have Option Explicit defined.

Typically, the code is called from the Form's on Current event.
 

Users who are viewing this thread

Top Bottom