Скрипт загрузки сформированных отчетов

Скрипт загрузки сформированных отчетов

В проекте рассмотренном в прошлой статье одним из компонентов был скрипт, позволяющий получить выбранное пользователем сообщение в журнале. В проекте, комментарий сообщения хранил путь к файлу осциллограммы, который впоследствии можно было открыть.

Поскольку данный функционал может быть полезен и в других случаях, мы решили разобрать данный скрипт в отдельной статье.[spoiler]

Распространенной задачей для SCADA системы является формирование отчетов. При этом отчет может иметь сложную форму и логику формирования, например – формирование отчета циклического процесса (варка, закалка, травление). Такие отчеты необходимо строить строго за определенный интервал (когда был запущен и остановлен процесс), зачастую со вспомогательными параметрами (например, номер изделия). Если возникнет необходимость вновь построить этот отчет в MasterSCADA, то необходимо указать исходные параметры отчета. Также необходимо иметь перечень таких отчетов, с датами их формирования. Для решения этой задачи мы и воспользуемся скриптом, описанным в прошлой статье – мы адаптируем его для нашей задачи.

Поскольку цель статьи рассмотреть только скрипт, то сам отчет будет простой формы – простой периодический отчет, с одним параметром. Также в объект добавлены команды Начало и Конец – для задания временного интервала отчета. Команда Сформировать отчет начнет формирование отчета – подав сигнал на вход ФБ Управление документом.

21.05-1.png

Теперь сделаем скрипт, который сначала сформирует сообщение, которое сохранит Начало и Конец.

 

Для этого добавим объект Перечень отчетов – в нем мы разместим все переменные необходимые для выбора и открытия отчета. Добавим в него скрипт и создадим следующий код:

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 аргументами:

  1. ID сообщения  - оно создается на вкладке Список сообщений;

  2. текст сообщения – в данном случае просто «Сформирован отчет». В реальных проектах можно сделать более сложный текст, который позволит понять, что за отчет был сформирован (например номер изделия, заказчик и т.д.);

  3. признак качества – в данном случае 192 (GOOD);

  4. метка времени – в данном случае текущее время по UTC;

  5. номер типизированного объекта (в данном случае 0 – не типизированный).

Наиболее важные это два оставшихся параметра – они используются если необходимо квитировать сообщение. Мы будем квитировать наше сообщение из скрипта, и в качестве комментария к квитированию указывать параметры Начало и Конец – это более красивое решение, чем добавлять их в текст сообщения (хотя такой вариант тоже допустим):

  1. оператор – оператор которым производится квитирование;

  2. текст примечания.

Текущего оператора мы получаем с помощи свойства:

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) указать их количество, и для каждого сделать свое преобразование.

Теперь можно проверить работу наших скриптов в режиме исполнения.

Формируем три отчета – в журнале появятся три сообщения:

21.05-2.png

Теперь выберем любое из сообщений, его параметры появятся на выходах скрипта и мнемосхеме.

21.05-3.png

Теперь на основе этих данных можно запускать формирование отчета.

Пример скрипта доступен по ссылке. Обратите внимание, что для корректной работы архивация сообщений должна идти в базу данных (в проекте используется Firebird Встроенный).

Данный скрипт может быть использован не только для повторного формирования отчета, но и для открытия сохраненных (в этом случае нужно сохранить путь к ним) или решения других подобных задач в MasterSCADA.