strEntry = Prop.Name & “: “ & Prop.Value
Set mItem = lvwMfgData.ListItems.Add(iIndex, Prop.Name, Prop.Name)
iIndex = iIndex + 1
mItem.SubItems(1) = Prop.Value
Next Prop
End Sub
Private Sub LoadInstallationData()
Dim InstallationData As PIProperty
Dim Prop As PIProperty
Dim strEntry As String
Dim mItem As ListItem
Dim iIndex As Integer
lvwInstallationData.ListItems.Clear
lvwInstallationData.ColumnHeaders.Clear
lvwInstallationData.ColumnHeaders.Add , , “Property”, lvwInstallationData.Width * 3 / 16
lvwInstallationData.ColumnHeaders.Add , , “Value”, lvwInstallationData.Width * 12 / 16
lvwInstallationData.View = lvwReport
SetInstallationData = Controller.PIProperties.Item(“Installation Data”)
iIndex = 1
For Each Prop In InstallationData.PIProperties
strEntry = Prop.Name & “: “ & Prop.Value
Set mItem = lvwInstallationData.ListItems.Add(iIndex, Prop.Name, Prop.Name)
iIndex = iIndex + 1
mItem.SubItems(1) = Prop.Value
NextProp
EndSub
Усовершенствуем наш модуль. Добавим тип контроллера к данным производителя, при этом новая информация отобразится при следующей загрузке экрана; никаких изменений в клиентском приложении при этом не потребуется.
Данный экран PI ProcessBook отображает стандартным образом работу контура управления, а также отображает имя производителя и информацию об установке. Для того, чтобы повторно использовать этот экран, нужно прежде всего добавить VBA-код, заменяющий использованные при конфигурировании экрана PI-точки, на операторы связи с Модульной базой данных. Для нужно задать свойства TagName или Trace объектов экрана. PI ProcessBook автоматически присваивает имена этим объектам. В режиме создания PI ProcessBook позволяет по правому щелчку мыши вывести свойства каждого объекта. Отображается имя объекта; можно также переименовать объект. Следующие VBA-функции извлекают соответствующие псевдонимы (alias) из модуля контроллера и и затем используют свойство datasource (источник данных) псевдонима для присвоения точке PI:
Private Sub LoadAliasesIntoTrend()
Dim Alias As PIAlias
DimPtAsPIPoint
‘ Убрать существующие точки
While Trend.TraceCount <> 0
Trend.RemoveTrace 1
Wend
Set Alias = Controller.PIAliases.Item(“Output”)
Set Pt = Alias.DataSource
Trend.AddTrace Pt.Name
Set Alias = Controller.PIAliases.Item(“ProcessVariable”)
Set Pt = Alias.DataSource
Trend.AddTrace Pt.Name
Set Alias = Controller.PIAliases.Item(“Setpoint”)
Set Pt = Alias.DataSource
Trend.AddTrace Pt.Name
Trend.GetFormat().ShowTagName = True
End Sub
Private Sub LoadAliasesIntoBarChart()
Dim Alias As PIAlias
Dim Pt As PIPoint
Set Alias = Controller.PIAliases.Item(“ProcessVariable”)
Set Pt = Alias.DataSource
Bar.SetTagName (Pt.Name)
Set Alias = Controller.PIAliases.Item(“SetPoint”)
Set Pt = Alias.DataSource
Bar1.SetTagName (Pt.Name)
Set Alias = Controller.PIAliases.Item(“Output”)
Set Pt = Alias.DataSource
Bar4.SetTagName (Pt.Name)
End Sub
Private Sub LoadAliasesIntoValues()
Dim Alias As PIAlias
Dim Pt As PIPoint
Set Alias = Controller.PIAliases.Item(“Proportion”)
Set Pt = Alias.DataSource
Value.SetTagName (Pt.Name)
Set Alias = Controller.PIAliases.Item(“Integral”)
Set Pt = Alias.DataSource
Value2.SetTagName (Pt.Name)
Set Alias = Controller.PIAliases.Item(“Derivative”)
Set Pt = Alias.DataSource
Value3.SetTagName (Pt.Name)
Set Alias = Controller.PIAliases.Item(“Mode”)
Set Pt = Alias.DataSource
Value9.SetTagName (Pt.Name)
EndSub
Предположим, что нам потребовались дополнительные контроллеры (на работающих предприятиях обычно очень много контроллеров). Мы воспользуемся дополнительными точками-имитаторами и создадим еще 9 модулей контроллеров. Приведенный код легко соответствующим образом модифицировать, либо можно воспользоваться инструментом конфигурирования. После того, как контроллеры созданы, мы добавим элемент управления "pick list" (список выбора) к экрану PI ProcessBook. При загрузке экрана мы будем добавлять ссылки на все контроллеры.
Масштабируемость и иерархия. Для того, чтобы использовать несколько контроллеров в одной группе, необходима масштабируемость. Масштабируемое решение состоит в том, чтобы организовать модули в более глубокую иерархию. Начиная с контроллеров и двигаясь "вверх", мы построим всю иерархию в соответствии со следующим подходом.
Масштабируемость (PIHeadingSets). Модульная база данных PI обеспечивает механизм для присвоения имен категориям и задания рекомендуемого уровня в иерархии. Каждой категории можно присвоить PIHeading (заголовок). Объекты типа PIHeading группируются в объект PIHeadingSet. Поскольку не существует ограничений на схемы иерархий, то нет и ограничений на количество объектов PIHeadingSet, которые можно сконфигурировать. Мы реализуем указанные группировки путем создания набора заголовков (heading set) и добавления 6 заголовков. Эти заголовки используются идентификации или присвоения меток модулям в данной схеме. Представим набор заголовков в виде таблицы:
Вот VB-код, который конфигурирует набор заголовков для данной схемы:
Private Sub cmdCreateHeadingSet_Click()
Dim Srv As Server
Dim HeadingSet As PIHeadingSet
Dim Heading As PIHeading
Set Srv = Servers.DefaultServer
Srv.Open
Set HeadingSet = Srv.PIModuleDB.PIHeadingSets.Add(“S-88 Equipment”, “S 88 equipment for example”)
Set Heading = HeadingSet.PIHeadings.Add(“Enterprise”, “S-88 Equipment definition”, 1)
Set Heading = HeadingSet.PIHeadings.Add(“Site”, “S-88 Equipment definition”, 2)
Set Heading = HeadingSet.PIHeadings.Add(“Area”, “S-88 Equipment definition”, 3)
Set Heading = HeadingSet.PIHeadings.Add(“Line”, “S-88 Equipment definition”, 4)
Set Heading = HeadingSet.PIHeadings.Add(“Unit”, “S-88 Equipment definition”, 5)
Set Heading = HeadingSet.PIHeadings.Add(“Controller”, “S-88 Equipment definition”, 6)
End Sub
Объект PIHeading имееттрисвойства: name (имя), description (описание) и level (уровень). Имя обязательно должно быть уникальным внутри набора заголовков. Уровень указывает желаемую позицию в иерархии; причем чем меньше это число, тем выше объект находится в иерархии. Свойство level (уровень), однако, не задает жестко иерархию.
Иерархия оборудования. Мы создадим иерархическую модель оборудования, начиная с самого верха иерархии и продвигаясь вниз к модулям. Контроллеры будут являться частью модуля. Поскольку один и тот же модуль может существовать в нескольких позициях иерархии, нет необходимости заново создавать каждый контроллер или перемещать контроллеры. Мы создадим новую иерархию и затем поместим контроллеры в соответствующие модули. Метод PIModules выполняет эту задачу..
Далее приведен блок VB-кода, где мы создаем модули более высокого уровня, а затем добавляем контроллеры в модуль. Метод insert (вставить) позволяет сделать ссылку на существующий контроллер в коллекции PIModules другого модуля.
Dim Enterprise As PIModule
Dim Site As PIModule
Dim Area As PIModule
Dim Line As PIModule
Dim Unit As PIModule
Dim Controllers As PIModule
Dim Controller As PIModule
Set Srv = PISDK.Servers.DefaultServer
Srv.Open (“uid=piadmin”)
On Error Resume Next
Set Controllers = Srv.PIModuleDB.PIModules.Item(“Controllers”)
Set Enterprise = Srv.PIModuleDB.PIModules.Add(“Demo Enterprises”)
Set Site = Enterprise.PIModules.Add(“Cleveland”)
Set Area = Site.PIModules.Add(“Area C-1”)
Set Line = Area.PIModules.Add(“Line 4”)
Set Unit = Line.PIModules.Add(“R-401”)
Set Controller = Controllers.PIModules.Item(“tic-104”)
Unit.PIModules.Insert Controller
Set Controller = Controllers.PIModules.Item(“tic-105”)
Unit.PIModules.Insert Controller
5. Внедрениемодулявприложение PI ProcessBook
Теперь, когда у нас имеется иерархическое представление оборудования, необходимо запрограммировать экран PI ProcessBook таким образом, чтобы он мог воспользоваться этой иерархией. Мы применим два подхода: 1) каскад из элементов управления типа "combo box"(комбинированный список выбора) 2) элемент управления Tree View (просмотр в виде дерева). В первом подходе мы используем combo box для сайта (site), зоны (area), линии (line), модуля (unit), и наконец, контроллеров. Изменение выбранных элементов в верхнем окне приведет обновлению нижних окон - в них появятся соответствующие модули.
Вот код VBA, который загружает элементы "combo box"; он вызывается при открытии экрана:
Private Sub LoadAllComboBoxes()
Dim i As Integer
For Each Site In Enterprise.PIModules
cboSites.AddItem Site.Name
Next Site
Set Site = Enterprise.PIModules.Item(1)
For Each Area In Site.PIModules
cboAreas.AddItem Area.Name
Next Area
Set Area = Site.PIModules.Item(1)
For Each Line In Area.PIModules
cboLines.AddItem Line.Name
Next Line
Set Line = Area.PIModules.Item(1)
For Each Unit In Line.PIModules
cboUnits.AddItem Unit.Name
Next Unit
Set Unit = Line.PIModules.Item(1)
For Each Controller In Unit.PIModules
cboControllers.AddItem Controller.Name
Next Controller
Set Controller = Unit.PIModules.Item(1)
cboSites.ListIndex = 0
cboAreas.ListIndex = 0
cboLines.ListIndex = 0
cboUnits.ListIndex = 0
cboControllers.ListIndex = 0
End Sub
Для каждого combo box имеется обработчик события выбора (select). Окна "combo box", находящиеся выше в иерархии, вызывают событие “select” у ближайшего снизу окна в иерархии. Это автоматически приводит к генерации последовательности событий выбора, что заставляет обновиться все окна, а вслед за ними, и экраны. Вотсоответствующийкод:
Private Sub cboControllers_Click()
Dim Reload As Boolean
Reload = False
If Controller Is Nothing Then
Reload = True
ElseIf cboControllers.Text <> Controller.Name Then
Reload = True
End If
If Reload Then
‘Set Controller = Controllers.PIModules.Item(cboControllers.Text)
Set Controller = Unit.PIModules.Item(cboControllers.Text)
LoadMfgData
LoadInstallationData
LoadAliasesIntoDisplay
End If
End Sub
Private Sub cboUnits_Click()
Dim Reload As Boolean
Reload = False
If Unit Is Nothing Then
Reload = True
ElseIf cboUnits.Text <> Unit.Name Then
Reload = True
End If
If Reload Then
Set Unit = Line.PIModules.Item(cboUnits.Text)
cboControllers.Clear
For Each Controller In Unit.PIModules
cboControllers.AddItem Controller.Name
Next Controller
If cboControllers.ListCount > 0 Then
cboControllers.ListIndex = 0
End If
End If
End Sub
Private Sub cboLines_Click()
Dim Reload As Boolean
Reload = False
If Line Is Nothing Then
Reload = True
ElseIf cboLines.Text <> Line.Name Then
Reload = True
End If
If Reload Then
Set Line = Area.PIModules.Item(cboLines.Text)
cboUnits.Clear
For Each Unit In Line.PIModules
cboUnits.AddItem Unit.Name
Next Unit
If cboUnits.ListCount > 0 Then
cboUnits.ListIndex = 0
Else
cboControllers.Clear
End If
End If
End Sub
Private Sub cboAreas_Click()
Dim Reload As Boolean
Reload = False
If Area Is Nothing Then
Reload = True
ElseIf Area.Name <> cboAreas.Text Then
Reload = True
End If
If Reload Then
Set Area = Site.PIModules.Item(cboAreas.Text)
cboLines.Clear
For Each Line In Area.PIModules
cboLines.AddItem Line.Name
Next Line
If cboLines.ListCount > 0 Then
cboLines.ListIndex = 0
Else
cboUnits.Clear
cboControllers.Clear
End If
End If
End Sub
Private Sub cboSites_Click()
If cboSites.Text <> Site.Name Then
Set Site = Enterprise.PIModules.Item(cboSites.Text)
cboAreas.Clear
For Each Area In Site.PIModules
cboAreas.AddItem Area.Name
Next Area
If cboAreas.ListCount > 0 Then
cboAreas.ListIndex = 0
Else
cboLines.Clear
cboUnits.Clear
cboControllers.Clear
End If
End If
End Sub
Другой способ создания структуры для навигации состоит в том, чтобы использовать элемент управления, представляющий данные в виде дерева. В данном подходе это дерево будет отображать структуру модулей нашего предприятия. При выборе узла обработчик события считывает заголовок модуля. Если это контроллер, то экран будет обновлен.
Первый шаг состоит в том, чтобы при загрузке экрана загрузить модули в элемент управления – дерево. В данном примере будет загружена вся структура. В усовершенствованном варианте можно было бы загружать нижние узлы дерева в тот момент, когда они выбираются. Иерархические структуры данных можно загружать при помощи рекурсивного кода (re-entrant code) – то есть функций, которые вызывают сами себя. Вот код, который загружает модули в элемент управления "tree view":