Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 23.01.2009, 21:58   #1
tolikman
Форумчанин
 
Регистрация: 25.08.2008
Сообщений: 159
По умолчанию Выгрузка(удаление) экземляра класса

Как грамотно удалять экземпляры класса?
Создал класс, экземпляры которого:
- при создании, попутно создают в родительском Frame'е (В форме, для наглядности) свой фрейм, а также label и CommandButton.
- по команде создают N-ное количество себе подобных и хранят в себе ссылки на эти подобные классы, становясь их "родителями" в котрых снова рисуются новые экземпляры.
т.е. - куча ссылок друг на друга.
Необходимо это для воспроизведения дерева решений, и выбора наиболее подходящего решения.
я изменяю все ссылки на экземпляры путем присвоения Nothing, так вроде написано в Help'е, однако не помогает, их "духи" все равно существуют, так как откликаются на тестовое событие.
Есть ли процедура полной выгрузки экземпляра?

Для наглядности посмотрите вложение, поймете о чем реч.
Решение логистической задачи, для универа... Двойным щелчком нажимайте на прямоугольное окошко и оно будет ветвиться на два таких же но с другим содержанием.
Вложения
Тип файла: rar Doc1.rar (53.8 Кб, 21 просмотров)

Последний раз редактировалось tolikman; 23.01.2009 в 22:13. Причина: добавил вложение
tolikman вне форума
Старый 23.01.2009, 22:24   #2
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Толик, тебе было бы проще в чистом VB работать с этим безобразием.
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума
Старый 23.01.2009, 23:04   #3
tolikman
Форумчанин
 
Регистрация: 25.08.2008
Сообщений: 159
По умолчанию

Знаю проще, но поздно, не думал что так глубоко зайдет. Была бы возможность - сделал в VB, мешает уже начатое.
Кстати можно unload форму, и все созданное в ней исчезнет. Но надеюсь на более лучший вариант.
tolikman вне форума
Старый 24.01.2009, 08:43   #4
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Цитата:
Была бы возможность - сделал в VB, мешает уже начатое
В принципе, ничего особо сложного нет. Код почти полностью совместим, вот только формы придётся перерисовывать с нуля...

Хотя, может, кто-нибудь знает способ (или спец. прогу) для конвертации VBA-формы в VB-форму? (имеется ввиду обработка файла .frm, чтобы этот файл начал понимать VB)

За день, в принципе, вполне реально портировать код из VBA в VB.
Но я не стал бы этого делать - редактировать код VBA можно на любом компьютере, где установлен Office (не надо устанавливать VB), да и запустить можно любую форму или процедуру (в отличие от предопределённой формы или Sub Main в VB) - именно поэтому я не вижу смыcла переносить код в VB... VBA в плане разработки намного удобнее.

Цитата:
я изменяю все ссылки на экземпляры путем присвоения Nothing
По идее, запись set obj=Nothing полностью уничтожает объект.


Несколько удивила строка Private childs() As New Matrix
среди свойств класса Matrix

То есть, при создании одного экземпляра класса Matrix автоматически создаётся ещё один дочерний экземпляр, и так далее до бесконечности?

Я бы описал класс Matrix примерно так:
Код:
Public Children As New Collection
Public Index as integer
' ... и т.д.

Private Sub Class_Initialize()
    If НадоСоздатьДочерниеЭкземпляры Then
        Dim child As Matrix
        For i = 1 To 5
            Set child = New Matrix
            child.Index = i    ' сразу прописываем нужные свойства дочернего объекта
            Children.Add child    ' добавляем объект в коллекцию
        Next
    End If
End Sub


Private Sub Class_Terminate()
    For Each child In Me.Children
        Set child = Nothing
    Next
End Sub
То есть, при создании экземпляра класса создавалась бы пустая коллекция Children, в которую по мере необходимости можно было бы добавлять новые дочерние экземпляры.
Причём, при создании нового экземпляра дочерние объекты создаются не автоматически, а лишь тогда, когда НадоСоздатьДочерниеЭкземпляры = TRUE
При уничтожении родительского объекта уничтожаются все его дочерние объекты.
Хотя, в принципе, процедура Class_Terminate не нужна - дочерние объекты уничтожатся сами при уничтожении родительского объекта.


