Давайте на нескольких простых примерах разберемся с технологией программирования в Visio. В качестве языка программирования используется встроенный Visual Basic for Applications (VBA) — широко распространенный и достаточно простой язык. Поэтому основной целью будем считать не тонкости языка, а основы его применения именно в Visio.
Программы опираются на объектную модель Visio. Все, что мы видим в Visio, является набором взаимосвязанных объектов. Любое программное воздействие — это либо добавление и удаление объекта, либо изменение каких-то свойств имеющихся объектов. При этом обычно решаются две задачи:
- найти нужный объект, т.е. определить ссылку на него;
- изменить свойство объекта.
Путь связи объектов в приложении и связи объектов с их свойствами, методами и событиями, то есть иерархию объектов, называют объектной моделью. Она отражает все типы объектов, доступных в Visio.
Нужно отметить, что в программах могут дополнительно применяться и другие объекты, например объекты ActiveX. Это дает возможность использовать стандартные диалоги Windows, кнопки, формы, выпадающие списки и т.д. Такие объекты не входят в объектную модель Visio, но подключаются к ней как элементы коллекций OLE-объектов или шейпов OLEObjects или Shapes. Ниже мы уточним этот способ доступа.
С чего начинать программирование
Программирование в Visio — это просто. Пожалуй, самым трудным моментом для начинающих является создание и запуск своей первой программы, а дальше только совершенствуй технику и отрабатывай тонкости.
VBA встроен непосредственно в Visio, поэтому можно писать программы, не запуская никаких других приложений. Один из вариантов начала программирования — запуск редактора VBA. Нажмите Tools/Macros/Visual Basic Editor и увидите окно редактора.
По умолчанию оно запускается в виде, разбитом на две части: слева окно проекта (Project Explorer), в котором просматривается структура вашего проекта, справа окно для написания кода программы. При необходимости можно раскрыть еще и окно Object Browser, в котором просматриваются свойства и методы любого из используемых в проекте объектов.
Напишем в правом окне три строчки:
Sub Hello() |
MsgBox «Первый макрос» |
End Sub |
Это первый макрос с именем «Hello», который должен просто нарисовать информационное окошко с надписью «Первый макрос». Переходим в окно рисунка Visio, выполняем команды Tools/Macros/Macros и видим, что в списке доступных для выполнения макросов появился только что написанный нами ThisDocument.Hello(). Выберем его и нажмем кнопку Run внизу окна. В качестве результата выполнения макроса на экране появляется информационное окошко.
Второй вариант создания макроса — в окне рисунка Visio выполняем команды Tools/Macros/Macros. Пишем имя макроса, например Hello2 и нажимаем кнопку Create (создать).Во-первых, при этом мы переходим в окно редактора VBA, во-вторых, видим, что оно изменилось. В окне проекта появляется папка Modules, в ней выбранный компонент Module1, а в правом окне вместо созданного ранее макроса появилась заготовка для нового с именем Hello2. Впишем между двумя строчками заготовки свою строку: MsgBox «Второй макрос»
Перейдем в окно рисунка и посмотрим каким стал состав доступных макросов. После выполнения команд Tools/Macros/Macros мы наблюдаем, что в списке появилось еще и имя Macros.Module1.Hello2. Это составное имя включает имя документа (или проекта) Macros, имя программного модуля Module1 и собственно имя макроса Hello2. Программный модуль может содержать множество макросов, а в проект можно включить множество модулей. Включение нового модуля выполняется командой Insert/Module в окне редактора VBA. Естественно, модули можно и удалять.
И, наконец, еще один вариант — выполним в окне редактора VBA команду Insert/UserForm. При этом появляется панель, на которой можно располагать кнопки, и инструменты для работы. В окне проекта можно увидеть новую коллекцию Forms с формой UserForm1. Щелкнув по левой кнопке в окне проекта с всплывающей подсказкой View Code, увидим еще одну заготовку макроса с именем Sub UserForm_Click().
Если два наших первых макроса были так сказать «отвлеченными», то этот будет вызываться в качестве реакции на событие — щелчок мышью по пользовательской форме. Полный список событий для объекта UserForm виден в выпадающем списке в правой части окна редактора «Procedure». Когда появится несколько объектов, то для каждого из них будет свой список событий.
Таким образом макросы могут быть введены как принадлежность документа, оформлены в отдельный модуль, который можно экспортировать или импортировать как программу VBA или являться реакцией на событие, связанное с определенным объектом. Запускаться макросы могут как вручную оператором, так и по определенному событию.
Объектная модель
Теперь посмотрим, как программа взаимодействует с объектами. В наши задачи не входит описание полной объектной модели Visio, возьмем только часть, касающуюся шейпов.
Как видим, проект Visio включает одно приложение (Application), а следующие уровни иерархии оформляются в коллекции. То есть приложение содержит коллекцию документов (Documents), ее элементом является документ (Document). Документ содержит коллекцию страниц (Pages), состоящую из нескольких страниц. Элементом страницы является коллекция Shapes из шейпов (Shape).
Так как шейп может являться группой, то он в свою очередь может содержать коллекцию шейпов. Доступ ко многим свойствам шейпов предоставляется через шейп-лист (ShapeSheet). В объектной модели для этого служат уровни секция шейп-листа (Seсtion), строка секции (Row) и ячейка (Cell).
На том же уровне, что и лист рисунка, выступает трафарет. Документ может содержать коллекцию трафаретов (Masters) из отдельных трафаретов (Master). На каждом трафарете размещается коллекция шейпов (в данном случае это будут мастер-шейпы).
Вот и все основные объекты для управления шейпами. Программа может добавлять элемент в коллекцию, удалять его или менять какие-то свойства объектов.
Доступ к объектам чаще всего производится либо по индексу соответствующей коллекции, либо по имени, либо по идентификатору. Немного проще получается ссылка на объект при его добавлении в коллекцию, она формируется в момент создания экземпляра шейпа. Рассмотрим, что делается в следующем фрагменте программы:
Set stnObj = Documents(«Basic Network Shapes 3D.vss») |
Set mastObj = stnObj.Masters(«Server») |
Set shpObj1 = ActivePage.Drop(mastObj, 2, 10) |
shpObj1.Text = «Первый сервер» |
Сначала определяется ссылка на трафарет, то есть оператор Set stnObj находит в коллекции документов открытого приложения объект — трафарет «Basic Network Shapes 3D.vss» и записывает указатель на него в переменную stnObj, через которую в дальнейшем можно будет ссылаться на этот объект.
Следующей строкой переменной mastObj присваивается ссылка на мастер-шейп с именем «Server» из коллекции шейпов этого трафарета. Затем метод Drop объекта Page (в данном случае для указания на активную страницу используется специальный объект ActivePage) добавляет к коллекции Shapes этой страницы экземпляр выбранного мастер-шейпа. Ссылкой на него будет shpObj1.
И, наконец, строка shpObj1.Text = «Первый сервер» изменяет свойство Text этого шейпа. В результате выполнения этой программы на странице рисунка появится шейп Server, в текстовом поле которого будет написано «Первый сервер».
Способы идентификации шейпа
Теперь рассмотрим способы идентификации шейпа. Следующая программа должна перебрать все шейпы активной страницы и для каждого из них распечатать имя и идентификатор ID. Так как результаты работы программы поясняют дальнейшие объяснения, рекомендуется выполнить этот пример практически.
Запускаем Visio, открываем новый документ на основе шаблона Basic Diagram, рисуем на чистом листе единственный прямоугольник (для вывода результатов). Запускаем VBA редактор, щелкаем по кнопочке View Code и на появившемся листе пишем следующую программу.
Sub Example1() |
s1 = «» |
For i = 1 To ActivePage.Shapes.Count |
s1 = s1 + «Name= » + ActivePage.Shapes(i).Name |
s1 = s1 + » Id= » + Str(ActivePage.Shapes(i).ID) + vbCrLf |
Next |
ActivePage.Shapes(1).Text = s1 |
End Sub |
Пусть наша программа запускается при двойном щелчке по нарисованному прямоугольнику. Для этого выделяем его и выполняем команду Format/Behavior/Double-Click/RunMacro/ThisDocument.Example1.
Переходим на лист рисунка и дважды щелкаем по прямоугольнику. В нем появляется надпись Name= Sheet.1 Id= 1. То есть программа опросила всю коллекцию шейпов на единственном листе рисунка, нашла там только один шейп и вывела в прямоугольник в качестве надписи его имя (Sheet.1) и идентификатор 1.
Для того, чтобы пояснить принцип формирования имен и идентификаторов, последовательно перетаскиваем с трафарета на лист рисунка два треугольника и квадрат, а затем рисуем одну линию. Дважды щелкаем по нашему первому прямоугольнику и смотрим, как образованы имена шейпов.
Первый шейп получил имя Sheet.1, то есть когда шейп не является экземпляром мастер-шейпа, а просто нарисован, то его имя образуется из слова Sheet и порядкового номера шейпа на листе.
Второй шейп получил имя мастер-шейпа без всякой добавки.
Третий шейп называется Triangle.3, то есть дополнительные копии получают имя мастер-шейпа плюс порядковый номер шейпа на листе.
Четвертый и пятый именуются по уже указанным правилам.
Удаляем первый треугольник и опять дважды щелкаем по квадрату. Как видим, одна строчка исчезла, а остальные имена остались без изменений. Если теперь добавить еще шейп, то он получит пропущенный идентификатор (заполняются дырки).
После этих экспериментов можно перечислить способы обращения к шейпу:
по индексу в коллекции | ActivePage.Shapes(i).Name |
по имени | Set shpObj = shpsObj.Item(«Desktop PC») |
по имени с идентификатором | Set shpObj = shpsObj.Item(«Sheet.5») |
(можно еще работать с уникальным идентификатором, но этот момент пока опустим).
Каталог трафарета
Теперь рассмотрим, как получить каталог трафарета. В общем-то это делается почти так же, как и со страницей рисунка, только вместо ActivePage мы обязаны прямо выбрать трафарет из коллекции документов и вместо коллекции шейпов Shapes будем использовать коллекцию мастер-шейпов Masters. Вот пример, формирующий список мастер-шейпов в трафарете Basic Shapes.vss.
Sub Example2() |
Set stnObj = Documents(«Basic Shapes.vss») |
s1 = «» |
For i = 1 To stnObj.Masters.Count |
s1 = s1 + «Name= » + stnObj.Masters(i).Name |
s1 = s1 + » Id= » + Str(stnObj.Masters(i).ID) + vbCrLf |
Next |
ActivePage.Shapes(1).Text = s1 |
End Sub |
Шаблон для документирования
Разобранные здесь примеры сведены в один шаблон Macros1.zip, а чтобы он не был уж слишком простым, туда добавлена еще формочка и несколько кнопок. С помощью такого шаблона легко посмотреть имена сразу всех имеющихся на рисунке шейпов или состав любого трафарета.
Формочка вызывается командой Tools/Macros/Macros…/ThisDocument.Example3/Run. Кнопка Новый обновляет список имеющихся в документе трафаретов, один из которых можно потом выбрать из выпадающего списка. Кнопка Трафарет выводит имена мастер-шейпов в окно. Кнопка Документ выводит туда же имена шейпов с листа рисунка. Кнопка Copy сохраняет список в буфере Windows, откуда он может быть вставлен в нужный редактор.