Страницы: 1 2 След.
RSS
Помогите бедолаге назначить событие
 
Помогите, пожалуйста. Месяц уже плохо сплю...  
 
Есть когд создания классов объектов.  
 
Как этим объектам назначить событие Click?
Audiatur et altera pars
 
http://www.intuit.ru/department/office/vba2000/4/vba2000_4.html
 
Спасибо. Читал.  
Если бы понял, не просил бы о помощи...  
 
Если знаете, помогите, плиз... Очень надо...
Audiatur et altera pars
 
Если бы знал, не просил бы почитать...
 
Извиняюсь, грубо получилось. Не хотел...  
 
Я облазил Инет. Прочитал 2 учебника... Но как назначить клик так и не понял.  
Уже месяц бьюсь. Не дается...
Audiatur et altera pars
 
{quote}{login=The_Prist}{date=07.10.2009 04:57}{thema=Re: }{post}{quote}{login=Kindness}{date=07.10.2009 04:48}{thema=}{post}Спасибо. Читал.  
Если бы понял, не просил бы о помощи...  
Если знаете, помогите, плиз... Очень надо...{/post}{/quote}Как бы сказать, чтоб не обидеть. Если Вы читали и не поняли, то стоит отказаться на время от использования классов. Пока не придет озарение.  
Поищите примеры использования классов и анализируйте.{/post}{/quote}  
 
The_Prist, спасибо. Вы помните, я давно спрашивал про классы. Тогда Вы мне дали совет изучить материалы. Я ему последовал. Я Вам благодарен, мои знания значительно пополнились. К сожалению задача осталась нерешенной... Бросить ее нельзя. Забыть тоже. Может Вы сможете дать мне хоть маленькую подсказку? И я надеюсь меня озарит...
Audiatur et altera pars
 
Попробуйте задать этот вопрос ещё и тут: http://sql.ru/forum/actualtopics.aspx?bid=22  
 
P.S.  
Если вам удастся решить эту задачу, просьба покажите решение... любопытно ;-)
 
Поскольку разговор общий, то и совет общий. На пальцах, так_сказать.  
Вы некоторым кодом объединили некие объекты в класс.  
Теперь в модуле класса создаете событие клик Private Sub ИмяКласса_Click()  
В нем код обработки. Клик на любом объекте тогда вызывает этот код.  
Еще совет. Скачайте любой пример с классами и измените под себя. Пока будете менять разберетесь как оно работает.
Bite my shiny metal ass!      
 
Спасибо. Всегда стараюсь выкладывать итоговое решение. Выложу файл, когда он будет готов.  
Вообще задача не из простых, и ответов по подобным задачам крайне мало... Плюс столкнулся с тем, что люди часто пишут код, а он не работает.  
Например я рассматривал возможность создания модуля с "Sub имя_Click" для созданного в коде объекта, а мой VBA почему-то не воспринимает слово CodeModule... Разные штуки случаются...
Audiatur et altera pars
 
Вот рабочий пример от Уокенбаха, там кнопки в класс загнали и меняют цвет.  
Первый раз с классами я на нем тренировался.
Bite my shiny metal ass!      
 
{quote}{login=Лузер™}{date=07.10.2009 05:16}{thema=}{post}Поскольку разговор общий, то и совет общий. На пальцах, так_сказать.  
Вы некоторым кодом объединили некие объекты в класс.  
Теперь в модуле класса создаете событие клик Private Sub ИмяКласса_Click()  
В нем код обработки. Клик на любом объекте тогда вызывает этот код.  
Еще совет. Скачайте любой пример с классами и измените под себя. Пока будете менять разберетесь как оно работает.{/post}{/quote}  
 
Наверное я неправильно объектв класс загоняю... именно в этом ошибка. Вот код:  
 
Public myListbox() As New myLB 'наименование классмодуля  
 
Sub SozdanieListboxov1()  
k = 0: KS = 6  
For n = 1 To KS  
k = k + 1  
T = T + 78  
Set NewListbox = UserForm1.Frame1.Controls.Add(bstrProgID:="Forms.ListBox.1")  
 
   With NewListbox  
        .Name = "myListBox"  
        .Left = 210  
        .Top = T  
        .Height = 60  
        .Width = 585  
        .Enabled = True  
        .TextAlign = 1  
        .Locked = False  
        .AddItem "pppppppp"  
        .AddItem "jjjjjjjj"  
   End With  
'переопределяем  
ReDim Preserve myListbox(1 To k)  
'загоняем созданный объект в класс  
Set myListbox(k) = New myLB  
 
Next n  
 