Цитата:
я изменяю все ссылки на экземпляры путем присвоения Nothing, так вроде написано в Help'е, однако не помогает, их "духи" все равно существуют, так как откликаются на тестовое событие.
Если Вы под "духами" подразумеваете дочерние экземпляры объектов, то можно по событию класса Class_Terminate уничтожать все ссылки на все дочерние объекты (и удалять с формы созданные этими объектами элементы управления):

Код:
Private Sub Class_Terminate()
    For Each Child In Me.childs
        Child.controls.delete ' соответственно, надо заранее прописать такой метод
        Set Child = Nothing ' ну а теперь уничтожаем объект (необязательно, он и сам бы уничтожился)
    Next
End Sub
Данный код в Вашем проекте работать не будет (поскольку Вы объявили childs как Private childs() As New Matrix, но суть, надеюсь, понятна.
Я бы использовал для childs коллекции вместо массивов - элементами коллекции были бы экземпляры класса Matrix. И никаких ReDim-ов...

По поводу того, что
Цитата:
"духи" все равно существуют
напишите небольшой макрос (строк из 5 - 10), в котором бы создавался объект, уничтожался, а потом производилось бы общение с духами.
Тогда будет намного проще разобраться в причинах происходящего...

Последний раз редактировалось EducatedFool; 24.01.2009 в 09:58.
EducatedFool вне форума
Старый 24.01.2009, 17:13   #5
tolikman
Форумчанин
 
Регистрация: 25.08.2008
Сообщений: 159
По умолчанию

EducatedFool, с Collections я незнакомился, самоучка... Спасибо, поэксперементирую) действительно будет удобнне...
1. в моем случае, я нашел более простой вариант, состояние формы важно для программы после открытия и закрытия, а на время открытия (userform_activate) форму в любом случае надо обнулять, я просто сначала выгружаю форму, а потом инициализирую
Код:
unload zad3_4
zad3_4.show
2. А на счет контролов класса, на сколько я понимаю когда создаем
set label = Parent.Controls.Add("Forms.Label.1" ),
новый созданный контрол не имеет никаких ссылок на клас, который спровоцировал его создание, а только на класс Parent, т.е. на userform, framе и т.д., который непосредственно его создал.
ведь ссылка не может быть "двухсторонней"? т.е. label однозначно ссылается на созданный контрол, кторый в свою очередь не имеет никаких ссылок на наш класс. следовательно сами контролы удалять не обязательно. Достаточно удалить экземпляр класса, точнее все ссылки на него (а их всего 3: ссылка у родителя, ссылка у ребенка(хотя ребенок удаляется раньше), ссылка у объекта Shpion, который её удаляет самым первым во всей этой очереди).
PS - я конечно буду удалять контролы, т.к. они не нужны, но понять особенности всего этого необходимо.
tolikman вне форума
Старый 24.01.2009, 17:26   #6
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Я бы сделал так:

В классе предусмотрел бы отдельную коллекцию для создаваемых элементов управления:
Код:
Public Children As New Collection
Public Controls As New Collection

Далее, каждый раз при создании нового контрола, я добавлял бы его в коллекцию соответствующего элемента класса:
Код:
set label = Parent.Controls.Add("Forms.Label.1")
ActiveMatrix.Controls.Add label

Потом, при уничтожении экземпляра класса Matrix, срабатывал бы следующий код:
Код:
Private Sub Class_Terminate()
    For Each Control In Me.Controls
        Control.delete ' или что-то вроде этого
    Next
End Sub
который удалял бы с формы все элементы управления, относящиеся к данному объекту.

Цитата:
EducatedFool, с Collections я незнакомился, самоучка...
А меня как будто в институте всему этому учили...

Советую как можно скорее изучить Collection - очень полезная штука...
А при работе с классами просто незаменимая.

Последний раз редактировалось EducatedFool; 24.01.2009 в 17:29.
EducatedFool вне форума
Старый 25.01.2009, 03:30   #7
tolikman
Форумчанин
 
Регистрация: 25.08.2008
Сообщений: 159
По умолчанию

EducatedFull огромное спасибо за советы и полезную информацию!!! учту и воспользуюсь...
tolikman вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выгрузка картинок в проект Rusl92 Общие вопросы Delphi 2 20.08.2008 23:00
Выгрузка более 65000 строк Xozer Microsoft Office Excel 4 01.02.2008 22:09
Выгрузка в файл с динамическим названием. Квэнди БД в Delphi 0 24.06.2007 15:39
выгрузка в файл zetrix БД в Delphi 0 30.10.2006 12:50