Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Как вывести в отчет интервалы времени?  (Прочитано 11198 раз)

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #15 : 09 Декабря 2018, 11:21:44 »
Создать свою таблицу и записывать в неё можно. Вывести данные в отчет затем можно как описано в этой статье.
Эту статью я изучил довольно детально. Но зачем городить отдельную таблицу, если все данные есть в стандартном архиве?
Если у переменной включена архивация, то можно брать данные из стандартных таблиц. Этот вариант обычно проще.
Да, я тоже так считаю. Но переменная ВЫЧИСЛЯЕМАЯ как разница времен между выходами щитов, вот я и спрашивал, можно ли эти времена вытащить из стандартной таблицы?
Когда Вы создаёте в отчете источник данных с типом "Периодический", или "По-изменению", то этот источник будет работать именно со стандартными архивными данными. Пример вывода трендов в отчет (в компонент Диаграмма) описан здесь.
Это я тоже все изучил. Но мне нужно вывести в диаграмму эффективность производства по суткам, которую рассчитываю как отношение потерь времени к общей продолжительности смены, а этих данных в стандартной базе нет.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Как вывести в отчет интервалы времени?
« Ответ #16 : 09 Декабря 2018, 11:26:52 »
Мы говорим о переменной, значение которой рассчитывается в скаде. Тогда не имеет значения рассчитываемая это переменная, или какая-то ещё, если у неё включить архивацию, то её значения будут записываться в БД и затем эти значения можно будет вывести в источник данных. Вы хотите вывести в отчет переменную, которая  рассчитывается не в скаде, а при построении отчета?

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #17 : 09 Декабря 2018, 11:57:27 »
Мы говорим о переменной, значение которой рассчитывается в скаде. Тогда не имеет значения рассчитываемая это переменная, или какая-то ещё, если у неё включить архивацию, то её значения будут записываться в БД и затем эти значения можно будет вывести в источник данных. Вы хотите вывести в отчет переменную, которая  рассчитывается не в скаде, а при построении отчета?
Экспортировать из отчета в скаду вычисляемую переменную невозможно, это Вы мне уже объяснили. Поэтому я хочу создать аналогичную переменную (vrTotalTime) в скаде и заархивировать ее в стандартной БД. Но для ее вычисления необходимы значения времен выхода щитов (изменения их количества), которые сидят в стандартном архиве. Вот я и пытаюсь выяснить - можно ли их оттуда вытащить? Или придется создать свою таблицу?
« Изменён: 09 Декабря 2018, 12:00:46 от alan54 »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Как вывести в отчет интервалы времени?
« Ответ #18 : 09 Декабря 2018, 20:00:44 »
Можно выполнить совершенно любой SQL-запрос к любой таблице из БД (не важно сами Вы её создали, или она создана скадой), для этого используется процедура RunSQL, которая подробно описана в руководстве. Чтобы выбрать данные какой-то конкретной переменной, достаточно указать её ID в запросе. ID любой переменной можно посмотреть через Редактор, меню Переменные -> Редактировать. После выполнения выборки из БД, результат можно как угодно обработать в скрипте с типом события "Выполнен SQL-запрос". Вот подробный пример выборки из руководства. Если результат выборки содержит множество строк, то пройти по ним можно в таком цикле:
Код: (delphi)
begin
  if DataSet.Tag = 1 then  // если это результат выполнения запроса с тегом = 1
    { выполняем цикл пока не дойдём до конца набора данных }
    while not DataSet.EOF do
    begin
      { здесь можем работать с текущей строкой и её ячейками, для
        примера обратимся к первой ячейке текущей строки }
      Text1.Text := DataSet[0].AsUTF8String;
 
      { переходим на следующую строку набора данных }
      DataSet.Next;
    end;
