Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 如何在Access窗体中有效地配对切换按钮和文本框?_Vba_Forms_Ms Access_Togglebutton - Fatal编程技术网

Vba 如何在Access窗体中有效地配对切换按钮和文本框?

Vba 如何在Access窗体中有效地配对切换按钮和文本框?,vba,forms,ms-access,togglebutton,Vba,Forms,Ms Access,Togglebutton,我知道标题有点混乱,所以让我尽可能清楚地说明一下。 在Access表单(2010)中,我有一组包含日期的文本字段。这些字段都是可选的,用户可以填写任意数量的日期。 为了使它更加用户友好,我想将每个字段与一个切换按钮相关联。然后我希望发生两件事: 当前事件: 如果文本字段有一个值,则它是可见的,并使用切换按钮 与之相关联的按钮被按下 如果文本字段为空,则该文本字段不可见,且未按下切换按钮 点击切换按钮: 如果与其关联的文本字段具有值,则该字段将被清除(且不可见),切换按钮将被取消按下 如果与

我知道标题有点混乱,所以让我尽可能清楚地说明一下。
在Access表单(2010)中,我有一组包含日期的文本字段。这些字段都是可选的,用户可以填写任意数量的日期。 为了使它更加用户友好,我想将每个字段与一个切换按钮相关联。然后我希望发生两件事:

当前事件:

  • 如果文本字段有一个值,则它是可见的,并使用切换按钮 与之相关联的按钮被按下
  • 如果文本字段为空,则该文本字段不可见,且未按下切换按钮
点击切换按钮:

  • 如果与其关联的文本字段具有值,则该字段将被清除(且不可见),切换按钮将被取消按下
  • 如果与其关联的文本字段为空,则焦点将设置在该字段上并按下切换按钮(如果在文本字段中输入了值,则保持该状态,否则所有内容都会恢复原来的状态,即不可见且未按下)
到目前为止,我已经完成了第一步,根据我在网上找到的一些示例设置了两个控件集合。 因此,在加载表单时,我将其称为:

  Private mcolGroupTxToggle As New Collection
  Private mcolGroupBuToggle As New Collection

  Private Sub InitializeCollections()
    Dim ctl As Control

    If mcolGroupTxToggle.Count = 0 Then
       For Each ctl In Me.Controls
         If ctl.Tag = "txtoggle" Then
            mcolGroupTxToggle.Add ctl, ctl.Name
         End If
       Next ctl
       Set ctl = Nothing
    End If

    If mcolGroupBuToggle.Count = 0 Then
       For Each ctl In Me.Controls
         If ctl.Tag = "butoggle" Then
            mcolGroupBuToggle.Add ctl, ctl.Name
         End If
       Next ctl
       Set ctl = Nothing
    End If

  End Sub
Private Sub ClickToggles()
    Dim ctl As Control
    Dim btn As Control
    Dim strBtn As String
    Dim strCtl As String

    strBtn = Me.ActiveControl.Name
    strCtl = Left(strBtn, Len(strBtn) - 1)
    Set ctl = Me(strCtl)
    Set btn = Me(strBtn)

        If IsNull(ctl) Then
            btn.Value = True
            ctl.Visible = True
            ctl.Enabled = True
            ctl.SetFocus
        Else
            ctl.Value = ""
            btn.Value = False
            ctl.Visible = False
        End If

End Sub
关于当前事件,我称之为:

  Private Sub OnLoadToggles(mcol As Collection, pcol As Collection)
    Dim ctl As Control
    Dim btn As Control
    Dim strBtn As String

    For Each ctl In mcol
    'Every button has the same name than the textbox + "b"
    strBtn = ctl.Name & "b"

        For Each btn In pcol
        If btn.Name = strBtn Then
            If IsNull(ctl) Then
                ctl.Visible = False
                btn.Value = False
            Else
                ctl.Visible = True
                btn.Value = True
            End If
        End If
        Next btn

    Next ctl
    Set ctl = Nothing

  End Sub
到目前为止,一切都很顺利,但我不确定这是最好的方法,我想我需要重复步骤2中的一些行。
在程序中区分文本框和按钮似乎有点奇怪,我觉得应该先这样做,这样我就不必在每个程序中都这样做了。我还觉得最好是遍历每对控件(文本+按钮),而不是两个集合中的每个控件

基本上,我想知道是否(1)更好,(2)可能有这样简单的东西:

Private Sub OnLoadToggles(Collection of pairs)
for each [pair of txt and btn]
  if isnull(txt) Then
    txt.visible = false
    btn.value = false
  else
  ...
  end if
