Панели инструментов Работа с панелями инструментов и меню в VBA

          Назад



8. Работа с панелями инструментов и меню


Работа с панелями инструментов и меню в VBA, объекты CommandBar, CommandBarControl, CommandBarPopup, контекстные меню

Очень часто в приложении VBA вам потребуются свои наборы меню и панелей инструментов вместо стандартных, предусмотренных приложением. Работу с меню и панелями инструментов обеспечивает коллекция CommandBars, которая находится в объекте Application (об этом важном объекте мы будем говорить в следующих модулях). Коллекция CommandBars содержит, как ясно из названия, набор объектов CommandBar(панели инструментов и меню), каждый из них, в свою очередь — коллекцию CommandBarControls (набор элементов из которых состоит панель/меню), а эта коллекция представляет из себя хранилище элементов, из которых и состоит меню. Таких элементов может быть три:

  • CommandBarButton — кнопка или элемент меню, который используется для выполнения программы или подпрограммы;
  • CommandBarComboBox — сложный элемент меню/панели управления (поле ввода, раскрывающийся список, поле со списком);
  • CommandBarPopup — меню или вложенное меню.

Пример создания собственной панели инструментов может выглядеть очень просто:

Dim CBar1 As CommandBar

Set CBar1 = CommandBars.Add("Документы", msoBarTop)

CBar1.Enabled = True

CBar1.Visible = True

У нас появилась новая панель инструментов Документы (см. рис. 8.1), которое можно, к примеру, убрать через меню Настройка -> Панели инструментов, однако пока она совершенно бесполезна: в нем нет ни одной кнопки. Для того, чтобы они появились, необходимо добавить новый элемент типа CommandBarControl (одного из трех типов, перечисленных выше) в коллекцию CommandBarControls для этого меню.

Рис. 8.1 В центре рисунка — пустая панель инструментов Документы

Но вначале — про некоторые важные свойства и методы объекта CommandBar:

  • BuiltIn — это свойство определяет, является ли данная панель/меню встроенной для этого приложения (то есть предусмотренной в нем разработчиками приложения Office). Менять значение этого свойства нельзя. Это свойство очень удобно использовать, чтобы убрать все стандартные меню, или, наоборот, убрать все свои меню, оставив только стандартные;
  • Context — определяет, где именно находится программный код для вашего меню (в Normal.dot, файле документа и т.п.). Можно использовать для проверок в случае потенциальной возможности вызова разных меню с одинаковыми именами;
  • Controls — через это свойство можно получить коллекцию элементов управления CommandBarControls, которая нам, скорее всего, потребуется;
  • Enabled — "включение/отключение" панели;
  • Height, Left, Top и Width — очевидные свойства, относящиеся к расположению панели в окне приложения;
  • Index, Name и NameLocal — эти свойства позволяют найти нужную нам панель в коллекции CommandBars. Name — это программное имя объекта, NameLocal — имя, которое будет видно пользователю, Index — это просто номер данной панели;
  • Protection — позволяет запретить пользователю убирать старые кнопки из этой панели или размещать на ней новые;
  • Type — наверное, самое важное свойство. Определяет, чем будет данная панель/меню (панелью инструментов, обычным меню или контекстным меню, доступным по щелчку правой кнопкой мыши). Однако это свойство доступно только для чтения. Тип объекта CommandBar определяется при выполнении метода Add() коллекции CommandBars, при этом определяется очень хитро — через второй параметр этого метода. В нашем случае вызов этого метода выглядит как

Set CBar1 = CommandBars.Add("Документы", msoBarTop, True, False)

Первый параметр ( "Документы") — это, конечно, имя объекта (название панели). Второй параметр ( msoBarTop) — либо положение пристыкованной панели ( msoBarTop, msoBarBottom, msoBarLeft, msoBarRight), либо знак того, что панель непристыкована ( msoBarFloating), либо вообще указание на то, что это — контекстное меню, которое до щелчка правой кнопкой мыши не видна ( msoBarPopup). Свойство Visible для контекстного меню неприменимо.

Как будет выглядеть в итоге панель — как меню или панель инструментов, зависит от того, какие элементы вы туда поместите.

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

Dim But1 As CommandBarControl

Set But1 = CBar1.Controls.Add(msoControlButton)

But1.Caption = "Кнопка 1"