end.
« Изменён: 09 Декабря 2018, 20:01:32 от Simple-Scada »

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #19 : 09 Декабря 2018, 20:16:36 »
Все на что Вы ссылаетесь, я изучил. ID переменной тоже умею находить. Запросы писать тоже могу. Мне непонятно, к какой из таблиц БД обращаться - action_data, messages_data, trends_*? При просмотре в MySQL Workbench я не вижу в них  ID переменных...
« Изменён: 09 Декабря 2018, 20:57:14 от alan54 »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Как вывести в отчет интервалы времени?
« Ответ #20 : 09 Декабря 2018, 20:30:26 »
Цитировать
При просмотре в MySQL Workbench я не вижу в них  ID
Значит Вы плохо искали. "action_data" - таблица для списка действий оператора, "messages_data" - для сообщений и эти таблицы действительно не содержат ID-переменной, он им не нужен. Переменные архивируются в таблицы "trends_data" (все данные, без прореживания), "trends_day", "trends_hour", "trends_minute" (прореженные данные). Все эти таблицы содержат столбец ID, который совпадает с ID архивируемой переменной. Вам нужно делать выборку из полной таблицы "trends_data". Пример с выборкой из "trends_data" тоже есть в руководстве.

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #21 : 09 Декабря 2018, 20:38:03 »
В этой таблице я вижу только ID = 0 и ID = 2 и последняя дата записи 2018-10-10. А где остальные?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Как вывести в отчет интервалы времени?
« Ответ #22 : 09 Декабря 2018, 20:55:05 »
Если у Вас в таблицах есть только данные с ID = 0 и 2 и Вы уверены, что правильно сделали выборку, значит у Вас архивируются переменные с такими же ID, а у остальных архивация выключена, либо они ещё не успели сброситься в БД. Другие варианты: Вы сделали выборку из другой БД (например БД другого проекта), либо просто выбрали не все данные из таблицы и т.п. Также учитывайте, что архивные данные не сразу попадают в БД, особенно для переменных которые редко меняются. Они сбрасываются в архив не реже одного раза в 5 минут и при перезапусках проекта.

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #23 : 09 Декабря 2018, 20:57:41 »
Все, разобрался - был установлен лимит строк. Спасибо, что навели на нужную таблицу, а уж данные я вытащу и обработаю.
« Изменён: 09 Декабря 2018, 21:02:15 от alan54 »

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #24 : 10 Декабря 2018, 21:05:29 »
Здравствуйте.
Опять нужна ваша помощь. Данные я вытащил, но обработать их по алгоритму, аналогичному в отчете, затрудняюсь.
Код: (delphi)
begin
  if DataSet.Tag = 1 then  // если это результат выполнения запроса с тегом = 1
    { выполняем цикл пока не дойдём до конца набора данных }
    while not DataSet.EOF do
    begin
      { здесь можем работать с текущей строкой и её ячейками, для
       примера обратимся к первой ячейке текущей строки }
       TimestampValue := DataSet[0].AsUTF8String;
       CounterValue := DataSet[1].AsUTF8String;

        ???????????????????????????????????????
       
       { переходим на следующую строку набора данных }
        DataSet.Next;
    end;
end.
Тут (где знаки вопроса) нужен какой-то оператор, вычисляющий разницу времени текущей и предыдущей записи
TimestampCurrent  - TimestampPrevious,
и если эта разница больше 5 минут, суммировать это время в некую переменную, например, IdleTime (время простоев).
« Изменён: 11 Декабря 2018, 15:25:31 от Simple-Scada »

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #25 : 11 Декабря 2018, 13:25:31 »
Нашел какую-то функцию LAG(), но как ее прописать применительно к дате-времени, не знаю. Подскажите, плиз.
P.S. Похоже, что функция LAG() в Delphi не работает... Но должна же быть какая-то аналогичная! Очень жду ответа.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Как вывести в отчет интервалы времени?
« Ответ #26 : 11 Декабря 2018, 15:44:39 »
Здравствуйте.

