Я прочитал лучшие практики для создания формы, в отношении того факта, что всегда следует обращаться к объекту формы, а не к самой форме. Таким образом, я решил построить для меня форму котельной.
Проблема
Все прошло гладко, до того момента, я решил закрыть форму с правой верхней красной X
. Он закрывается нормально. Но тогда, когда я пытаюсь открыть форму снова, я получаю эту ошибку во время выполнения:
Ошибка на objPresenter.Show
(см код ниже). Очевидно, что он не входит в if
выше. Но проблема в том, что закрытие с X
не работает нормально. Когда я закрываю форму с кнопки End
, все работает. И даже, если я скопирую код для закрытия с btnEnd на UserForm_QueryClose
, он все равно не работает.
Форма
Таким образом, у меня есть modMain
, frmMain
и clsSummaryPresenter
, которые все заботиться о форме. Я начинаю код из modMain
Моей формы выглядит следующим образом:
имеет btnRun
, btnExit
, lblInfo
. Название класса: frmMain
.
Код
В frmMain
:
Option Explicit
Public Event OnRunReport()
Public Event OnExit()
Public Property Get InformationText() As String
InformationText = lblInfo.Caption
End Property
Public Property Let InformationText(ByVal value As String)
lblInfo.Caption = value
End Property
Public Property Get InformationCaption() As String
InformationCaption = Caption
End Property
Public Property Let InformationCaption(ByVal value As String)
Caption = value
End Property
Private Sub btnRun_Click()
RaiseEvent OnRunReport
End Sub
Private Sub btnExit_Click()
RaiseEvent OnExit
End Sub
Private Sub UserForm_QueryClose(CloseMode As Integer, Cancel As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
Hide
'Even if I change the two lines above with this the error happens:
'RaiseEvent OnExit
'However, if I simply write END in stead of those two lines
'anything works quite ok...
'but that is a bit brutal.
End If
End Sub
В clsSummaryPresenter
Option Explicit
Private WithEvents objSummaryForm As frmMain
Private Sub Class_Initialize()
Set objSummaryForm = New frmMain
End Sub
Private Sub Class_Terminate()
Set objSummaryForm = Nothing
End Sub
Public Sub Show()
If Not objSummaryForm.Visible Then
objSummaryForm.Show vbModeless
Call ChangeLabelAndCaption("Press Run to Start", "Starting")
End If
With objSummaryForm
.Top = CLng((Application.Height/2 + Application.Top) - .Height/2)
.Left = CLng((Application.Width/2 + Application.Left) - .Width/2)
End With
End Sub
Public Sub Hide()
If objSummaryForm.Visible Then objSummaryForm.Hide
End Sub
Public Sub ChangeLabelAndCaption(strLabelInfo As String, strCaption As String)
objSummaryForm.InformationText = strLabelInfo
objSummaryForm.InformationCaption = strCaption
objSummaryForm.Repaint
End Sub
Private Sub objSummaryForm_OnRunReport()
MainGenerateReport
Refresh
End Sub
Private Sub objSummaryForm_OnExit()
Hide
End Sub
Public Sub Refresh()
With objSummaryForm
.lblInfo = "Ready"
.Caption = "Task performed"
End With
End Sub
modMain
В
Option Explicit
Private objPresenter As clsSummaryPresenter
Public Sub MainGenerateReport()
objPresenter.ChangeLabelAndCaption "Starting and running...", "Running..."
GenerateNumbers
End Sub
Public Sub GenerateNumbers()
Dim lngLong As Long
Dim lngLong2 As Long
tblMain.Cells.Clear
For lngLong = 1 To 4
For lngLong2 = 1 To 1
tblMain.Cells(lngLong, lngLong2) = lngLong * lngLong2
Next lngLong2
Next lngLong
End Sub
Public Sub ShowMainForm()
If (objPresenter Is Nothing) Then
Set objPresenter = New clsSummaryPresenter
End If
objPresenter.Show
End Sub
Вопрос
Еще раз, почему я не могу закрыть форму с красным X
? Я могу заменить код UserForm_QueryClose
на End
, но это немного жестоко. Есть идеи?
Я видел эту ошибку, когда люди имеют версии Excel старше и пытаются работать в Win7 или новее. Я считаю, что это связано с тем, как вызывается вызываемый пользовательский формуляр. UserForm1.Show (или аналогичный) должен быть так, как вызывается UserForm. Все остальное в новых версиях Excel, как известно, дает ошибку 80010007. – Cyril
Не уверен, что дает, но что-то не так. Если вы удалите код Скрыть из события Queryclose, форма все равно будет закрыта. – jkpieterse
@ Кирилл: Никогда не слышал об этом. Я всегда вызываю userforms с помощью переменных объекта, никогда не испытываю проблем, как вы предлагаете. В любой версии Excel начиная с '97 до 2016 года включительно. – jkpieterse