访问VBA:使用布尔变量来锁定/解锁表单控件

时间:2016-04-19 17:05:06

标签: vba ms-access access-vba boolean case

我设置了以下公共函数来帮助我锁定并启用(false)或反之,表单上的特定控件。这样我可以锁定/启用它们,或者我可以解锁并启用A组或B组,具体取决于所选的组合框。我设置了它,似乎锁定正在工作,但没有启用NOT。

我正在传递要触发的控件组,然后使用布尔值将它们锁定为true或false。这些控件的启用属性应该是变量的布尔变量或非逆的反转。

有人可以看看我可能需要调整的内容吗?

Public Function CostModelLock(LockType As String, LockOn As Boolean)
    Select Case LockType
        Case "A"
            'Lock A controls
            Forms!frmRequest.AField1.Locked = LockOn
            Forms!frmRequest.AField2.Locked = LockOn
            Forms!frmRequest.AField3.Locked = LockOn

            'Enable A controls
            Forms!frmRequest.AField1.Enabled = Not LockOn
            Forms!frmRequest.AField2.Enabled = Not LockOn
            Forms!frmRequest.AField3.Enabled = Not LockOn

        Case "B"

            'Lock B controls
            Forms!frmRequest.BField1.Locked = LockOn
            Forms!frmRequest.BField2.Locked = LockOn
            Forms!frmRequest.BField3.Locked = LockOn

            'Enable B controls
            Forms!frmRequest.BField1.Enabled = Not LockOn
            Forms!frmRequest.BField2.Enabled = Not LockOn
            Forms!frmRequest.BField3.Enabled = Not LockOn

    End Select
    Forms!frmRequest.Repaint
End Function

编辑 - 继续:

是的,我正在尝试锁定它并禁用它。我可以翻转可见性,但我试图避免这种情况,因此用户可以填写两者,如果应用的话,但一次只能激活1个。我希望那些不是他们选择的选项变灰,所以很明显这些领域没有发挥作用。我有一个组合框,这是用户选择他们需要的集合的方式,此功能在该组合的更新后运行。

在加载表单时,我会在两个集合上运行此函数,以确保它们已被锁定。这是因为表单加载时没有记录。他们必须使用组合来查找请求,或者单击“新建”以启动新请求。在更新后,我有以下代码:

If Nz(Me.FKCostModelType.Value) <> 0 Then
    If Me.FKCostModelType.Column(0) = 1 Then
        Call CostModelLock("A", False)
        Call CostModelLock("B", True)
    ElseIf Me.FKCostModelType.Column(0) = 2 Then
        Call CostModelLock("B", False)
        Call CostModelLock("A", True)
    End If
ElseIf Nz(Me.FKCostModelType.Value) = 0 Then
    Call CostModelLock("A", True)
    Call CostModelLock("B", True)
End If

我尝试将功能顺序切换为禁用然后锁定,但这也不起作用。我还将上面的代码添加到查找请求中,以便在找到请求后,正确设置该部分。我已经更新了上面最初发布的代码,添加一个由if语句设置的变量来设置传递给函数的布尔值的倒数,所以我可以更容易地将相反的布尔值传递给控件。

Public Function CostModelLock(LockType As String, LockOn As Boolean)
    Dim NotLockOn As Boolean

    If LockOn = True Then
        NotLockOn = False
    Else
        NotLockOn = True
    End If

    Select Case LockType
        Case "A"
            'Enable A controls
            Forms!frmRequest.AField1.Enabled = NotLockOn
            Forms!frmRequest.AField2.Enabled = NotLockOn
            Forms!frmRequest.AField3.Enabled = NotLockOn

            'Lock A controls
            Forms!frmRequest.AField1.Locked = LockOn
            Forms!frmRequest.AField2.Locked = LockOn
            Forms!frmRequest.AField3.Locked = LockOn

        Case "B"
            'Enable B controls
            Forms!frmRequest.BField1.Enabled = NotLockOn
            Forms!frmRequest.BField2.Enabled = NotLockOn
            Forms!frmRequest.BField3.Enabled = NotLockOn

            'Lock B controls
            Forms!frmRequest.BField1.Locked = LockOn
            Forms!frmRequest.BField2.Locked = LockOn
            Forms!frmRequest.BField3.Locked = LockOn

    End Select
    Forms!frmRequest.Repaint
End Function

这不是什么大不了的事。我可能只是删除启用的属性设置,看看我是否可以将它们变灰,就像enabled属性一样。

谢谢大家的回复!从真正擅长这一点的开发人员那里获得建议很有帮助。

继续再次:

好吧,所以我再次重写了它,但它仍然没有按照我想要的方式工作,我不确定我做错了什么。下面是公共函数,然后是组合的更新后,用户选择他们想要的模型,并且此函数将触发以适当地设置2组控件。

公共职能代码:

Public Function CostModelLock(TagType As String, LockOn As Boolean)
    Dim frm As Form
    Dim ctl As Control
    Dim bColor As String

    Set frm = Forms!frmRequest
    If LockOn = True Then
        bColor = RGB(192, 192, 192)
    Else
        bColor = vbWhite
    End If

    'Loop through every control on the form
    For Each ctl In frm.Controls
    'Look for a Particular Tag
        If ctl.Tag = TagType And (TypeOf ctl Is TextBox Or TypeOf ctl Is ComboBox) Then
            ctl.Locked = LockOn
            ctl.BackColor = bColor
        End If
    Next ctl
    frm.Repaint
End Function

