Страницы: 1
RSS
Инициализация UserForm при её выгрузке.
 
Столкнулся с ситуацией, с которой раньше не встречался: есть необходимость по событию Worksheet_SelectionChange загружать форму. Если она уже отображается – предварительно выгрузить её и снова загрузить. Не скрывать, а именно выгружать.  
Обнаружил, что сразу после выполнения Unload UserForm1 происходит её инициализация. Кто может прояснить ситуацию?  
Малюсенький пример прилагаю.
 
А так:  
Private Sub Worksheet_SelectionChange(ByVal Target As Range)  
   Application.EnableEvents = 0  
   If UserForm1.Visible Then  
       Unload UserForm1  
   End If  
   If Target.Cells.Count > 1 Then Exit Sub  
   If Not Intersect(Target, Range("B2:D10")) Is Nothing Then  
       UserForm1.Show 0  
   Else  
   End If  
   Application.EnableEvents = -1  
End Sub  
Юр, ты когда пытаешься выгрузить незагруженную форму, она инициализируется, а потом выгружается:-)
Я сам - дурнее всякого примера! ...
 
интересно.  
в справке ex'2002 нет отдельной справки по событию initialize  
а при описании объекта userform написано так:  
User forms can also respond to events initiated by a user or triggered by the system. For example, you can write code in the Initialize event procedure of the UserForm to initialize module-level variables before the UserForm is displayed.  
 
и всё.  
то есть сказано, что обработчик события initialize будет вызываться перед отображением формы, а больше ничего.    
 
выкрутиться, конечно, можно, объявив в стандартном модуле глобальную переменную и написав обработчик так:  
Private Sub UserForm_Initialize()  
   If fInitialized Then  
     MsgBox "не поминайте лихом..."  
     fInitialized = False  
   Else  
     MsgBox "инициализация"  
     fInitialized = True  
   End If  
End Sub  
 
но согласен: странные дела творятся в вашем VBA.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Так получше, но всё равно есть лишняя инициализация - при вызове формы из жёлтого диапазона, и "ручном" её закрытии кликаем за пределы диапазона - инициализируется. Если и дальше кликать за пределами диапазона - всё нормально.  
{quote}{login=KukLP}{date=24.08.2012 03:36}{thema=}{post}  
Юр, ты когда пытаешься выгрузить незагруженную форму, она инициализируется, а потом выгружается:-){/post}{/quote}Серж, спасибо! Я вижу, что она инициализируется. Вопрос - почему/зачем? :-)
 
Сань, да тут ничего странного. Мы обращаемся к незагруженной форме, она инициализируется. Можешь из кода самой формы запустить ее по F5:-)
Я сам - дурнее всякого примера! ...
 
> Серж, спасибо! Я вижу, что она инициализируется. Вопрос - почему/зачем? :-)  
это объект
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Sub io()  
   Set x = New UserForm1  
End Sub
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
справка по Unload потрясающе лаконична:  
 
Unload Statement  
Removes an object from memory.  
 
Syntax  
Unload object  
 
The required object placeholder represents an object expression that evaluates to an object in the Applies To list.  
 
Remarks  
When an object is unloaded, it's removed from memory and all memory associated with the object is reclaimed. Until it is placed in memory again using the Load statement, a user can't interact with an object, and the object can't be manipulated programmatically.  
 
 
честно скажу - я в оксфордах не бывал, поэтому не все буквы здесь мне знакомы, но что-то я не вижу ничего о том, что при Unload'е незагруженного объекта будет происходить его инициализация... наоборот - сказано, что пока юзер ЯВНО не поюзает выражение Load, объекта в памяти не будет!
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Sub io()  
   Set x = New Application ' = CreateObject("Excel.Application")  
     
   MsgBox Application Is Application  
   MsgBox x Is Application  
     
   x.Quit  
End Sub
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Private frmMain As UserForm1  
 
Private Sub Worksheet_SelectionChange(ByVal Target As Range)  
   If Not frmMain Is Nothing Then  
       Unload frmMain  
   End If  
 
   If Target.Cells.Count > 1 Then Exit Sub  
   If Not Intersect(Target, Range("B2:D10")) Is Nothing Then  
       Set frmMain = New UserForm1  
       frmMain.Show 0  
   Else  
   End If  
End Sub
 
Юр, так попробуй:  
Private Sub Worksheet_SelectionChange(ByVal Target As Range)  
   Application.EnableEvents = 0  
   If Target.Cells.Count > 1 Then Exit Sub  
   If Not Intersect(Target, Range("B2:D10")) Is Nothing Then  
       If UserForm1.Visible Then  
           Unload UserForm1  
       End If  
       UserForm1.Show 0  
   Else  
   End If  
   Application.EnableEvents = -1  
End Sub
Я сам - дурнее всякого примера! ...
 
Ща я напишу : )
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Private Sub Worksheet_SelectionChange(ByVal Target As Range)  
   Static form As Object  
   With Target  
     
       If .Cells.Count > 1 Then  
           Exit Sub  
       End If  
             
       If Not form Is Nothing Then  
           Unload form  
           Set form = Nothing  
       End If  
             
       If Not Intersect(.Cells, Range("B2:D10")) Is Nothing Then  
           Set form = New UserForm1  
           form.Show False  
       End If  
         
   End With  
