Excel это не сложно
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
20.04.2024, 02:31:42

Войти
На форуме добавлена возможность подписки на RSS-ленты любого раздела форума. Подписаться можно, нажав на иконку RSS , расположенную левее наименования раздела.
33 242 Сообщений в 5 457 Тем от 6 758 Пользователей
Последний пользователь: Сергей2662
*
Перейти на сайт Хитрости Надстройка MulTEx Обучающие тренинги Наша группа ВКонтакте
Правила форума Начало Помощь Поиск Календарь Войти Регистрация Выйти
+  Excel это не сложно
|-+  Основные форумы
| |-+  Вопросы по Excel и VBA
| | |-+  Перебор контролов на листе и работа с формой пользователя
Страниц: [1] 2 3  Все   Вниз
Печать
Автор Тема: Перебор контролов на листе и работа с формой пользователя  (Прочитано 14615 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« : 16.04.2020, 16:02:33 »

Общее:
8 чекбоксов расположены в ряд, имена от cb11 до cb18(это только для первого ряда, а рядов там 10), задача:
если устанавливается какой-то чекбокс, то устанавить и все чекбоксы левее его в ряду, если какой-то чек сбрасываются, то сбрасывать и чеки расположенные правее в ряду.
В общую процедуру на событие "Click" каждого чека передаю цифровую часть его имени и перебираю контролы в  ряду.

Создал форму, добавил чекбоксы, работает, но криво: в дебагере видно, что как только какой-то чек устанавливается кодом, то тут же не понятно почему происходит обработка события [этот чек]_Click и, соответственно повторный вызов общей процедуры, что не есть правильно.

Решил попробовать расположить чеки прямо на листе, теперь не понятно как кодом создать имя контрола? У формы было свойство Controls и можно было обращаться:  ...Controls("cb" & i & j)..., где i,j - меняющиеся в цикле значения, а сейчас как?
Конструкция Me."cb" & i & j, естественно не работает.
... а может все чеки в массив загнать и бегать потом по нему? (это просто размышление)
Записан
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #1 : 17.04.2020, 10:28:14 »

тут же не понятно почему
Нет, все понятно. Вы же изменили его состояние. Этим вызвали процедуру. Делается в таких случаях так: объявляется переменная типа Boolean уровня модуля(или глобальная) и при изменении чекбокса ей присваивается значение True. После выполнения процедуры возвращаем в False. А далее она при каждом изменении проверяется: если True - выход из процедуры. Если False - выполняем. Что-то вроде того:
Код: (vb)
Option Explicit
Dim IsNonEvents As Boolean
Private Sub CheckBox1_Click()
    IsNonEvents = True
    CheckBox2.Value = CheckBox1.Value
    CheckBox3.Value = CheckBox1.Value
    IsNonEvents = False
End Sub

Private Sub CheckBox2_Click()
    If IsNonEvents Then
        Exit Sub
    End If
    'some code
End Sub

Private Sub CheckBox3_Click()
    If IsNonEvents Then
        Exit Sub
    End If
    'some code
End Sub

Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« Ответ #2 : 17.04.2020, 12:34:16 »

Нет, все понятно. Вы же изменили его состояние.
Не-а, не понятно: если это реакция на изменения состояния, то логично ожидается событие Change, но никак не Click Грустный
В любом случае, за идею с "защёлкой" - спасибо!

А как-же, всё-таки, кодом создать имя контрола, если этот контрол расположен не на форме, а на листе?
Записан
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #3 : 17.04.2020, 15:34:48 »

если это реакция на изменения состояния, то логично ожидается событие Change, но никак не Click
тут как бы...в спецификации для него все описано: Click реагирует на изменение состояния CheckBox-а. Т.е. если был Change, то будет за ним и Click. Согласен, не логично. Но документировано.

кодом создать имя контрола
вот это точно не понятно. Создать имя? Назначить другое имеется ввиду? Здесь прежде чем ответить надо знать ТИП контрола: ActiveX или Элемент управления формы. Если ActiveX - я бы не советовал менять его имя, т.к. сгенерированные автоматически события могут работать в итоге некорректно. Да и вообще я бы рекомендовал не использовать ActiveX.
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« Ответ #4 : 17.04.2020, 17:09:08 »

Создать имя?
Я не точно сформулировал - не переименовать контрол, а обратиться к нему в коде, вот, если контрол принадлежит форме, то всё просто:
передавая в процедуру значения i и j, я могу создать такую строку:
Код: (vb)
 Me.Controls("cb" & i & j) = FALSE
и при i=1, а j=2, сбросится чекбокс с именем "cb12".
А как указанную строку, создать, когда чекбокс расположен на самом листе? Ну нет у листа семейства Controls. В замешательстве

И почему вообще рекомендуете вместо ActiveX использовать обычный флажок?
Записан
RAN
Эксперты
Старожил
*

Репутация: +43/-0
Офлайн Офлайн

Сообщений: 440



Просмотр профиля E-mail
« Ответ #5 : 17.04.2020, 18:31:28 »

Примерно так
Код: (vb)
Sub ww()
ActiveSheet.OLEObjects("CheckBox1").Object.Value = Not ActiveSheet.OLEObjects("CheckBox1").Object.Value
End Sub

Записан

А что ты умеешь?
Учиться...
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« Ответ #6 : 19.04.2020, 12:11:40 »

Примерно так
Спасибо большое, получилось!
Записан
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« Ответ #7 : 19.04.2020, 13:16:55 »

... но беда караулила за углом:
оказалось, что у чекбоксов размещаемых прямо на листе отсутствует очень нужное мне св-во Tag! А в нём планировал хранить данные, которые "отдавал" бы чекбокс при своём нажатии Плачущий
Tag есть у этих же контролов, если их на форме размещать, но там другая засада:
и на листе, и на форме эти 80 чеков размещаю процедурой (через Add)
spoiler for Hiden:
Код: (vb)
Const OBJ_COLUMN     As Long = 8 число столбцов
Const OBJ_ROW     As Long = 1 'число строк
Const CTL_HEIGHT    As Long = 20
Const CTL_WIDTH     As Long = 50
Private Sub ForForm()
    Dim r As Integer, c As Integer, o As Object, q As Object
    myForm.Show
    Set o = myForm
    For r = 1 To OBJ_ROW
        For c = 1 To OBJ_COLUMN
            Set q = o.Controls.Add("Forms.CheckBox.1", "cb" & r & c)
            q.Caption = "cb" & r & c
            q.Left = CTL_WIDTH * c
            q.Top = CTL_HEIGHT * r
            q.SpecialEffect = 0
        Next c
    Next r
End Sub

Private Sub ForList()
Dim r As Integer, c As Integer, o As Object
For r = 1 To OBJ_ROW
    For c = 1 To OBJ_COLUMN
        Set o = ActiveSheet.OLEObjects.Add("Forms.CheckBox.1")
        With o
            .Name = "cb_" & r & c
            .Object.SpecialEffect = 0
            .Left = CTL_WIDTH * (c - 1)
            .Top = CTL_HEIGHT * (r - 1)
            .Width = CTL_WIDTH
            .Height = CTL_HEIGHT
            .Visible = True
            .Object.Caption = "cb" & r & c
        End With
    Next c
Next r
End Sub

так вот лист сохраняет вставленные контролы, а форма, зараза!, - нет! <смайлик гнева>
Записан
vikttur
Глобальный модератор
Ветеран
*****

Репутация: +124/-0
Офлайн Офлайн

Сообщений: 1 816



Просмотр профиля
« Ответ #8 : 19.04.2020, 13:44:54 »

Десятки флажков... И макросом? Почему сразу не разместить их на форме?
Если заранее неизвестно количество - "пойдем другим путем": разместить на форме ListBox с мультивыбором.
Записан
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« Ответ #9 : 19.04.2020, 14:58:53 »

Почему сразу не разместить их на форме?
руками 80 штук? Пробовал: добавить, выровнять, посмотреть, опять выровнять, опять выровнять... А ещё же у  каждого и в свойствах покопаться надо... вообщем, к пятому десятку я одурел...
А никак нельзя, создав кодом на форме контролы, сохранить их навсегда(на листе же сохраняются)?
« Последнее редактирование: 19.04.2020, 20:36:21 от vikttur » Записан
vikttur
Глобальный модератор
Ветеран
*****

Репутация: +124/-0
Офлайн Офлайн

Сообщений: 1 816



Просмотр профиля
« Ответ #10 : 19.04.2020, 20:34:51 »

Разместить вручную можно и довольно быстро. Не по односму выравнивать, а группами.

разместить на форме ListBox с мультивыбором.
...не пробовали?

Записан
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« Ответ #11 : 19.04.2020, 23:04:10 »


Вариант с ListBox-ом сразу мимо - нарушится вся логика интерфейса. Группами выравнивать пробовал, особой скорости не заметил. Как ещё можно быстро разместить вручную не понял: вставлять то их всё-равно по одному придётся. Проблему решила бы возможность сохранения формы, после заполнения её кодом.
« Последнее редактирование: 19.04.2020, 23:50:53 от vikttur » Записан
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #12 : 20.04.2020, 10:15:02 »

почему вообще рекомендуете вместо ActiveX использовать обычный флажок?
Потому что ActiveX в какой-то момент могут просто перестать работать. Вот один из примеров: Элементы ActiveX перестали работать или ведут себя непредсказуемо

отсутствует очень нужное мне св-во Tag! А в нём планировал хранить данные, которые "отдавал" бы чекбокс при своём нажатии
Как вариант вместо этого использовать словарь ключом для которого было бы имя контрола, а значением - что-то, что должно быть в Tag. Больше посоветовать нечего, т.к. сам смысл мне лично пока не очень понятен.
возможность сохранения формы, после заполнения её кодом
На время пользования файлом вполне возможно. Достаточно форму закрывать не через Unload(т.е. выгрузку из памяти), а через Hide. Тогда все данные формы сохранятся.
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Andrew_Ko
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 48


Просмотр профиля
« Ответ #13 : 20.04.2020, 14:20:32 »

Потому что ActiveX в какой-то момент ...
Ну, допустим... Но я отдал ему предпочтение только потому, что он богат свойствами/событиями, а у "сермяжного" Флажка их  совсем ничего.

...вместо этого использовать словарь  ...
Т.е. - 80 заранее заполненных скрытых ячеек?

...смысл мне лично пока не очень понятен.
Основной принцип работы - в первом посте, а в Tag я планировал хранить число, которое либо прибавляется к общей сумме при установке чекбокса, либо вычитается - при сбросе.

На время пользования файлом вполне возможно.
Возможно только пользоваться созданным (кликать чекбоксы), но если файл закрыть-открыть, то на форме ничего созданного не окажется!
С листом же такого не происходит: создал программно контролы, сохранил лист, закрыл-открыл файл, созданные контролы - на месте!
Получается, что в случае с формой, в коде обрабатывается не она сама, а её экземпляр(копия), оригинал же остаётся в первозданном виде и сохранить все изменения невозможно?
Идею добавления на форму контролов взял отсюда: https://www.excel-vba.ru/chto-umeet-excel/rabota-s-modulyami-klassov/, к сожалению, там забыли написать, что все свойства контрола (а не только Left, Top) надо продумать заранее и указать их в коде, т.к. вручную потом исправить нельзя.
Записан
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #14 : 20.04.2020, 14:29:11 »

Основной принцип работы - в первом посте, а в Tag я планировал хранить число, которое либо прибавляется к общей сумме при установке чекбокса, либо вычитается - при сбросе
но он как бы мне лично все равно не раскрывает необходимости использования свойства Tag. Возможно, конечно, речь о псевдогруппировке контролов в группы, но это догадки. И опять же - это правильнее делать не Tag-ом, а назначением имен, которые бы четки идентифицировали каждый элемент его группе.
но если файл закрыть-открыть, то на форме ничего созданного не окажется!
Ага. И поэтому я написал:
На время пользования файлом вполне возможно
Когда я писал про словарь, я имел ввиду объект Dictionary Улыбка Есть такой объект.
Ну а вообще да, можно привязываться и к ячейкам на скрытом листе. Я бы даже сказал, что в данной ситуации правильнее. Тогда можно будет и состояние всех контролов хранить там и выдергивать при открытии файла, а сохранять при каждом изменении или перед закрытием файла. Операция не очень сложная, но весьма полезная в любом случае.

отдал ему предпочтение только потому, что он богат свойствами/событиями,
я же не отговариваю. Осознание необходимости выкручиваться другими свойствами придет лишь тогда, когда наделаете в файле всяких красивостей и нужностей при помощи ActiveX, а Microsoft возьмет и опять где-то напортачит, а Вам сидеть и восстанавливать  В замешательстве

там забыли написать
Согласен. Но там и упор сделан на то, как использовать классы для отслеживания событий созданных программно контролов. Предполагалось, что после пары запуском станет понятно, что они не остаются на форме навсегда. Они лишь на время запуска формы. Но все же их можно потом программно же и менять. Достаточно при создании контрола дать ему уникальное имя(это для простоты) и потом через это имя обращаться при необходимости из любого контрола формы:
Код: (vb)
With .Controls.Add("Forms.OptionButton.1")
        .Left = 1
        .Top =1
        .Width = 1
        .Height = 1
        .Name = "optBtn2"
    End With
Me.Controls("optBtn2").Value = Not Me.Controls("optBtn2").Value

Но как правило в этом нет необходимости, т.к. такие контролы создаются при запуске формы каждый раз, а их события отслеживаются через классы.
« Последнее редактирование: 20.04.2020, 14:41:07 от Дмитрий Щербаков(The_Prist) » Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Страниц: [1] 2 3  Все   Вверх
Печать
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Яндекс.Метрика Рейтинг@Mail.ru