【问题标题】:Change state of content control checkbox based on other checkboxes state根据其他复选框状态更改内容控件复选框的状态
【发布时间】:2019-09-26 02:53:29
【问题描述】:

我有一个模板 .dotm,其中有多个复选框内容控件。它们按如下方式组织:

[chk_1] Attach all the items listed below:

      [chk_1_1] Item A
      [chk_1_2] Item B
      [chk_1_3] Item C

[chk_2] Send the details provided below:

      [chk_2_1] Info A
      [chk_2_2] Info B
      [chk_2_3] Info C

如果用户忘记手动检查chk_1,作为某种防故障系统,我正在尝试做的是一种自动检查chk_1 的方法,作为某种防故障系统。 到目前为止,我已经设法手动执行此操作,如下所示:

Private Sub btnSubmit_Click()
Dim ctl As ContentControl
For Each ctl In ActiveDocument.ContentControls
If ctl.Type = wdContentControlCheckBox Then
    If ctl.Tag = "chk_1_1" or ctl.Tag = "chk_1_2" or ctl.Tag = "chk_1_3" Then
        If ctl.Checked = True Then
            ActiveDocument.SelectContentControlsByTag("chk_1").Item(1).Checked = True
        End If
    End If
End If         
Next
Dim ctl2 As ContentControl
For Each ctl2 In ActiveDocument.ContentControls
If ctl2.Type = wdContentControlCheckBox Then
    If ctl2.Tag = "chk_2_1" or ctl2.Tag = "chk_2_2" or ctl2.Tag = "chk_2_3" Then
        If ctl2.Checked = True Then
            ActiveDocument.SelectContentControlsByTag("chk_2").Item(1).Checked = True
        End If
    End If
End If         
Next
End Sub

此代码在单击 ActiveX 按钮 btnSubmit 时执行,如果选中任何子复选框,则自动勾选父复选框。

我想简化代码,因为随着时间的推移,将有多个组,每个组有 20 多个复选框,并且代码将更难编写。

有没有办法使用字符串或检查所有标记为chk_x_y 的复选框的状态,然后修改状态chk_x?

【问题讨论】:

    标签: vba ms-word word-contentcontrol


    【解决方案1】:

    这样的东西可能更容易阅读和维护。

    如果控件命名一致,则无需检查控件是否为复选框 - 名称将识别它。

    Select Case 是If 在使用多个“或”标准时的替代品 - 更容易阅读......在这种情况下,它可以比较一组标签名称的公共部分。 “大于”将选取上级控件下只有常用字符的较长标签名称。

    请注意,使用此方法时,您需要按字母顺序向后工作。

    然后,每次执行的实际操作都放在一个单独的过程中,由每个“案例”调用。

    因此,在为多个控件编写代码时,您几乎可以复制/粘贴Case,然后更改每个控件集的两个标记字符串。

    Sub GetCC_Set()
        Dim cc As Word.ContentControl
        Dim doc As Word.Document
    
        Set doc = ActiveDocument
        For Each cc In doc.Contentcontrols
            Select Case cc.tag
                Case Is > "ck2"
                    Debug.Print 2
                    CheckItems "ck2", cc
                Case Is > "ck1"
                    Debug.Print 1
                    CheckItems "ck1", cc
                Case Else
                    Debug.Print cc.tag
            End Select
        Next                
    End Sub
    
    Sub CheckItems(tag As String, cc As Word.ContentControl)
        If cc.Checked = True Then
            cc.Parent.SelectContentControlsByTag(tag).Item(1).Checked = True
        End If
    End Sub
    

    【讨论】:

    • 谢谢!它工作得很好。实际上,这比我目前的 VBA 知识水平要复杂得多,但我很高兴我正在学习新技巧。我正在检查控件是否是复选框,因为我认为对控件使用某种过滤器会以某种方式使过程更快,而不是通过所有内容控件检查标签。我还是个新手。
    • @MarianV。实际上,额外的检查会使它执行得更慢。 If 不会按照您的想法进行过滤 - For 仍然循环所有控件。在问题的代码中,它为每个标签变体循环;在建议的答案中,循环只执行一次。一个可能的“过滤器”是检查If Instr(cc.tag, "ck") <> 0 Then 以跳过Select Case(如果不是复选框)。这是否会更快取决于文档是否有许多其他类型的控件,并且有必要测试它实际会带来多少。
    • 为了更好地理解Select Case,如果内容控件的布局包含三层复选框(chk1 -> chk1_1 -> chk1_1_1),那么代码需要进行哪些调整?我已经测试过,代码只执行满足条件的Case Is 的第一次出现。一种解决方法是在 For Each 行之前使用 For i = 1 to 2 循环两次。
    • 我目前在移动设备上,所以无法测试,但是:在第一级Case Is > "chk1" 下立即放置另一个Select Case 测试Case Is > "chk1_n",其中有n 的顺序是最高值用于最低值。
    • 是的,它起作用了,它就像一个嵌套的选择案例。这些天来测试,我发现使用Case "chk1_" To "chk1_99" 是我的代码的最佳方法,而不是Case Is > "chk1",因为它为错误提供了最小的空间。感谢您的意见,非常有帮助。
    猜你喜欢
    • 2023-03-18
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多