Мяв. Имеем 2 кода вызова календаря. На мой взгляд, коды идентичны, однако при закрытии календаря крестом первый код выдает ошибку, а второй - нет. В чем причина такого поведения?
Код
Sub test1()
Dim d#
With slancalendar
.StartUpPosition = 1
.Show
d = .Value
End With
Unload slancalendar
MsgBox d
End Sub
Sub test2()
Dim d#
With slancalendar
.StartUpPosition = 1
.Show
End With
d = slancalendar.Value
Unload slancalendar
MsgBox d
End Sub
Андрей, здесь происходит ровно одно: в случае с With создается ссылка на объект. Метод Show показывает форму в модальном режиме, а это как известно заставляет код ждать закрытия оной. Но как только ты жмешь крестик - ссылка на UserForm уничтожается и строка .Value ссылается на несуществующий уже в памяти объект. Однако With заставляет ссылаться именно на него, но не заставляет его сохранять при выгрузке. Собственно, если ты при этом перескочишь на Unload - то форма сначала заново загрузится, а уже потом выгрузится. А при втором коде ты сначала показываешь форму, закрываешь её, уничтожая ссылку, но строка:
Код
d = slancalendar.Value
с упоминанием формы полностью(slancalendar), заставляет VBA заново инициализировать эту самую форму(собственно, при Unload в первом коде происходит так же ситуация). Это легко проверить, поставив точку останова или некий Debug.Print в процедуре Initialize формы. В первом код она будет запущена лишь один раз(до появления ошибки), во втором - дважды. Дополни процедуру так:
Option Explicit
Public sStartTest
Sub test1()
Dim d#
sStartTest = "With"
With slancalendar
.StartUpPosition = 1
.Show
d = .Value
End With
Unload slancalendar
MsgBox d
End Sub
Sub test2()
Dim d#
sStartTest = "Non With"
With slancalendar
.StartUpPosition = 1
.Show
End With
d = slancalendar.Value
Unload slancalendar
MsgBox d
End Sub