Как открыть пользовательскую форму через пользовательскую ленту Excel - PullRequest
1 голос
/ 16 апреля 2019

Я пытаюсь открыть пользовательскую форму через пользовательскую ленту 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. Он переходит к подпункту queryclose, когда запускает код workbooks.open, и говорит, что wb - ничто. Я попытался открыть книгу отдельно, а затем установить книгу как ActiveWorkbook. Я также попробовал: делай пока wb это ничего set wb = ActiveWorkbook петля Этот цикл работал бесконечно, пока мне не пришлось его вручную отменить. Первоначально было установлено wb = workbooks.open (тест)

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")

Для пояснения, подпункт queryclose следует активировать только тогда, когда в пользовательской форме нажата красная рамка с крестиком. Это встроенная функция пользовательской формы.

1 Ответ

0 голосов
/ 16 апреля 2019

Единственное время, когда подпрограмма queryclose должна запускаться, это когда кнопка X нажимается на пользовательской форме.

Но это не так, как QueryClose работает.Событие UserForm.QueryClose вызывается всякий раз, когда форма закрывается, и ее параметры дают вам возможность отменить ее, в зависимости от того, что побудило ее закрыть.

Что вы хотите - это запустить wb.Close False условно, когда значение параметра CloseMode равно vbFormControlMenu (кнопка X - см. Константы QueryClose ):

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

Я попытался вернуться к инициализации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.

...