...
我的猜测是,我需要创建一个公共sub,其中我根据按钮和文本字段的标记(我的表单中还有其他控件需要单独使用)和名称设置了一组成对的按钮和文本字段,但我不确定如何创建,我是VBA的初学者

有什么建议吗

--编辑步骤2-- 多亏了安德烈的回答,第二部分比我想象的要容易。我已经更新了我的密码。所以点击事件我称之为:

  Private mcolGroupTxToggle As New Collection
  Private mcolGroupBuToggle As New Collection

  Private Sub InitializeCollections()
    Dim ctl As Control

    If mcolGroupTxToggle.Count = 0 Then
       For Each ctl In Me.Controls
         If ctl.Tag = "txtoggle" Then
            mcolGroupTxToggle.Add ctl, ctl.Name
         End If
       Next ctl
       Set ctl = Nothing
    End If

    If mcolGroupBuToggle.Count = 0 Then
       For Each ctl In Me.Controls
         If ctl.Tag = "butoggle" Then
            mcolGroupBuToggle.Add ctl, ctl.Name
         End If
       Next ctl
       Set ctl = Nothing
    End If

  End Sub
Private Sub ClickToggles()
    Dim ctl As Control
    Dim btn As Control
    Dim strBtn As String
    Dim strCtl As String

    strBtn = Me.ActiveControl.Name
    strCtl = Left(strBtn, Len(strBtn) - 1)
    Set ctl = Me(strCtl)
    Set btn = Me(strBtn)

        If IsNull(ctl) Then
            btn.Value = True
            ctl.Visible = True
            ctl.Enabled = True
            ctl.SetFocus
        Else
            ctl.Value = ""
            btn.Value = False
            ctl.Visible = False
        End If

End Sub
这不是完美的,但很有效。此时清除数据可能不是一个好主意,因为可能会发生错误点击。最好在保存表单和清除集合中不可见和/或禁用控件的值之前,循环浏览文本框。我可能以后再谈。
我必须在.visible属性旁边添加.enabled属性,因为在lostfocus事件中,我收到一个错误,表示控件仍然处于活动状态,因此无法使其不可见

现在我更关心的是点击量和失焦事件。我希望有一些公共函数和事件处理程序来处理它,但它对我来说太复杂了。当我知道更多关于…的事情时,我会再谈的。。。一切


无论如何,建议仍然是受欢迎的=)

由于控件对是按名称“配对”的,因此不需要任何花哨的构造,甚至不需要第二个集合。只需直接按匹配控件的名称对其进行寻址

与使用If/Else设置布尔属性不同,为属性指定变量通常更容易

Private Sub OnLoadToggles(mcol As Collection)

    Dim ctl As Control
    Dim btn As Control
    Dim strBtn As String
    Dim bShowIt As Boolean

    For Each ctl In mcol
        'Every button has the same name than the textbox + "b"
        strBtn = ctl.Name & "b"
        ' If you have the control name, you can get the control directly:
        Set btn = Me(strBtn)

        ' Using a variable you don't need If/Else
        bShowIt = Not IsNull(ctl.Value)

        ctl.Visible = bShowIt
        btn.Value = bShowIt

    Next ctl

    ' Note: this is not necessary for local variables - they go automatically out of scope
    Set ctl = Nothing

End Sub

这个问题可能更适合你,你说得对!我以后会考虑的。同时,让我们假设我希望在第2步中得到一些帮助,而不必再发布其他问题?谢谢,它看起来真的很不错!我很高兴摆脱了其中一个系列。问题是:字符串也应用于按钮,所以我得到一条错误消息“Datebb不存在”。所以我仍然需要一个If来避免这种情况,除非有一种方法来检查控件是否存在?对不起,我应该补充一点,使用一个简单的“on Error Resume Next”似乎会给切换按钮带来奇怪的误报(有些按钮在不应该的时候被按下)。我做了一个解释,我不明白。如果上面的
mcol
是您的
mcolGroupTxToggle
,则它只包含文本框。那么,mcol中每个ctl的
如何应用于按钮@ZieOooh对不起,我的错,我把纽扣包括在收藏中,以为它们应该在里面,而它们不在里面,这就是你说的。我很慢。它现在工作得很好,非常感谢!没问题。:)如果答案解决了你的问题,你可以这样做,这也标志着问题已经解决。关于你的编辑:这应该是一个新问题。堆栈溢出的目标是每个问题有一个问题,其答案可能也适用于具有类似问题的其他用户。