Если некоторые команды меню выполняют действия, связанные с определенными объектами (документами), имеет смысл делать их видимыми при активизации этих объектов и скрывать, когда соответствующие объекты недоступны. Для этого свойству Visible этих команд нужно задать значение True при активизации объекта и False - при его деактивизации (закрытии, удалении и т. п.). Точно так же можно делать видимой и скрывать и панель меню, предназначенную для работы с определенным объектом.
Проще всего выполнять переустановку свойства Visible в процедурах, обрабатывающих события активизации (открытия, загрузки, появления на экране и т. п.) и деактивизации (закрытия, выгрузки, удаления с экрана и т. п.). Если для данного объекта нет подходящих событий, можно попытаться включить изменение свойства Visible для интересующих нас команд в процедуры, обрабатывающие событие OnAction других команд меню или управляющих кнопок.
Word сохраняет параметры настройки (в том числе и пользовательские меню) в документах и шаблонах. Поэтому эти компоненты меню видны, если соответствующий документ или шаблон доступен в данном контексте, и они исчезают с экрана, когда документ или шаблон недоступен. Excel же сохраняет пользовательские изменения интерфейса в рабочей памяти, поэтому для управления видимостью компонентов меню применяется изменение свойства Visible в процедурах обработки событий.
Добавить новую команду в меню можно, применив метод Add коллекции CommandBarControls к объекту, представляющему изменяемое меню. Чтобы добавить собственную команду, вставьте ее имя в меню, а затем в качестве значения свойства OnAction задайте имя VBA-процедуры, которая должна вызываться при выборе данной команды. В качестве значения аргумента Type (Тип) метода Add укажите msoControlButton, означающее, что вставляемый в меню элемент будет командой. Добавим команду "Накладная" в выпадающее меню "Ввод документов" из панели "Головное меню". Выбор этой команды запускает процедуру Invoice.
Set CstmCtrl = CstmPopUp1.Controls.Add(Type:=msoControlButton) CstmCtrl.Caption = "Накладная" CstmCtrl.OnAction = "Module1.Invoice"
Метод Add позволяет вставлять в меню и встроенные команды. Для этого при вызове задайте значение параметра Id, равное числовому идентификатору данной команды в Office 2000. Поскольку в Office 2000 количество команд доходит до 4000, мы приведем здесь лишь два фрагмента из начала таблицы идентификаторов, включающих, в частности, некоторые популярные команды из меню File и Edit.
2 | &Spelling | Орфография | 19 | &Copy | Копировать |
3 | &Save | Сохранить | 21 | &Cut | Вырезать |
4 | Печать | 22 | &Paste | Вставить | |
18 | &New | Создать | 23 | &Open | Открыть |
Взгляните, как в меню "Проверки" из панели "Головное меню" можно вставить команду проверки правописания Spelling.
Set mySpell = CommandBars("Головное меню").Controls("Проверки") _ .Controls.Add(Id:=2)
Подменю (или дочернее меню) примыкает к боковой стороне другого меню - родительского - на уровне той команды родительского меню, которая является заголовком подменю. Подменю можно добавлять как к выпадающим меню, так и к другим подменю и к всплывающим меню. Сначала добавляется пустое подменю, затем в него вставляются команды. Добавить подменю можно двумя способами: с помощью диалогового окна Настройка и через вызов метода Add в VBA.
Рассмотрим вначале визуальный способ. Для добавления подменю нужно, как и раньше, активизировать диалоговое окно Настройка и сделать модифицируемое меню видимым. После этого нужно действовать так.
На вкладке Команды в списке Категории выберите команду Новое меню.Выберите команду Новое меню справа в списке Команды и перетащите ее в то место меню, куда нужно добавить подменю. Чтобы выпадающее меню открылось, показав уже имеющиеся в нем элементы, протащите Новое меню через имя выпадающего меню. При этом горизонтальная черта будет отмечать то место в списке рубрик выпадающего меню, куда попадет заголовок нового подменю.Щелкните правой кнопкой мыши Новое меню и введите заголовок нового подменю в поле Имя появившегося окна. Одновременно можно задать ключ быстрого доступа к нему, поставив символ "&" перед той буквой, которая будет этим ключом.
Теперь при щелчке заголовка подменю справа или слева от него появится пустое подменю.
Чтобы добавить новое подменю программно, к объекту, представляющему родительское выпадающее меню, нужно применить метод Add коллекции CommandBarControls. В качестве параметра Type (Тип) нужно использовать значение msoControlPopup.
В следующем примере в конец выпадающего меню "Ввод документов", расположенного на панели меню "Головное меню", добавляется подменю "о движении товаров".
Dim CstmPopUp1 As CommandBarPopup Set CstmPopUp1 = CstmCtrl.Controls.Add(Type:=msoControlPopup) CstmPopUp1.Caption = " о движении товаров"
Добавление команды с помощью окна Настройка в собственное или встроенное меню зависит от приложения Office 2000, в котором оно выполняется.
. Microsoft Access. Чтобы добавить команду, запускающую на исполнение макрос, нужно выполнить те же действия, что и при добавлении встроенной команды. При этом в списке Категории выберите Все макросы (All Macros) и перетащите имя нужного макроса из списка Команды в меню. Вызов процедуры-функции вставляется, как и встроенная команда. Выберите в списке Категории нужную категорию и перетащите затем нужный элемент из списка Команды в свое меню. Щелкнув этот элемент правой кнопкой мыши, в появившемся меню выберите команду Свойства (Control Properties). На экране появится окно с тем же именем. В поле Подпись (Caption) этого окна замените прежнее имя функции на новое (это будет имя команды в меню). В поле Действие (On Action) введите выражение =имя-функции(), запускающее VBA-функцию на исполнение.Microsoft Excel. Действуя, как и при вставке встроенной команды, выберите в списке Категории команду Макрос (Macros ) и перетащите элемент Настраиваемая команда меню (Custom Menu Item) из списка Команды в меню. Щелкните эту команду правой кнопкой мыши и выберите в появившемся меню команду Назначить макрос (Assign Macro). Затем введите в поле Имя (Macro Name) имя макроса, который должен запускаться командой меню.Microsoft Word и Microsoft PowerPoint. Как при вставке встроенной команды, выберите в списке Категории команду Макрос и перетащите в меню имя нужного макроса из списка Команды.
В диалоговом окне Настройка сделайте модифицируемое меню видимым, а затем:
На вкладке Команды выберите в списке Категории категорию добавляемой команды - все команды данной категории будут показаны в списке Команды.Выберите в списке Команды команду и перетащите в то меню или подменю, куда она добавляется. Чтобы выпадающее меню или подменю открылось, показав имеющиеся в нем элементы, протащите команду через заголовок соответствующего выпадающего меню или подменю. Горизонтальная черта отмечает место в списке команд выпадающего меню, куда попадет заголовок нового подменю, когда Вы отпустите кнопку мыши.
Скопировать команду можно и иначе: выведите на экран меню с нужной командой и перетащите ее в свое меню при нажатой клавише Ctrl.
Чтобы добавить новое меню программно, нужно использовать метод Add коллекции CommandBarControls, применив его к объекту типа CommandBar, который представляет панель нашего меню. Этот метод позволяет помещать на панель кнопки (CommandBarButton), комбинированные списки (Command-BarComboBox) и выпадающие меню (ComandBarPopup). Его вызов имеет вид:
выражение.Add(Type, Id, Parameter, Before, Temporary)
где выражение должно возвратить объект типа CommandBarsControl, параметры в скобках необязательны. Параметр Type (Тип) задает тип добавляемого объекта. Его значение msoControlPopup указывает, что добавляемый управляющий элемент - выпадающее меню. Для пользовательских меню параметры Id и Parameter можно опустить. Значение аргумента Before - число, указывающее положение нового элемента в последовательности элементов панели (если его нет, элемент помещается в конец). Определить имя и ключ быстрого доступа к созданному меню можно, задав значение свойства Caption.
Взгляните, как к панели "Головное меню" добавить выпадающее меню "Ввод документов" с ключом быстрого доступа "B":
Dim CstmCtrl As CommandBarControl Set CstmCtrl = CstmBar.Controls _ .Add(Type:=msoControlPopup, Before:=1) CstmCtrl.Caption = "&Ввод документов"
Добавлять новые меню (подменю) и команды к существующим меню, встроенным в Office 2000 или созданным пользователем, также можно двумя способами: используя диалоговое окно Настройка или VBA. Рассмотрим, как добавить выпадающее меню к существующей панели меню (головному меню).
Разделение групп логически связанных команд меню горизонтальными линиями позволяет пользователям более эффективно работать с большими меню, содержащими разнотипные команды. Сами разделяющие линии командами не являются. Установить или убрать их можно в диалоговом окне Настройка. Для этого в этом окне сделайте видимым модифицируемое меню. Затем щелкните правой кнопкой мыши команду, над которой хотите провести линию. В появившемся меню выберите команду Начало группы (Begin Group). Убирается линия аналогично.
Ту же задачу разбиения команд на группы можно решить из VBA, присвоив значение True свойству BeginGroup (Начало группы) объекта, представляющего команду, которая должна открывать очередную группу. Чтобы убрать разделяющую линию, присвойте этому свойству False. Вот как выделить группу команд меню "Ввод документов", начинающуюся со вставленной команды "ввод накладной":
Set InvCommand = CommandBars("Головное меню").Controls("Ввод документов") _ .Controls("ввод накладной") InvCommand.BeginGroup = True
Во всех приложениях Office 2000 можно спроектировать собственное головное меню визуально, используя для этого диалоговое окно Настройка. Для его вызова нужно в меню Вид выбрать команду Панели инструментов (Toolbars), а затем в появившемся подменю - команду Настройка.
Новое меню создается так:
Щелкните кнопку Создать (New) на вкладке "Панели инструментов".В появившемся окне "Создание панели инструментов" (New Toolbar) введите имя создаваемого меню и щелкните кнопку OK. На экране появится плавающее меню с заданным именем. При работе в Access появляются дополнительные возможности, позволяющие установить свойства панели, что нельзя сделать в других приложениях - Word, Excel, Power Point. При работе в Access:Щелчком кнопки Свойства (Properties) выведите на экран окно "Свойства панели инструментов" (Toolbar Properties).Установите в списке Тип (Type) команду "Строка меню" (Menu Bar) в качестве типа создаваемой панели и закройте окно.
Вот, как выглядит окно свойств:
Имя нового меню появится в списке Панели инструментов на вкладке Панели инструментов.
В окне "Свойства панели инструментов" можно задать и другие свойства создаваемого меню. В частности, свойство закрепление (Docking) и опция перемещение (Allow Moving) позволяют разрешить или полностью или частично запретить перемещение меню по экрану. Для головного меню приложения естественно установить постоянное место на экране. Опция настройка (Allow Customizing) позволяет после завершения создания меню отключить возможность его модификации, а если отключить опцию отображение/скрытие (Allow Showing/Hiding), то меню будет на экране постоянно.
Это способ добавления меню или команды более нагляден, и в отличие от процедуры создания нового меню, его можно применять в любом приложении Office 2000, а не только в Access. Откройте диалоговое окно Настройка, а затем:
Если модифицируемого меню на экране нет, щелкните кнопку выбора рядом с именем изменяемого меню в списке Панели инструментов на одноименной вкладке Панели инструментов.В списке Категории (Categories) на вкладке Команды (Commands) выберите Новое меню (New Menu).Выберите команду Новое меню (New Menu) справа в списке Команды (Commands) и перетащите ее в то меню, к которому Вы хотите добавить новое меню. При этом знак I отмечает то место в меню, куда попадет имя нового меню, когда Вы отпустите кнопку мыши.Щелкните правой кнопкой мыши Новое меню (New Menu), и введите имя этого меню в поле Имя (Name) появившегося окна. Одновременно можно задать ключ быстрого доступа к этому меню, поставив символ "&" перед буквой, которая будет этим ключом.
Если теперь щелкнуть имя нового меню, на экране под ним появится пустой прямоугольник. Ниже мы покажем, как вставлять в созданное меню новые команды.
Во всех приложениях Office 2000 можно спроектировать собственное головное меню визуально, используя для этого диалоговое окно Настройка. Для его вызова нужно в меню Вид выбрать команду Панели инструментов (Toolbars), а затем в появившемся подменю - команду Настройка.
Новое меню создается так:
Щелкните кнопку Создать (New) на вкладке "Панели инструментов".В появившемся окне "Создание панели инструментов" (New Toolbar) введите имя создаваемого меню и щелкните кнопку OK. На экране появится плавающее меню с заданным именем. При работе в Access появляются дополнительные возможности, позволяющие установить свойства панели, что нельзя сделать в других приложениях - Word, Excel, Power Point. При работе в Access:Щелчком кнопки Свойства (Properties) выведите на экран окно "Свойства панели инструментов" (Toolbar Properties).Установите в списке Тип (Type) команду "Строка меню" (Menu Bar) в качестве типа создаваемой панели и закройте окно.
Вот, как выглядит окно свойств:
Имя нового меню появится в списке Панели инструментов на вкладке Панели инструментов.
В окне "Свойства панели инструментов" можно задать и другие свойства создаваемого меню. В частности, свойство закрепление (Docking) и опция перемещение (Allow Moving) позволяют разрешить или полностью или частично запретить перемещение меню по экрану. Для головного меню приложения естественно установить постоянное место на экране. Опция настройка (Allow Customizing) позволяет после завершения создания меню отключить возможность его модификации, а если отключить опцию отображение/скрытие (Allow Showing/Hiding), то меню будет на экране постоянно.
Это способ добавления меню или команды более нагляден, и в отличие от процедуры создания нового меню, его можно применять в любом приложении Office 2000, а не только в Access. Откройте диалоговое окно Настройка, а затем:
Если модифицируемого меню на экране нет, щелкните кнопку выбора рядом с именем изменяемого меню в списке Панели инструментов на одноименной вкладке Панели инструментов.В списке Категории (Categories) на вкладке Команды (Commands) выберите Новое меню (New Menu).Выберите команду Новое меню (New Menu) справа в списке Команды (Commands) и перетащите ее в то меню, к которому Вы хотите добавить новое меню. При этом знак I отмечает то место в меню, куда попадет имя нового меню, когда Вы отпустите кнопку мыши.Щелкните правой кнопкой мыши Новое меню (New Menu), и введите имя этого меню в поле Имя (Name) появившегося окна. Одновременно можно задать ключ быстрого доступа к этому меню, поставив символ "&" перед буквой, которая будет этим ключом.
Если теперь щелкнуть имя нового меню, на экране под ним появится пустой прямоугольник. Ниже мы покажем, как вставлять в созданное меню новые команды.
VBA позволяет изменять и настраивать систему меню приложения динамически во время его работы. Предоставляемые для этого возможности велики. Вы можете заменять одну панель меню на другую, удалять команды меню или делать их временно недоступными ("серыми"), переименовывать команды. Рассмотрим эти возможности подробнее.
Диалоговое окно Настройка позволяет просто добавить (скопировать) любое из встроенных меню к меню, которое Вы создаете. При этом исходное встроенное меню не изменяется. Для этого в диалоговом окне Настройка сделайте модифицируемое меню видимым, а затем:
Выберите в списке Категории вкладки Команды команду Встроенные меню (Builtin Menus).Выберите в списке Команды имя нужного встроенного меню и перетащите его на нужное место в панель меню, к которой Вы хотите добавить выбранное встроенное выпадающее меню. Знак I отмечает место на панели, куда попадет встроенное меню.
Есть и другой способ копирования встроенного меню: выберите его на его собственной панели и перетащите в свою панель меню при нажатой клавише Ctrl.
Восстановить можно только встроенный удаленный элемент меню. Как и другие действия над меню, это делается в окне Настройка или из VBA. Если при этом восстановится заголовок выпадающего меню или подменю, вместе с ним восстановится само меню и все его потомки.
Как всегда, в диалоговом окне Настройка нужно сделать модифицируемое меню видимым. Затем, щелкнув правой кнопкой мыши заголовок выпадающего меню или подменю, которое нужно восстановить, в появившемся меню выберите команду Сброс (Reset).
Чтобы восстановить встроенную панель меню, перейдите на вкладку Панели инструментов окна Настройка, выберите в списке Панели инструментов имя восстанавливаемой панели меню и щелкните кнопку Сброс(Reset).
Восстановить встроенный компонент меню программно можно методом Reset. Например, следующий оператор восстанавливает выпадающее подменю Favorites из панели меню Web:
CommandBars("Web").Controls("Favorites").Reset
А вот как восстановить всю панель меню Menu Bar из Word:
CommandBars("Menu Bar").Reset
Эта коллекция обладает только традиционными свойствами и методами. Единственное, что следует рассмотреть - это метод Add и его параметры:
Function Add([Type], [Id], [Parameter], [Before], [Temporary]) As CommandBarControl
Метод позволяет добавлять новые элементы в коллекцию. Параметр Type устанавливает тип элемента и тем самым, как мы говорили ранее, определяет и класс этого элемента, возвращаемый функцией Add. Если значением Type является константа msoControlButton, то возвращается объект класса CommandBarButton, для значений: msoControlEdit, msoControlDropdown, msoControlComboBox - возвращается объект CommandBarComboBox и, наконец, если тип имеет значение msoControlPopup, то возвращаемый класс объекта - CommandBarPopup. Параметр Id задает идентификатор встроенного элемента, добавляемого в коллекцию. Если он опущен, то на панели появится пользовательский, пустой элемент, свойства которого позднее следует определить. Параметр Parameter для встроенных элементов используется приложением при запуске команды, для пользовательских элементов может хранить некотор ую информацию об элементе. Параметр Before задает местоположение элемента на панели, если он опущен, элемент добавляется в конец панели. Значение True булева параметра Temporary говорит о том, что элемент является временным, он будет удален с панели при закрытии приложения. По умолчанию элементы являются постоянными.
Мы уже говорили, что создаваемые элементы панели могут быть одного из трех классов. Кроме того, все они принадлежат к объединяющему классу CommandBarControl. Мы не будем подробно останавливаться на всех свойствах и методах, как отдельных классов, так и объединяющего элементы класса. Рассмотрим только, как решить главную для команд задачу - выполнить некоторую процедуру в ответ на выбор команды меню или щелчок кнопки. Действия, выполняемые командой, должны быть запрограммированы в виде макроса на языке VBA. Напомним, что макрос - это процедура без параметров. Однако есть некоторый способ передачи информации в исполняемый макрос. Для этого можно использовать параметр Parameter, задаваемый при создании элемента или, что удобнее, свойство Parameter. Конечно, для всех встроенных элементов макрос, задающий команду, уже написан. Но для собственных элементов его нужно написать самому, а затем макрос связать с элементом. Свойство OnAction, которым обладают все элементы панели, позволяет связать элемент с исполняемым макросом. Формально свойство является строкой, задающей имя макроса, который и будет вызываться в ответ на выбор пользователя.
Пришла пора рассказать о наиболее "почтенных" представителях пользовательского интерфейса - меню и инструментальных кнопках. Интерфейс начинался с меню и до сих пор практически ни одно приложение без него не обходится. Все приложения Office 2000 обладают мощной встроенной системой меню и набором инструментальных панелей. И все эти средства доступны и при работе конечного пользователя с документами Office 2000. Но надо иметь в виду, что для "серьезных" приложений, требующих программирования и являющихся предметом нашей книги, только встроенными средствами не обойтись. Все основные приложения Office 2000 - Excel, Word, PowerPoint и Access разделяют на этапе проектирования единые средства настройки, позволяющие как модификацию встроенных, так и создание пользовательских панелей меню и инструментов. На этапе программирования во всех приложениях также используется единый набор объектов, корневым из которых является коллекция CommandBars, входящая в состав библиотеки Office. Вот как выглядит ее стр уктура:
Элементами коллекции являются объекты класса CommandBar, каждый из которых представляет панель команд. Но то, что расположено на панели: меню, подменю, команды меню, кнопки,- все это задается другим объектом - коллекцией CommandBarControls. Объект CommandBar имеет свойство Controls, возвращающее эту коллекцию. Итак, CommandBar (панель команд) задает любую панель, на которой расположено как меню, так и инструментальные кнопки. На каждой панели, как известно, располагается некоторое число элементов. Они и составляют коллекцию CommandBarControls с элементами класса CommandBarControl. Конечно, эти элементы разнотипны и, по сути, являются объектами трех разных классов: CommandBarButton, CommandBarPopup и CommandBarComboBox. Класс, которому будет принадлежать элемент, определяется в момент его создания. В этот же момент определяется и тип элемента. По типу однозначно определяется клас с, но обратное утверждение неверно, например, элемент класса CommandBarComboBox имеет несколько возможных типов.
Поясним, в чем сущность этих трех классов, в каком случае элемент следует относить к тому или иному классу. Прежде всего, заметим, что "панельные" элементы могут иметь свою сложную внутреннюю структуру. К примеру, у каждого пункта главного меню обычно древовидная структура, при его раскрытии появляются терминальные вершины (команды меню) и вершины - подменю, которые, в свою очередь, содержат терминальные вершины и подменю. Вы ошибаетесь, если полагаете, что инструментальные кнопки можно только щелкать, и что они просто устроены. В Office 2000 в роли кнопок могут выступать такие элементы как ComboBox, TextBox и ListBox. Класс CommandBarButton определяет терминальную вершину (кнопку или команду меню), CommandBarPopup - подменю, CommandBarComboBox - сложно организованные кнопки, заданные элементами управления. Заметьте, что объект PopUp (подменю) имеет свойство Controls, возвращающее коллекцию CommandBarControls , что и обеспечивает требуемую иерархию вложенности меню.
Система меню в Office 2000 включает головную строку меню (menu bar), обычно расположенную в верхней части активного окна. Оно постоянно находится на экране. Изменяться это меню может при переходе к другому активному окну или по командам из программ на VBA. Каждая команда головного меню является именем вертикально расположенного меню, выпадающего при выборе этой команды. Команда такого меню может быть именем подменю, при этом она отмечается направленной вправо стрелкой. Подменю появляется на экране справа или слева от родительского меню, когда пользователь выбирает команду с его именем.
Здесь в головном меню выбрана команда Вид (View), а в меню Вид - команда Панели инструментов (Toolbars), которая является именем соответствующего подменю. В подменю Панели инструментов выделена команда Настройка (Customize), которая будет неоднократно упоминаться далее в этой лекции, поскольку с ее помощью можно производить многие действия, связанные с изменениями меню. Меню Вид называется родительским по отношению к подменю Панели инструментов, а меню Панели инструментов - дочерним по отношению к меню Вид. Вообще команды подменю тоже могут быть именами отдельных меню и т. д. Таким образом, меню приложений Office 2000 образуют иерархическую (древовидную) структуру. Корень этой структуры - головное горизонтально расположенное меню, его непосредственными потомками являются выпадающие меню, заголовки которых и образуют головное меню. Концевые вершины (листья) этой иерархии - непосредственно исполняемые команды (часто - это вызовы диалоговых окон), а пути от корня к вершинам проходят по заголовкам соответст вующих меню и подменю.
Трудно переоценить роль интерфейса пользователя в современных программах. Удачный или неудачный интерфейс во многом предопределяет успех или неудачу всей системы. В еще большей степени это относится к офисным системам, пользователи которых не искушены в программировании и зачастую не имеют большого опыта работы на компьютере. Разработчик таких систем обычно сосредоточивает усилия на создании дружелюбного и удобного интерфейса пользователя. Удобство интерфейса - вещь субъективная: то, что нравится одному пользователю, может оказаться неудобным и даже совершенно неприемлемым для другого. Поэтому при проектировании системы желательно заранее включать в нее возможность настройки интерфейса на различные категории пользователей. Приложения Office 2000 позволяют без труда перестраивать меню и панели инструментов, управлять параметрами окон, выбирать нужные форматы представления данных на экране (цвет, шрифт, размер и т. д.), создавать собственные диалоговые окна и размещать на них разнообразные управляющие элементы. Возможность присоединения ActiveX -объектов к формам и документам сделало перечень элементов управления практически неограниченным, поскольку число ActiveX -объектов в доступных разработчикам библиотеках постоянно растет.
В этой и двух следующих лекциях мы рассмотрим ряд компонент VBA, связанных с проектированием интерфейса, которые и позволяют называть этот язык визуальным. В этой лекции мы изучим способы создания собственных меню. Эти возможности лучше всего поддержаны в Access, но и в других приложениях можно создавать собственные системы меню, как руками, так и с использованием VBA.
VBA позволяет динамически переименовывать команды меню, используя свойство Caption (Заголовок) изменяемой команды. Это может пригодиться, например, при настройке меню на язык пользователя. В следующем примере в англоязычной версии Office 2000 имя команды "Open Database" переводится на русский язык.
CommandBars("MyMenubar").Controls("File").Controls("Open Database") _ .Caption = "Открыть базу данных"
Другой способ - завести переменную, ссылающуюся на данную команду:
Set openData = CommandBars("My Menubar").Controls _ ("File").Controls("Open Database")
и затем использовать ее в программе для доступа к команде. При этом изменить заголовок можно так:
openData.Caption = "Открыть базу данных"
Option Explicit Public Sub CreateCustomMenu() Dim CstmBar As CommandBar Dim CstmPopUp1 As CommandBarPopup, CstmPopUp2 As CommandBarPopup Dim CstmCtrl As CommandBarControl Dim Exist As Boolean 'Выключаем все панели For Each CstmBar In CommandBars CstmBar.Enabled = False Next CstmBar 'Создаем, включаем и делаем видимой собственную панель Exist = False For Each CstmBar In CommandBars If CstmBar.Name = "Головное меню" Then Exist = True Exit For End If Next CstmBar If Not Exist Then Set CstmBar = CommandBars.Add(Name:="Головное меню", _ Position:=msoBarTop, MenuBar:=True, Temporary:=False) End If CstmBar.Enabled = True CstmBar.Visible = True 'Добавляем меню на панель Exist = False For Each CstmCtrl In CstmBar.Controls If CstmCtrl.Caption = "&Ввод документов" Then Exist = True Exit For End If Next CstmCtrl If Not Exist Then Set CstmCtrl = CstmBar.Controls _ .Add(Type:=msoControlPopup, Before:=1) CstmCtrl.Caption = "&Ввод документов" 'Добавляем две команды подменю Set CstmPopUp1 = CstmCtrl.Controls.Add(Type:=msoControlPopup) CstmPopUp1.Caption = " о движении товаров" Set CstmPopUp2 = CstmCtrl.Controls.Add(Type:=msoControlPopup) CstmPopUp2.Caption = " финансовых" 'Добавляем команду в каждое подменю Set CstmCtrl = CstmPopUp1.Controls.Add(Type:=msoControlButton) CstmCtrl.Caption = "Накладная" CstmCtrl.OnAction = "Module1.Invoice" Set CstmCtrl = CstmPopUp2.Controls.Add(Type:=msoControlButton) CstmCtrl.Caption = "Счет" CstmCtrl.OnAction = "Module1.Account" End If End Sub |
Пример 11.1. |
Закрыть окно |
Обобщим приведенные сведения по построению меню и создадим документ, в котором все встроенные меню будут отключены и создано собственное иерархическое меню. На верхнем уровне меню будет состоять из одного пункта, оно будет включать два подменю, каждое из которых содержит по одной команде. Приведем процедуру, реализующую создание такого меню:
Пример 11.1.
(html, txt)
Заметьте, вначале, используя свойство Enabled, были отключены все панели. Затем было сформировано головное меню, содержащее всего один пункт, с двумя подменю и командами. Обратите внимание, перед добавлением нового пункта, обычно делается проверка, а не был ли он уже добавлен. Подобная проверка позволяет избежать ошибок, возникающих при попытках добавить уже существующий пункт или удалить несуществующий. Чтобы наш пример был законченным, приведем процедуры, вызываемые в ответ на выбор команд меню Накладная и Счет:
Public Sub Invoice() MsgBox ("Накладная!") End Sub
Public Sub Account() MsgBox ("Счет!") End Sub
Вот как выглядит документ по завершении работы процедуры CreateCustomMenu:
В заключение, приведем процедуру, восстанавливающую стандартное окружение:
Public Sub ResetMainMenu() Dim CstmBar As CommandBar 'Включаем все панели For Each CstmBar In CommandBars CstmBar.Enabled = True Next CstmBar
Set CstmBar = CommandBars.Item("Menu Bar") CstmBar.Visible = True End Sub
В предыдущих лекциях в примерах и описании VBA использовалась заключительная англоязычная бета - версия Office 2000. При описании интерфейса я перешел на русифицированную бета - версию Office 2000. Я полагаю, что программисту должно быть все равно, с какой версией он работает, как называется соответствующий пункт меню "Сервис" или "Tools". Тем не менее, разумнее описывать интерфейс применительно к русифицированному варианту. Кроме того, это входило в мои планы тестирования этой версии Office 2000.
Новое меню в Excel, Word или PowerPoint обычно создается средствами VBA, поскольку в этих приложениях диалоговое окно Настройка не содержит кнопки Свойства. В Access тоже можно создать меню, используя VBA, но, все же, удобнее действовать описанным выше способом.
Новое меню создается методом Add коллекции CommandBars (Панели команд):
выражение.Add(Name, Position, MenuBar, Temporary)
где выражение - обязательное выражение, возвращающее объект CommandBars, а все параметры в скобках необязательны. Name задает имя нового меню; Position определяет его положение (значения-константы msoBarLeft, msoBarTop, msoBarRight, msoBarButtom определяют положение меню слева, вверху, справа или внизу окна, msoBarFloating задает "плавающее" меню, msoBarPopup указывает, что новое меню будет всплывающим). Значение True параметра MenuBar указывает, что новое меню заменит текущую активную строку меню (по умолчанию - False). Значение True параметраTemporary означает, что новое меню будет временным и исчезнет, когда закроется содержащее его приложение (по умолчанию - False).
В следующем примере создается новое меню "Головное меню"
Dim CstmBar As CommandBar Set CstmBar = CommandBars.Add(Name:="Головное меню", _ Position:=msoBarTop, MenuBar:=True, Temporary:=False)
Согласно существующим формальным и фактическим стандартам проектирования интерфейса, работа прикладной программы должна начинаться с активизации головного меню, которое находится в верхней части окна приложения. Собственное головное меню для прикладной системы можно спроектировать визуально - "руками", вызвав диалоговое окно Настройка (Customize), или используя VBA.
В меню объединяют последовательности, группы, наборы команд (рубрик), одну из которых может выбрать пользователь для совершения очередного действия. Как правило, названия команд в меню достаточно информативны, так что пользователь может легко найти нужную ему команду. Команды для решения близких задач можно объединить в группу, поместив их рядом в одном меню и отделив чертой от команд, решающих другие задачи. В одном меню команды объединяют на основе одного из двух принципов: либо это различные действия над одним объектом, либо однотипные действия над различными объектами. Первый принцип реализован в меню Файл (File) всех приложений Office 2000, объединяющем различные действия над основным объектом приложения: создание, открытие и закрытие, сохранение, пересылка и печать объекта. Меню Вставка (Insert) построено по другому принципу - действие "вставить" выполняется для различных объектов. Если вариантов исполняемых действий много, их структурируют, используя подменю - списки команд, появляющиеся правее или левее выбранной команды родительского меню. Еще один вид меню - контекстные (shortcut) меню, всплывающие при нажатии правой кнопки мыши в определенном контексте. В них можно объединять действия, допустимые (факультативно) в данном контексте. Доступ пользователя к команде меню можно ускорить, определив для нее "горячие" клавиши, нажатие которых эквивалентно выбору этой команды.
Мы уже рассмотрели основные свойства и методы коллекции CommandBars и ее объектов CommandBar, представляющих панели команд, на которых располагаются меню, подменю, кнопки и другие элементы, образующие коллекцию CommandBarControls. Рассмотрим работу с объектами, относящимися к меню. Эту работу, как правило, можно проводить двумя способами: "визуально", используя встроенные команды и диалоговые окна приложений Office 2000, или "программно", создавая в процедурах VBA объекты указанных классов, задавая и изменяя их свойства соответствующими методами.
Коллекция CommandBars обладает не только традиционными свойствами и методами, но и некоторыми специфическими свойствами. Давайте кратко познакомимся с большинством из них:
Property ActionControl As CommandBarControl вызывается обычно в одной из OnAction процедур и возвращает объект CommandBarControl, чье свойство Action связано с этой выполняемой процедурой. Если же такого объекта нет, то возвращается Nothing, что бывает при вызове этого свойства из обычной процедуры. Позволяет отключить доступ к объекту на время выполнения процедуры.Property ActiveMenuBar As CommandBar возвращает объект CommandBar, представляющий активную панель меню.Property DisplayKeysInTooltips As Boolean, DisplayTooltips As Boolean - если свойства имеют значения True, то на панели отображаются назначения "горячих" клавиш.Property LargeButtons As Boolean - значение True позволяет включить клавиши "большого" размера.Function Add([Name], [Position], [MenuBar], [Temporary]) As CommandBar. Метод Add позволяет программным путем добавить в коллекцию новую панель, дав ей имя Name. Параметр Position указывает расположение панели на экране. Его возможные значения: msoBarLeft, msoBarTop, msoBarRight, msoBarBottom указывают куда стыковочная панель будет причалена- вверху, справа, слева или снизу экрана. Значение msoBarFloating этого параметра указывает, что панель не является стыковочной и находится в плавающем состоянии. Значение msoBarPopup указывает, что новая панель создается для контекстного меню. Булев параметр MenuBar имеет значение True, когда новая панель заменяет существующую панель меню. Параметр Temporary позволяет это назначение сделать временным.Function FindControl([Type], [Id], [Tag], [Visible]) As CommandBarControl - Позволяет найти на панелях, входящих в коллекцию, элемент, удовлетворяющий критериям поиска. Параметры, являющиеся ключами поиска, могут быть опущены, достаточно задания одного из них.Sub ReleaseFocus() - Все панели теряют фокус.
В Office 2000 у этой коллекции появились новое свойство и новое событие:
Property AdaptiveMenus As Boolean. Позволяет включить или выключить адаптивные меню, - собственные меню, заменяющие стандартные.Event OnUpdate() - Событие возникает при любых изменениях командной панели - объекта CommandBar.
Вот основные свойства и методы самого объекта CommandBar, представляющего отдельную панель:
Property BuiltIn As Boolean Это булево свойство определено как для панели, так и для ее элементов, значение True указывает, что панель или элемент являются встроенными, False - определены пользователем.Property Context As String - позволяет установить или проверить контекст, определяющий местоположение хранения панели, то ли непосредственно с самим документом, то ли в другом возможном месте, зависящем от приложения. Это важная информация для корректной работы.Property Controls As CommandBarControls - можно сказать центральное свойство, возвращающее, как мы уже говорили, коллекцию элементов, располагаемых на панели.Property Enabled As Boolean, Visible As Boolean - тоже два центральных и широко используемых свойства. Первое позволяет выключить доступ к панели, обычно временно, второе делает панель вообще невидимой и тем более недоступной.Property Height As Long, Left As Long, Top As Long, Width As Long - типичные свойства графических элементов, в том числе для панели и ее элементов. Задают размеры элемента.Property Index As Long - возвращает порядковый номер элемента в коллекции.Property Name As String, NameLocal As String - имя панели или ее элемента, для встроенных панелей (элементов) имеют смысл два имени "родное" английское имя и локализованное.Property Position As MsoBarPosition - такое же свойство, как у коллекции панелей, но применяемое к отдельно взятой панели.Property Protection As MsoBarProtection - защищает панель от тех или иных действий пользователя. Значением свойства являются константы, определяющие, что конкретно нельзя делать с панелью, например, менять ее размеры или передвигать.Property Type As MsoBarType - возвращает тип панели.Sub Delete() - удаляет панельFunction FindControl([Type], [Id], [Tag], [Visible], [Recursive]) As CommandBarControl - такой же метод поиска элемента, как и описанный выше для коллекции, но поиск ограничен пределами одной панели.Sub Reset() - Восстанавливает установки, принятые по умолчанию, в частности конфигурацию встроенных панелей.Sub ShowPopup([x], [y]) - отображает контекстную панель в позиции, заданной курсором или параметрами X и Y, если они указаны.Также как и коллекция, этот объект приобрел новое булево свойство AdaptiveMenu
Удаление команд, подменю и меню позволяет упростить работу с приложением, приспособить его к нуждам отдельного пользователя. В Office 2000 можно удалять встроенные и пользовательские выпадающие меню из панелей меню, дочерние подменю из родительских меню, команды из всех видов меню. Единственное, чего сделать нельзя - удалить встроенную панель меню или встроенное всплывающее меню, даже если из них удалены все команды. Главное, что этого делать не нужно ни в коем случае. Панель можно сделать только недоступной или невидимой, что мы и демонстрировали в наших примерах.
Удаленные из меню встроенные подменю и команды можно восстановить в нужный момент. Собственные же удаленные подменю и команды придется при необходимости воссоздавать заново.
Для удаления компонента меню нужно в диалоговом окне Настройка модифицируемое меню сделать видимым, щелкнуть правой кнопкой мыши удаляемый элемент и в появившемся меню выбрать команду Удалить (Delete).
Чтобы удалить целиком пользовательскую панель меню, нужно перейти на вкладку Панели инструментов диалогового окна Настройка и, выбрав в списке Панели инструментов имя удаляемой панели меню, щелкнуть кнопку Удалить.
Для удаления компонента меню используется метод Delete (Удалить). Этот оператор, например, удаляет выпадающее подменю Favorites из панели меню Web:
CommandBars("Web").Controls("Favorites").Delete
Собственную (пользовательскую) панель меню "Головное меню" можно целиком удалить оператором:
CommandBars("Головное меню").Delete
Иногда удобней управлять доступом пользователя к командам меню, не скрывая и восстанавливая их на экране, а отключая реакции на их выбор и нажатие. Такие команды видны на экране, но отличаются от активных команд своим тусклым, "серым" видом. Для управления доступом к компонентам меню служит булево свойство Enabled (Включен). Если оно равно True, соответствующий компонент (команда, выпадающее меню или подменю) доступен - False делает компонент недоступным ("серым"). Установив для свойства Enabled подменю значение False, можно сделать недоступными все его команды. Так можно управлять доступом к собственным компонентам меню. Для встроенных компонентов меню переустановить свойство Enabled нельзя. Сделаем недоступной пользовательскую команду "Сохранить базу" выпадающего меню "Файлы" на панели "Worksheet Menu Bar" рабочего листа Excel.
CommandBars("Worksheet Menu Bar").Controls("Файлы") _ Controls.Add("Сохранить базу").Enabled = False
Все команды выпадающего меню "Файлы" можно сделать недоступными оператором:
CommandBars("Worksheet Menu Bar").Controls("Файлы").Enabled = False
Office 2000 предоставляет широкие возможности для настройки и модификации меню приложений. Пользователи могут создавать новые головные меню, добавлять команды в уже существующие меню и связывать с ними новые подменю. Можно также создавать новые и изменять существующие контекстные меню. Есть средства, позволяющие в любой момент восстановить первоначальную систему меню.
Возникают вопросы: когда создавать свою собственную систему меню, а когда лишь модернизировать систему приложения? Общий совет Microsoft состоит в том, что если добавления или изменения невелики, то следует модернизировать систему меню, а при существенных изменениях (например, добавлении нескольких новых меню и подменю) целесообразно создавать собственную систему меню. Разумеется, в этом случае следует принимать во внимание будущих пользователей создаваемой прикладной офисной системы, их образование, квалификацию, опыт работы с компьютером и т.д. Для "среднего" пользователя - типичного сотрудника типичной организации - прикладная система над Excel или Access, видимо, должна иметь собственный интерфейс, лишь в небольшой степени использующий встроенные меню, панели инструментов и диалоговые окна Office 2000. Поэтому в большинстве случаев разработчику следует создавать свое головное меню и, возможно, панель инструментов, перекрывающие частично или полностью на экране головное меню и панель инструментов соот ветствующего приложения Office 2000. Другими вариантами построения интерфейса могут быть собственные диалоговые окна или расположение управляющих элементов непосредственно на поверхности основных документов (например, на рабочих листах Excel).
Office 2000 позволяет добавлять команды к любым встроенным и пользовательским меню, а также изменять внешний вид, группировать и визуально отделять одну группу команд от другой.
Чтобы на экране показалась новая панель меню вместо текущей, задайте значение True свойству Visible объекта CommandBar, представляющего панель меню, которая должна появиться. Новая панель меню заменит прежнюю активную панель на экране. Чтобы восстановить прежнюю панель, при завершении работы программы нужно задать свойству Visible значение False.
В Excel и PowerPoint для замены основной панели приложения применяется процедура, обрабатывающая событие, после которого должна появиться новая панель или макрос. В Word можно обеспечить вывод собственной панели меню при запуске приложения, если заранее активизировать ее и сохранить в проекте Normal. Тогда при следующем запуске эта панель появится на экране как основная. Другой вариант - установить свойство Visible в процедуре обрабатывающей событие Open.
Диалоговые окна (формы) и элементы управления составляют основу современного визуального интерфейса. Все эти элементы и технология работы с ними в основном стандартизованы и являются похожими для разных платформ и программных сред. Поэтому не удивительно, что приложения Excel, Word и PowerPoint разделяют единые объекты, задающие диалоговые окна и элементы управления. Эти объекты помещены в специальную библиотеку MSForms. Несколько особняком стоит Access. И здесь все доступно, но по-своему.
В этом параграфе мы дадим краткий обзор основных объектов библиотеки MSForms и остановимся лишь на некоторых моментах работы с ними. Изложение, принятое здесь, предполагает, что читатель, так или иначе, уже работал с диалоговыми окнами и элементами управления. С другой стороны, этот материал можно рассматривать, как вводный, дающий общее представление о проблеме. Далее в этой лекции он рассмотрен более подробно со многими деталями и примерами.
Выделим некоторые основные моменты, которые следует иметь в виду при создании визуального интерфейса:
Все загруженные диалоговые окна представляют коллекцию UserForms. Формально, это глобальная внутренняя переменная, - Вы не найдете UserForms в окне просмотра объектов. Тем не менее, это нормальная коллекция со стандартными методами и свойствами, - метод Item позволяет по имени или номеру добраться до любого ее элемента, а метод Add добавляет новое диалоговое окно (форму) в коллекцию. Элемент коллекции - объект класса UserForm задает отдельное окно.
Для каждого типа элементов управления в библиотеке MSForms имеется класс объектов, имя которого совпадает с именем элемента управления (его типа). Например, есть классы SpinButton и TextBox.
Конечно, диалоговые окна создаются, как правило, не программно, а визуально. Вначале создается само окно, а затем оно заселяется элементами управления. Этот этап называется этапом проектирования и его следует отличать от этапа выполнения, когда приложение выполняется и конечный пользователь взаимодействует с приложением, в частности, через диалоговые окна и их элементы управления.
Важно понимать, что как только Вы визуально создали диалоговое окно, как только Вы визуально поместили в него тот или иной элемент управления, - в этот же самый момент автоматически в программе появляется объект соответствующего класса и с этим объектом можно работать, вызывая его методы и изменяя его свойства.
На этапе проектирования, используя окно свойств, можно задать большинство свойств, как самого диалогового окна, так и всех элементов управления, помещенных в это окно. Автоматически, конечно же, меняются и свойства соответствующего объекта. Заметьте, что есть еще две возможности изменения свойств этих объектов. Свойства может менять конечный пользователь. Заметьте, что элементы управления именно для этого и существуют, чтобы конечный пользователь мог определять некоторые (но не все) свойства, например, пользователю разрешается вводить текст в окна редактирования. Но есть и третья возможность - изменение свойств программным путем. Как правило, все свойства, доступные конечному пользователю, либо доступные на этапе проектирования, доступны для изменения программным путем.
Никаких проблем с программированием не возникает, - есть обычные объекты, у которых можно менять или проверять некоторые свойства и вызывать некоторые из их методов. Единственно следует помнить, что объекты могут создаваться автоматически (но могут и программно) и имеют видимое отображение на экране дисплея.
Есть все-таки одна проблема: куда помещать программный код? Ведь методы объектов жестко запрограммированы и не подлежат изменениям. К счастью есть у объектов события и обработчики событий надо программировать самому. Именно сюда и помещают код. Обработчик события может быть достаточно сложным и по ходу своей работы может вызывать десяток, другой локальных процедур и функций. Как правило, события задают реакцию на действия конечного пользователя, - ответом может быть изменение свойств объектов, вызов их методов, появление новых элементов управления и переход к новым диалоговым окнам.
Поговорим об отладке.
Написание обработчиков событий следует относить, по-видимому, к этапу проектирования. Когда этот этап закончен, - окно создано и заселено элементами, их свойства установлены, обработчики событий написаны, - возникает естественный вопрос " А будет ли все это правильно работать?" Чтобы вести отладку, можно, конечно, перейти в режим выполнения приложения. Однако это не эффективно, лучше вести локальную отладку - для этого достаточно выбрать команду Run Sub/UserForm из меню Run в VBA редакторе. Заметьте, что для отображения формы в режиме выполнения должен быть вызван ее метод Show.
Несколько слов следует сказать о методах Show, Hide и Load объекта UserForm. Метод Load загружает диалоговое окно и делает его доступным для программирования (объект определен). Но окно не отображается на экране дисплея и конечный пользователь не может работать с ним и его элементами. Чтобы окно сделать видимым, нужно вызвать его метод Show, чтобы видимое окно спрятать - метод Hide.
Можно прятать не только само окно, но и отдельные его элементы управления. Возможен, например, такой способ, - в одну половину "большого" окна поместить одни элементы управления, в другую - другие. Затем, в режиме выполнения динамически задать размеры окна так, чтобы они определяли только одну половину окна - тогда и видимы будут элементы только этой половины. Затем можно организовать переключение так, чтобы видимой была та или другая половина окна со своими элементами.
В предыдущем пункте мы говорили о том, как сделать некоторые элементы управления невидимыми, а, следовательно, и недоступными для изменений. Чаще, однако, применяется другая стратегия - видимые элементы можно сделать недоступными для изменений. Практически все элементы имеют булево свойство Enabled. Если дать ему значение True, то элемент считается включенным и доступен для изменения. Чтобы "выключить" его и сделать недоступным, достаточно изменить значение свойства Enabled на False. Обычно, программным путем проверяются контекстные условия, при выполнении которых элемент включается и является доступным для изменений.
Объекты, отвечающие за диалоговое окно и элементы управления, определены в период загрузки диалогового окна. Окно можно выгрузить, вызвав метод UnLoad, и тогда сам объект UserForm и все объекты, соответствующие вложенным в него элементам управления, становятся недоступны для программирования, - их свойства теряются. Важно понимать, что, зачастую, необходимо сохранять информацию о свойствах элемента управления долговременно в файлах постоянной памяти, - это и ввод, сделанный пользователем, и полученные в процессе работы результаты. В этих случаях в программу вводятся переменные, предназначенные для хранения значений тех или иных свойств элементов управления. Их срок жизни другой и не связан с загруженной формой. Поэтому перед применением UnLoad следует запомнить значения нужных свойств в переменных программы с возможной записью их в файл перед окончанием работы. Аналогично, при повторном сеансе свойства устанавливаются, используя сохраненные в файле значения.
Еще несколько слов о методах Load и UnLoad. Понятно, что это не совсем обычные методы, особенно Load - он не может быть методом, так как до его выполнения объект UserForm не существует, а не существующий объект не может вызывать никаких методов. Поэтому Load является оператором, синтаксис которого:
Load <объект класса UserForm>.
За компанию и UnLoad является оператором с аналогичным синтаксисом.
Диалоговые окна всегда модальные. Поэтому, когда пользователь заканчивает с ним работу и щелкает соответствующую кнопку выхода, то в обработчике этой кнопки должен быть предусмотрен оператор UnLoad.
При проектировании диалогового окна наряду с элементами управления, взятыми из стандартного ограниченного набора, в нем можно разместить ActiveX элементы, число которых не ограниченно и постоянно пополняется.
Созданное диалоговое окно в одном приложении можно экспортировать в другие приложения Office 2000. Но нужно быть осторожным - для корректной работы должны использоваться только средства VBA, не содержащие специфических для приложения объектов.
Если Вы спроектировали диалоговое окно, которое предполагается использовать и в последующих разработках, то можно на основе окна создать шаблон - для чего достаточно выполнить операцию, обратную проектированию, - перетащить созданное окно на инструментальную панель, содержащую элементы управления.
В Office 2000 определен весьма полезный элемент управления MultiPage. С его помощью достаточно просто организовать многостраничное диалоговое окно (окно с несколькими вкладками). Вначале в окно помещается этот элемент, устанавливается нужное число страниц, а затем, выбирая вкладку, соответствующую нужной странице, эта страница проектируется обычным способом.
Близким по духу к MultiPage является элемент управления TabStrip. Если первый задает несколько страниц с разнородным составом элементов управления, то второй определяет несколько страниц с одинаковым набором элементов. Типичная ситуация применения TabStrip - диалоговое окно отвечает за обработку данных нескольких отделов. Все формы представления данных по каждому отделу одинаковы и отличаются только содержащейся в этих формах информацией. TabStrip для каждого из отделов создает свою вкладку.
До сих пор мы говорили, что ActiveX и элементы управления можно располагать в диалоговых окнах. Эти окна представляют некоторый способ группирования элементов и придают структуру пользовательскому интерфейсу. Можно, однако, размещать все эти элементы и вне диалогового окна непосредственно на документе Word, рабочем листе или листе диаграмм Excel или на слайде презентации PowerPoint. Иногда, особенно когда число элементов невелико, так поступать удобнее - есть данные, а рядом - кнопка, щелчок которой обрабатывает эти данные. Злоупотреблять такой возможностью мы, правда, не рекомендуем.
На панели элементов находятся пиктограммы не всех элементов управления, доступных в Office 2000. Доступ к дополнительным элементам управления Вы получите, щелкнув правой кнопкой панель элементов и выбрав в появившемся контекстном меню команду Дополнительные элементы (Additional Controls). На экране появится одноименное окно со списком доступных элементов управления (Available Controls).
В этом списке отмечены элементы, находящиеся в данный момент на панели инструментов. Отметив в списке нужные дополнительные элементы, и выйдя из этого окна, Вы увидите их на панели инструментов и сможете использовать при создании своих диалоговых окон.
Для упрощения написания кода процедур VBA позволяет в качестве имени текущего диалогового окна применять ключевое слово Me (это похоже на использование указателя текущего объекта This в С++). В частности, в предыдущем примере вместо оператора:
With frmInit
можно было использовать:
With Me
Из процедур обработки событий можно менять свойства не только отдельных элементов управления, но и всего окна. В качестве примера рассмотрим динамическое изменение его размеров. Ранее мы уже говорили о том, что, изменяя размеры окна, можно скрывать те или иные элементы управления. Сейчас продемонстрируем это на примере. На стадии проектирования разместим в окне элементы управления, которые при первоначальном открытии окна не должны быть видны, но должны появиться в процессе работы пользователя с этим окном. Пусть в форме Cutting есть командная кнопка "Получить данные", и поля ввода "Доходы" и "Расходы" При открытии окна поля ввода недоступны, что достигается "отсечением" нижней части формы в процедуре инициализации. Вот как выглядит обработчик события Initialize нашей формы:
Private Sub UserForm_Initialize() 'Отсечение нижней части формы Me.Height = 90 End Sub
Так выглядит форма при ее открытии:
После щелчка командной кнопки обработчик события Click восстанавливает размер, заданный при проектировании формы. Он задает также и значения скрытых ранее полей:
Private Sub CommandButton1_Click() With Me 'Установить нормальную высоту формы .Height = 200 'Задать значения ранее не видимых полей .Доходы = 1570 .Расходы = 1500 End With
End Sub
А так выглядит эта же форма после щелчка командной кнопки:
Рассматривая общие объекты, используемые при организации пользовательского интерфейса, нельзя не упомянуть коллекцию Dialogs, которую можно использовать в приложениях Word и Excel. Элементы этой коллекции - объекты класса Dialog представляют встроенные в приложение диалоговые окна, появляющиеся по ходу работы с документами. Из этой коллекции ничего нельзя удалить и ничего в нее нельзя добавить. В любой момент можно только открыть любое из существующих встроенных диалоговых окон и предоставить пользователю возможность работы с ним, например, открыть файл или организовать поиск нужной информации. Чтобы добраться до нужного диалогового окна, используется обычная конструкция: Dialogs (<имя окна>), где имя окна задается константой. Все имена констант строятся по одному принципу, - они начинаются с префикса wdDialog или xlDialog (для Word и Excel соответственно), а затем идет имя окна. В приложении Word это полное имя, включающее все меню, которые надо открыть при вызове диалогового окна "вручную". Так, например, для открытия диалогового окна "Open" из меню File в приложении Word следует вызвать метод Show следующим образом:
Dialogs(wdDialogFileOpen).Show
Сразу же появится окно:
В Excel этот же вызов будет иметь вид:
Application.Dialogs(xlDialogOpen).Show
Заметьте, что в первом случае - это глобальный объект и поэтому его можно вызывать непосредственно, в Excel же необходимо указание корневого объекта Application, чье свойство Dialogs и возвращает коллекцию Dialogs. Но зато в Excel достаточно короткого имени для вызова диалогового окна. Метод Show открывает диалоговое окно и позволяет пользователю работать в нем. В зависимости от того, какую кнопку нажал пользователь при выходе из окна, возвращается результат: в Excel это True или False (нажаты кнопки OK или Cancel), в Word можно точнее проанализировать, какая кнопка была нажата. Метод Show - основа работы с диалоговыми окнами, по сути больше ничего и не нужно: в нужный момент открывается нужное диалоговое окно, пользователь работает в нем и по закрытии можно понять, успешно ли закончилась его работа.
Устанавливать программно новые значения свойств элементов управления можно не только при инициализации диалогового окна, но и во время работы пользователя (и системы) в нем. В любой процедуре обработки события, связанного со всем диалоговым окном или его отдельным элементом, можно присвоить значение свойству или вызвать метод любого управляющего элемента. Например, эти команды изменяют текст в окне редактора и снимают флажок в окне предыдущего примера:
Public Sub ChangeForm() With Me .MyText.Text = "Нелюбимый цвет:" 'новый текст в редакторе .lstColors.ListIndex = 1 'черный .chkGood.Value = False 'отключение флажка End With
End Sub
Благодаря возможности подобных изменений система может гибко реагировать на действия пользователя и использовать одно диалоговое окно для решения нескольких связанных или однотипных задач.
Диалоговые окна служат для обмена информацией между пользователем и документом. При открытии формы с заранее спроектированными свойствами элементов управления и после ее инициализации пользователь попадает в мир ее объектов. В этом мире он может выполнять разные действия, вводя требуемые данные, выбирая нужные ему опции и щелкая те или иные командные кнопки. В ответ на изменения, совершаемые пользователем, могут вызываться обработчики событий, которые в свою очередь производят изменения свойств объектов, как самой формы, так и объектов документа. Во многих случаях, изменения, сделанные в результате взаимодействия должны быть сохранены перед тем, как форма будет закрыта, с тем, чтобы их можно было восстановить при последующих открытиях формы. Для этого можно использовать рабочую память самого приложения (ячейки рабочих листов в Excel, записи БД в Access, текст документа в Word), внешние дисковые файлы или переменные уровня модуля.
Приведем сейчас пример уже знакомой нам формы, дополненной командными кнопками Save и Reset, обработчики события Click которых позволяют сохранить текущее состояние элементов управления и восстановить его в нужный момент. Для хранения информации используется память документа Excel. Вот как выглядит лист Excel, в ячейках которого хранятся данные о состоянии формы:
Пять ячеек листа SavedData рабочей книги BookOne12 хранят нужную информацию. Заметьте, ячейка A1 именована. Ее имя "Данные" будет использовано в обработчиках событий. На этом же листе расположена командная кнопка "Вызов Формы". Ее обработчик события очень прост, ѕ он вызывает форму:
Private Sub CommandButton1_Click() frmInit.Show End Sub
А вот как выглядит сама форма в момент ее открытия:
Эта форма уже использовалась в наших примерах. Ранее она была связана с документом Word, а теперь мы перетащили ее в рабочую книгу Excel, используя операции Export - Import.
После чего форма была слегка модифицирована добавлением в нее новых командных кнопок ѕ Save, Reset и Cancel. Прежде, чем рассказать о них подробнее, приведем уже встречавшиеся обработчики событий. Наша форма одинаково реагирует на два события Initialize и Activate. Первое из них возникает, когда форма открывается после того, как она была выгружена. Если же форма удаляется с экрана методом Hide, то при ее повторном открытии событие Initialize не возникает. Поскольку мы хотим, чтобы и в этом случае происходила инициализация свойств формы, то определен и обработчик события Activate, выполняющий те же действия. Поскольку оба обработчика эквивалентны, то приведем текст только одного из них:
Private Sub UserForm_Activate() With frmInit .Caption = "Окно после инициализации" ' заголовок диалогового окна .CurrDate.Caption = "Сегодня " & Format(Date, "dd/mm/yy") 'метка - текущая дата .MyText.Text = "Любимый цвет:" 'начальный текст в редакторе .chkGood.Value = True 'включение флажка .chkGood.Caption = " Хороший день" ' заголовок флажка With.lstColors 'задание элементов списка: .AddItem "белый" .AddItem "черный" .AddItem "синий" .AddItem "красный" .AddItem "зеленый" .AddItem "желтый" .AddItem "голубой" .ListIndex = 4 'выбор 5-го элемента в списке ("зеленый") End With End With
End Sub
Этот обработчик задает начальные свойства элементов управления ѕ объектов формы в момент ее открытия. После чего с формой работает пользователь. Форма простая, поэтому возможностей у него не много, тем не менее, он может выбрать из списка понравившийся ему цвет, отключить флажок, щелкнуть по командной кнопке "Change". В ответ на последнее действие будет вызван соответствующий обработчик, который программно изменит состояние объектов формы. Текст этого обработчика уже приводился ранее, напомним его:
Private Sub CommandButton1_Click() ChangeForm End Sub Public Sub ChangeForm() With Me .MyText.Text = "Нелюбимый цвет:" 'новый текст .lstColors.ListIndex = 1 'черный .chkGood.Value = False 'отключение флажка End With
End Sub
Нам осталось рассмотреть действие новых командных кнопок. Обработчик события Click кнопки Save позволяет сохранить текущее состояние элементов управления формы. Затем это состояние может быть проанализировано, например, для того, чтобы выдать психологический портрет пользователя. Цель сохранения может быть и другая, ѕ иметь возможность вернуться к текущему состоянию при повторном открытии формы. С чисто программистской точки зрения задача сохранения состояния решается просто, главный вопрос это, где и в какой форме хранить состояние элементов управления. В данном случае мы выбрали ячейки листа Excel. Вот текст этого обработчика:
Private Sub cmdSave_Click() 'Сохранение данных формы в ячейках листа SavedData книги BookOne12 Dim Beg As Range Set Beg = Range("[BookOne12.xls]SavedData!Данные") With frmInit Beg.Offset(1, 0) =.CurrDate.Caption 'дата Beg.Offset(1, 1) =.lstColors.ListIndex 'индекс в списке Beg.Offset(1, 2) =.lstColors.Value 'цвет Beg.Offset(1, 3) =.chkGood.Value 'состояние флажка Beg.Offset(1, 4) =.MyText.Text 'текст в окне ввода 'Форма прячется .Hide End With
End Sub
Обратите внимание, при работе с ячейками Excel используется техника, основанная на смещении Offset. Вначале фиксируется начальная ячейка, имеющая имя "Данные", и уже относительно ее выполняются действия над остальными ячейками.
Командная кнопка Reset позволяет восстановить сохраненное состояние элементов управления формы. Обработчик события Click для этой кнопки выполняет действия, обратные тем, что делаются при сохранении состояния. Вот текст этого обработчика:
Private Sub cmdReset_Click() 'Восстановление данных формы из ячеек листа SavedData книги BookOne12 Dim Beg As Range Set Beg = Range("[BookOne12.xls]SavedData!Данные") With frmInit .CurrDate.Caption = Beg.Offset(1, 0) .lstColors.ListIndex = Beg.Offset(1, 1) .lstColors.Value = Beg.Offset(1, 2) .chkGood.Value = Beg.Offset(1, 3) .MyText.Text = Beg.Offset(1, 4) End With End Sub
Обработчик события Click для кнопки Cancel просто закрывает форму без сохранения состояния элементов:
Private Sub cmdCancel_Click() frmInit.Hide End Sub
Диалоговое окно представляет собой прямоугольную область экрана, где размещены элементы управления, с которыми работает пользователь. В Office 2000 масса встроенных элементов управления, позволяющих спроектировать и реализовать интерфейс типичной офисной системы. Если же встроенных элементов управления не хватает, Вы можете использовать в своем диалоговом окне произвольные ActiveX -объекты.
Три приложения Office 2000 - Excel, Word и PowerPoint - содержат в редакторе VBA одинаковые средства создания диалоговых окон и программирования процедур обработки событий для них и для их управляющих элементов. В Access наряду с аналогичными средствами создания собственного диалогового окна, включены также мастера, помогающие проектировать специальные диалоговые окна, связанные с вводом и выводом информации, хранящейся в базе данных.
Диалоговое окно и каждый элемент управления, размещенный в нем, - это объект определенного класса с предопределенным набором свойств, методов и событий. Начальные значения свойств диалогового окна и его отдельных элементов можно задать при проектировании окна. Затем при работе системы некоторые свойства могут меняться пользователем (например, текст в окне редактирования, состояния кнопок выбора и т. п.), а некоторые - из программы. Программные изменения происходят обычно в процедурах обработки событий, автоматически запускаемых при наступлении событий, связанных с диалоговым окном и его элементами.
Чтобы диалоговое окно стало доступно пользователю, его нужно вывести на экран в ответ на некоторое действие пользователя или автоматически при некотором изменении состояния системы. Обычно диалоговые окна выводятся командами выпадающих или вспомогательных меню. Диалоговые окна могут также вызываться из других окон. Автоматически выводятся окна, в которых система после завершения задания сообщает о полученных результатах, окна с информацией об обнаруженных ошибках и т. п.
Окно, создаваемое функцией InputBox, предназначено для ввода строки и содержит однострочное окно редактирования, сообщение и кнопки OK и Cancel. При выборе кнопки OK (или нажатии клавиши Enter) строка, введенная пользователем в окне редактирования, передается в программу; щелчок кнопки Cancel (нажатие клавиши Esc) означает отказ от ввода - InputBox возвращает пустую строку.
Синтаксис вызова функции InputBox таков:
InputBox(prompt [,title ] [,default] [, xpos] [, ypos] [,helpfile, context])
Здесь параметры prompt (сообщение), title (заголовок), helpfile и context имеют тот же смысл, что и для функции MsgBox. Параметр default является строкой, задающей подсказку, появляющуюся в текстовом окне редактирования. Если пользователь не введет новый текст, то эта подсказка и будет служить его ответом. Когда этот параметр не задан, то окно редактирования при открытии пусто. Числовое выражение xpos задает расстояние по горизонтали левой границы окна от левой границы экрана. Если его нет, окно центрируется по горизонтали. ypos - расстояние верхней границы окна от верхней границы экрана. Если его нет, окно центрируется по вертикали.
В следующем примере в окно функции InputBox пользователь должен ввести дату рождения. Далее она проверяется. Если она в интервале от 01.01.1900 до 01.01.1985, запрашивается имя пользователя еще одним вызовом функции InputBox, иначе выдаются информационные сообщения с помощью функции MsgBox. Так как возвращаемое при первом вызове функции InputBox значение - строка, для его преобразования в дату применяется функция DateValue (для преобразования вводимых строк в числовые значения используется функция Val).
Sub ExInput() Dim Msg As String, Title As String, Имя As String Dim Birthday As Date
Msg = "Введите, пожалуйста, " & vbCrLf & "дату своего рождения." 'сообщение. Title = "Окно для ввода даты" 'заголовок. ' Вывод окна для ввода даты в позицию (1500,1000): Birthday = DateValue(InputBox(Msg, Title,, 1500, 1000))
' Проверка даты: If Birthday < "01/01/1900" Then MsgBox "Вы выглядите гораздо моложе!", vbExclamation ElseIf Birthday > "01/01/1983" Then MsgBox "Эта программа не для детей до 16!", vbExclamation Else ' Дата корректна.
Запрос имени пользователя: Имя = InputBox("Здравствуйте! Как Вас зовут?", "Знакомство", _ "Владимир Биллиг",,, "My.hlp", 12) MsgBox Имя & ", рады Вам помочь.", vbExclamation, " Проверка ввода" End If End Sub
Ниже представлен один из возможных диалогов, реализуемых этим фрагментом в случае, когда введенная пользователем дата рождения корректна и вызывается окно для ввода его имени.
Только один из элементов управления формы находится в фокусе. Это означает, что этот элемент может принимать данные ввода, например, при нажатии клавиш клавиатуры или щелчки мыши. Пользователь, работающий с формой, может перемещать фокус по элементам управления в прямом направлении нажатием клавиши Tab, а в обратном - комбинацией Shift+Tab. Порядок перемещения задается на стадии проектирования окна. Программно можно установить фокус, используя методSetFocus (Поместить в фокус) элемента, который должен оказаться в фокусе.
Рассмотрим форму, в которой есть поле ввода и командная кнопка. Нормальные действия пользователя предполагают, что он вводит информацию в поле ввода, а затем щелкает по командной кнопке. В этом случае обработчик события Click передает информацию из поля ввода переменной программе. Если же пользователь щелкнул по кнопке, забыв ввести информацию, то следует выдать предупреждающее сообщение, например, звуковой сигнал и вернуть фокус полю ввода. Вот такой сценарий и был реализован. Не будем приводить детали проектирования формы и все обработчики событий. Ограничимся только одним из них -обработчиком события щелчка командной кнопки:
Private Sub CommandButton1_Click() With Me If.TextBox1.Text = "" Then Beep: Beep: Beep .TextBox1.SetFocus Else GlobeVar =.TextBox1.Text MsgBox GlobeVar .Hide End If End With End Sub
Вот как выглядит эта простая форма ввода в процессе работы с ней:
Public Sub Mes2() Dim Msg As String, MyString As String Dim Btns As Integer Dim Title As String, Help As String Dim NmbCont As Integer, Result As Integer Title = " Вы ввели неверные данные !" ' заголовок окна. Msg = "Будем продолжать работу ?" ' сообщение. Btns = vbYesNo + vbCritical + vbDefaultButton2 ' кнопки и свойства Help = "ERRORS.HLP" ' имя файла со справкой NmbCont = 200 ' номер темы ' Вывод сообщения. Result = MsgBox(Msg, Btns, Title, Help, NmbCont) If Result = vbYes Then ' пользователь нажал кнопку Yes. MyString = "Да" ' действия по продолжению работы '... Else ' пользователь нажал кнопку No. MyString = "Нет" ' действия по прекращению работы '... End If End Sub |
Пример 12.1. |
Закрыть окно |
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) Dim Msg As String Const MinTemp = 34 Const MaxTemp = 42 Msg = "Ошибка ввода:" & vbCrLf 'Проверка, являются ли данные числовыми If Not IsNumeric(TextBox1.Text) Then Msg = Msg & "Введите числовые данные в формате: ##.#" MsgBox Msg Cancel = True 'Оставляет фокус в поле ввода ElseIf TextBox1.Text < MinTemp Then Msg = Msg & "Температура слишком низкая" & vbCrLf _ & "Проверьте, что с Вашим больным!" MsgBox Msg Cancel = True 'Оставляет фокус в поле ввода ElseIf TextBox1.Text > MaxTemp Then Msg = Msg & "Температура слишком высокая" & vbCrLf _ & "Проверьте, что с Вашим больным!" MsgBox Msg Cancel = True 'Оставляет фокус в поле ввода Else GlobeVar = TextBox1.Text Debug.Print GlobeVar End If End Sub |
Пример 12.2. |
Закрыть окно |
Давайте создадим диалоговое окно "Цветная форма", в котором будут расположены изображение (Image), поле ввода (TextBox) и командная кнопка (CommandButton).
В меню Вставка выберите команду UserForm для создания нового диалогового окна. Щелкнув правой кнопкой появившееся окно UserForm1, выберите в контекстном меню команду Свойства. Введите новое имя ColorForm1 в правом столбце строки со свойством (Name), в качестве значения свойства Caption введите заголовок окна: "Цветная форма". Щелкните правый столбец в строке со свойством BackColor (Цвет фона), затем - появившийся справа значок списка. В таблице появившегося окна щелчком выберите понравившийся цвет. Окно "перекрасится". Закройте окно свойств. Перетащите с панели инструментов на окно элемент Image (изображение). Щелкните его правой кнопкой и снова выберите команду Свойства. В появившемся окне со списком свойств отыщите строку со свойством Picture (Рисунок). Чтобы перейти к поиску нужного файла с картинкой, щелкните кнопку с многоточием (…) справа в этой строке. В диалоговом окне Загрузка рисунка (Load Picture) выберите файл с симпатичной картинкой и щелкните кнопку OK. Перетащите на диалоговое окно элемент управления поле ввода (TextBox). Как и в п. 3, щелкнув его правой кнопкой, вызовите окно Свойства. Введите в качестве значения свойства Value название выбранной вами картинки - оно появится в окне редактора. Затем выберите свойство Font Справа появится кнопка (…). Щелкните ее и в появившемся списке шрифтов выберите шрифт для редактора. Перетащите на диалоговое окно командную кнопку (CommandButton). Вызовите окно Свойства для этой кнопки, и измените в нем значение свойства Caption (Заголовок) на "Нажми меня" - текст станет именем кнопки. Измените имя кнопки (Name) на cmdClickMe. По этому имени к кнопке будут обращаться процедуры и методы в программе. Введите справку "Командная кнопка" как значение свойства ControlTipText - надпись будет появляться на экране под кнопкой всякий раз, когда на ней окажется указатель. Установите для кнопки ключ быстрого выбора: найдите в списке свойств строку со свойством Accelerator (Ускоритель) и введите в поле справа букву "Н" - в имени кнопки первый символ "Н" будет подчеркнут и нажатие клавиш Alt+Н будет эквивалентно выбору кнопки. Установите также подходящий шрифт с помощью свойства Font, как и для поля ввода. В меню Запуск выберите команду "Запуск подпрограммы/UserForm". На экране приложения появится спроектированное диалоговое окно.
Щелкните кнопку Close на заголовке диалогового окна, чтобы выйти из него.
Одна из важных функций диалоговых окон, - прием и передача данных, введенных пользователем, для хранения и дальнейшей обработки в систему. Основной вид элементов управления, предназначенных для ввода, - это окна редактирования (TextBox). Для предотвращения ошибок, связанных с неверным типом введенных данных или нарушением некоторых условий, которым эти данные должны удовлетворять следует проверять их корректность до выхода из диалогового окна. Чуть выше мы приводили пример работы с простой формой ввода, где проверялась ситуация, когда пользователь "забыл" ввести данные в окно ввода. Сейчас мы рассмотрим ситуацию, в которой пользователь пытается ввести некорректные данные в поле ввода. Возникает вопрос, где следует проводить проверку на корректность данных? По-видимому, одним из лучших мест является обработчик события Exit, которым обладает элемент управления TextBox. Обработчик этого события вызывается при попытке выхода из окна редактирования. Здесь и следует проводить проверку введенных данных, чтобы не допустить выхода, если данные заданы некорректно.
Продолжим работу с простой формой ввода и предположим, что в поле ввода следует ввести температуру больного человека, значение, которой, естественно, ограничено сверху и снизу. Вот как выглядит обработчик события Exit:
Пример 12.2.
(html, txt)
Событие Exit имеет параметр Cancel, значение которого следует установить в обработчике события. Если параметру присвоить значение True, то фокус остается на текущем элементе, в противном случае он переходит к элементу, следующему согласно Tab - порядка. Вот как выглядит форма при попытке задания некорректного значения температуры:
Процедуры, обрабатывающие события, связанные с диалоговыми окнами и элементами управления, - это частный случай процедур, обрабатывающих события объектов Office 2000. С диалоговым окном (формой) и с элементом управления каждого типа связан заранее определенный набор событий, возникающих для этого объекта по инициативе пользователя или системы. Например, одно из связанных с формой событий Initialize (Инициализация) возникает при загрузке формы, а связанное с командной кнопкой (CommandButton) событие Click возникает, когда пользователь щелкает эту кнопку (или нажимает клавишу Enter, если эта кнопка определена как нажимаемая по умолчанию). Процедуры обработки событий позволяют описать поведение диалогового окна или отдельного элемента управления при наступлении того или иного события.
Чтобы перейти в окно редактора для ввода текста процедуры обработки события, щелкните дважды объект, к которому оно относится (элемент управления или свободную от элементов часть формы). Появится окно Code (Код). В раскрывающемся списке слева вверху перечислены все объекты формы; при выборе объекта в этом списке справа вверху появляются события, связанные с данным объектом. Ниже на рис. 12.10 показан список событий для командной кнопки.
События, для обработки которых процедуры уже написаны, выделены полужирным начертанием. Чтобы создать новую процедуру или отредактировать имеющуюся, нужно щелкнуть в списке соответствующее событие. На экране появится шаблон новой процедуры или текст написанной. Имя такой процедуры состоит из имени устройства или формы, за которым после подчеркивания идет имя события. Так, процедура, обрабатывающая событие Click для командной кнопки CommandButton1, называется CommandButton1_Click. Из-за такого способа именования процедур будьте осторожны при переименовании элементов управления. Если Вы сначала определили для элемента процедуры обработки событий, а затем переименовали его (изменив свойство Name), никаких процедур обработки событий у элемента с новым именем не будет (их придется перенести с помощью редактора).
Новые пользовательские диалоговые окна проектируются в редакторе VBA. В процессе создания диалогового окна вначале определяется его видимое изображение на экране (форма с управляющими элементами), затем задаются их свойства и разрабатываются процедуры, обрабатывающие события, связанные с формой и ее элементами управления.
Для создания новой формы нужно в меню редактора VBA выбрать выпадающее меню Вставка (Insert), а в нем - команду UserForm. На экране появится новое окно с пустой формой и расположенной рядом панелью элементов (Toolbox).
Щелкните это окно правой кнопкой мыши и выберите в появившемся контекстном меню команду Свойства (Properties). На экране появится окно Свойства-UserForm со списком свойств нового окна. Если выбрать вкладку По категориям, будет показан список свойств, сгруппированных по категориям. В частности, в категории Вид можно задать цвета окна и его границ и установить нужный заголовок окна в свойстве Caption. Свойства из других групп позволяют установить шрифт, используемый в окне, положение и размер окна и др. Чтобы подробнее узнать о свойстве, щелкните его и нажмите клавишу F1.
Затем нужно расположить в окне управляющие элементы (controls). Они выбираются на панели элементов Toolbox Если ее нет на экране, выберите команду Панель элементов (Toolbox) в меню Вид или щелкните ее пиктограмму на панели инструментов VBA. На панели элементов управляющие элементы представлены пиктограммами. Вы увидите имя элемента, установив указатель мыши на его пиктограмме.
Перетащите нужный элемент с панели элементов на предназначенное место в окно формы. Когда вы отпустите кнопку мыши, вокруг элемента появится прямоугольная рамка с выделенными точками, за которые ее можно перемещать по экрану, чтобы точнее расположить элемент управления в диалоговом окне и установить его размеры. Уточнить положения элемента в окне можно командами меню Формат (Format). Порядок обхода управляющих элементов формы устанавливает команда Последовательность перехода (TabOrder)из меню Вид или контекстного меню формы.
Чтобы данный управляющий элемент никогда не попадал в фокус, щелкните его правой кнопкой мыши, выберите в появившемся контекстном меню команду Свойства, а затем в появившемся списке установите для свойства TabStop значение False. Отметим, что для текстовых надписей (элементов вида Label) это значение устанавливается по умолчанию. В окне "Свойства-элемента" можно установить при проектировании и другие свойства элемента управления. Списки свойств появляются в этом окне на вкладках По алфавиту (Alphabetic) и По категориям (Categorized) на первой - в алфавитном порядке, на второй - сгруппированы по категориям. Устанавливать значение свойства можно на любой из них.
Система автоматически именует новые элементы управления, образуя имя из типа элемента и его порядкового номера среди элементов данного типа. Например, у второй командной кнопки по умолчанию будет имя CommandButton2. Элементу можно присвоить новое имя, установив его в качестве значения свойства (Name). Помните, что имя идентифицирует объект (элемент управления или форму) в программе, поэтому изменение имени должно повлечь изменения в текстах процедур, его использующих. Не надо путать имя объекта (Name) со свойством Caption (заголовок, надпись), имеющимся у многих элементов управления. По умолчанию при создании элемента система присваивает этому свойству то же значение, что и имени Name. Изменение свойства Caption отражается на "внешности" элемента (надписи на экране), а на доступ к объекту из программы не влияет.
Можно одновременно изменить значение свойства для нескольких одновременно выделенных элементов управления (щелкните их при нажатой клавише Ctrl), установив нужное значение свойства для одного из этих элементов.
Если элемент или группа элементов будут использоваться в нескольких диалоговых окнах, их можно после настройки в первом из этих окон перетащить на панель элементов и оттуда уже в готовом виде перетаскивать на остальные окна.
В одном диалоговом окне можно разместить несколько страниц и вкладок со своими управляющими элементами. Страницы и вкладки стали непременными элементами интерфейса систем, работающих с Windows. Отметим, что названия этих элементов в Office 2000 отличаются от принятых, например, в Windows 95: элемент MultiPage (набор страниц) позволяет создавать страницы с разными элементами управления (традиционно они назывались вкладками), а новый элемент TabStrip (полоса вкладок) создает "вкладки" с одинаковыми наборами элементов управления. Чтобы создать новый набор страниц, нужно перетащить на форму элемент MultiPage. Вначале будут созданы две страницы, которым можно дать нужные заголовки, сделав их значениями свойства Caption в списке свойств. На следующем рисунке эти страницы получили имена "Ссуды" и "Ренты".
Для того, чтобы добавить следующую страницу, щелкните правой кнопкой мыши правее имени последней страницы и в появившемся контекстном меню выберите команду Создать страницу (New Page). Это меню позволяет также переименовывать, перемещать и удалять страницы. Повторив операцию создания страницы несколько раз, можно разместить в окне необходимое число страниц. Затем на каждую из них нужно перетащить элементы управления.
Аналогично создаются вкладки элементом TabStrip. Отличие в том, что каждый помещаемый на одну вкладку элемент управления одновременно попадает на все вкладки набора.
Все элементы управления обладают свойством Enabled (Доступен), позволяющим управлять их доступностью. В результате действий пользователя или системы доступный элемент может стать активным - получить фокус клавиатуры. Если свойству Enabled присвоить False, элемент управления становится недоступен ("сереет") и не может попасть в фокус. Управление доступностью производится динамически и зависит от задач, решаемых в диалоговом окне. Типичный случай - запрет на доступ к окну поля ввода (TextBox) после того, как система поместила в него данные, которые не должны далее изменяться пользователем (например, текст справки, которую можно только прочесть и распечатать). Другой случай - отключение/включение доступа к группам переключателей или кнопок зависимого выбора (OptionButton) или отдельным таким кнопкам в зависимости от состояния флажка (CheckBox). При этом действия по изменению доступа надо проводить в процедуре, обрабатывающей событие Change (Изменение), автоматически вызываемой в тот момент, когда флажок меняет свое состояние, т. е. становится неотмеченным или отмеченным.
Выполните следующие действия:
Создайте новое диалоговое окно (UserForm) и включите в него флажок (CheckBox), управляющий элемент Frame (Рамка), и командную кнопку (ComandButton). Поместите в рамку еще 4 флажка (CheckBox). Заголовки управляющих элементов (значения свойства Caption ) задайте как на рисунке:
Дважды щелкните верхний флажок, чтобы вывести окно с кодом процедур, выберите в списке объектов слева вверху CheckBox1 (это имя присвоила флажку система), затем в списке процедур обработки событий справа вверху щелкните событие Change. Дополните появившуюся заготовку процедуры CheckBox1_Change:
Private Sub CheckBox1_Change() With Me If.CheckBox1.Value Then 'отключение опций .CheckBox4.Enabled = False .CheckBox5.Enabled = False Else 'включение опций .CheckBox4.Enabled = True .CheckBox5.Enabled = True End If End With
End Sub
Начальное значение (или значение по умолчанию) свойства элемента управления можно установить в процедуре, обрабатывающей событие Initialize (Инициализация) диалогового окна, содержащего данный элемент. Это событие возникает всякий раз при выводе диалогового окна на экран и запускает на выполнение процедуру без аргументов с именем ИмяОкна_Initialize. Поэтому установленные в ней значения свойств всегда будут начальными. Это не значит, что они должны быть постоянными. Значения могут зависеть от текущей даты, данных в ячейках рабочего листа Excel, некоторых записей в базе данных Access и т. п.
Давайте создадим диалоговое окно с процедурой инициализации.
Создайте новое диалоговое окно и разместите в нем статический текст Label (Метка), поле ввода TextBox, окно списка ListBox и кнопку независимого выбора (флажок) CheckBox. В окне Свойства, измените их имена (свойство Name): Label - на CurrDate, TextBox - на MyText, ListBox - на lstColors, CheckBox - на chkGood, UserForm - на frmInit. Эти изменения внутренних имен элементов и окна не скажутся на его изображении в редакторе.
Дважды щелкните диалоговое окно, чтобы вызвать окно с кодом (Code). Установите в списке объектов слева вверху UserForm (по умолчанию этот объект и будет выбран при вызове окна кода) и выберите команду Initialize в списке процедур справа вверху. На экране появится шаблон процедуры инициализации диалогового окна UserForm_Initialize. Введите текст следующей процедуры.
Private Sub UserForm_Initialize() With frmInit .Caption = "Окно после инициализации" ' заголовок диалогового окна .CurrDate.Caption = "Сегодня " & Format(Date, "dd/mm/yy") 'метка - текущая дата .MyText.Text = "Любимый цвет:" 'начальный текст в редакторе .chkGood.Value = True 'включение флажка .chkGood.Caption = " Хороший день" ' заголовок флажка With.lstColors 'задание элементов списка: .AddItem "белый" .AddItem "черный" .AddItem "синий" .AddItem "красный" .AddItem "зеленый" .AddItem "желтый" .AddItem "голубой" .ListIndex = 4 'выбор 5-го элемента в списке ("зеленый") End With End With
End Sub
Нумерация элементов массивов и коллекций, связанных с формами, начинается с 0. Поэтому, чтобы выделить при выводе окна пятый элемент в списке цветов, свойству ListIndex присвоено значение 4. Запустите диалоговое окно в отладчике. На экране оно будет выглядеть так:
Щелкнув кнопку Close (Закрыть) на строке заголовка окна, возвратитесь в режим проектирования.
Рассмотрим сейчас встроенные диалоговые окна, которые появляются при вызове некоторых функций VBA. И начнем наше рассмотрение с функции MsgBox, предназначенной для вывода сообщений. Диалоговое окно, создаваемое функцией MsgBox, служит для вывода на экран сообщения программы и получения от пользователя простой реакции на это сообщение в виде щелчка одной из кнопок окна. В простейшем случае эта функция вызывается как процедура. Например, вызов:
MsgBox "Сегодня на календаре" & Date
выведет окно:
После щелчка кнопки OK вызов функции завершится, и выполнение программы возобновится с оператора, стоящего непосредственно за этим вызовом.
Диалоговое окно, выводимое функцией MsgBox, можно обогатить несколькими кнопками, чтобы пользователь мог указать с их помощью направление дальнейшего вычисления, а также присоединить к нему контекстную справку. В общем случае вызов MsgBox имеет вид:
MsgBox(prompt[, buttons] [, title] [, helpfile, context])
Здесь параметр prompt (сообщение) - строковое выражение, значение которого выводится в окне. Его максимальная длина не должна превышать 1024 символов. Разбиение на строки в этом выражении можно производить, используя символ возврата каретки (Chr(13)), символ перевода строки (Chr(10)), их комбинацию (Chr(13) & Chr(10)) или константу vbCrLf. Числовой параметр buttons (кнопки) задает виды командных кнопок, помещаемых в окне, кнопку, выбираемую по умолчанию, и модальность диалогового окна. Он получается как сумма кодов соответствующих кнопок и свойств. Явно не заданный, этот параметр считается равным 0. Строковое выражение title (заголовок) задает заголовок окна. Если его нет, заголовком становится имя приложения (см. пример, приведенный выше, где мы использовали Word). Параметры helpfile (файл справки) и context (контекст) должны присутствовать (или отсутствовать) вместе. Первый из них - имя файла, содержащего справку, которая будет выведена при нажатии клавиши F1, а второй - числовое выражение, задающее номер темы со справкой в этом файле.
Коды наборов командных кнопок | ||
vbOKOnly | 0 | только кнопка OK (Готово) |
VbOKCancel | 1 | кнопки OK и Cancel (Отказ) |
VbAbortRetryIgnore | 2 | кнопки Abort (Прервать), Retry (Продолжить) и Ignore (Игнорировать) |
VbYesNoCancel | 3 | кнопки Yes (Да), No (Нет) и Cancel |
VbYesNo | 4 | кнопки Yes и No |
VbRetryCancel | 5 | кнопки Retry и Cancel |
Коды пиктограмм | ||
VbCritical | 16 | важное сообщение (крестик в круге) |
VbQuestion | 32 | запрос (вопросительный знак) |
VbExclamation | 48 | предупреждение (восклицательный знак) |
VbInformation | 64 | информационное сообщение (i в круге) |
Кнопка, выбранная по умолчанию | ||
VbDefaultButton1 | 0 | первая кнопка |
VbDefaultButton2 | 256 | вторая кнопка |
VbDefaultButton3 | 512 | третья кнопка |
VbDefaultButton4 | 768 | четвертая кнопка |
Модальность диалога | ||
VbApplicationModal | 0 | модален относительно приложения |
VbSystemModal | 4096 | модален относительно системы |
vbOK | 1 | OK |
vbCancel | 2 | Cancel |
vbAbort | 3 | Abort |
vbRetry | 4 | Retry |
vbIgnore | 5 | Ignore |
vbYes | 6 | Yes |
vbNo | 7 | No |
Диалоговое окно нуждается в отладке. В редакторе VBA Вы видите его изображение, но управляющие элементы находятся в "замороженном" состоянии, и их реакция на действия пользователя - это реакция редактора, а не самих элементов. Диалоговое окно запускается на исполнение командой запуска процедуры или формы Запуск подпрограммы/UserForm меню Запуск редактора или нажатием клавиши F5. - Ваше диалоговое окно появится в рабочем состоянии на основной панели того приложения Office 2000, в котором оно создано.
А вызывается диалоговое окно в прикладной системе методом Show (Показать). Он позволяет выводить окно на экран в качестве реакции на выбор соответствующей команды меню или командной кнопки в другом окне и т. п. Например, диалоговое окно MyForm выводится так:
MyForm.Show
Диалоговые окна в Office 2000 всегда работают в режиме модального диалога. Это значит, что пользователь должен полностью завершить работу в окне и закрыть его, прежде чем сможет перейти к действиям, не связанным с работой в этом диалоговом окне. Заметим, что немодальный диалог в Office 2000 также можно организовать, но для этого потребуется использовать объект Assistant с его баллончиками ѕ объектами Balloon. Для завершения работы с диалоговым окном применяется оператор UnLoad или метод Hide, вызываемые в обработчиках события, завершающих работу в диалоговом окне. Обычно в диалоговое окно включается одна или несколько кнопок, выбор которых приводит к завершению работы в нем ("Отказ", "Выход", "Сохранить", "Готово", "Конец работы" и т. п.).
Ранее мы уже говорили о разнице между UnLoad и Hide, первый ѕ выгружает форму, второй только прячет ее. Есть и синтаксическая разница, Hide - это метод формы, в то время как UnLoad и Load - это встроенные функции, которым в качестве параметра передается имя формы. Мы обращали также внимание и на то, что при открытии спрятанной формы не возникает событие Initialize. В заключение, скажем, что в Office 97 были проблемы с методом Hide, поэтому я всегда пользовался только методом UnLoad, в Office 2000 метод Hide работает должным образом.