如何通过自定义Excel功能区打开用户窗体

时间:2019-04-16 19:23:33

标签: excel vba userform

我正在尝试通过自定义Excel功能区打开用户窗体。当我单击功能区中的按钮时,它将开始初始化,并在workbooks.open函数上将代码发送到queryclose子目录。显示用户表单代码如下:

Sub RemoveFixture_onAction(control As IRibbonControl)
    SelectedCompType = Fixture
    Set EditComp = New ufUpdateComp
        With EditComp
            .Top = Application.Top + 125
            .Left = Application.Left + 25
            .Show
        End With
End Sub

当代码以userform_Initialize代码开始时,它最终移至query_close子目录。的代码如下:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    'If wb Is Nothing Then UserForm_Initialize
    wb.Close False
End Sub

如上所示,在注释掉的部分中,当代码移至queryclose函数时,我试图返回到initialize子项。运行workbooks.open代码时,它将移至queryclose子目录,并表示wb无效。我尝试过单独打开工作簿,然后将工作簿设置为ActiveWorkbook。我也尝试过: 当wb什么都没有做 设置wb = ActiveWorkbook 环 这个循环不断地运行,直到我不得不手动取消它为止。 最初设置为wb = workbooks.open(Test)

Private Sub UserForm_Initialize()
    Workbooks.Open Test, , , , , DynoCompPassword, True
    Set wb = ActiveWorkbook
    Set ws = wb.Worksheets("Info")
    Set ws = wb.Worksheets("Info")
    Set wsC = wb.Worksheets("Calipers")
    Set wsF = wb.Worksheets("Fixtures")
    Set wsW = wb.Worksheets("Wheel Sims")
    ws.Visible = True
    wsC.Visible = True
    wsF.Visible = True

btnCreate.Enabled = False
Dim rng As Range

lblLocation.Visible = False
tbLocation.Visible = False
Me.cbOut.AddItem "Sent To"
Me.cbOut.AddItem "Scrapped"
Me.cbOut.AddItem "Returned"
Me.btnCreate.Enabled = True

For Each rngprojectcode In ws.Range("ProjectCode")
    Me.cbProjectCode.AddItem rngprojectcode.Value
Next rngprojectcode

Set ProjCodeDictionary = New Dictionary 'Create the dictionary
Dim i As Integer
Dim j As Integer
Dim ProjCodeString As String
Dim AssociatedCodes As ProjectCodeList

If ws Is Nothing Then Exit Sub

    ProjCodeDictionary.CompareMode = vbTextCompare 'Make the .exists method case insensitive in an attempt to avoid duplicate values

    Set AssociatedCodes = New ProjectCodeList 'create the class module which will split up the associated codes into individual values
    i = 1
    While ws.Range("F1").Offset(i, 0) <> ""
        With AssociatedCodes
            .SetCodes = CStr(ws.Range("F1").Offset(i, 0).Value)
            For j = 1 To .NumCodes
                ProjCodeDictionary.Add .ProjCode(j), i 'key, item
            Next j
        End With
        i = i + 1
     Wend

If SelectedCompType = Fixture Then
    Me.lblCompNum.Caption = "Fixture ID"
    Me.btnCreate.Caption = "Update Fixture"
        'Automation Error occurs here
    Me.Caption = "Edit Fixture"
    Me.frChangeFrame.Height = 65
    Me.frChangeFrame.Caption = "Bolt Circle"
    Me.cbPartNum.Text = "FIX"
        For Each rng In wsF.Range("FixtureNum")
        Me.cbPartNum.AddItem rng.Value
        Next rng
    Set tbNumStuds = frChangeFrame.Controls.Add("Forms.TextBox.1", , "True")

为澄清起见,只有在用户窗体中按下带有X的红色框时,才应激活queryclose子菜单。它是用户窗体的内置功能。<​​/ p>

1 个答案:

答案 0 :(得分:0)

  

只有当在用户窗体上按下X按钮时,queryclose子项才应运行。

但这不是QueryClose的工作方式。每当表单即将关闭时,都会触发UserForm.QueryClose事件,它的参数使您可以取消它,具体取决于促使它关闭的原因。

wb.Close False参数值为CloseMode(X按钮-参见QueryClose constants)时,您希望有条件地运行vbFormControlMenu

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        wb.Close False
    End If
End Sub
  

当代码[...]

时,我试图返回到初始化子项

不要这样做。事件处理程序是由VBA本身而不是用户代码调用的。如果您需要调用已在事件处理程序中实现的逻辑,请从处理程序中将代码重构为它自己的过程,而不是:

Private Sub UserForm_Initialize()
    DoInitializationStuff
End Sub

Private Sub DoInitializationStuff()
    '...
End Sub

最后,UserForm.Initialize事件在显示表单之前就已触发。

Set EditComp = New ufUpdateComp ' <~ initialize handler runs before this instruction returns
With EditComp
    .Top = Application.Top + 125
    .Left = Application.Left + 25
    .Show
End With

请注意,如果仅在With块中使用局部变量,则无需声明局部变量-让该块保留对象引用:

With New ufUpdateComp ' <~ initialize handler runs before this instruction returns
    .Top = Application.Top + 125
    .Left = Application.Left + 25
    .Show
End With

如果希望DoInitializationStuff在显示之后运行,请在Activate事件中调用它。