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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.10.2009, 16:56   #1
litvin44
Пользователь
 
Регистрация: 26.09.2009
Сообщений: 15
По умолчанию Динамический массив элементов управления в VBA

В VB делается легко и просто, а вот как на VBA?
Тема старая, но информации по ней и на этом форуме и в других местах очень мало. По крайней мере, у меня поиск занял много времени.
Поэтому, не сочтите за наглость, выкладываю пример решения

Код:
'   ДОБАЛЕНИЕ И УБИРАНИЕ ЭЛЕМЕНТОВ УПРАВЛЕНИЯ

'   Форма ufContr (вставьте в проект UserForm)
'   на ней 2 кнопки cbAddContr и cbRemoveContr

Dim ArContr() As New clContr, NContr As Long      'массив ЭУ, кол-во ЭУ

Private Sub cbAddContr_Click() '' Добавление ЭУ
Dim TB As MSForms.TextBox, TBN As String    'ЭУ, его имя
Dim ChB As MSForms.CheckBox, ChBN As String 'ЭУ, его имя
    NContr = NContr + 1 'вместо этого можно сделать цикл
    ReDim Preserve ArContr(NContr)
    'добавление TextBox
    TBN = "TextBox" & NContr
    Set TB = Me.Controls.Add("Forms.TextBox.1", TBN)
        'сдвиг на нужное место
        TB.Top = NContr * 20
        TB.Text = TBN
    'в массив
    Set ArContr(NContr).TextBox = TB
    'добавление CheckBox
    ChBN = "CheckBox" & NContr
    Set ChB = Me.Controls.Add("Forms.CheckBox.1", ChBN)
        'сдвиг на нужное место
        ChB.Left = TB.Left + TB.Width + 5
        ChB.Top = NContr * 20
        ChB.Caption = ChBN
    'в массив
    Set ArContr(NContr).CheckBox = ChB
End Sub

Private Sub cbRemoveContr_Click() '' Удаление последних ЭУ
    If NContr > 0 Then  'так как 0-й пуст
        Me.Controls.Remove (ArContr(NContr).TextBox.Name)
        Me.Controls.Remove (ArContr(NContr).CheckBox.Name)
        NContr = NContr - 1
        ReDim Preserve ArContr(NContr)
    End If
End Sub

Sub iCheckBox_Click(i As Long) '' Событие: Изменение i-ой добавленой галки
    MsgBox i & "-я галка=" & ArContr(i).CheckBox.Value
End Sub

Sub iTextBox_Change(i As Long) '' Событие: Изменение i-го добавленного текст.окна
    MsgBox i & "-й текст=" & ArContr(i).TextBox.Text
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    NContr = 0
    ReDim ArContr(NContr) 'очистка, erase не работает
End Sub


'   Модуль класса clContr (вставьте в проект ClassModule)

Public IndexInArray As Long   'номер в массиве
Public WithEvents TextBox As MSForms.TextBox
Public WithEvents CheckBox As MSForms.CheckBox

Private Sub TextBox_Change() ''изменение текста
    Call ufContr.iTextBox_Change(IndexInArray)
End Sub

Private Sub CheckBox_Click() ''поставить/снять галку
    Call ufContr.iCheckBox_Click(IndexInArray)
End Sub
litvin44 вне форума Ответить с цитированием
Старый 07.10.2009, 13:33   #2
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Можно обойтись без массива. Если уж начали использовать классы, то создать отдельный класс, в котором хранить коллекции компонентов, и добавлять элементы с событиями не в массив, а в эти коллекции.
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Старый 07.10.2009, 14:07   #3
litvin44
Пользователь
 
Регистрация: 26.09.2009
Сообщений: 15
По умолчанию

Цитата:
Сообщение от viter.alex Посмотреть сообщение
Можно обойтись без массива. Если уж начали использовать классы, то создать отдельный класс, в котором хранить коллекции компонентов, и добавлять элементы с событиями не в массив, а в эти коллекции.
1. А что это даст, в чем преимущество? Только в том что "так принято"?
2. Мне удобнее как раз в массив. У меня данные в массивах и желательна единая индексация. Можно, конечно, пересчитывать индексы, но это лишняя путаница.
litvin44 вне форума Ответить с цитированием
Старый 07.10.2009, 14:19   #4
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Это даст выигрыш в быстродействии
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Старый 02.07.2017, 04:37   #5
xxx8xxx
Новичок
Джуниор
 
Регистрация: 05.09.2015
Сообщений: 1
По умолчанию

Не работает обработка событий в textbox и checkbox. не определяет номер элементов.
как быть?
xxx8xxx вне форума Ответить с цитированием
Старый 16.08.2018, 22:13   #6
GreenIsle
Новичок
Джуниор
 
Регистрация: 16.08.2018
Сообщений: 1
По умолчанию

Специально зарегистрировался на этом форуме, дабы сообщить, что код автора работает, только в модуле классе перед запуском исполнительных процедур необходимо вычислить IndexInArray.
Я так же прошел долгий путь по просторам интернета. И вслед за профессорами программирования на vbstreets (http://bbs.vbstreets.ru/viewtopic.php?p=37547#37547) попытался сделать навороченную обертку. Но запустить ее так и не сумел. Наткнулся на решение на cyberforumе ( http://www.cyberforum.ru/vba/thread4...ml#post2460384), и когда интегрировал - увидел, что не задан IndexInArray.
Решение с киберфорума - дополнительно в Tag новых элементов управления вносится NContr. Это и будет IndexInArray.
Решение можно расширить в любую сторону - можно удалять не группой элементы, можно обрабатывать индивидуально. Но у меня в проекте они именно группой.
Хорошо, что решение не имеет привязки к листу Excel, поскольку у меня применено в CAD системе - там листа нет.
Подгружаю готовый рабочий пример автора, интегрированный с примером с киберфорума
Вложения
Тип файла: zip Эксперименты с формой в3.zip (15.5 Кб, 34 просмотров)
GreenIsle вне форума Ответить с цитированием
Старый 08.01.2022, 22:36   #7
brain1999
Новичок
Джуниор
 
Регистрация: 08.01.2022
Сообщений: 1
Хорошо

Специально зарегистрировался на этом форуме, дабы сообщить, что код последнего автора полностью работоспособен. Ура, закончилось гугление!!!
brain1999 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамический список. Поиск и удаление элементов. Paulo Помощь студентам 2 01.05.2009 12:37
создания элементов управления на turbo pascal albatros Паскаль, Turbo Pascal, PascalABC.NET 4 15.01.2009 19:15
Дан массив из N элементов (чисел),определить количество элементов кратных 3. Woha Общие вопросы C/C++ 2 08.12.2008 13:12
Список элементов (Динамический массив) SeverBaP Помощь студентам 7 28.11.2008 15:21