Возвращение параметров выбранного сообщения

<< Click to Display Table of Contents >>

Navigation:  Проект > Элементы дерева объектов > Палитра ФБ > Служебные > Скрипт > Руководство и примеры > Работа с журналами >

Возвращение параметров выбранного сообщения

Журнал имеет возможность задания временного диапазона вывода сообщений (Начало и Конец), в нем можно выполнять поиск в полях определенных столбцов (в том числе через регулярные выражения). Все это позволяет использовать журнал, как инструмент сохранения и вывода сохраненных документов - например сохраненных отчетов. Используя скрипт, мы можем сформировать сообщение с определенными параметрами, в которые, например можно передать Начало и Конец отчета или путь к сохраненному отчету, затем, также с помощью скрипта, можно получить выбранное оператором сообщение, получить его параметры и обработать. Пример такого скрипта мы и разберем.

Сделаем заготовки - создадим скрипт с дискретным входом, на него подадим сигнал от команды Сгенерировать. Также создадим БД коннектор Firebird и назначим в него архивацию сообщений.

sluzhebnie_skript_rukovodstvo_i_primery_rabota_s_zhurnalami_vozvrashchenie_parametrov_vybrannogo_soobshcheniya

С помощью данного скрипта мы будем генерировать сообщения.

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;
    }
}

Проверим работу в режиме исполнения. Сгенерируем несколько сообщений и выберем любой из них:

sluzhebnie_skript_rukovodstvo_i_primery_rabota_s_zhurnalami_vozvrashchenie_parametrov_vybrannogo_soobshcheniya1

На выходах скрипта появились значения с параметрами скрипта.

Такой скрипт можно легко адаптировать под любую подобную задачу.

Скачать готовый пример можно по ссылке.