UserForm1.Frame1.ScrollHeight = T  
k = 0: KS = 0: T = 0  
End Sub  
 
Извините, файл пока выложить не могу, его надо почистить...
Audiatur et altera pars
 
Да. Не так.  
Либо:  
 
Set myListbox(k) = NewListbox  
Либо сразу:  
Sub SozdanieListboxov1()  
k = 0: KS = 6  
For n = 1 To KS  
k = k + 1  
T = T + 78  
ReDim Preserve myListbox(1 To k)  
Set myListbox(k)  = UserForm1.Frame1.Controls.Add(bstrProgID:="Forms.ListBox.1")  
With myListbox(k)  
 
...
Bite my shiny metal ass!      
 
И, наверное, имя стоит поменять. Что они все как близнецы...  
.Name = "myListBox" & k  
Или что-то в этом роде. Я не пробовал, но думаю одноименные объекты не допускаются.
Bite my shiny metal ass!      
 
Kindness, если е секрет, что за фичу вы творите. Как это должно выглядеть? Почему спрашиваю - управлять вновь созданными Листбоксами занчительно сложнее - привязки, размеры, месторасположение, связи все это надо описывать. Гораздо проще на мой взгляд использовать свойство .Visible. То есть все ListBox-ы, которые будут участвовать в расчетах на момент описания кода вы можете расставить на просторной UserForm, а по завершении работы наложить один на другой, включая отображение нужных по стандартным событиям. Не пожалейте трафика и скачайте http://www.planetaexcel.ru/docs/forum_upload/post_64038.rar. Здесь пример управления элементами, наложенными друг на друга в несколько слоев. Думаю Вам этот опыт пригодится. Ну а классы могут подождать, потому как осваивать VBA, начиная с классов, это все равно что учиться водить на формуле 1. Не успеете получить удовольствие, как пропадет охота этим заниматься.
 
VovaK, нет там ничего сложного. Есть нюансы, но не сложнее остального кода в VBA.  
Чем лучше класс:  
- Для обработки события нужно написать один раз один код. Если Вы создадите Х элементов управления без класса, Вам нужно будет Х процедур, как минимум. Для двух событий Х*2 процедур, а в классе всего две.  
- Если Вы не знаете заранее сколько нужно будет элементов управления, тогда без класса вообще труба.  
 
Потом, Kindness создает листбоксы не друг на друге, а друг под другом. Может ему нужно все 6 одновременно видеть.  
И не похоже, чтобы Kindness только начинал осваивать VBA.
Bite my shiny metal ass!      
 
Лузер, спасибо большое, от Вас такие слова для меня огромная награда за труды. Скажу честно, мозг мой потемки. Почему увлекся программированием не знаю, но затянуло. Образование у меня экономическое, сейчас учусь на юриста. Много технических моментов для меня загадка, но интересно безумно. С VBA борюсь уже года два, но считаю что двигаюсь вперед очень медленно. На курсы не ходил (времени свободного недостаточно), пытаюсь сам, очень часто нахожу решение здесь на сайте, или обращаюсь за помощью. После подсказки (подсказок) как правило все становится ясно и начинаю рулить новыми возможностями с легкость.  
Владимир, действительно, рисовать заранее неопределенное количество объектов не представляется возможным. Это просто, но не всегда решает поставленную задачу. Вы же не можете не использовать циклы? Здесь что-то похожее...  
 
Сейчас буду разбирать советы Лузера. Результат объявлю по завершении процесса.
Audiatur et altera pars
 
{quote}{login=Лузер™}{date=07.10.2009 07:35}{thema=}{post}Да. Не так.  
Либо:  
 
Set myListbox(k) = NewListbox  
Либо сразу:  
Sub SozdanieListboxov1()  
k = 0: KS = 6  
For n = 1 To KS  
k = k + 1  
T = T + 78  
ReDim Preserve myListbox(1 To k)  
Set myListbox(k)  = UserForm1.Frame1.Controls.Add(bstrProgID:="Forms.ListBox.1")  
With myListbox(k)  
 
...{/post}{/quote}  
 
В первом случае, выдает ошибку Type mismatch  
Во втором случае не распознает методы объекта как методы листбокса. То есть видимо программа не понимает, что создаваемый класс - это листбоксы. Понимаю, что чисто теоретически можно определить для класса каждый из методов. Но интуитивно делать этого не желаю, так как задача точно решается намного проще...
Audiatur et altera pars
 
Попробовал так:  
 
Public myListBox() As New myLB  
Public NewListBox As MSForms.ListBox  
 
