【问题标题】:VBA - ContentControlOnEnter is affecting all my Controls, not just the one specifiedVBA - ContentControlOnEnter 正在影响我的所有控件,而不仅仅是指定的控件
【发布时间】:2019-02-22 21:52:46
【问题描述】:

我已经为课程设置了一个可填写的表格。我正在尝试根据所选课程和开始日期自动填充课程结束日期。

它不是在进入“结束”控件时触发,而是在输入所有引发重复运行时错误的控件时触发。我愿意在单击时填充该字段,但这似乎不是一个选项。

Private Sub Document_ContentControlOnEnter(ByVal Endate As ContentControl)

'Declare variable names to deal with the content control data
Dim SD As ContentControl
Dim TC As ContentControl
Dim TC1 As ContentControl
Dim ED As ContentControl
Dim NewDate

'Connect each variable name to its content control
Set TC = ActiveDocument.SelectContentControlsByTag("Training").Item(1)
Set SD = ActiveDocument.SelectContentControlsByTag("Stardate").Item(1)
Set ED = ActiveDocument.SelectContentControlsByTag("Endate").Item(1)
'For some reason, twice removed from the source works better
Set TC1 = TC

    If SD.Range.Text <> "Click to enter a date" Then
    NewDate = DateValue(SD.Range.Text)

'Look at Training Content Control - what was selected.
'If one of the two longer courses is picked, add 2 days to the start date
'and use that as the end date. Otherwise just add one day.
    Select Case TC1.Range.Text
        Case "Basic Skills"
            ED.Range.Text = Format((NewDate + 2), "MMM d, yyyy")
        Case "Caseworker"
            ED.Range.Text = Format((NewDate + 2), "MMM d, yyyy")
        Case Else
            ED.Range.Text = Format((NewDate + 1), "MMM d, yyyy")
    End Select
    End If

'Once we're done, re-set the variables for the next round. This does not change
'the content of the form.
    Set TC = Nothing
    Set SD = Nothing
    Set ED = Nothing

End Sub

【问题讨论】:

  • The documentation 对此并不十分清楚,但它确实说它会在“输入”控件时触发。我猜当您使用SelectContentControlsByTag 时,您是通过选择它来“进入”控件。我会尝试枚举 Document.ContentControls 集合来查找控件。

标签: vba ms-word


【解决方案1】:

您看到所描述行为的原因

不是在进入“结束”控件时触发,而是 进入所有控件时触发

是由于 Microsoft 对文档中包含的内容控件的设计决定。所有内容控件都将触发的每种事件类型都有一个事件。这意味着,如果代码特定于一个或几个内容控件,则需要评估触发事件的内容控件并根据需要分支代码。

请注意,事件签名传递了参数ByVal ContentControl As ContentControl。这是触发事件的内容控件。因此,为这个参数指定特定内容控件的名称并不是最佳方法 - 它可以是任何内容控件。

我修改了代码的第一部分,以说明如何构造它来测试哪个内容控件触发了事件:

Private Sub Document_ContentControlOnEnter(ByVal cc As ContentControl)

'Declare variable names to deal with the content control data
Dim SD As ContentControl
Dim TC As ContentControl
Dim TC1 As ContentControl
Dim ED As ContentControl
Dim NewDate

If cc.Tag = "EndDate" Then
  'Connect each variable name to its content control
  Set TC = ActiveDocument.SelectContentControlsByTag("Training").Item(1)
  Set SD = ActiveDocument.SelectContentControlsByTag("Stardate").Item(1)
  Set ED = cc 
  'Do other things, here
End If
End Sub

【讨论】:

  • 现在完美运行。太感谢了!周一快乐!
【解决方案2】:

根据事件的名称,我看到的是,每当您输入控件时,它都会将 enddate 控件传递给代码。基本上,只需检查并查看 enddate 是否具有值,然后再继续执行其余操作。

Private Sub Document_ContentControlOnEnter(ByVal Endate As ContentControl)
If len(Endate.Range.Text) > 0 then
    'Declare variable names to deal with the content control data
    Dim SD As ContentControl
    Dim TC As ContentControl
    Dim TC1 As ContentControl
    Dim ED As ContentControl
    Dim NewDate

    'Connect each variable name to its content control
    Set TC = ActiveDocument.SelectContentControlsByTag("Training").Item(1)
    Set SD = ActiveDocument.SelectContentControlsByTag("Stardate").Item(1)
    Set ED = ActiveDocument.SelectContentControlsByTag("Endate").Item(1)
    'For some reason, twice removed from the source works better
    Set TC1 = TC

        If SD.Range.Text <> "Click to enter a date" Then
        NewDate = DateValue(SD.Range.Text)

    'Look at Training Content Control - what was selected.
    'If one of the two longer courses is picked, add 2 days to the start date
    'and use that as the end date. Otherwise just add one day.
        Select Case TC1.Range.Text
            Case "Basic Skills"
                ED.Range.Text = Format((NewDate + 2), "MMM d, yyyy")
            Case "Caseworker"
                ED.Range.Text = Format((NewDate + 2), "MMM d, yyyy")
            Case Else
                ED.Range.Text = Format((NewDate + 1), "MMM d, yyyy")
        End Select
        End If

    'Once we're done, re-set the variables for the next round. This does not change
    'the content of the form.
        Set TC = Nothing
        Set SD = Nothing
        Set ED = Nothing
end if
End Sub

【讨论】:

  • 感谢您的快速响应和建议的测试。我输入了两个必需的数据并运行了调试。事实证明,Select 块中的 ED.Range.Text 包含 。更奇怪的是,当我返回文档时,正确的日期出现在表单中(?!?)。
  • 这很奇怪,我的重点是基于 Access 的 VBA,所以,我将不得不做一些探索,看看我是否能弄清楚其他任何事情。
  • 输入您提供的代码行时出现方法错误。当我尝试选择课程并再次选择开始日期时会出现该错误。我对找到的各种帮助文档的理解是,通过在子行中声明内容控件的名称,这应该是运行时唯一考虑的内容控件。显然不是。我感谢您的所有帮助。 :-)
  • OK - 我将您的代码更改为 If len(Endate.Range.Text) = 0 Then (etc.) 并且它停止在其他内容控件上崩溃,但没有在该字段中返回结束日期.所以我猜问题解决了一半。哈哈。
  • 是的,回到 Access 领域,所有文本框控件都使用 .value,而您只会在按键事件等事件中弄乱 .text 属性。我没看到,抱歉。
猜你喜欢
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多