<< Click to Display Table of Contents >> Navigation: Проект > Элементы дерева объектов > Палитра ФБ > Служебные > Скрипт > Руководство и примеры > Работа с журналами > Возвращение параметров выбранного сообщения |
Журнал имеет возможность задания временного диапазона вывода сообщений (Начало и Конец), в нем можно выполнять поиск в полях определенных столбцов (в том числе через регулярные выражения). Все это позволяет использовать журнал, как инструмент сохранения и вывода сохраненных документов - например сохраненных отчетов. Используя скрипт, мы можем сформировать сообщение с определенными параметрами, в которые, например можно передать Начало и Конец отчета или путь к сохраненному отчету, затем, также с помощью скрипта, можно получить выбранное оператором сообщение, получить его параметры и обработать. Пример такого скрипта мы и разберем.
Сделаем заготовки - создадим скрипт с дискретным входом, на него подадим сигнал от команды Сгенерировать. Также создадим БД коннектор Firebird и назначим в него архивацию сообщений.
С помощью данного скрипта мы будем генерировать сообщения.
public partial class ФБ : ScriptBase
{
bool? M = false;
public override void Execute()
{
if (Выполнен == true && M == false)
{
string MessageText = "Сформирован отчет";
var oper = HostFB.TreeItemHlp.Project.CurrentComputer.Operators[HostFB.TreeItemHlp.Project.RTPermissions.CurrentUser];
string Comment = string.Format("{0};{1}", DateTime.Now.AddMinutes(-1), DateTime.Now);
HostFB.FireEvent(1, MessageText, 192, DateTime.UtcNow, 0, oper, Comment);
}
M = Выполнен;
}
}
Код скрипта простой - в нем формируется текст сообщения "Сформирован отчет", который квитируется от имени текущего оператора, и в качестве комментария передается время начала и конца разделенных точкой с запятой. Для примера берется текущее время для конца, и минус одна минута для начала. В реальном проекте это могут быть отдельные входы скрипта (только обязательно проверьте, что на этих входах есть значения).
Теперь сделаем скрипт который будет обращаться к журналу и определять какое сообщение выбрал оператор. После этого можно проанализировать текст комментария и выдать его на выходы.
Подключаться к журналу нужно только в момент когда открыта мнемосхема. Можно определить это с помощью ФБ "Управление документом", но ранее мы уже рассмотрели как можно в скрипте определить открытие мнемосхемы.
Сделаем в методе Start подписку на открытие и закрытие окон.
DocumentWindowService DWS;
public override void Start()
{
DWS = HostFB.TreeItemHlp.Project.GetService<DocumentWindowService>();
DWS.WindowOpened += WindowService_WindowOpened;
DWS.WindowClosed += WindowService_WindowClosed;
ПодпискаВключена = false;
}
В методе на открытие окна напишем код, который уже по большей части, нам знаком:
public void WindowService_WindowOpened(IAttributeHlp attribute, IMnemoInfoHlp info)
{
if (attribute.TreeItem == HostFB.TreeItemHlp.ParentObject && attribute.Name == "Мнемосхема" && info.CallType == MasterSCADA.Interfaces.ECallType.ctDocument)
{
//Ссылка на текущий проект
var Project = HostFB.TreeItemHlp.Project;
//получаем корневой объект
var ObjectParent = (ITreeItemHlp)HostFB.TreeItemHlp.Parent;
//получаем журнал
RTManager.Instance.ThreadHolder.BeginInvoke(new ThreadStart(delegate
{
foreach (Trend journal in Project.GetService<TrendService>().Opened)
{
var host = journal.Host as System.Windows.Forms.Control;
Object name;
if (host == null) continue;
name = WinFormsControlBase.GetAmbientProperty(host, WindowlessControlBase.DISPID.DISPID_AMBIENT_NAME);
if (name.ToString() != ИмяЖурнала || journal.Attribute.TreeItem.ID != ObjectParent.ID) continue;
journal.PropertyChanged += journal_PropertyChanged;
ПодпискаВключена = true;
Journal = journal;
}
}));
}
}
Здесь происходит обращение к тренду расположенному на мнемосхеме. Новых здесь только вот эти строки:
journal.PropertyChanged += journal_PropertyChanged;
ПодпискаВключена=true;
Journal=journal;
Здесь мы производим подписку в методе journal_PropertyChanged на изменение свойств журнала, именно через изменение этого свойства мы и определим выбор сообщения. Далее включается выход "ПодпискаВключена" (данный выход носит скорее сервисный характер), а также сохраняем указатель на журнал, чтобы потом можно было с ним работать в методе journal_PropertyChanged.
Теперь осталось обработать выбранное сообщение в методе journal_PropertyChanged
private void journal_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "CurrentEvent")
{
try
{
var firstselectedRec = Journal.CurrentEvent;
if (firstselectedRec == null) return;
if (firstselectedRec.AlarmCategory.Name != "Информация") return;
string Comment = firstselectedRec.Comment;
string[] Arr = Comment.Split(';');
Начало = DateTime.Parse(Arr[0]);
Конец = DateTime.Parse(Arr[1]);
}
catch
{
HostFB.FireEvent(1, "Ошибка обработки сообщения");
}
}
}
Сначала мы проверяем что наше изменение - это текущее сообщение (CurrentEvent). Затем мы обращаемся к текущему сообщению журнала, проверяем что его категория "Информация". Если сообщение корректное, то можно взять его комментарий, используя свойство Comment.
Теперь нужно сделать разбор комментария, для используем стандартный метод string.Split, а результат преобразовать через метод DateTime.Parse.
На всякий случай обработку лучше завернуть в try-catch.
При закрытии мнемосхемы, нужно обязательно отписаться от изменения свойств:
public void WindowService_WindowClosed(IAttributeHlp attribute, IMnemoInfoHlp info)
{
if (attribute.TreeItem == HostFB.TreeItemHlp.ParentObject && attribute.Name == "Мнемосхема" && info.CallType == MasterSCADA.Interfaces.ECallType.ctDocument)
{
if (Journal.MessageControl1 != null)
Journal.PropertyChanged -= journal_PropertyChanged;
ПодпискаВключена = false;
}
}
Проверим работу в режиме исполнения. Сгенерируем несколько сообщений и выберем любой из них:
На выходах скрипта появились значения с параметрами скрипта.
Такой скрипт можно легко адаптировать под любую подобную задачу.
Скачать готовый пример можно по ссылке.