Sub SozdanieListboxov1()  
k = 0: KS = 6  
For n = 1 To KS  
k = k + 1  
T = T + 78  
 
ReDim Preserve myListBox(1 To k)  
Set myListBox(k) = NewListBox  
 
Set NewListBox = UserForm1.Frame1.Controls.Add(bstrProgID:="Forms.ListBox.1")  
 
   With NewListBox  
        .Name = "myListBox"  
        .Left = 210  
        .Top = T  
        .Height = 60  
        .Width = 585  
        .Enabled = True  
        .TextAlign = 1  
        .Locked = False  
        .AddItem "pppppppp"  
        .AddItem "jjjjjjjj"  
   End With  
 
Next n  
 
UserForm1.Frame1.ScrollHeight = T  
k = 0: KS = 0: T = 0  
End Sub  
 
Создает один лист бокс, а потом доходит до строки Set myListBox(k) = NewListBox и пишет Type mismatch
Audiatur et altera pars
 
Но даже если я убираю цикл, чтобы создавался только один объект, клик не работает...
Audiatur et altera pars
 
Еще попробовал так (не ругается, но клик не работает):  
Стандартный модуль:  
 
Public myListBox() As New myLB  
Public NewListBox As MSForms.ListBox  
Public TB As Object  
 
Sub SozdanieListboxov1()  
k = 0: KS = 6  
 
For n = 1 To KS  
k = k + 1  
T = T + 78  
 
Set NewListBox = UserForm1.Frame1.Controls.Add(bstrProgID:="Forms.ListBox.1")  
 
   With NewListBox  
        .Name = "myLBox" & k  
        .Left = 210  
        .Top = T  
        .Height = 60  
        .Width = 585  
        .Enabled = True  
        .TextAlign = 1  
        .Locked = False  
        .AddItem "pppppppp"  
        .AddItem "jjjjjjjj"  
   End With  
 
Next n  
 
For Each TB In UserForm1.Frame1.Controls  
 
If TypeName(TB) = "myLBox" Then  
ReDim Preserve myListBox(1 To k)  
Set TB = myListBox(k)  
End If  
 
Next TB  
 
UserForm1.Frame1.ScrollHeight = T  
k = 0: KS = 0: T = 0  
End Sub  
 
Модуль класса (myLB):  
 
Public WithEvents myLBox As MSForms.ListBox  
 
Private Sub myLBox_Click()  
MsgBox "Сработало"  
End Sub
Audiatur et altera pars
 
Маленький кусочек забыл, но пока Вы не выложили Public WithEvents myLBox As MSForms.ListBox - его и написать было нельзя.  
 
значит так Либо:  
 
Set myListbox(k).myLBox = NewListbox  
 
Либо сразу:  
 
Sub SozdanieListboxov1()  
k = 0: KS = 6  
For n = 1 To KS  
k = k + 1  
T = T + 78  
ReDim Preserve myListbox(1 To k)  
Set myListbox(k).myLBox = UserForm1.Frame1.Controls.Add(bstrProgID:="Forms.ListBox.1")  
With myListbox(k).myLBox  
 
 
фрейм поленился рисовать :)
Bite my shiny metal ass!      
 
Вы ГЕНИЙ!!!  
 
СПАСИБО ВАМ ОГРОМНЕЙШЕЕ!!!  
 
В ближайшее время выложу итоговый почищенный от лишнего файл!
Audiatur et altera pars
 
Возникла еще одна загвоздка с созданным классом листбоксов.  
 
Как в последствии при работе с ними на них ссылаться?  
 
Смысл такой - кликаю листбокс - в текстбоксе ниже появляется значение кликнутой строки - это я сделал через событие класса.  
При изменении текста текстбокса - меняется и значение строки листбокса - вот с этим труба. Как только не пробовал, не получается. Как правильно писать ссылку на него?  
 
Одна из попыток была такова: Userform1.Frame1.Activecontrol.Text = Userform1.Textbox1.Text
Audiatur et altera pars
 
вопрос , а для чего вообще создавать свой класс? в чем состоит задача?
 
Я пришел к необходимости создания класса, когда столкнулся со следующей задачей:  
заранее неизвестно количество элементов, которые будут созданы друг под другом. Так как количество неизвестно, их заранее нельзя нарисовать на форме. Можно в коде. Нарисовал. А дальше возникла проблема - как назначить им событие, т.е. как прописать что будет, когда пользователь на них кликает? Получается, что только через определение их в отдельном классе... Кликаешь на каждый, а действие одно... Вот так вот. А теперь вопрос - как с ними дальше работать, если событие исходит не от них, но в коде к этому событию необходимо произвести с одним из элементов класса определенное действие...  
 
