在Word VBA中将MSForms.Control作为参数传递

时间:2018-06-21 10:14:35

标签: vba ms-word arguments word-vba

我必须使用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格式的制表符顺序。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

在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