End Sub
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Не проще, Сань:  
Private Sub Worksheet_SelectionChange(ByVal Target As Range)  
   If Target.Cells.Count > 1 Then Exit Sub  
   If Not Intersect(Target, Range("B2:D10")) Is Nothing Then  
       If UserForm1.Visible Then  
           Unload UserForm1  
       End If  
       UserForm1.Show 0  
   End If  
End Sub  
?
Я сам - дурнее всякого примера! ...
 
{quote}{login=KukLP}{date=24.08.2012 04:00}{thema=}{post}Юр, так попробуй{/post}{/quote}Так не будет выгрузки при клике за пределами диапазона.
 
{quote}{login=nerv}{date=24.08.2012 04:14}{thema=}{post}Private Sub Worksheet_SelectionChange(ByVal Target As Range)  
   Static form As Object{/post}{/quote}Работает.
 
{quote}{login=аналитик}{date=24.08.2012 03:57}{thema=}{post}Private frmMain As UserForm1{/post}{/quote}Тоже работает.  
Но с засадой осталась "непонятка" :-)
 
{quote}{login=Юрий М}{date=24.08.2012 04:48}{thema=Re: }{post}  
Но с засадой осталась "непонятка" :-){/post}{/quote}  
 
все логично:  
при выгрузке идет обращение к форме (объекту, как было верно подмечено - Unload obj), что в свою очередь инициирует (подгружает) ее...  
 
форму инициирует любое обращение к ней, либо к ее контролам, напр., если на форме есть кнопка, то след. строка подгружает саму форму:  
UserForm1.CommandButton1.Caption="ok"
 
Увы, ничего логичного нет.  Создайте Class1 c полем Public t As String. И выполните следующую процедуру Public Sub TestObject Dim p As New Class1 p.t = “Text” Unload p End Sub Получите сообщение об ошибке «Can’t unload and load this object». Для UserForm же Public Sub TestForm Unload UserForm1 Set UserForm1 = Nothing Debig.Print UserForm1.Caption End Sub Выполняется в любом случае. Видимо UserForm специальный тип не убиваемого объекта VBA. Unload лишь очищает его состояние. Так что в случае Юрия М лучше работать через переменную этого типа UserForm1.
 
Проверил: событие CommandButton1_Click инициализации формы не вызывает, да и не должно, как я понимаю...
 
Ведь Unload - это выгрузка из памяти. Так почему должна срабатывать инициализация?
 
{quote}{login=Юрий М}{date=24.08.2012 06:26}{thema=}{post}Ведь Unload - это выгрузка из памяти. Так почему должна срабатывать инициализация?{/post}{/quote}  
 
> Видимо UserForm специальный тип не убиваемого объекта VBA. Unload лишь очищает его состояние. Так что в случае Юрия М лучше работать через переменную этого типа UserForm1  
 
Sub bad()  
   Unload UserForm1  
     
   Set UserForm1 = Nothing  
     
   Unload UserForm1  
End Sub  
 
 
Sub good()  
   Set x = New UserForm1  
     
   Unload x  
     
   Set x = Nothing  
     
   Unload x  
End Sub
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
http://msdn.microsoft.com/en-us/library/aa445829(v=vs.60).aspx  
 
'----------------------------  
Note   When a form is unloaded, only the displayed component is unloaded. The code associated with the form module remains in memory.  
'----------------------------  
Обратите внимание, когда форма выгружается, только отображается компонент выгружается.Код, связанный с формой модуль остается в памяти.  
'----------------------------  
 
Еще вопросы?
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Есть вопрос: код остаётся, а не форма.
 
{quote}{login=KukLP}{date=24.08.2012 04:29}{thema=}{post}Не проще, Сань:  
Private Sub Worksheet_SelectionChange(ByVal Target As Range)  
   If Target.Cells.Count > 1 Then Exit Sub  
   If Not Intersect(Target, Range("B2:D10")) Is Nothing Then  
       If UserForm1.Visible Then  
           Unload UserForm1  
       End If  
       UserForm1.Show 0  
   End If  
End Sub  
?{/post}{/quote}  
см. файл  
 
Юрий М, см. Sub bad()
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
{quote}{login=Юрий М}{date=24.08.2012 06:26}{thema=}{post}Так почему должна срабатывать инициализация?{/post}{/quote}  
 
процедура:  
Sub s1()  
   Unload UserForm1  
End Sub  
 
по-факту есть:  
Sub s1()  
   Dim o As Object: Set o = UserForm1  
   Unload o  
End Sub  
 
Чтобы что-то выгрузить, нужно чтобы это что-то было, а поэтому сначала это загружается.
 
Тогда почему "это" на активируется (не включается процедура активации)? :-)
 
"оно" на экране не появляется - невидимая суть, загрузка в память происходит, а активация нет
 
:-) Как бороться - понятно, но как-то неправильно с этой инициализацией...  
"Ложечки нашлись, но осадок остался" :-)
Страницы: 1
Наверх