Вроде бы ничего не произошло — перед нами та же пустая панель. Однако, если навести указатель мыши на начало панели, в нем можно увидеть пустую кнопку, которая называется "Кнопка 1" (см. рис. 8.2).

Рис. 8.2 На панели инструментов Документы появлилась почти невидимая Кнопка 1

Как видно из кода, мы использовали для создания элемента управления (кнопки в панели инструментов) метод Add() коллекции Controls объекта CommandBar (у нас он называется CBar1). Свойства и методы у этой коллекции стандартные, как у множества других коллекций:

  • свойство Application возвращает ссылку на объект приложения (Word, Excel и т.п.)
  • свойство Count позволяет узнать, сколько всего элементов управления помещено в эту коллекцию;
  • свойство Item позволяет по индексу (номеру) получить ссылку на объект элемента управления CommandBarControl в этой коллекции;
  • метод Add() (которым мы и воспользовались) позволяет добавить элемент управления в эту коллекцию (удаление элемента управления производится уже при помощи метода Delete() самого элемента управления).

Чуть подробнее о методе Add(). Этот метод принимает пять необязательных параметров из которых два первых параметра — очень важны. Первый параметр — Type, он определяет тип передаваемого в коллекцию элемента управления. Таких типов — пять: msoControlButton (кнопка — то есть в итоге получится панель инструментов), msoControlEdit (будет создано поле для ввода текста), msoControlDropdown (ниспадающий список), msoControlComboBox (комбинированный список), or msoControlPopup (пункт меню), например, чтобы наша кнопка превратилась в начальный пункт ниспадающего меню (см. рис. 8.3), в нашем коде можно изменить один этот параметр:

Dim But1 As CommandBarControl

Set But1 = CBar1.Controls.Add(msoControlPopup)

But1.Caption = "Меню 1"

Рис. 8.3 На созданной нами панели инструментов появился пункт меню

Второй важный параметр метода Add() — параметр ID. Этот параметр позволяет привязать элемент управления к уже имеющемуся в системе встроенному элементу управления. Например, чтобы добавить кнопку печати, этот параметр должен быть равен 4, а чтобы добавить кнопку предпросмотра документа, этот параметр должен быть равен 5. Если оставить этот параметр пустым, или указать для него значение 1, то будет создан пользовательский элемент управления, не привязанный ни к каким встроенным.

Остальные параметры этого метода относятся к созданию идентификатора элемента управления, его положению относительно других элементов управления и должен ли он быть постоянным или временным.

Конечно, работа с панелью управления/меню на этом не завершена. Нам потребуется еще донастроить свойства элементов управления. Например, для кнопки из первого примера нам, как минимум, нужно еще определить изображение, которое будет на кнопке, и процедуру, которая при нажатии на нее будет называться. Для объекта CommandBarButton важнейшие свойства, методы и события приводятся ниже:

  • Caption — надпись на элементе управления. Для кнопки выводится в виде всплывающей подсказки, а для пункта меню это — название пункта.
  • Enabled — включен или отключен данный элемент управления. Обычно используется для предупреждения ошибок пользователя.
  • FaceId (только для кнопок) — возможность воспользоваться системной картинкой для кнопки (не назначая ей соответствующую функцию). Например, значение 4 присвоит кнопке изображение принтера. В Word и Excel встроено несколько тысяч иконок, и поэтому вместо создания иконки, всегда есть возможность подобрать готовую.
  • Id — идентификатор встроенной функции, назначенной этой кнопке. Если вы назначили этой кнопке пользовательскую процедуру, то значение Id будет всегда равно 1.
  • Index — номер элемента управления в коллекции Controls. Используется для выполнения всяких служебных операций с элементами управления.
  • Mask — возможность наложить на рисунок объекта маску для показа только части рисунка. Маска выглядит как отдельный рисунок, прозрачные части которого должны быть белыми, а непрозрачные — черными.
  • OnAction — самое важное свойство элемента управления. Его значение используется, когда активизируется элемент управления (щелчок по кнопке или пункту меню, завершение ввода текста в текстовом поле, выбор нового значения в списке). Предназначено для указания запускаемой процедуры или внешнего приложения (COM Add In). Пример: But1.OnAction = "MySub".
  • Parameter — это свойство можно использовать для передачи параметров вызываемой подпроцедуре или просто для хранения своих данных. Работает с типом данных String.
  • Picture — это свойство позволяет назначить рисунок (иконку) кнопке панели инструментов. Чаще используется не оно, а свойство FaceId (выше). Если есть необходимость, то необходимые иконки можно подобрать из большой коллекции, которая есть в Visual Studio, или воспользоваться одним из свободно доступных генераторов иконок.
  • ShortcutText — текст с описанием клавиатурного сочетания, назначенного этой кнопке или пункту меню.
  • State — вид кнопки — обычная, утопленная или обведенная рамкой.
  • Style — еще одно свойство, влияющее на внешний вид. Позволяет определить, как будет выглядеть кнопка: будет показана только иконка, только надпись или и то, и другое вместе в разных вариантах.
  • ToolTip — определяет текст всплывающей подсказки. По умолчанию "всплывает" значение свойства Caption.
  • Type — возвращает тип элемента управления (использоваться для изменения типа не может!)
  • Visible — будет или не будет этот элемент управления видимым.
  • метод Delete() — позволяет удалить кнопку из коллекции кнопок;
  • метод Execute() — запускает на выполнение то, что определено при помощи свойства OnAction;
  • Reset() — вернуться к исходным параметрам кнопки после внесенных изменений;

