【问题标题】:Passing MSForms.Control as argument in Word VBA将 MSForms.Control 作为 Word VBA 中的参数传递
【发布时间】:2018-11-30 15:15:52
【问题描述】:

我必须使用 VBA 在 MS Word 中设置 ActiveX 控件选项卡顺序。所以这里是基本代码:

Private Sub radioFull_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
                              ByVal Shift As Integer)
    If KeyCode = 9 Then
        radioIntern.Activate
    End If
End Sub

问题是我对由密码设置的文档设置了有效的限制编辑保护。因此,在开始保护后,在任何控件上按下选项卡时,它拒绝运行,说我对文档有保护。

因此,在执行上述功能期间,我首先必须取消保护文档,将选项卡移动到下一个字段,然后通过以下功能重新保护:

Private Sub ToggleProtect()
    If ActiveDocument.ProtectionType <> wdNoProtection Then
        ActiveDocument.Unprotect Password:="password"
    Else
        ActiveDocument.Protect Password:="password", NoReset:=True, _
                               Type:=wdAllowOnlyFormFields, _
                               UseIRM:=False, EnforceStyleLock:=False
    End If        
End Sub

Private Sub radioFull_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
                              ByVal Shift As Integer)
    If KeyCode = 9 Then
        ToggleProtect
        radioIntern.Activate
        ToggleProtect
    End If
End Sub

效果很好。所以我打算通过这样的方式进一步缩短主代码:

Private Sub radioFull_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
                              ByVal Shift As Integer)
    tabOrder(KeyCode, controlName)
End Sub

在这种情况下,tabOrder 函数如下所示:

Public Sub tabOrder(K as integer,t as string)
    If KeyCode = K Then
        ToggleProtect
        t.Activate
        ToggleProtect
    End If
End Sub

但我对 VBA 函数参数并不熟悉。那么请告诉我如何正确传递参数或编写函数,以便我可以在 MS Word 表单中保持 Tab 键顺序?

【问题讨论】:

  • 您在参数方面向哪个函数寻求帮助?此外,在您的 tabOrder 子中,您不能“激活”t,因为它是 String 而不是控件。

标签: vba arguments ms-word


【解决方案1】:

即使 MS Forms 控件派生自 MSForms.Control,VBA 显然也无法将它们“强制转换”为这种数据类型。但是,它可以与通用类型一起使用。诀窍是将过程参数声明为数据类型Variant。

在此过程中,我通过声明Word.Document 类型的对象变量将文档传递给ToggleProtect,对代码进行了另一个小的优化。虽然不太可能,但理论上用户可能会在代码执行期间更改文档,从而使ActiveDocument 与触发代码的文档不同。因此,如果您立即获得目标文档,那么代码将始终在正确的文档上执行,无论当前哪个文档具有焦点。

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
                             ByVal Shift As Integer)
        Dim doc As Word.Document

        Set doc = Me
        tabOrder KeyCode, doc, Me.TextBox1
End Sub

Public Sub tabOrder(ByVal KeyCode As MSForms.ReturnInteger, _
                    ByRef doc As Word.Document, ByRef t As Variant)

   If KeyCode = 9 Then
      ToggleProtect doc
      t.Activate
      ToggleProtect doc
   End If
End Sub

Private Sub ToggleProtect(doc As Word.Document)
    If doc.ProtectionType <> wdNoProtection Then
        doc.Unprotect Password:="password"
    Else
        doc.Protect Password:="password", NoReset:=True, _
                               Type:=wdAllowOnlyFormFields, _
                               UseIRM:=False, EnforceStyleLock:=False
    End If
End Sub

【讨论】:

  • 谢谢!它有效,虽然我只使用了t As Variant 选项。由于用户更改文件的可能性最小,因为它是一份申请表,更改文件会影响他/她自己的职业生涯。所以我排除了代码的修改部分,以便通过更少的代码行来保持文件大小更小。再次感谢。您节省了时间和劳动力。
【解决方案2】:

在您的 KeyDown 事件中,您似乎想要传递 KeyCode 和 Control。因此,您传递的参数必须与tabOrder 子的签名相匹配。查看如何定义 KeyCode 并将其复制/粘贴到您的 tabOrder 子。第二个参数将被定义为 Control 允许传递任何控件。这是我所说的一个例子:

Private Sub radioFull_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
   tabOrder KeyCode, radioFull
End Sub

Public Sub tabOrder(ByVal KeyCode As MSForms.ReturnInteger, ByRef t As MSForms.Control)
   If KeyCode = 9 Then
      ToggleProtect
      t.Activate
      ToggleProtect
   End If
End Sub

【讨论】:

  • 不工作。按下 Tab 键时,它显示 Run-time error 13, Type mismatch,如果按下调试,它会转到这行代码:tabOrder KeyCode, radioIntern [我的目标是在选项按钮(activeX 控件)-radioFull 中,如果我按下 Tab,它需要将光标移到另一个名为 radioIntern 的选项按钮(activeX 控件)上,它将继续在文档的所有 activeX 控件之间切换]
  • 看看@Cindy 的回答,或许会有帮助。
猜你喜欢
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 2014-04-13
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多