Я когда создам конечный продукт, выложу его здесь.
Audiatur et altera pars
 
{quote}{login=The_Prist}{date=08.10.2009 03:02}{thema=}{post}Наверное, как-то так  
Private Sub TextBox1_Change()  
Me.Controls("myListBox" & Mid(Me.ActiveControl.Name, 8)).List(0) = Me.ActiveControl.Value  
End Sub  
Но если учесть, что все равно все события TextBox-ов прописывать и имена их известны, то можно и так:  
Private Sub TextBox1_Change()  
Me.Controls("myListBox" & 1).List(0) = TextBox1  
End Sub{/post}{/quote}  
 
Второй вариант работает.  
А вот первый выдает ошибку: Does not suppot this property or method  
 
Попробовал так    
Me.Controls("myListBox" & Mid(Me.ActiveControl.Name, 8)).List(0)=Textbox1  
Пишет, "не могу найти такой объект".  
Текстбокс всегда один. Активные листбоксы разные.  
Расшифруйте, плиз,Mid(Me.ActiveControl.Name, 8) - и что значит "8"?
Audiatur et altera pars
 
{quote}{login=The_Prist}{date=08.10.2009 03:19}{thema=}{post}8 - это кол-во буковок в имени объекта TextBox + 1. Это чтоб выцепить номер TextBox-а.  
А ошибку выдает, скоре всего потому, что у Вас Textbox-ы расположены на объекте Frame, который является, так сказать, доминирующим и соответственно активным при обращении к любому TextBox-у(и не только) на нем. Кстати с объектами MultiPage такая же история.  
Чтобы это проверить можете вставить в код строку  
dim sControlName as string  
sControlName = Me.ActiveControl.Name  
И посмотрите, какой объект форма считает активным.{/post}{/quote}  
 
Про Frame понял, действительно это так.  
Написал вот так:  
Me.Controls("myLBoxes" & Mid(Userform1.Frame1.ActiveControl.Name, 9)).List(0) = Me.ActiveControl.Value  
Все равно ругается на метод... (myLBoxes - я их просто переименовал ранее...).
Audiatur et altera pars
 
{quote}{login=Kindness}{date=08.10.2009 03:24}{thema=Re: }{post}{quote}{login=The_Prist}{date=08.10.2009 03:19}{thema=}{post}8 - это кол-во буковок в имени объекта TextBox + 1. Это чтоб выцепить номер TextBox-а.  
А ошибку выдает, скоре всего потому, что у Вас Textbox-ы расположены на объекте Frame, который является, так сказать, доминирующим и соответственно активным при обращении к любому TextBox-у(и не только) на нем. Кстати с объектами MultiPage такая же история.  
Чтобы это проверить можете вставить в код строку  
dim sControlName as string  
sControlName = Me.ActiveControl.Name  
И посмотрите, какой объект форма считает активным.{/post}{/quote}  
 
Про Frame понял, действительно это так.  
Написал вот так:  
Me.Controls("myLBoxes" & Mid(Userform1.Frame1.ActiveControl.Name, 9)).List(0) = Me.ActiveControl.Value  
Все равно ругается на метод... (myLBoxes - я их просто переименовал ранее...).{/post}{/quote}  
 
Работает вот так, но все время на первой строке листбокса(а как сослась на выделенную?):  
Me.Controls("myLBoxes" & Mid(Userform1.Frame1.ActiveControl.Name, 9)).List(0) = TextBox1
Audiatur et altera pars
 
а параметр не передать ?  
 
типа так :  
 
....  
mac1 data.value  
....  
 
 
sub mac1 (data as Date)  
....  
peremennaya = data  
....  
end sub
 
{quote}{login=Марчук}{date=08.10.2009 03:42}{thema=}{post}а параметр не передать ?  
 
типа так :  
 
....  
mac1 data.value  
....  
 
 
sub mac1 (data as Date)  
....  
peremennaya = data  
....  
end sub{/post}{/quote}  
 
Попробовал так:  
e.Controls("myLBoxes" & Mid(Userform1.Frame1.ActiveControl.Name, 9)).ListIndex = n  
 
Me.Controls("myLBoxes" & Mid(Userform1.Frame1.ActiveControl.Name, 9)).List(n) = TextBox1  
Не вышло... так что врядли поможет (я так понимаю, то, что Вы предлагаете и мой вариант - одно и тоже, да?)
Audiatur et altera pars
Страницы: 1 2 След.
Читают тему
Наверх