В проекте рассмотренном в прошлой статье одним из компонентов был скрипт, позволяющий получить выбранное пользователем сообщение в журнале. В проекте, комментарий сообщения хранил путь к файлу осциллограммы, который впоследствии можно было открыть.
Поскольку данный функционал может быть полезен и в других случаях, мы решили разобрать данный скрипт в отдельной статье.[spoiler]
Распространенной задачей для SCADA системы является формирование отчетов. При этом отчет может иметь сложную форму и логику формирования, например – формирование отчета циклического процесса (варка, закалка, травление). Такие отчеты необходимо строить строго за определенный интервал (когда был запущен и остановлен процесс), зачастую со вспомогательными параметрами (например, номер изделия). Если возникнет необходимость вновь построить этот отчет в MasterSCADA, то необходимо указать исходные параметры отчета. Также необходимо иметь перечень таких отчетов, с датами их формирования. Для решения этой задачи мы и воспользуемся скриптом, описанным в прошлой статье – мы адаптируем его для нашей задачи.
Поскольку цель статьи рассмотреть только скрипт, то сам отчет будет простой формы – простой периодический отчет, с одним параметром. Также в объект добавлены команды Начало и Конец – для задания временного интервала отчета. Команда Сформировать отчет начнет формирование отчета – подав сигнал на вход ФБ Управление документом.
Теперь сделаем скрипт, который сначала сформирует сообщение, которое сохранит Начало и Конец.
Для этого добавим объект Перечень отчетов – в нем мы разместим все переменные необходимые для выбора и открытия отчета. Добавим в него скрипт и создадим следующий код:
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}",Начало,Конец); HostFB.FireEvent(1,MessageText, 192,DateTime.UtcNow,0,oper,Comment); } M=Выполнен; } } |
Начиная с версии 3.9 в MasterSCADA можно генерировать сообщения с помощью ФБ «Скрипт C#» - именно это и делает метод HostFB.FireEvent. Данный метод имеет несколько перегрузок – подробное описание данного метода можно найти в справке к скрипту.
В нашем случае используется перегрузка с 8 аргументами:
ID сообщения - оно создается на вкладке Список сообщений;
текст сообщения – в данном случае просто «Сформирован отчет». В реальных проектах можно сделать более сложный текст, который позволит понять, что за отчет был сформирован (например номер изделия, заказчик и т.д.);
признак качества – в данном случае 192 (GOOD);
метка времени – в данном случае текущее время по UTC;
номер типизированного объекта (в данном случае 0 – не типизированный).
Наиболее важные это два оставшихся параметра – они используются если необходимо квитировать сообщение. Мы будем квитировать наше сообщение из скрипта, и в качестве комментария к квитированию указывать параметры Начало и Конец – это более красивое решение, чем добавлять их в текст сообщения (хотя такой вариант тоже допустим):
оператор – оператор которым производится квитирование;
текст примечания.
Текущего оператора мы получаем с помощи свойства:
var oper=HostFB.TreeItemHlp.Project.CurrentComputer.Operators[HostFB.TreeItemHlp.Project.RTPermissions.CurrentUser]; |
Теперь рассмотрим сам текст примечания. Здесь все просто. С помощью стандартного метода C# - string.format производится формирование строки – состоящей из строкового представления Начало и Конец, разделенным символом «точка с запятой». Если у вас будет не 2 параметра, а больше, просто продолжите строку – “{0};{1};{2} и т.д.” и укажите после Начало и Конец, ваши переменные. Метод сам их преобразует к строке.
В режиме исполнения, при подаче сигнала на вход Выполнен, будет сформировано сообщение с текущим временем, и комментарий с параметрами отчета. Все это мы сможем увидеть в журнале. В нашем проекте мы будет подавать сигнал на вход от команды Сформировать отчет, в реальных проектах это может быть, например, сигнал о завершении процесса.
Теперь рассмотрим скрипт, который обработает выбранное сообщение из журнала. Сначала рассмотрим метод Execute (метод вызывается при опросе ФБ):
string ИмяЖурнала = "Журнал"; public override void Execute() { if (ОкноОткрыто==true) { //Ссылка на текущий проект var проект = HostFB.TreeItemHlp.Project; //получаем корневой объект var объект = (ITreeItemHlp)HostFB.TreeItemHlp.Parent; //получаем журнал RTManager.Instance.ThreadHolder.BeginInvoke(new ThreadStart(delegate { foreach (Trend journal in проект.GetService<TrendService>().Opened) { var host = journal.Host as System.Windows.Forms.Control; Object name; if (host!=null) { name = WinFormsControlBase.GetAmbientProperty(host, WindowlessControlBase.DISPID.DISPID_AMBIENT_NAME); if (name.ToString()!=ИмяЖурнала || journal.Attribute.TreeItem.ID!=объект.ID) continue; Journal=journal; Выбрана=false; journal.MessageControl1.SelectionChanged += MessageControl1_SelectionChanged; } } })); } } |
В данном методе проверяется что журнал действительно открыт, и производится подписка на изменение выделенных сообщений – в этом случае будет вызываться метод MessageControl1_SelectionChanged.
Данный код не требует какой-либо правки. Единственное – если ваш журнал будет иметь имя отличное от «Журнал», то исправьте константу ИмяЖурнала перед методом.
Наиболее важным для нас как раз является метод MessageControl1_SelectionChanged – в нем мы обработаем выбранное сообщение.
private void MessageControl1_SelectionChanged(object sender, SelectionChangedArgs e) { //обработка выбранного в журнале сообщения var firstselectedRec =Journal.MessageControl1.SelectedItem as EventRec; var allRecs = e.Object.Cast<EventRec>().ToArray(); if (allRecs.Length>0) { if (allRecs[0].AlarmCategory.Name!="Информация") return; //парсинг комментария string Comment=allRecs[0].Comment; var sub=Comment.Split(';'); if (sub.Length==2) { try { Начало=DateTime.Parse(sub[0]); Конец=DateTime.Parse(sub[1]); } catch { HostFB.FireEvent(1,"Ошибка обработки сообщения"); return; } } Выбрана=true; } } |
В начале метода происходит получение коллекции выбранный сообщений. Необходимо убедится, что выбрано хотя бы одно сообщение. Сообщений может выбрано несколько, но мы будем обрабатывать самое первое – с нулевым индексом. У сообщения мы берем свойство Comment – это как раз и есть примечание при квитировании. Начало и конец у нас представлены в виде строки разделенных символом «точка с запятой». Для разбора используется стандартный метод string.split.
Убеждаемся, что сформированы две подстроки и делаем их преобразование. Для этого также используются стандартные методы C# - Parse. На всяких случай подобные преобразования лучше делать, обернув их в перехватчик ошибок – try-catch. Результаты пишем на выходы скрипта.
Вот и все. Если у вас не два параметра, а больше, то все что потребуется на проверке количества элементов (sub.Length) указать их количество, и для каждого сделать свое преобразование.
Теперь можно проверить работу наших скриптов в режиме исполнения.
Формируем три отчета – в журнале появятся три сообщения:
Теперь выберем любое из сообщений, его параметры появятся на выходах скрипта и мнемосхеме.
Теперь на основе этих данных можно запускать формирование отчета.
Пример скрипта доступен по ссылке. Обратите внимание, что для корректной работы архивация сообщений должна идти в базу данных (в проекте используется Firebird Встроенный).
Данный скрипт может быть использован не только для повторного формирования отчета, но и для открытия сохраненных (в этом случае нужно сохранить путь к ним) или решения других подобных задач в MasterSCADA.