Основы офисного программирования и язык VBA

Проектирование интерфейса. Меню

Разбить на страницы
Показывать лекцию целиком

Программный код большинства примеров данной лекции можно найти в проектах, доступных для просмотра: DocOne.

Проектирование интерфейса. Меню

В предыдущих лекциях в примерах и описании VBA использовалась заключительная англоязычная бета - версия Office 2000. При описании интерфейса я перешел на русифицированную бета - версию Office 2000. Я полагаю, что программисту должно быть все равно, с какой версией он работает, как называется соответствующий пункт меню "Сервис" или "Tools". Тем не менее, разумнее описывать интерфейс применительно к русифицированному варианту. Кроме того, это входило в мои планы тестирования этой версии Office 2000.

Общие объекты Office 2000

Среди библиотек Office 2000, хранящих объекты, есть библиотеки, связанные с конкретным приложением - Word, Excel, Access, PowerPoint, но не только они. Всякий раз, когда открывается приложение, наряду с библиотекой, связанной с этим приложением, становятся доступными библиотеки общих объектов, где в первую очередь следует отметить библиотеки MSForms и Office. Первая из этих библиотек обеспечивает единство интерфейса при проектировании диалоговых окон (форм). Она содержит объекты, определяющие как само диалоговое окно (форму), так и многочисленные элементы управления, которые могут быть помещены в это окно. Библиотека Office также содержит объекты, используемые при организации интерфейса. В Office 2000 в этой библиотеке появилось много новых объектов: Answer Wizard, Com AddIn, HTML Project, Script, WebPageFont, Language Settings. Но разговор о них пойдет не в этой книге. Заметим, что в чисто интерфейсных объектах существенных изменений не произошло. Говоря о таких объектах, в первую очередь можно выделить объект Assistant, объект CommandBar и коллекцию этих объектов. Объект Assistant и входящий в него объект Baloon предназначены для организации контекстной помощи в более живой визуальной форме, отличной от традиционных окон. Объект CommandBar составляет основу интерфейса, - он представляет панель, на которой расположены команды меню и инструментальные кнопки.

Коллекция CommandBars

Пришла пора рассказать о наиболее "почтенных" представителях пользовательского интерфейса - меню и инструментальных кнопках. Интерфейс начинался с меню и до сих пор практически ни одно приложение без него не обходится. Все приложения Office 2000 обладают мощной встроенной системой меню и набором инструментальных панелей. И все эти средства доступны и при работе конечного пользователя с документами Office 2000. Но надо иметь в виду, что для "серьезных" приложений, требующих программирования и являющихся предметом нашей книги, только встроенными средствами не обойтись. Все основные приложения Office 2000 - Excel, Word, PowerPoint и Access разделяют на этапе проектирования единые средства настройки, позволяющие как модификацию встроенных, так и создание пользовательских панелей меню и инструментов. На этапе программирования во всех приложениях также используется единый набор объектов, корневым из которых является коллекция CommandBars, входящая в состав библиотеки Office. Вот как выглядит ее стр уктура:

(рис 11.1) Структура коллекции CommandBars

Элементами коллекции являются объекты класса CommandBar, каждый из которых представляет панель команд. Но то, что расположено на панели: меню, подменю, команды меню, кнопки,- все это задается другим объектом - коллекцией CommandBarControls. Объект CommandBar имеет свойство Controls, возвращающее эту коллекцию. Итак, CommandBar (панель команд) задает любую панель, на которой расположено как меню, так и инструментальные кнопки. На каждой панели, как известно, располагается некоторое число элементов. Они и составляют коллекцию CommandBarControls с элементами класса CommandBarControl. Конечно, эти элементы разнотипны и, по сути, являются объектами трех разных классов: CommandBarButton, CommandBarPopup и CommandBarComboBox. Класс, которому будет принадлежать элемент, определяется в момент его создания. В этот же момент определяется и тип элемента. По типу однозначно определяется клас с, но обратное утверждение неверно, например, элемент класса CommandBarComboBox имеет несколько возможных типов.

Поясним, в чем сущность этих трех классов, в каком случае элемент следует относить к тому или иному классу. Прежде всего, заметим, что "панельные" элементы могут иметь свою сложную внутреннюю структуру. К примеру, у каждого пункта главного меню обычно древовидная структура, при его раскрытии появляются терминальные вершины (команды меню) и вершины - подменю, которые, в свою очередь, содержат терминальные вершины и подменю. Вы ошибаетесь, если полагаете, что инструментальные кнопки можно только щелкать, и что они просто устроены. В Office 2000 в роли кнопок могут выступать такие элементы как ComboBox, TextBox и ListBox. Класс CommandBarButton определяет терминальную вершину (кнопку или команду меню), CommandBarPopup - подменю, CommandBarComboBox - сложно организованные кнопки, заданные элементами управления. Заметьте, что объект PopUp (подменю) имеет свойство Controls, возвращающее коллекцию CommandBarControls , что и обеспечивает требуемую иерархию вложенности меню.

Свойства и методы коллекции CommandBars

