Для русскоязычных пользователей Visio. Начинающих и профессионалов. Где взять, как сделать, что купить и т.д.

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

Геннадий Туманов. 3 августа 2014 г.

Как это выглядит

Для более предметного разговора о том, как может обеспечиваться двустороняя синхронизация данных между Visio и базой данных, было создано приложение-пример, выполняющее такую функцию.

В качестве базы использован файл Excel 2007. Само приложение выполнено в виде набора макросов в Visio 2007. Для его функционирования достаточно версии Standard (Стандартная).

Задача приложения - создать и поддерживать базу различных компоновок мебели в помещении. То есть в таблице базы данных хранится множество проектов, а Visio используется для их редактирования.

Данные простейшие: тип мебели, координаты и угол поворота.

Небольшое видео, демонстрирующее работу приложения - файл AVI.

Основные технические решения

Возможности приложения видно из дополнительного пользовательского меню.

Для реализации задачи понадобились две функции работы с проектами:
Загрузить проект - строит рисунок по данным, выбранным из базы.
Сохранить новый проект - сохраняет в базе данные одного рисунка.

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

Вся индикация различий при сравнении выполняется в графической форме путем подкраски шейпов. В результате редактирования могут измениться (в данном примере) координаты и угол поворота объекта. Кроме того могут быть добавлены новые объекты или удалены имеющиеся. Соответственно, при выполнении функции "Проверить" измененные шейпы красятся зеленым цветом, новые красным, а вместо удаленных временно рисуются фантомы по данным базы. После обновления рисунка или базы раскраска и фантомы исчезают.

Структура данных

Фрагмент базы данных (в данном случае листа Excel) показан на рисунке.

Это всего лишь одна таблица, в которой запись (строка) соответствует одной единице мебели. Она содержит уникальный идентификатор, тип мебели (соответствует имени используемого мастер-шейпа), координаты, угол и ссылку на проект.

Механизм ADODB позволяет обращаться к такой таблице с использованием SQL запросов.

Структура приложения

Статическая структура приложения показана на рисунке

Рисунок получен реинжинирингом созданного набора макросов с помощью штатного дополнения Visio для работы с UML диаграммами.

Весь набор макросов размещен в четырех модулях. ThisDocument содержит макросы для навески пользовательского меню и обработчики для меню. Модуль Scheme хранит глобальные переменные и пару функций для работы с базой. Основной функционал собран в двух классах: специализированной коллекции Project и члене этой коллекции fItem, ответственном за одну запись в базе или одну единицу мебели на рисунке. Класс fItem содержит не только передаваемые атрибуты (идентификатор, координаты), но и ссылку Shape на шейп, размещаемый на странице Visio.

Аналогичный подход, кстати, используется в подобных приложениях довольно часто. Над объектной моделью Visio надстраиваются прикладные объекты, включающие при необходимости "штатные" объекты Visio. Они могут быть очень простыми, как в данном примере, и сложными, в том числе со своей иерархией, в более серьезных приложениях.

В итоге при работе приложения две коллекции (BasCol с данными, полученными из базы, и DocCol с данными, полученными из документа). Все операции сравнения и изменения данных выполняются методами входящих объектов.

Подробности выполнения операций с данными

Для связи между документом и базой используется ADODB. Все взаимодействие происходит через два основных объекта: ConnectionString и RecordSet. Первый отвечает за подключение, второй - за передачу данных.

Фрагмент макроса (метода объекта fItem), выбирающий из базы данные одного проекта и складывающий их в коллекцию.

    Set rs1 = New ADODB.Recordset

    strSQL1 = "Select * from [Sheet1$] Where InstanceID > 0 and ProjectName like '" & ProjName & "'"

    rs1.Open strSQL1, cn1, adOpenStatic, adLockOptimistic

    For i = 1 To rs1.RecordCount

        Dim tmpItem As fItem

        Set tmpItem = New fItem

        tmpItem.InstanceID = rs1.Fields("InstanceID").Value

        tmpItem.fType = rs1.Fields("fType").Value

        tmpItem.x = rs1.Fields("x").Value

        tmpItem.y = rs1.Fields("y").Value

        tmpItem.ang = rs1.Fields("ang").Value

        Item.Add tmpItem

        rs1.MoveNext

    Next

    rs1.Close

Фрагмент кода для выборки из базы максимального имеющегося значения уникального идентификатора.

    strSQL1 = "Select Max(InstanceID) From [Sheet1$]"

    Set rs1 = New ADODB.Recordset

    rs1.Open strSQL1, cn1, adOpenStatic, adLockOptimistic

    GetMaxInstanceID = rs1.Fields(0).Value

Метод прорисовки шейпа по данным объекта fItem.

Public Sub Draw()

    Dim sh As Visio.Shape

    Dim Mas As Visio.Master

    Set Mas = ActiveDocument.Masters(fType)

    Set sh = ActivePage.Drop(Mas, 1, 1)

    sh.Cells("PinX") = x

    sh.Cells("PinY") = y

    sh.Cells("Prop.ID").Formula = Chr(34) & InstanceID & Chr(34)

    sh.Cells("Angle") = ang

    Set Shape = sh

End Sub

В целом основной объем функционального кода, содержащийся в модулях Project и fItem, занимает порядка 450 строк кода. Это с учетом того, что решение делалось для примера и не подвергалось серьезной оптимизации.

Резюме

Таким образом, в примере продемонстрирована реализация простейшей задачи синхронизации рисунка Visio с базой данных через механизм ADODB.

В этом решении Visio используется для редактирования содержимого базы данных графическими методами.

Факт, что для реализации решения потребовалось порядка 450 строк кода подтверждает эффективность метода для использования в сложных решениях, связанных с внешними данными.