У Вас ведь колонка с датой и временем, поэтому её нужно переводить не в строку (DataSet[0].AsUTF8String), а в дату-время (DataSet[0].AsDateTime). Для работы с переменными даты-времени используются эти функции. Например:
Код: (delphi)
var
  aSeconds: Int64;
  aTime, aPrevTime: TDateTime; // время в текущей и пред. строке
  aIdleTime: Int64;            // полученная сумма в секундах
  aResultDateTime: TDateTime;  // полученная сумма как дата-время
begin
  if DataSet.Tag = 1 then  // если это результат выполнения запроса с тегом = 1
  begin
    aIdleTime := 0;        // обнуляем переменную в которую будем суммировать сремя
    aPrevTime := -1;       // "обнуляем" переменную времени предыдущей строки
    { выполняем цикл пока не дойдём до конца набора данных }
    while not DataSet.EOF do
    begin
      { берём время из текущей строки в переменную aTime }
      aTime := DataSet[0].AsDateTime;

      { далее код для суммирования интервалов более 5 минут }
      if aPrevTime > -1 then
      begin
        aSeconds := SecondsBetween(aTime, aPrevTime);
        if aSeconds > 5 * 60 then
          aIdleTime := aIdleTime + aSeconds;
      end;

      { в переменную времени пред. строки записываем время текущей строки }
      aPrevTime := aTime;
      { переходим на следующую строку набора данных }
      DataSet.Next;
    end;

    { расчеты окончены, в переменной aIdleTime будет сумма всех интервалов
      более 5 минут (сумма будет в секундах!). При желании можем эти секунды
      перевести в переменную даты-времени }
    aResultDateTime := SecondsToDateTime(aIdleTime);
  end;
end.

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #27 : 11 Декабря 2018, 17:39:46 »
Спасибо огромное! Вы за меня сделали половину работы!

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Re: Как вывести в отчет интервалы времени?
« Ответ #28 : 01 Марта 2019, 11:52:20 »
...нужно вывести время прошедшее между временем предыдущей строки и временем текущей строки? Для этого можно в бэнде данных разместить компонент Текст, дважды кликнуть его для редактирования и использовать следующее выражение:
Код: (c#)
{DateDiff(Данные.Время, (System.DateTime)Previous(Данные, "Время"))}
Данный код получает разницу во времени между текущей и предыдущей строкой...
Здравствуйте. Возникла такая проблема. Как на этот код синтаксически правильно наложить условие, чтобы разница времени рассчитывалась только для строк с ненулевыми значениями счетчика (vrCounter != 0). Фильтр для DataBand не годится, так как первый нуль в начале смены надо учитывать.
Или, как вариант - можно ли выключить запись в архив нулевых показателей параметра с архивацией "по изменению" каждый час, и если да, то как?
« Изменён: 02 Марта 2019, 12:01:28 от alan54 »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Как вывести в отчет интервалы времени?
« Ответ #29 : 04 Марта 2019, 10:35:58 »
Цитировать
Как на этот код синтаксически правильно наложить условие, чтобы разница времени рассчитывалась только для строк с ненулевыми значениями счетчика (vrCounter != 0). Фильтр для DataBand не годится, так как первый нуль в начале смены надо учитывать.
Уникальные условия придется реализовывать через собственные переменные. Например:
1. создать в отчете новую переменную с типом данных "timespan". С именем, например, vrDiff;
2. выделить бэнд данных и на событие "перед печатью" описать нужные условия и вычисления, например:
Код: (c#)
if (!PreviousIsNull(Данные, "Время"))
  if (vrCounter != 0) {
    vrDiff = DateDiff(Данные.Время, (System.DateTime)Previous(Данные, "Время"));
  } else {
    vrDiff = new TimeSpan(0, 0, 0);
  }
3. Вывести полученную переменную vrDiff в любом месте отчета.


Цитировать
Или, как вариант - можно ли выключить запись в архив нулевых показателей параметра с архивацией "по изменению" каждый час, и если да, то как?
Архивация "по-изменению" просто записывает каждое изменение переменной в архив. Если значение переменной не будет меняться на ноль, то и в архив нули не попадут. Исключить из архивации какие-то определённые изменения нельзя.