воскресенье, 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 строк кода подтверждает эффективность метода для использования в сложных решениях, связанных с внешними данными.

Комментариев нет:

Отправить комментарий