Проектирование панели с элементами Combobox
Макросы, отвечающие за вызов команд меню, встроенных или собственных, могут быть сколь угодно сложными. Зачастую, выбор команды меню является, по существу, приглашением к началу диалога с пользователем. Соответствующий макрос открывает форму (диалоговое окно), содержащее многочисленные кнопки, вкладки и другие элементы интерфейса. Типичным примером являются встроенные команды "Открыть…" и "Сохранить как…", диалоговые окна которых пополнились новыми возможностями в Office 2000. Но не всегда следует применять формы, чтобы организовать диалог с пользователем в процессе выбора команды меню. Нередко можно обойтись специальными элементами класса CommandBarCombobox, позволяющими пользователю при работе с меню задать самостоятельно или выбрать подходящее значение из раскрывающегося списка. Примеры таких элементов хорошо знакомы по встроенному меню. С ними приходится, например, встречаться при выборе стиля, шрифта, подходящего размера шрифта или масштаба.
Давайте создадим панель с собственными элементами подобного типа. Я помещу на панель три элемента разных типов, но принадлежащих одному классу - CommandBarComboBox:
- Первый элемент будет представлять окно редактирования Edit. При работе с таким элементом пользователь имеет возможность ввести свой текст в окно редактирования или согласиться с предложенным ему текстом. Макрос, вызываемый в ответ на действия пользователя, может проанализировать текст, введенный пользователем и реагировать на это соответствующим образом.
- Второй элемент будет представлять выпадающий список (Dropdown List), из которого пользователь может выбрать подходящее значение. На примере я покажу, как можно задать элементы списка и как в макросе, вызываемом в ответ на выбор пользователя, можно проанализировать, какое значение выбрал пользователь из списка.
- Третий элемент - ComboBox - объединяет достоинства двух предыдущих элементов, обладая как окном редактирования, так и возможностью выбора значения из списка.
Вот текст процедуры, решающей поставленную задачу:
Листинг 3.14.
(html, txt)
Обратите внимание, прежде чем анализировать свойства объекта, нужно получить сам объект, определяющий элемент меню. Для этого используется метод ActionControl коллекции CommandBars, возвращающий активный элемент этой коллекции, то есть тот самый элемент меню, с которым работал пользователь. Получив этот объект на первом шаге, можно далее анализировать его свойства, чтобы определить выбор пользователя.
С окном редактирования все достаточно просто, поскольку уже знакомое свойство Text позволяет понять, какое значение введено пользователем или он согласился с предложенным ему значением. Для списков, как правило, устраивается разбор случаев. Заметьте, я привел два альтернативных способа, позволяющих узнать, какой элемент списка был выбран пользователем. В первом случае используется свойство текст. Альтернативой является использование свойства ListIndex, фиксирующего номер элемента списка, выбранного пользователем. Замечу, что часто приходится пользоваться и свойством List(i), хранящим значение i-го элемента списка.
Public Sub CreateComboPanel() 'Создание панели с элементами класса CommandBarCombobox ' Создаем панель Dim panel As CommandBar Dim Ctrl As CommandBarComboBox AddPanel ("ComboPanel") Set panel = CommandBars("ComboPanel") 'Добавляем на панель три Combo кнопки разного типа 'Добавление окна редактирования Edit Set Ctrl = AddCustomCombo(panel, "Edititem", msoControlEdit) 'Добавляем text в окно редактирования Ctrl.Text = "Один" Ctrl.OnAction = "EditReaction" 'Добавление выпадающего списка Set Ctrl = AddCustomCombo(panel, "DropdownItem", msoControlDropdown) 'Задание элементов списка Ctrl.AddItem "One", 1 Ctrl.AddItem "Two", 2 Ctrl.AddItem "Three", 3 'Отчеркивание группы элементов Ctrl.ListHeaderCount = 3 'Добавление элемента в конец списка Ctrl.AddItem "Others" Ctrl.OnAction = "DropdownReaction" 'Добавление элемента Combobox - окно редактирования и список Set Ctrl = AddCustomCombo(panel, "ComboBoxItem", msoControlComboBox) Ctrl.Text = "One" Ctrl.AddItem "One" Ctrl.AddItem "Five" Ctrl.OnAction = "DropdownReaction" End Sub
Листинг 3.12.
По ходу дела вызывается процедура AddCustomCombo, добавляющая после соответствующей проверки элементы на панель. Поскольку о семействе процедур добавления было сказано достаточно много, то я приведу ее текст без дополнительных комментариев:
Public Function AddCustomCombo(panel As CommandBar, _ name As String, tip As Variant) As CommandBarComboBox 'Добавляет на панель элемент, тип которого задан параметром tip 'возвращая объект CommandBarComboBox в качестве результата Dim Ctrl As CommandBarComboBox If Not ExistControl(panel, name) Then Set Ctrl = panel.Controls.Add(Type:=tip) Ctrl.Caption = name End If Set AddCustomCombo = panel.Controls(name) End Function
Листинг 3.13.
Хотя в процедуре CreateComboPanel есть подробные комментарии, но есть смысл сказать о ней еще несколько слов и остановится на используемых в ней методах и свойствах объектов. Это тем более уместно по той причине, что ранее я не стал описывать свойства и методы объектов класса CommandBarComboBox, ни их общего класса CommandbarControl. Теперь пришла пора в какой-то мере исправить это положение. Прежде всего, напомню, что объекты класса CommandbarComboBox могут быть разного типа. Их тип задается в момент создания элемента и определяется значением соответствующей константы. Так тип наших трех элементов задается соответственно константами: msoControlEdit, msoControlDropdown, msoControlComboBox. Тип определяет, какие свойства и методы класса CommandBarComboBox доступны для использования у данного элемента.
Так, например, я использую свойство Text, чтобы задать текст, появляющийся в окне редактирования у первого и третьего элементов, которые обладают окном редактирования, доступным для ввода значений. Это свойство нельзя задать для второго элемента, задающего выпадающий список. Для него значение свойства Text формируется автоматически при выборе пользователем значения из списка.
С другой стороны, все свойства и методы, связанные со списком, доступны только для второго и третьего элемента и, естественно, недоступны для окна редактирования. Метод AddItem позволяет добавить новое значение, которое будет показано пользователю в раскрывающемся списке. Параметры этого метода позволяют задать как само значение, так и позицию в списке. Свойство ListHeaderCount позволяет разбить список на группы и отчеркнуть начальную группу значений.
Некоторые другие свойства и методы объектов этого класса я использовал в макросах, вызываемых в ответ на выбор пользователем соответствующего элемента меню. Мне они понадобились для решения главной задачи - получения в макросе информации, введенной пользователем или выбранной им из списка. Но прежде, приведем тексты соответствующих макросов:
Public Sub EditReaction() 'Обработчик меню - Edit ComboBox Dim Ctrl As CommandBarComboBox 'Определяем активный элемент коллекции панелей, 'задающий меню, выбранное пользователем Set Ctrl = CommandBars.ActionControl MsgBox ("Привет! В окне редактирования набран (выбран) текст: " & Ctrl.Text)
'Далее можно задать реакцию на введенный текст
End Sub
Public Sub DropdownReaction() 'Обработчик кнопки меню - Dropdown ComboBox Dim Ctrl As CommandBarComboBox Set Ctrl = CommandBars.ActionControl 'MsgBox ("Hi! Here is Dropdown Box") With Ctrl Select Case .Text Case "One", "Two" MsgBox ("Your Choice : one or two") Case "Three" MsgBox ("Your Choice : three") Case Else MsgBox ("Your Choice : unknown") End Select
Select Case .ListIndex Case 1, 2 MsgBox ("Your Choice : one or two") Case 3 MsgBox ("Your Choice : three") Case Else MsgBox ("Your Choice : unknown") End Select
End With End Sub
Листинг 3.14.
Обратите внимание, прежде чем анализировать свойства объекта, нужно получить сам объект, определяющий элемент меню. Для этого используется метод ActionControl коллекции CommandBars, возвращающий активный элемент этой коллекции, то есть тот самый элемент меню, с которым работал пользователь. Получив этот объект на первом шаге, можно далее анализировать его свойства, чтобы определить выбор пользователя.
С окном редактирования все достаточно просто, поскольку уже знакомое свойство Text позволяет понять, какое значение введено пользователем или он согласился с предложенным ему значением. Для списков, как правило, устраивается разбор случаев. Заметьте, я привел два альтернативных способа, позволяющих узнать, какой элемент списка был выбран пользователем. В первом случае используется свойство текст. Альтернативой является использование свойства ListIndex, фиксирующего номер элемента списка, выбранного пользователем. Замечу, что часто приходится пользоваться и свойством List(i), хранящим значение i-го элемента списка.