更新组合以激活公共功能:

Private Sub FKCostModelType_AfterUpdate()
    If Nz(Me.FKCostModelType.Value) <> 0 Then
        If Me.FKCostModelType.Column(0) = 1 Then
            Call CostModelLock("ReqA", False)
            Call CostModelLock("ReqB", True)
        ElseIf Me.FKCostModelType.Column(0) = 2 Then
            Call CostModelLock("ReqB", False)
            Call CostModelLock("ReqA", True)
        End If
    ElseIf Nz(Me.FKCostModelType.Value) = 0 Then
        Call CostModelLock("ReqA", True)
        Call CostModelLock("ReqB", True)
    End If
    Call UpdateCostEstimate
End Sub

我还在组合中有代码来查找记录。就是这样:

Private Sub cboFindRequest_AfterUpdate()
    Dim ctl As Control
    Me.RecordSource = "SELECT * FROM tblRequest"
    With Me.RecordsetClone
        .FindFirst "ID = " & _
        Me.cboFindRequest.Column(0)
        If Not .NoMatch Then
            Me.Bookmark = .Bookmark
            'Set detail, footer and save button visible
            Me.Detail.Visible = True
            Me.FormFooter.Visible = True
            Me.cmdSave.Visible = True
            'Set new record and cancel not visible
            Me.cmdNew.Visible = False
            Me.cmdCancel.Visible = False
            'setErr formats red borders around controls, and this is set to false, to remove any red borders
            For Each ctl In Forms!frmSoftwareRequest.Controls
                setErr ctl, False
            Next ctl
            'Set focus on first field, so find combo doesn't have focus and can be set to not visible
            Me.RequestName.SetFocus
            Me.cboFindRequest.Visible = False
            Me.Requery
            'call the after update function from above
            FKCostModelType_AfterUpdate
            'call a function to update a calculated control on form
            UpdateCostEstimate
        End If
    End With
End Sub

现在有2件事情出了问题 - 其中一件事就是控件没有被正确锁定。我使用组合查找请求,然后向下滚动到包含组合的部分以选择成本模型。当我尝试更改该组合时,第二个问题就出现了。我收到一个错误:数据已更改。另一位用户在您尝试保存更改之前编辑了此记录并保存了更改。重新编辑记录。

唉。我确定我做错了10件事,但我似乎无法弄清楚是什么。这个新编辑中的第一个函数(CostModelLock)我认为问题是frm和ctl调用我一直在做一个debug.print等等,但没有看到我期望发生的事情。我可以提供更多信息,但不确定要提供什么。非常感谢帮助!

2 个答案:

答案 0 :(得分:2)

如果,正如汉斯所指出的那样,没有一个控件有焦点,你的代码应该可以工作,所以 - 最有可能的 - 其他的东西正在发生。

作为旁注,您的代码可以简化为:

Public Function CostModelLock(LockType As String, LockOn As Boolean)

    Dim Index As Integer

    For Index = 1 to 3
        With Forms!frmRequest(LockType & "Field" & CStr(Index))
            .Locked = LockOn
            .Enabled = Not LockOn
        End With
    Next
    Forms!frmRequest.Repaint

End Function

答案 1 :(得分:0)

我明白了!我正在回答我自己的问题,所以我可以把我的整个代码放在这里,以防它帮助别人。我也会标记古斯塔夫的回答,因为它引导我来到这里。

首先,这是最终的公共函数,它禁用并锁定每个标记属性设置为通过TagType传递的值的控件,并且是一个文本框或组合框。

Public Function CostModelLock(TagType As String, LockOn As Boolean)
    Dim ctl As Control
    Dim bColor As String
    Dim NotLockOn

    If LockOn = True Then
        NotLockOn = False
    Else
        NotLockOn = True
    End If

    If LockOn = True Then
        bColor = RGB(192, 192, 192)
    Else
        bColor = vbWhite
    End If

    'Loop through every control on the form
    For Each ctl In Forms!frmRequest.Controls
    Debug.Print ctl.Name
        If ctl.Tag = TagType Then
        Debug.Print ctl.Tag
            If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Then
            Debug.Print Nz(ctl.ControlType, 0)
            Debug.Print ctl.Locked
                ctl.Enabled = NotLockOn
                ctl.Locked = LockOn
                ctl.BackColor = bColor
            Debug.Print ctl.Locked
            End If
        Else
        Debug.Print ctl.Tag
        End If

    Next ctl
    Forms!frmSoftwareRequest.Repaint
End Function

我有一个冗余的启用和背景颜色,但这不会伤害任何东西。我可能会删除背面颜色部分,但现在不太关注。

表单上组合的后续更新现在调用公共函数,以便我可以在需要时调用其他函数:

Public Function ActiveCostModel()
    If Nz(Forms!frmRequest.FKCostModelType.Value) <> 0 Then
        If Forms!frmRequest.FKCostModelType.Column(0) = 1 Then
            CostModelLock "ReqCostA", False
            CostModelLock "ReqCostB", True
        ElseIf Forms!frmRequest.FKCostModelType.Column(0) = 2 Then
            CostModelLock "ReqCostB", False
            CostModelLock "ReqCostA", True
        End If
    ElseIf Nz(Forms!frmRequest.FKCostModelType.Value) = 0 Then
        CostModelLock "ReqCostA", True
        CostModelLock "ReqCostB", True
    End If
    Call UpdateCostEstimate
End Function

最好的部分 - &gt;一切正常!非常感谢@Gustav和其他所有人的回复和帮助!