У этого объекта есть единственное событие — Click. Оно также позволяет определить реакцию на нажатие кнопки, но работать с ним сложнее, чем со свойством OnAction.

В принципе, для работы с панелями инструментов этого вполне достаточно. Однако меню — ниспадающие и контекстные — устроены несколько сложнее. В ниспадающем меню вам потребуется еще определить вложения элементов, а в контекстном меню — еще и привязать это меню к какому-то объекту.

Для работы с вложенными меню используется точно та же коллекция Controls, которой мы уже пользовались. Единственное отличие — эта коллекция Controls принадлежит не объекту CommandBar, а объекту CommandBarPopup — то есть другому меню! В нашем примере вложение будет выглядеть так:

'Создаем стандартный объект CommandBar

Dim CBar1 As CommandBar

Set CBar1 = CommandBars.Add("Документы", msoBarTop)

CBar1.Enabled = True

CBar1.Visible = True

 

Dim Menu1 As CommandBarPopup

Dim SubMenu1 As CommandBarPopup

Dim SubMenu1Item As CommandBarButton

 

Set Menu1 = CBar1.Controls.Add(msoControlPopup) ' Создаем верхнее меню

Menu1.Caption = " Меню 1"

 

Set SubMenu1 = Menu1.Controls.Add(msoControlPopup) ' Создаем вложенное меню

SubMenu1.Caption = "Подменю 1"

 

'Создаем элемент во вложенном подменю и назначаем ему процедуру Proc1

Set SubMenu1Item = SubMenu1.Controls.Add(msoControlButton)

SubMenu1Item.FaceId = 5

SubMenu1Item.Caption = "Элемент подменю"

SubMenu1Item.OnAction = "Proc1"

То, что получилось, можно посмотреть на рис. 8.4.

Рис. 8.4 Наше меню приобретает законченные очертания

Конечно, можно добавлять элементы не только в свои меню, но и во встроенные. Добавление происходит точно так же, а найти нужное встроенное меню можно при помощи цикла For Each и проверки значения свойства Name.

Контекстные меню (в справке VBA — shortcut menus) — это меню, которые открываются по щелчку правой кнопкой мыши. С ними работа выглядит так:

Set CBar1 = CommandBars.Add ("Мое контекстное меню", msoBarPopup , , True )

Set MenuItem1 = CBar1.Controls.Add

MenuItem1.FaceId = 3

MenuItem1.Caption = "Элемент меню 1"

Set MenuItem2 = CBar1.Controls.Add

MenuItem2.FaceId = 5

MenuItem2.Caption = "Элемент меню 2"

Как мы видим, все очень просто и стандартно. Однако если просто выполним этот код, то никакого контекстного меню не появится: необходимо еще добавить вызов метода ShowPopup():

CBar1.ShowPopup

Тогда контекстное меню возникнет в том месте, где сейчас находится указатель мыши (можно передать этому методу координаты места появления).

Конечно, этот метод нужно положить в обработчик события, связанного с правой кнопкой мыши, а его как раз и нет для многих объектов. Например, в Excel для листа есть событие BeforeRightClick, а для документа Word такого события нет. Но и в этом случае у нас останется возможность добавить свои пункты в стандартное контекстное меню.




Далее