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

在Word VBA中将MSForms.Control作为参数传递,vba,arguments,ms-word,Vba,Arguments,Ms Word,我必须使用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 问题是,我对通过

我必须使用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
本例中的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表单中保持制表符顺序?

在您的KeyDown事件中,看起来您希望传递KeyCode和控件。因此,您传递的参数必须与tabOrder sub的签名相匹配。查看如何定义KeyCode并复制/粘贴到tabOrder sub。第二个参数将定义为允许传递任何控件的控件。下面是我所说的一个例子:

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

即使MS Forms控件是从MSForms.Control派生的,VBA显然也无法将它们转换为此数据类型。但是,它可以与常规类型一起使用。诀窍是将过程参数声明为数据类型变量

在编写过程中,我对代码进行了另一个小优化,声明了一个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

关于参数,您需要哪一个函数的帮助?此外,在tabOrder sub中,您不能激活t,因为它是字符串而不是控件。无法工作。按tab键时,会显示运行时错误13,类型不匹配,如果按debug,则会显示这行代码:tabOrder KeyCode,radioIntern[我的目标是,在选项按钮activeX控件-radioFull中,如果我按tab键,光标将移到另一个名为radioIntern的选项按钮activeX控件,它将继续在文档的所有activeX控件之间进行tab键切换]看看@Cindy的答案,可能会有帮助。谢谢!虽然我只使用了t作为变体选项,但效果很好。因为用户更改文档的机会很小,因为这是一个申请表,更改文档会影响他/她自己的职业生涯。因此,我排除了代码中修改的部分,以使文件大小更小代码之一。再次感谢。您节省了时间和人力。
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