Коллекция 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

    Вот основные свойства и методы самого объекта 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
  • Коллекция CommandBarControls и ее элементы

    Эта коллекция обладает только традиционными свойствами и методами. Единственное, что следует рассмотреть - это метод 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 позволяют без труда перестраивать меню и панели инструментов, управлять параметрами окон, выбирать нужные форматы представления данных на экране (цвет, шрифт, размер и т. д.), создавать собственные диалоговые окна и размещать на них разнообразные управляющие элементы. Возможность присоединения ActiveX -объектов к формам и документам сделало перечень элементов управления практически неограниченным, поскольку число ActiveX -объектов в доступных разработчикам библиотеках постоянно растет.

    В этой и двух следующих лекциях мы рассмотрим ряд компонент VBA, связанных с проектированием интерфейса, которые и позволяют называть этот язык визуальным. В этой лекции мы изучим способы создания собственных меню. Эти возможности лучше всего поддержаны в Access, но и в других приложениях можно создавать собственные системы меню, как руками, так и с использованием VBA.

    Создание собственных и модификация встроенных меню

    В меню объединяют последовательности, группы, наборы команд (рубрик), одну из которых может выбрать пользователь для совершения очередного действия. Как правило, названия команд в меню достаточно информативны, так что пользователь может легко найти нужную ему команду. Команды для решения близких задач можно объединить в группу, поместив их рядом в одном меню и отделив чертой от команд, решающих другие задачи. В одном меню команды объединяют на основе одного из двух принципов: либо это различные действия над одним объектом, либо однотипные действия над различными объектами. Первый принцип реализован в меню Файл (File) всех приложений Office 2000, объединяющем различные действия над основным объектом приложения: создание, открытие и закрытие, сохранение, пересылка и печать объекта. Меню Вставка (Insert) построено по другому принципу - действие "вставить" выполняется для различных объектов. Если вариантов исполняемых действий много, их структурируют, используя подменю - списки команд, появляющиеся правее или левее выбранной команды родительского меню. Еще один вид меню - контекстные (shortcut) меню, всплывающие при нажатии правой кнопки мыши в определенном контексте. В них можно объединять действия, допустимые (факультативно) в данном контексте. Доступ пользователя к команде меню можно ускорить, определив для нее "горячие" клавиши, нажатие которых эквивалентно выбору этой команды.

    Мы уже рассмотрели основные свойства и методы коллекции CommandBars и ее объектов CommandBar, представляющих панели команд, на которых располагаются меню, подменю, кнопки и другие элементы, образующие коллекцию CommandBarControls. Рассмотрим работу с объектами, относящимися к меню. Эту работу, как правило, можно проводить двумя способами: "визуально", используя встроенные команды и диалоговые окна приложений Office 2000, или "программно", создавая в процедурах VBA объекты указанных классов, задавая и изменяя их свойства соответствующими методами.

    Немного терминологии

    Система меню в Office 2000 включает головную строку меню (menu bar), обычно расположенную в верхней части активного окна. Оно постоянно находится на экране. Изменяться это меню может при переходе к другому активному окну или по командам из программ на VBA. Каждая команда головного меню является именем вертикально расположенного меню, выпадающего при выборе этой команды. Команда такого меню может быть именем подменю, при этом она отмечается направленной вправо стрелкой. Подменю появляется на экране справа или слева от родительского меню, когда пользователь выбирает команду с его именем.

    (рис 11.2) Строка меню Word. Меню "Вид". Подменю "Панели инструментов"

    Здесь в головном меню выбрана команда Вид (View), а в меню Вид - команда Панели инструментов (Toolbars), которая является именем соответствующего подменю. В подменю Панели инструментов выделена команда Настройка (Customize), которая будет неоднократно упоминаться далее в этой лекции, поскольку с ее помощью можно производить многие действия, связанные с изменениями меню. Меню Вид называется родительским по отношению к подменю Панели инструментов, а меню Панели инструментов - дочерним по отношению к меню Вид. Вообще команды подменю тоже могут быть именами отдельных меню и т. д. Таким образом, меню приложений Office 2000 образуют иерархическую (древовидную) структуру. Корень этой структуры - головное горизонтально расположенное меню, его непосредственными потомками являются выпадающие меню, заголовки которых и образуют головное меню. Концевые вершины (листья) этой иерархии - непосредственно исполняемые команды (часто - это вызовы диалоговых окон), а пути от корня к вершинам проходят по заголовкам соответст вующих меню и подменю.

    Возможности настройки и изменения системы меню

    Office 2000 предоставляет широкие возможности для настройки и модификации меню приложений. Пользователи могут создавать новые головные меню, добавлять команды в уже существующие меню и связывать с ними новые подменю. Можно также создавать новые и изменять существующие контекстные меню. Есть средства, позволяющие в любой момент восстановить первоначальную систему меню.

    Возникают вопросы: когда создавать свою собственную систему меню, а когда лишь модернизировать систему приложения? Общий совет Microsoft состоит в том, что если добавления или изменения невелики, то следует модернизировать систему меню, а при существенных изменениях (например, добавлении нескольких новых меню и подменю) целесообразно создавать собственную систему меню. Разумеется, в этом случае следует принимать во внимание будущих пользователей создаваемой прикладной офисной системы, их образование, квалификацию, опыт работы с компьютером и т.д. Для "среднего" пользователя - типичного сотрудника типичной организации - прикладная система над Excel или Access, видимо, должна иметь собственный интерфейс, лишь в небольшой степени использующий встроенные меню, панели инструментов и диалоговые окна Office 2000. Поэтому в большинстве случаев разработчику следует создавать свое головное меню и, возможно, панель инструментов, перекрывающие частично или полностью на экране головное меню и панель инструментов соот ветствующего приложения Office 2000. Другими вариантами построения интерфейса могут быть собственные диалоговые окна или расположение управляющих элементов непосредственно на поверхности основных документов (например, на рабочих листах Excel).

    Создание собственного головного меню

    Согласно существующим формальным и фактическим стандартам проектирования интерфейса, работа прикладной программы должна начинаться с активизации головного меню, которое находится в верхней части окна приложения. Собственное головное меню для прикладной системы можно спроектировать визуально - "руками", вызвав диалоговое окно Настройка (Customize), или используя VBA.

    Использование диалогового окна Настройка

    Во всех приложениях Office 2000 можно спроектировать собственное головное меню визуально, используя для этого диалоговое окно Настройка. Для его вызова нужно в меню Вид выбрать команду Панели инструментов (Toolbars), а затем в появившемся подменю - команду Настройка.

    Новое меню создается так:

  • Щелкните кнопку Создать (New) на вкладке "Панели инструментов".
  • В появившемся окне "Создание панели инструментов" (New Toolbar) введите имя создаваемого меню и щелкните кнопку OK. На экране появится плавающее меню с заданным именем. При работе в Access появляются дополнительные возможности, позволяющие установить свойства панели, что нельзя сделать в других приложениях - Word, Excel, Power Point. При работе в Access:
  • Щелчком кнопки Свойства (Properties) выведите на экран окно "Свойства панели инструментов" (Toolbar Properties).
  • Установите в списке Тип (Type) команду "Строка меню" (Menu Bar) в качестве типа создаваемой панели и закройте окно.
  • Вот, как выглядит окно свойств:

    (рис 11.3) Окно свойств командной панели в приложении Access

    Имя нового меню появится в списке Панели инструментов на вкладке Панели инструментов.

    В окне "Свойства панели инструментов" можно задать и другие свойства создаваемого меню. В частности, свойство закрепление (Docking) и опция перемещение (Allow Moving) позволяют разрешить или полностью или частично запретить перемещение меню по экрану. Для головного меню приложения естественно установить постоянное место на экране. Опция настройка (Allow Customizing) позволяет после завершения создания меню отключить возможность его модификации, а если отключить опцию отображение/скрытие (Allow Showing/Hiding), то меню будет на экране постоянно.

    Создание меню с помощью VBA

    Новое меню в 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)

    Добавление выпадающих меню

    Добавлять новые меню (подменю) и команды к существующим меню, встроенным в Office 2000 или созданным пользователем, также можно двумя способами: используя диалоговое окно Настройка или VBA. Рассмотрим, как добавить выпадающее меню к существующей панели меню (головному меню).

    Использование диалогового окна Настройка

    Это способ добавления меню или команды более нагляден, и в отличие от процедуры создания нового меню, его можно применять в любом приложении Office 2000, а не только в Access. Откройте диалоговое окно Настройка, а затем:

  • Если модифицируемого меню на экране нет, щелкните кнопку выбора рядом с именем изменяемого меню в списке Панели инструментов на одноименной вкладке Панели инструментов.
  • В списке Категории (Categories) на вкладке Команды (Commands) выберите Новое меню (New Menu).
  • Выберите команду Новое меню (New Menu) справа в списке Команды (Commands) и перетащите ее в то меню, к которому Вы хотите добавить новое меню. При этом знак I отмечает то место в меню, куда попадет имя нового меню, когда Вы отпустите кнопку мыши.
  • Щелкните правой кнопкой мыши Новое меню (New Menu), и введите имя этого меню в поле Имя (Name) появившегося окна. Одновременно можно задать ключ быстрого доступа к этому меню, поставив символ "" перед буквой, которая будет этим ключом.
  • Если теперь щелкнуть имя нового меню, на экране под ним появится пустой прямоугольник. Ниже мы покажем, как вставлять в созданное меню новые команды.

    Как добавить встроенное меню

    Диалоговое окно Настройка позволяет просто добавить (скопировать) любое из встроенных меню к меню, которое Вы создаете. При этом исходное встроенное меню не изменяется. Для этого в диалоговом окне Настройка сделайте модифицируемое меню видимым, а затем:

  • Выберите в списке Категории вкладки Команды команду Встроенные меню (Built­in Menus).
  • Выберите в списке Команды имя нужного встроенного меню и перетащите его на нужное место в панель меню, к которой Вы хотите добавить выбранное встроенное выпадающее меню. Знак I отмечает место на панели, куда попадет встроенное меню.
  • Есть и другой способ копирования встроенного меню: выберите его на его собственной панели и перетащите в свою панель меню при нажатой клавише Ctrl.

    Добавление выпадающего меню с помощью VBA

    Чтобы добавить новое меню программно, нужно использовать метод 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 = "Ввод документов"

    Добавление подменю

    Подменю (или дочернее меню) примыкает к боковой стороне другого меню - родительского - на уровне той команды родительского меню, которая является заголовком подменю. Подменю можно добавлять как к выпадающим меню, так и к другим подменю и к всплывающим меню. Сначала добавляется пустое подменю, затем в него вставляются команды. Добавить подменю можно двумя способами: с помощью диалогового окна Настройка и через вызов метода Add в VBA.

    Рассмотрим вначале визуальный способ. Для добавления подменю нужно, как и раньше, активизировать диалоговое окно Настройка и сделать модифицируемое меню видимым. После этого нужно действовать так.

  • На вкладке Команды в списке Категории выберите команду Новое меню.
  • Выберите команду Новое меню справа в списке Команды и перетащите ее в то место меню, куда нужно добавить подменю. Чтобы выпадающее меню открылось, показав уже имеющиеся в нем элементы, протащите Новое меню через имя выпадающего меню. При этом горизонтальная черта будет отмечать то место в списке рубрик выпадающего меню, куда попадет заголовок нового подменю.
  • Щелкните правой кнопкой мыши Новое меню и введите заголовок нового подменю в поле Имя появившегося окна. Одновременно можно задать ключ быстрого доступа к нему, поставив символ "" перед той буквой, которая будет этим ключом.
  • Теперь при щелчке заголовка подменю справа или слева от него появится пустое подменю.

    Чтобы добавить новое подменю программно, к объекту, представляющему родительское выпадающее меню, нужно применить метод Add коллекции CommandBarControls. В качестве параметра Type (Тип) нужно использовать значение msoControlPopup.

    В следующем примере в конец выпадающего меню "Ввод документов", расположенного на панели меню "Головное меню", добавляется подменю "о движении товаров".

    Dim CstmPopUp1 As CommandBarPopup
    Set CstmPopUp1 = CstmCtrl.Controls.Add(Type:=msoControlPopup)
    	 CstmPopUp1.Caption = " о движении товаров"

    Вставка и группировка команд

    Office 2000 позволяет добавлять команды к любым встроенным и пользовательским меню, а также изменять внешний вид, группировать и визуально отделять одну группу команд от другой.

    Добавление встроенной команды с помощью окна Настройка

    В диалоговом окне Настройка сделайте модифицируемое меню видимым, а затем:

  • На вкладке Команды выберите в списке Категории категорию добавляемой команды - все команды данной категории будут показаны в списке Команды.
  • Выберите в списке Команды команду и перетащите в то меню или подменю, куда она добавляется. Чтобы выпадающее меню или подменю открылось, показав имеющиеся в нем элементы, протащите команду через заголовок соответствующего выпадающего меню или подменю. Горизонтальная черта отмечает место в списке команд выпадающего меню, куда попадет заголовок нового подменю, когда Вы отпустите кнопку мыши.
  • Скопировать команду можно и иначе: выведите на экран меню с нужной командой и перетащите ее в свое меню при нажатой клавише Ctrl.

    Добавление собственной команды с помощью окна Настройка

    Добавление команды с помощью окна Настройка в собственное или встроенное меню зависит от приложения 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. Как при вставке встроенной команды, выберите в списке Категории команду Макрос и перетащите в меню имя нужного макроса из списка Команды.
  • Добавление команд с помощью VBA

    Добавить новую команду в меню можно, применив метод 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 Print Печать 22 Paste Вставить
    18 New Создать 23 Open Открыть

    Взгляните, как в меню "Проверки" из панели "Головное меню" можно вставить команду проверки правописания Spelling.

    Set mySpell = CommandBars("Головное меню").Controls("Проверки") _
    .Controls.Add(Id:=2)

    Пример построения документа с собственным меню

    Обобщим приведенные сведения по построению меню и создадим документ, в котором все встроенные меню будут отключены и создано собственное иерархическое меню. На верхнем уровне меню будет состоять из одного пункта, оно будет включать два подменю, каждое из которых содержит по одной команде. Приведем процедуру, реализующую создание такого меню:

    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

    Заметьте, вначале, используя свойство Enabled, были отключены все панели. Затем было сформировано головное меню, содержащее всего один пункт, с двумя подменю и командами. Обратите внимание, перед добавлением нового пункта, обычно делается проверка, а не был ли он уже добавлен. Подобная проверка позволяет избежать ошибок, возникающих при попытках добавить уже существующий пункт или удалить несуществующий. Чтобы наш пример был законченным, приведем процедуры, вызываемые в ответ на выбор команд меню Накладная и Счет:

    Public Sub Invoice()
    	MsgBox ("Накладная!")
    End Sub
    
    Public Sub Account()
    	MsgBox ("Счет!")
    End Sub

    Вот как выглядит документ по завершении работы процедуры CreateCustomMenu:

    (рис 11.4) Документ, имеющий собственное меню

    В заключение, приведем процедуру, восстанавливающую стандартное окружение:

    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

    Группировка команд меню

    Разделение групп логически связанных команд меню горизонтальными линиями позволяет пользователям более эффективно работать с большими меню, содержащими разнотипные команды. Сами разделяющие линии командами не являются. Установить или убрать их можно в диалоговом окне Настройка. Для этого в этом окне сделайте видимым модифицируемое меню. Затем щелкните правой кнопкой мыши команду, над которой хотите провести линию. В появившемся меню выберите команду Начало группы (Begin Group). Убирается линия аналогично.

    Ту же задачу разбиения команд на группы можно решить из VBA, присвоив значение True свойству BeginGroup (Начало группы) объекта, представляющего команду, которая должна открывать очередную группу. Чтобы убрать разделяющую линию, присвойте этому свойству False. Вот как выделить группу команд меню "Ввод документов", начинающуюся со вставленной команды "ввод накладной":

    Set InvCommand = CommandBars("Головное меню").Controls("Ввод документов") _
    	.Controls("ввод накладной")
    InvCommand.BeginGroup = True

    Удаление команд меню

    Удаление команд, подменю и меню позволяет упростить работу с приложением, приспособить его к нуждам отдельного пользователя. В Office 2000 можно удалять встроенные и пользовательские выпадающие меню из панелей меню, дочерние подменю из родительских меню, команды из всех видов меню. Единственное, чего сделать нельзя - удалить встроенную панель меню или встроенное всплывающее меню, даже если из них удалены все команды. Главное, что этого делать не нужно ни в коем случае. Панель можно сделать только недоступной или невидимой, что мы и демонстрировали в наших примерах.

    Удаленные из меню встроенные подменю и команды можно восстановить в нужный момент. Собственные же удаленные подменю и команды придется при необходимости воссоздавать заново.

    Удаление команды с помощью окна Настройка

    Для удаления компонента меню нужно в диалоговом окне Настройка модифицируемое меню сделать видимым, щелкнуть правой кнопкой мыши удаляемый элемент и в появившемся меню выбрать команду Удалить (Delete).

    Чтобы удалить целиком пользовательскую панель меню, нужно перейти на вкладку Панели инструментов диалогового окна Настройка и, выбрав в списке Панели инструментов имя удаляемой панели меню, щелкнуть кнопку Удалить.

    Удаление команды с помощью VBA

    Для удаления компонента меню используется метод Delete (Удалить). Этот оператор, например, удаляет выпадающее подменю Favorites из панели меню Web:

    CommandBars("Web").Controls("Favorites").Delete

    Собственную (пользовательскую) панель меню "Головное меню" можно целиком удалить оператором:

    CommandBars("Головное меню").Delete

    Как восстановить удаленные встроенные компоненты меню

    Восстановить можно только встроенный удаленный элемент меню. Как и другие действия над меню, это делается в окне Настройка или из VBA. Если при этом восстановится заголовок выпадающего меню или подменю, вместе с ним восстановится само меню и все его потомки.

    Как всегда, в диалоговом окне Настройка нужно сделать модифицируемое меню видимым. Затем, щелкнув правой кнопкой мыши заголовок выпадающего меню или подменю, которое нужно восстановить, в появившемся меню выберите команду Сброс (Reset).

    Чтобы восстановить встроенную панель меню, перейдите на вкладку Панели инструментов окна Настройка, выберите в списке Панели инструментов имя восстанавливаемой панели меню и щелкните кнопку Сброс(Reset).

    Восстановить встроенный компонент меню программно можно методом Reset. Например, следующий оператор восстанавливает выпадающее подменю Favorites из панели меню Web:

    CommandBars("Web").Controls("Favorites").Reset

    А вот как восстановить всю панель меню Menu Bar из Word:

    CommandBars("Menu Bar").Reset

    Изменение меню во время работы программы

    VBA позволяет изменять и настраивать систему меню приложения динамически во время его работы. Предоставляемые для этого возможности велики. Вы можете заменять одну панель меню на другую, удалять команды меню или делать их временно недоступными ("серыми"), переименовывать команды. Рассмотрим эти возможности подробнее.

    Вывод собственной панели меню

    Чтобы на экране показалась новая панель меню вместо текущей, задайте значение True свойству Visible объекта CommandBar, представляющего панель меню, которая должна появиться. Новая панель меню заменит прежнюю активную панель на экране. Чтобы восстановить прежнюю панель, при завершении работы программы нужно задать свойству Visible значение False.

    В Excel и PowerPoint для замены основной панели приложения применяется процедура, обрабатывающая событие, после которого должна появиться новая панель или макрос. В Word можно обеспечить вывод собственной панели меню при запуске приложения, если заранее активизировать ее и сохранить в проекте Normal. Тогда при следующем запуске эта панель появится на экране как основная. Другой вариант - установить свойство Visible в процедуре обрабатывающей событие Open.

    Динамическое изменение видимости команд меню

    Если некоторые команды меню выполняют действия, связанные с определенными объектами (документами), имеет смысл делать их видимыми при активизации этих объектов и скрывать, когда соответствующие объекты недоступны. Для этого свойству Visible этих команд нужно задать значение True при активизации объекта и False - при его деактивизации (закрытии, удалении и т. п.). Точно так же можно делать видимой и скрывать и панель меню, предназначенную для работы с определенным объектом.

    Проще всего выполнять переустановку свойства Visible в процедурах, обрабатывающих события активизации (открытия, загрузки, появления на экране и т. п.) и деактивизации (закрытия, выгрузки, удаления с экрана и т. п.). Если для данного объекта нет подходящих событий, можно попытаться включить изменение свойства Visible для интересующих нас команд в процедуры, обрабатывающие событие OnAction других команд меню или управляющих кнопок.

    Word сохраняет параметры настройки (в том числе и пользовательские меню) в документах и шаблонах. Поэтому эти компоненты меню видны, если соответствующий документ или шаблон доступен в данном контексте, и они исчезают с экрана, когда документ или шаблон недоступен. Excel же сохраняет пользовательские изменения интерфейса в рабочей памяти, поэтому для управления видимостью компонентов меню применяется изменение свойства Visible в процедурах обработки событий.

    Управление доступом к командам меню

    Иногда удобней управлять доступом пользователя к командам меню, не скрывая и восстанавливая их на экране, а отключая реакции на их выбор и нажатие. Такие команды видны на экране, но отличаются от активных команд своим тусклым, "серым" видом. Для управления доступом к компонентам меню служит булево свойство 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

    Переименование команды меню

    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 = "Открыть базу данных"
    Страницы:

    Программный код большинства примеров данной лекции можно найти в проектах, доступных для просмотра: DocOne.

    Проектирование интерфейса. Меню

    В предыдущих лекциях в примерах и описании VBA использовалась заключительная англоязычная бета - версия Office 2000. При описании интерфейса я перешел на русифицированную бета - версию Office 2000. Я полагаю, что программисту должно быть все равно, с какой версией он работает, как называется соответствующий пункт меню "Сервис" или "Tools". Тем не менее, разумнее описывать интерфейс применительно к русифицированному варианту. Кроме того, это входило в мои планы тестирования этой версии Office 2000.

    Общие объекты Office 2000

    Среди библиотек Office 2000, хранящих объекты, есть библиотеки, связанные с конкретным приложением - Word, Excel, Access, PowerPoint, но не только они. Всякий раз, когда открывается приложение, наряду с библиотекой, связанной с этим приложением, становятся доступными библиотеки общих объектов, где в первую очередь следует отметить библиотеки MSForms и Office. Первая из этих библиотек обеспечивает единство интерфейса при проектировании диалоговых окон (форм). Она содержит объекты, определяющие как само диалоговое окно (форму), так и многочисленные элементы управления, которые могут быть помещены в это окно. Библиотека Office также содержит объекты, используемые при организации интерфейса. В Office 2000 в этой библиотеке появилось много новых объектов: Answer Wizard, Com AddIn, HTML Project, Script, WebPageFont, Language Settings. Но разговор о них пойдет не в этой книге. Заметим, что в чисто интерфейсных объектах существенных изменений не произошло. Говоря о таких объектах, в первую очередь можно выделить объект Assistant, объект CommandBar и коллекцию этих объектов. Объект Assistant и входящий в него объект Baloon предназначены для организации контекстной помощи в более живой визуальной форме, отличной от традиционных окон. Объект CommandBar составляет основу интерфейса, - он представляет панель, на которой расположены команды меню и инструментальные кнопки.

    Коллекция CommandBars

    Пришла пора рассказать о наиболее "почтенных" представителях пользовательского интерфейса - меню и инструментальных кнопках. Интерфейс начинался с меню и до сих пор практически ни одно приложение без него не обходится. Все приложения Office 2000 обладают мощной встроенной системой меню и набором инструментальных панелей. И все эти средства доступны и при работе конечного пользователя с документами Office 2000. Но надо иметь в виду, что для "серьезных" приложений, требующих программирования и являющихся предметом нашей книги, только встроенными средствами не обойтись. Все основные приложения Office 2000 - Excel, Word, PowerPoint и Access разделяют на этапе проектирования единые средства настройки, позволяющие как модификацию встроенных, так и создание пользовательских панелей меню и инструментов. На этапе программирования во всех приложениях также используется единый набор объектов, корневым из которых является коллекция CommandBars, входящая в состав библиотеки Office. Вот как выглядит ее стр уктура:

    (рис 11.1) Структура коллекции CommandBars

    Элементами коллекции являются объекты класса CommandBar, каждый из которых представляет панель команд. Но то, что расположено на панели: меню, подменю, команды меню, кнопки,- все это задается другим объектом - коллекцией CommandBarControls. Объект CommandBar имеет свойство Controls, возвращающее эту коллекцию. Итак, CommandBar (панель команд) задает любую панель, на которой расположено как меню, так и инструментальные кнопки. На каждой панели, как известно, располагается некоторое число элементов. Они и составляют коллекцию CommandBarControls с элементами класса CommandBarControl. Конечно, эти элементы разнотипны и, по сути, являются объектами трех разных классов: CommandBarButton, CommandBarPopup и CommandBarComboBox. Класс, которому будет принадлежать элемент, определяется в момент его создания. В этот же момент определяется и тип элемента. По типу однозначно определяется клас с, но обратное утверждение неверно, например, элемент класса CommandBarComboBox имеет несколько возможных типов.

    Поясним, в чем сущность этих трех классов, в каком случае элемент следует относить к тому или иному классу. Прежде всего, заметим, что "панельные" элементы могут иметь свою сложную внутреннюю структуру. К примеру, у каждого пункта главного меню обычно древовидная структура, при его раскрытии появляются терминальные вершины (команды меню) и вершины - подменю, которые, в свою очередь, содержат терминальные вершины и подменю. Вы ошибаетесь, если полагаете, что инструментальные кнопки можно только щелкать, и что они просто устроены. В Office 2000 в роли кнопок могут выступать такие элементы как ComboBox, TextBox и ListBox. Класс CommandBarButton определяет терминальную вершину (кнопку или команду меню), CommandBarPopup - подменю, CommandBarComboBox - сложно организованные кнопки, заданные элементами управления. Заметьте, что объект PopUp (подменю) имеет свойство Controls, возвращающее коллекцию CommandBarControls , что и обеспечивает требуемую иерархию вложенности меню.

    Свойства и методы коллекции CommandBars

    Коллекция 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

    Вот основные свойства и методы самого объекта 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
  • Коллекция CommandBarControls и ее элементы

    Эта коллекция обладает только традиционными свойствами и методами. Единственное, что следует рассмотреть - это метод 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 позволяют без труда перестраивать меню и панели инструментов, управлять параметрами окон, выбирать нужные форматы представления данных на экране (цвет, шрифт, размер и т. д.), создавать собственные диалоговые окна и размещать на них разнообразные управляющие элементы. Возможность присоединения ActiveX -объектов к формам и документам сделало перечень элементов управления практически неограниченным, поскольку число ActiveX -объектов в доступных разработчикам библиотеках постоянно растет.

    В этой и двух следующих лекциях мы рассмотрим ряд компонент VBA, связанных с проектированием интерфейса, которые и позволяют называть этот язык визуальным. В этой лекции мы изучим способы создания собственных меню. Эти возможности лучше всего поддержаны в Access, но и в других приложениях можно создавать собственные системы меню, как руками, так и с использованием VBA.

    Создание собственных и модификация встроенных меню

    В меню объединяют последовательности, группы, наборы команд (рубрик), одну из которых может выбрать пользователь для совершения очередного действия. Как правило, названия команд в меню достаточно информативны, так что пользователь может легко найти нужную ему команду. Команды для решения близких задач можно объединить в группу, поместив их рядом в одном меню и отделив чертой от команд, решающих другие задачи. В одном меню команды объединяют на основе одного из двух принципов: либо это различные действия над одним объектом, либо однотипные действия над различными объектами. Первый принцип реализован в меню Файл (File) всех приложений Office 2000, объединяющем различные действия над основным объектом приложения: создание, открытие и закрытие, сохранение, пересылка и печать объекта. Меню Вставка (Insert) построено по другому принципу - действие "вставить" выполняется для различных объектов. Если вариантов исполняемых действий много, их структурируют, используя подменю - списки команд, появляющиеся правее или левее выбранной команды родительского меню. Еще один вид меню - контекстные (shortcut) меню, всплывающие при нажатии правой кнопки мыши в определенном контексте. В них можно объединять действия, допустимые (факультативно) в данном контексте. Доступ пользователя к команде меню можно ускорить, определив для нее "горячие" клавиши, нажатие которых эквивалентно выбору этой команды.

    Мы уже рассмотрели основные свойства и методы коллекции CommandBars и ее объектов CommandBar, представляющих панели команд, на которых располагаются меню, подменю, кнопки и другие элементы, образующие коллекцию CommandBarControls. Рассмотрим работу с объектами, относящимися к меню. Эту работу, как правило, можно проводить двумя способами: "визуально", используя встроенные команды и диалоговые окна приложений Office 2000, или "программно", создавая в процедурах VBA объекты указанных классов, задавая и изменяя их свойства соответствующими методами.

    Немного терминологии

    Система меню в Office 2000 включает головную строку меню (menu bar), обычно расположенную в верхней части активного окна. Оно постоянно находится на экране. Изменяться это меню может при переходе к другому активному окну или по командам из программ на VBA. Каждая команда головного меню является именем вертикально расположенного меню, выпадающего при выборе этой команды. Команда такого меню может быть именем подменю, при этом она отмечается направленной вправо стрелкой. Подменю появляется на экране справа или слева от родительского меню, когда пользователь выбирает команду с его именем.

    (рис 11.2) Строка меню Word. Меню "Вид". Подменю "Панели инструментов"

    Здесь в головном меню выбрана команда Вид (View), а в меню Вид - команда Панели инструментов (Toolbars), которая является именем соответствующего подменю. В подменю Панели инструментов выделена команда Настройка (Customize), которая будет неоднократно упоминаться далее в этой лекции, поскольку с ее помощью можно производить многие действия, связанные с изменениями меню. Меню Вид называется родительским по отношению к подменю Панели инструментов, а меню Панели инструментов - дочерним по отношению к меню Вид. Вообще команды подменю тоже могут быть именами отдельных меню и т. д. Таким образом, меню приложений Office 2000 образуют иерархическую (древовидную) структуру. Корень этой структуры - головное горизонтально расположенное меню, его непосредственными потомками являются выпадающие меню, заголовки которых и образуют головное меню. Концевые вершины (листья) этой иерархии - непосредственно исполняемые команды (часто - это вызовы диалоговых окон), а пути от корня к вершинам проходят по заголовкам соответст вующих меню и подменю.

    Возможности настройки и изменения системы меню

    Office 2000 предоставляет широкие возможности для настройки и модификации меню приложений. Пользователи могут создавать новые головные меню, добавлять команды в уже существующие меню и связывать с ними новые подменю. Можно также создавать новые и изменять существующие контекстные меню. Есть средства, позволяющие в любой момент восстановить первоначальную систему меню.

    Возникают вопросы: когда создавать свою собственную систему меню, а когда лишь модернизировать систему приложения? Общий совет Microsoft состоит в том, что если добавления или изменения невелики, то следует модернизировать систему меню, а при существенных изменениях (например, добавлении нескольких новых меню и подменю) целесообразно создавать собственную систему меню. Разумеется, в этом случае следует принимать во внимание будущих пользователей создаваемой прикладной офисной системы, их образование, квалификацию, опыт работы с компьютером и т.д. Для "среднего" пользователя - типичного сотрудника типичной организации - прикладная система над Excel или Access, видимо, должна иметь собственный интерфейс, лишь в небольшой степени использующий встроенные меню, панели инструментов и диалоговые окна Office 2000. Поэтому в большинстве случаев разработчику следует создавать свое головное меню и, возможно, панель инструментов, перекрывающие частично или полностью на экране головное меню и панель инструментов соот ветствующего приложения Office 2000. Другими вариантами построения интерфейса могут быть собственные диалоговые окна или расположение управляющих элементов непосредственно на поверхности основных документов (например, на рабочих листах Excel).

    Создание собственного головного меню

    Согласно существующим формальным и фактическим стандартам проектирования интерфейса, работа прикладной программы должна начинаться с активизации головного меню, которое находится в верхней части окна приложения. Собственное головное меню для прикладной системы можно спроектировать визуально - "руками", вызвав диалоговое окно Настройка (Customize), или используя VBA.

    Использование диалогового окна Настройка

    Во всех приложениях Office 2000 можно спроектировать собственное головное меню визуально, используя для этого диалоговое окно Настройка. Для его вызова нужно в меню Вид выбрать команду Панели инструментов (Toolbars), а затем в появившемся подменю - команду Настройка.

    Новое меню создается так:

  • Щелкните кнопку Создать (New) на вкладке "Панели инструментов".
  • В появившемся окне "Создание панели инструментов" (New Toolbar) введите имя создаваемого меню и щелкните кнопку OK. На экране появится плавающее меню с заданным именем. При работе в Access появляются дополнительные возможности, позволяющие установить свойства панели, что нельзя сделать в других приложениях - Word, Excel, Power Point. При работе в Access:
  • Щелчком кнопки Свойства (Properties) выведите на экран окно "Свойства панели инструментов" (Toolbar Properties).
  • Установите в списке Тип (Type) команду "Строка меню" (Menu Bar) в качестве типа создаваемой панели и закройте окно.
  • Вот, как выглядит окно свойств:

    (рис 11.3) Окно свойств командной панели в приложении Access

    Имя нового меню появится в списке Панели инструментов на вкладке Панели инструментов.

    В окне "Свойства панели инструментов" можно задать и другие свойства создаваемого меню. В частности, свойство закрепление (Docking) и опция перемещение (Allow Moving) позволяют разрешить или полностью или частично запретить перемещение меню по экрану. Для головного меню приложения естественно установить постоянное место на экране. Опция настройка (Allow Customizing) позволяет после завершения создания меню отключить возможность его модификации, а если отключить опцию отображение/скрытие (Allow Showing/Hiding), то меню будет на экране постоянно.

    Создание меню с помощью VBA

    Новое меню в 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)

    Добавление выпадающих меню

    Добавлять новые меню (подменю) и команды к существующим меню, встроенным в Office 2000 или созданным пользователем, также можно двумя способами: используя диалоговое окно Настройка или VBA. Рассмотрим, как добавить выпадающее меню к существующей панели меню (головному меню).

    Использование диалогового окна Настройка

    Это способ добавления меню или команды более нагляден, и в отличие от процедуры создания нового меню, его можно применять в любом приложении Office 2000, а не только в Access. Откройте диалоговое окно Настройка, а затем:

  • Если модифицируемого меню на экране нет, щелкните кнопку выбора рядом с именем изменяемого меню в списке Панели инструментов на одноименной вкладке Панели инструментов.
  • В списке Категории (Categories) на вкладке Команды (Commands) выберите Новое меню (New Menu).
  • Выберите команду Новое меню (New Menu) справа в списке Команды (Commands) и перетащите ее в то меню, к которому Вы хотите добавить новое меню. При этом знак I отмечает то место в меню, куда попадет имя нового меню, когда Вы отпустите кнопку мыши.
  • Щелкните правой кнопкой мыши Новое меню (New Menu), и введите имя этого меню в поле Имя (Name) появившегося окна. Одновременно можно задать ключ быстрого доступа к этому меню, поставив символ "" перед буквой, которая будет этим ключом.
  • Если теперь щелкнуть имя нового меню, на экране под ним появится пустой прямоугольник. Ниже мы покажем, как вставлять в созданное меню новые команды.

    Как добавить встроенное меню

    Диалоговое окно Настройка позволяет просто добавить (скопировать) любое из встроенных меню к меню, которое Вы создаете. При этом исходное встроенное меню не изменяется. Для этого в диалоговом окне Настройка сделайте модифицируемое меню видимым, а затем:

  • Выберите в списке Категории вкладки Команды команду Встроенные меню (Built­in Menus).
  • Выберите в списке Команды имя нужного встроенного меню и перетащите его на нужное место в панель меню, к которой Вы хотите добавить выбранное встроенное выпадающее меню. Знак I отмечает место на панели, куда попадет встроенное меню.
  • Есть и другой способ копирования встроенного меню: выберите его на его собственной панели и перетащите в свою панель меню при нажатой клавише Ctrl.

    Добавление выпадающего меню с помощью VBA

    Чтобы добавить новое меню программно, нужно использовать метод 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 = "Ввод документов"

    Добавление подменю

    Подменю (или дочернее меню) примыкает к боковой стороне другого меню - родительского - на уровне той команды родительского меню, которая является заголовком подменю. Подменю можно добавлять как к выпадающим меню, так и к другим подменю и к всплывающим меню. Сначала добавляется пустое подменю, затем в него вставляются команды. Добавить подменю можно двумя способами: с помощью диалогового окна Настройка и через вызов метода Add в VBA.

    Рассмотрим вначале визуальный способ. Для добавления подменю нужно, как и раньше, активизировать диалоговое окно Настройка и сделать модифицируемое меню видимым. После этого нужно действовать так.

  • На вкладке Команды в списке Категории выберите команду Новое меню.
  • Выберите команду Новое меню справа в списке Команды и перетащите ее в то место меню, куда нужно добавить подменю. Чтобы выпадающее меню открылось, показав уже имеющиеся в нем элементы, протащите Новое меню через имя выпадающего меню. При этом горизонтальная черта будет отмечать то место в списке рубрик выпадающего меню, куда попадет заголовок нового подменю.
  • Щелкните правой кнопкой мыши Новое меню и введите заголовок нового подменю в поле Имя появившегося окна. Одновременно можно задать ключ быстрого доступа к нему, поставив символ "" перед той буквой, которая будет этим ключом.
  • Теперь при щелчке заголовка подменю справа или слева от него появится пустое подменю.

    Чтобы добавить новое подменю программно, к объекту, представляющему родительское выпадающее меню, нужно применить метод Add коллекции CommandBarControls. В качестве параметра Type (Тип) нужно использовать значение msoControlPopup.

    В следующем примере в конец выпадающего меню "Ввод документов", расположенного на панели меню "Головное меню", добавляется подменю "о движении товаров".

    Dim CstmPopUp1 As CommandBarPopup
    Set CstmPopUp1 = CstmCtrl.Controls.Add(Type:=msoControlPopup)
    	 CstmPopUp1.Caption = " о движении товаров"

    Вставка и группировка команд

    Office 2000 позволяет добавлять команды к любым встроенным и пользовательским меню, а также изменять внешний вид, группировать и визуально отделять одну группу команд от другой.

    Добавление встроенной команды с помощью окна Настройка

    В диалоговом окне Настройка сделайте модифицируемое меню видимым, а затем:

  • На вкладке Команды выберите в списке Категории категорию добавляемой команды - все команды данной категории будут показаны в списке Команды.
  • Выберите в списке Команды команду и перетащите в то меню или подменю, куда она добавляется. Чтобы выпадающее меню или подменю открылось, показав имеющиеся в нем элементы, протащите команду через заголовок соответствующего выпадающего меню или подменю. Горизонтальная черта отмечает место в списке команд выпадающего меню, куда попадет заголовок нового подменю, когда Вы отпустите кнопку мыши.
  • Скопировать команду можно и иначе: выведите на экран меню с нужной командой и перетащите ее в свое меню при нажатой клавише Ctrl.

    Добавление собственной команды с помощью окна Настройка

    Добавление команды с помощью окна Настройка в собственное или встроенное меню зависит от приложения 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. Как при вставке встроенной команды, выберите в списке Категории команду Макрос и перетащите в меню имя нужного макроса из списка Команды.
  • Добавление команд с помощью VBA

    Добавить новую команду в меню можно, применив метод 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 Print Печать 22 Paste Вставить
    18 New Создать 23 Open Открыть

    Взгляните, как в меню "Проверки" из панели "Головное меню" можно вставить команду проверки правописания Spelling.

    Set mySpell = CommandBars("Головное меню").Controls("Проверки") _
    .Controls.Add(Id:=2)

    Пример построения документа с собственным меню

    Обобщим приведенные сведения по построению меню и создадим документ, в котором все встроенные меню будут отключены и создано собственное иерархическое меню. На верхнем уровне меню будет состоять из одного пункта, оно будет включать два подменю, каждое из которых содержит по одной команде. Приведем процедуру, реализующую создание такого меню:

    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

    Заметьте, вначале, используя свойство Enabled, были отключены все панели. Затем было сформировано головное меню, содержащее всего один пункт, с двумя подменю и командами. Обратите внимание, перед добавлением нового пункта, обычно делается проверка, а не был ли он уже добавлен. Подобная проверка позволяет избежать ошибок, возникающих при попытках добавить уже существующий пункт или удалить несуществующий. Чтобы наш пример был законченным, приведем процедуры, вызываемые в ответ на выбор команд меню Накладная и Счет:

    Public Sub Invoice()
    	MsgBox ("Накладная!")
    End Sub
    
    Public Sub Account()
    	MsgBox ("Счет!")
    End Sub

    Вот как выглядит документ по завершении работы процедуры CreateCustomMenu:

    (рис 11.4) Документ, имеющий собственное меню

    В заключение, приведем процедуру, восстанавливающую стандартное окружение:

    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

    Группировка команд меню

    Разделение групп логически связанных команд меню горизонтальными линиями позволяет пользователям более эффективно работать с большими меню, содержащими разнотипные команды. Сами разделяющие линии командами не являются. Установить или убрать их можно в диалоговом окне Настройка. Для этого в этом окне сделайте видимым модифицируемое меню. Затем щелкните правой кнопкой мыши команду, над которой хотите провести линию. В появившемся меню выберите команду Начало группы (Begin Group). Убирается линия аналогично.

    Ту же задачу разбиения команд на группы можно решить из VBA, присвоив значение True свойству BeginGroup (Начало группы) объекта, представляющего команду, которая должна открывать очередную группу. Чтобы убрать разделяющую линию, присвойте этому свойству False. Вот как выделить группу команд меню "Ввод документов", начинающуюся со вставленной команды "ввод накладной":

    Set InvCommand = CommandBars("Головное меню").Controls("Ввод документов") _
    	.Controls("ввод накладной")
    InvCommand.BeginGroup = True

    Удаление команд меню

    Удаление команд, подменю и меню позволяет упростить работу с приложением, приспособить его к нуждам отдельного пользователя. В Office 2000 можно удалять встроенные и пользовательские выпадающие меню из панелей меню, дочерние подменю из родительских меню, команды из всех видов меню. Единственное, чего сделать нельзя - удалить встроенную панель меню или встроенное всплывающее меню, даже если из них удалены все команды. Главное, что этого делать не нужно ни в коем случае. Панель можно сделать только недоступной или невидимой, что мы и демонстрировали в наших примерах.

    Удаленные из меню встроенные подменю и команды можно восстановить в нужный момент. Собственные же удаленные подменю и команды придется при необходимости воссоздавать заново.

    Удаление команды с помощью окна Настройка

    Для удаления компонента меню нужно в диалоговом окне Настройка модифицируемое меню сделать видимым, щелкнуть правой кнопкой мыши удаляемый элемент и в появившемся меню выбрать команду Удалить (Delete).

    Чтобы удалить целиком пользовательскую панель меню, нужно перейти на вкладку Панели инструментов диалогового окна Настройка и, выбрав в списке Панели инструментов имя удаляемой панели меню, щелкнуть кнопку Удалить.

    Удаление команды с помощью VBA

    Для удаления компонента меню используется метод Delete (Удалить). Этот оператор, например, удаляет выпадающее подменю Favorites из панели меню Web:

    CommandBars("Web").Controls("Favorites").Delete

    Собственную (пользовательскую) панель меню "Головное меню" можно целиком удалить оператором:

    CommandBars("Головное меню").Delete

    Как восстановить удаленные встроенные компоненты меню

    Восстановить можно только встроенный удаленный элемент меню. Как и другие действия над меню, это делается в окне Настройка или из VBA. Если при этом восстановится заголовок выпадающего меню или подменю, вместе с ним восстановится само меню и все его потомки.

    Как всегда, в диалоговом окне Настройка нужно сделать модифицируемое меню видимым. Затем, щелкнув правой кнопкой мыши заголовок выпадающего меню или подменю, которое нужно восстановить, в появившемся меню выберите команду Сброс (Reset).

    Чтобы восстановить встроенную панель меню, перейдите на вкладку Панели инструментов окна Настройка, выберите в списке Панели инструментов имя восстанавливаемой панели меню и щелкните кнопку Сброс(Reset).

    Восстановить встроенный компонент меню программно можно методом Reset. Например, следующий оператор восстанавливает выпадающее подменю Favorites из панели меню Web:

    CommandBars("Web").Controls("Favorites").Reset

    А вот как восстановить всю панель меню Menu Bar из Word:

    CommandBars("Menu Bar").Reset

    Изменение меню во время работы программы

    VBA позволяет изменять и настраивать систему меню приложения динамически во время его работы. Предоставляемые для этого возможности велики. Вы можете заменять одну панель меню на другую, удалять команды меню или делать их временно недоступными ("серыми"), переименовывать команды. Рассмотрим эти возможности подробнее.

    Вывод собственной панели меню

    Чтобы на экране показалась новая панель меню вместо текущей, задайте значение True свойству Visible объекта CommandBar, представляющего панель меню, которая должна появиться. Новая панель меню заменит прежнюю активную панель на экране. Чтобы восстановить прежнюю панель, при завершении работы программы нужно задать свойству Visible значение False.

    В Excel и PowerPoint для замены основной панели приложения применяется процедура, обрабатывающая событие, после которого должна появиться новая панель или макрос. В Word можно обеспечить вывод собственной панели меню при запуске приложения, если заранее активизировать ее и сохранить в проекте Normal. Тогда при следующем запуске эта панель появится на экране как основная. Другой вариант - установить свойство Visible в процедуре обрабатывающей событие Open.

    Динамическое изменение видимости команд меню

    Если некоторые команды меню выполняют действия, связанные с определенными объектами (документами), имеет смысл делать их видимыми при активизации этих объектов и скрывать, когда соответствующие объекты недоступны. Для этого свойству Visible этих команд нужно задать значение True при активизации объекта и False - при его деактивизации (закрытии, удалении и т. п.). Точно так же можно делать видимой и скрывать и панель меню, предназначенную для работы с определенным объектом.

    Проще всего выполнять переустановку свойства Visible в процедурах, обрабатывающих события активизации (открытия, загрузки, появления на экране и т. п.) и деактивизации (закрытия, выгрузки, удаления с экрана и т. п.). Если для данного объекта нет подходящих событий, можно попытаться включить изменение свойства Visible для интересующих нас команд в процедуры, обрабатывающие событие OnAction других команд меню или управляющих кнопок.

    Word сохраняет параметры настройки (в том числе и пользовательские меню) в документах и шаблонах. Поэтому эти компоненты меню видны, если соответствующий документ или шаблон доступен в данном контексте, и они исчезают с экрана, когда документ или шаблон недоступен. Excel же сохраняет пользовательские изменения интерфейса в рабочей памяти, поэтому для управления видимостью компонентов меню применяется изменение свойства Visible в процедурах обработки событий.

    Управление доступом к командам меню

    Иногда удобней управлять доступом пользователя к командам меню, не скрывая и восстанавливая их на экране, а отключая реакции на их выбор и нажатие. Такие команды видны на экране, но отличаются от активных команд своим тусклым, "серым" видом. Для управления доступом к компонентам меню служит булево свойство 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

    Переименование команды меню

    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 = "Открыть базу данных"
    Вернуться к учебному плану