Страницы: 1
RSS
With или не With?, Почему возникает ошибка?
 
Мяв.
Имеем 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
Изменено: RAN - 27.01.2019 12:06:37
 
Цитата
RAN написал:
.Show
       d = .Value
Андрей, здесь происходит ровно одно:
в случае с With создается ссылка на объект. Метод Show показывает форму в модальном режиме, а это как известно заставляет код ждать закрытия оной. Но как только ты жмешь крестик - ссылка на UserForm уничтожается и строка .Value ссылается на несуществующий уже в памяти объект. Однако With заставляет ссылаться именно на него, но не заставляет его сохранять при выгрузке. Собственно, если ты при этом перескочишь на Unload - то форма сначала заново загрузится, а уже потом выгрузится.
А при втором коде ты сначала показываешь форму, закрываешь её, уничтожая ссылку, но строка:
Код
d = slancalendar.Value

с упоминанием формы полностью(slancalendar), заставляет VBA заново инициализировать эту самую форму(собственно, при Unload в первом коде происходит так же ситуация).
Это легко проверить, поставив точку останова или некий Debug.Print в процедуре Initialize формы. В первом код она будет запущена лишь один раз(до появления ошибки), во втором - дважды.
Дополни процедуру так:
Код
Private Sub UserForm_Initialize()
'    Me.StartUpPosition = 0
    combomon.List = Array("январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь")
    Call setcal(Date)   'инициализация текущей датой
    Me.Caption = "Сегодня " & Format(Date, "dd mmm yyyy")
    Me.now.Caption = "Сегодня " & Format(Date, "dd mmmm yyyy")
    '    Call ZVI_SetFormPosition(Me)
    
    Debug.Print "Start on " & sStartTest
End Sub

А стандартный модуль с вызовами так:
Код
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
Изменено: Дмитрий(The_Prist) Щербаков - 27.01.2019 12:16:52
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дим, спасибо. Крутился рядом, но выцепить и сформулировать ответ не получалось.
 
Здравствуйте, коллеги! Дмитрий, спасибо за замечательное разъяснение! Скорость ответа впечатляет... 8)  
Владимир
Страницы: 1
Наверх