PDA

Просмотр полной версии : Агрегатные функции в отчёте



ks21
21.03.2014, 09:07
Архивируются данные имеющие тип строка, вещественный, время. В отчёте агрегатные функции FIRST, LAST работают только с переменными STRING. А если, к примеру, переменная имеет тип время или вещественный, то не работают - то есть первые и последние значения таких данных вообще не выводятся. Это так и задумано?

lara197a
21.03.2014, 09:10
Конвертируйте в строку перед сохранением.

ks21
21.03.2014, 09:16
Если конвертировать в строку, то эти функции работают. Я спросил то, что спросил - работают ли функции FIRST, LAST для данных типа время, вещественный? У меня не работают, потому что я что-то не правильно делаю? Или в принципе не работают для этих типов?

ks21
21.03.2014, 09:23
Поясняю, почему не подходит конвертировать время в строку:
Есть колонка с данными в архиве, имеющими тип время. Необходимо найти первое или последнее значение, чтобы использовать эти значения при построении других данных в отчёте. Для этого нужен тип именно время, а не строковый.

SCADAMaster
21.03.2014, 09:50
Архивируются данные имеющие тип строка, вещественный, время. В отчёте агрегатные функции FIRST, LAST работают только с переменными STRING. А если, к примеру, переменная имеет тип время или вещественный, то не работают - то есть первые и последние значения таких данных вообще не выводятся. Это так и задумано?
Вы имеете ввиду функции при подсчете итогов? Опишите вашу задачу подробнее - какой именно отчет вам требуется.
Выложите ваш проект - выполните Проект - Экспортировать.
Также рекомендуем вам сначала ознакомится с нашей документацией по отчетам:
http://www.masterscada.ru/?additional_section_id=141
и видеопримерами:
http://www.masterscada.ru/?additional_section_id=233

ks21
21.03.2014, 10:11
Проект не могу выложить. Он огромный. Попробую создать нечто простое для примера и выложу. И тем не менее хотелось бы услышать ответ именно на мой вопрос - работают ли функции FIRST, LAST для данных типа время, вещественный? Хотя бы чисто теоретически - они работаю с этими типами данных или не работают?) А то получается, что Вы мне пытаетесь помочь в том, что я не прошу- я знаю какой отчёт мне требуется и как его построить.))) Я Ваши примеры изучал внимательно и не пришёл бы на форум, если бы ответ там нашёл. Так что вопрос остаётся - работают ли функции FIRST, LAST для данных типа время, вещественный? Надеюсь на ответ такого вида: да - работают, нет - не работают.)))

ks21
21.03.2014, 11:13
Выкладываю проект, в котором функции FIRST LAST у меня не работают в отчёте. Данные в архиве уже есть, хотя можете создать свои, включая и выключая команду "Запись значения времени в архив". В отчёте три источника данных. Один на основе архива и 2 на основе первого с применением функций FIRST и LAST. Ошибок нет, но отчёт не строится. Данные в первом источнике просматриваются командой "Просмотр данных". Если два последние источника удалить, то отчёт построится. Что я делаю не правильно?

SCADAMaster
21.03.2014, 13:17
Нужно у колонок в источниках данных "Данные First" и "Данные Last" задать тип DateTime (см. приложение).
Опишите какой отчет вы хотите построить.

ks21
21.03.2014, 14:11
Большое спасибо. Сам бы вряд ли догадался.) Потому что не очевидно, так как исходные данные имеют тип datetime (Nullable). Проверил тоже самое для вещественных чисел. Функции работают, если изменить тип данных double (Nullable) на double.
В отчёте мне нужно вывести значения данных в моменты некоторых событий. Мне нужно знать время, когда эти события произошли и посмотреть в архиве значения других данных в эти моменты. Для этого я архивирую время. Имея время события я могу использовать его в фильтрах вывода. Может быть есть другой способ - не архивируя время? Подскажите. Есть ли, к примеру, у логической переменной при переходах из ИСТИНА в ЛОЖЬ и наоборот метки времени, которые можно получить в дереве объекта или в отчёте? Сейчас-то я их сам формирую, видели в примере - получается много вспомогательных ФБ и связей. Допустим в архиве есть колонка логической переменной. Можно ли как то сформировать дополнительную колонку со значениями времени этих переходов, не архивируя время явно, как я?

ks21
21.03.2014, 14:35
Спасибо, ещё раз. Я разобрался, как получить время для любого значения в архиве. Раньше не получалось, потому что не знал, что надо менять тип данных при создании данных на основе других данных.

SCADAMaster
21.03.2014, 16:09
В отчёте мне нужно вывести значения данных в моменты некоторых событий. Мне нужно знать время, когда эти события произошли и посмотреть в архиве значения других данных в эти моменты. Для этого я архивирую время. Имея время события я могу использовать его в фильтрах вывода. Может быть есть другой способ - не архивируя время? Подскажите. Есть ли, к примеру, у логической переменной при переходах из ИСТИНА в ЛОЖЬ и наоборот метки времени, которые можно получить в дереве объекта или в отчёте? Сейчас-то я их сам формирую, видели в примере - получается много вспомогательных ФБ и связей. Допустим в архиве есть колонка логической переменной. Можно ли как то сформировать дополнительную колонку со значениями времени этих переходов, не архивируя время явно, как я?
Посмотрите пример "отчет по условию":
http://www.masterscada.ru/?additional_section_id=233
это примерно соответсвует вашему отчету.

ks21
21.03.2014, 16:26
Спасибо, посмотрю.

ks21
01.12.2017, 15:38
Жизнь снова вернула к вопросу об агрегатных функциях в отчёте. Теперь система Win10 32бита , Скада - 3.8.0.58188 3.8(RT32ReleaseMax)_17_04_21_13_34. И опять не работают агрегатные функции FIRST, LAST для типов данных float, double. И изменение типа данных double (Nullable) на double теперь не помогает. Отчёт просто не строится и ошибок при компиляции не показывает. Может быть я что-то не так делаю? Работают ли функции функции FIRST, LAST для типов данных float, double в этой версии MasterScada? Досадно терять то, что раньше, в версии 3.6 работало... И просмотр данных в отчётах в версии 3.8 не работает, а, ведь, в версии 3.6 он прекрасно работал...

SCADAMaster
01.12.2017, 16:14
Работает.
Пришлите ваш проект (выполните Проект - Экспортировать), укажите путь к проблемному отчету.

ks21
08.04.2019, 08:26
Годы идут, вопросы так и остаются.))) Снова пришлось воспользоваться агрегатными функциями в отчёте. И снова те же самые вопросы - как заставить работать агрегатные функции с типами отличными от string? Проект, для примера самый простейший - один объект, в нём одна переменная "вещественный двойной точности". Создаём отчёт для объекта с этой переменной. Создаём данные в отчёте на основе архива Мастерскада. Кидаем в данные нашу переменную. Тип переменной в отчёте получается double (Nullable). Выводим эту переменную на страницу отчёта. Отчёт строится - переменная выводится.
Создаём данные на основе других данных и указываем в них нашу переменную. Применяем в итогах агрегатную функцию Last, к примеру. Выводим её на страницу - отчёт не строится, а в Скаде появляется сообщение от ошибке:
"System.NotSupportedException: DataSet не поддерживает System.Nullable<>.
в System.Data.DataColumn..ctor(String columnName, Type dataType, String expr, MappingType type)
в System.Data.DataColumn..ctor(String columnName, Type dataType)"
Изменяем тип переменной в данных на основе других данных на double. После этого отчёт строится.
Вопрос-то в чём - в том, что нельзя изменить тип переменных в данных на основе архива мастерскада. Изменить-то его можно, но при закрытии скады и новом запуске он опять восстановится в double (Nullable). И применять к нему агрегатные функции будет нельзя. Надо создавать данные на основе других данных, добавлять в них результаты, выбирать функцию обработки... Получается какая-то двойная работа. Сначала перенеси данные в отчёт, а потом создай те же самые данные на основе других данных с типами без Nullable. Что удручает - что эти ухищрения в документации я не нашёл, хотя может плохо искал. Или я не понимаю Вашей документации. Но крови себе попортил много, пока хоть немного разобрался. Ранее мне тут предлагали использовать для отчёт тип string. Да - с ним агрегатные функции работают сразу, без прокладок в виде данных на основе других данных. Но, не очень это удобно иногда. Например, надо изменить разрядность вывода - надо в проекте менять, при преобразовании в тип string. А ещё, к примеру тип bool - его как использовать в отчёте? Заменить его каким-нибудь строковым эквивалентом? Не... ну понятно, что безногому и костыль в радость. Но, ведь, "красота спасёт мир" - и было бы здорово, если бы агрегатные функции в отчёте работали сразу после копирования в отчёт переменных из проекта.
Собственно, кроме этого пожелания вопросов нет, а то, что написано выше, написано на случай, "вдруг кому поможет" и сохранит время потерянное на выяснение особенностей работы отчёта.

SCADAMaster
08.04.2019, 08:49
Из вашего описания не понятно в чем именно у вас проблема.
Если у вас переменная типа Nullable, то получить ее значение можно через свойство Value

ks21
08.04.2019, 08:56
В том, что агрегатные функции работают только с типами без Nullable. А при переносе переменной из проекта создаётся тип с Nullable. И изменить его нельзя. По Вашей документации - я переношу переменную в отчёт и могу с ней делать что угодно, в частности применять к ней агрегатные функции. А это не так. И описание того, что же сделать, чтобы агрегатные функции работали я не нашёл. Укажите ссылку на документ, прочитав который у меня сразу заработает отчёт с агрегатными функциями. Буду признателен за указание. Сам не нашёл.

SCADAMaster
08.04.2019, 09:04
В том, что агрегатные функции работают только с типами без Nullable. А при переносе переменной из проекта создаётся тип с Nullable. И изменить его нельзя. По Вашей документации - я переношу переменную в отчёт и могу с ней делать что угодно, в частности применять к ней агрегатные функции. А это не так. И описание того, что же сделать, чтобы агрегатные функции работали я не нашёл. Укажите ссылку на документ, прочитав который у меня сразу заработает отчёт с агрегатными функциями. Буду признателен за указание. Сам не нашёл.
Приложите тестовый пример (с одной переменной) с нужной вам агрегатной функцией, который не формируется изначально.

ks21
08.04.2019, 09:29
Пример приложил

SCADAMaster
08.04.2019, 09:37
Если использовать источник "Данные на основе других данных", то да - в нем, у конкретной переменной нужно выставлять тип без Nullable.
А какая в конечном счете задача? Именно в этом случае чтобы найти последнее значение можно использовать у источника способ формирования "Итоговый" а у переменной - "Последнее значение".

ks21
08.04.2019, 09:41
Попытаюсь ещё раз сформулировать проблему в общем случае, не применительно к этому проекту. Создаем отчёт. Бросаем в него переменные из проекта. Выводим некоторые переменные на страницу в виде таблицы, а некоторые используем в фильтрах вывода. Применяем к таблице фильтр - например, выводить строки в зависимости от значения какой-нибудь переменной типа bool. Отчёт не построится, пока у этой переменной будет тип с Nullable. Чтобы получить отчёт надо создавать данные на основе данных, менять там тип на bool... На мой взгляд - это лишняя операция. К тому же не очевидная, потому что нигде не описанная в документации.

ks21
08.04.2019, 09:45
Наверное, не внятно сформулировал. Подумаю, как по другому описать проблему

SCADAMaster
08.04.2019, 10:08
Применяем к таблице фильтр - например, выводить строки в зависимости от значения какой-нибудь переменной типа bool. Отчёт не построится, пока у этой переменной будет тип с Nullable.
Вообще должен.
Приведите конкретный пример такого отчета - который не строится.

ks21
08.04.2019, 10:41
Вот пример отчёта с агрегатной функцией и ошибкой отчёта. Подскажите, что в нём не так.

ks21
08.04.2019, 10:47
Что любопытно - если удалить переменную типа bool из отчёта, то он построится без ошибок.

ks21
08.04.2019, 11:13
Вот ещё пример с непонятной мне ошибкой в отчёте. Этот без использования агрегатных функций. Хотелось бы понять, что в нём не правильно.

ks21
08.04.2019, 11:28
В примере test3 хоть и с предупреждением, но отчёт построился. А вот test4 - развитие проекта test3. Я думал, что таким способом можно будет использовать агрегатные функции в своём проекте. А оказывается, что в нём не все переменные выводятся на страницу. Может быть дело и не в агрегатных функциях совсем. Мне в рабочем проекте было не очевидно, что именно не работает в отчёте. Там много переменных разных типов и агрегатные функции используются.

SCADAMaster
08.04.2019, 11:42
Что именно вы хотите сделать в этом отчете?

ks21
08.04.2019, 15:08
Мне хотелось бы приведённые в моих примерах конструкции использовать в своих отчётах. Или знать точно, что такие способы не работают. Также хотелось бы понять суть сообщений типа "Expression in Text property of 'Текст27' can't be evaluated! Ссылка на объект не указывает на экземпляр объекта." Чтобы хоть знать что я не так сделал.

SCADAMaster
08.04.2019, 15:16
Пока что вы пытаетесь построить отчет неправильными способами.
Еще раз - что именно вы хотите сделать. Опишите какой отчет вам требуется.

ks21
08.04.2019, 15:48
Могу, конечно, описать что мне нужно. А Вы, видимо, вставите несколько ссылок на Вашу документацию с предложением её почитать.))) А отчёт нужен, примерно, такой... Идут испытания двигателя, меняются режимы работы двигателя, снимаются показания датчиков, которыми он обвешан... Испытания имеют разные типы - разный набор режимов работы двигателя, ну... к примеру 1,2,3,4. В отчёте должны быть таблицы для каждого типа испытаний с замерами с датчиков на каждом режиме работы двигателя. Испытания могут повторяться, но в протокол должны попадать данные только с последнего испытания каждого типа. То есть испытание номер 1 можно провести 10 раз, но в протоколе должен быть отражён только последнее испытание. Такой отчёт мы сделали и он работает.
Но, кроме этих данных, нужны данные из архива, которые получаются с помощью агрегатных функций. Например - узнать время начала первого испытания, узнать название испытания... Вот с этим - проблема. Строим данные на основе других данных, применяем фильтры и агрегатные функции. Иногда это работает, иногда - нет. Я привёл примеры, когда не работает.

SCADAMaster
08.04.2019, 16:12
Но, кроме этих данных, нужны данные из архива, которые получаются с помощью агрегатных функций. Например - узнать время начала первого испытания, узнать название испытания... Вот с этим - проблема. Строим данные на основе других данных, применяем фильтры и агрегатные функции. Иногда это работает, иногда - нет. Я привёл примеры, когда не работает.
Т.е. задача за определенный интервал времени найти первое испытание и например его время?
Создаете источник данных, добавляете нужные переменные (можно одну - по которой можно судить что испытание началось). Ставите способ формирования отчета - итоговые, у колонки ставите обработку - первое значение (или последнее). Если нужно получить время этого испытания (время этой переменной), тащите переменую еще раз в этот источник, ставите Атрибут - метка времени, обработка - также первое значение

ks21
09.04.2019, 07:18
Т.е. задача за определенный интервал времени найти первое испытание и например его время?
Нет, не так. Интервал времени неизвестен. Испытаний с номером один могло быть проведено сколько угодно. Запоминать для каждого время начала и конца как-то... не красивое решение. А итоговый отчёт без интервалов работать не будет, как я понимаю. Надо не за определённый интервал времени, а по состоянию других переменных. Есть переменные "номер двигателя во время испытания"(строковый), "номер двигателя текущий"(строковый), "номер испытания"(целый), "строб начала испытания"(логический). Как правильно сделать обработку архива с такой задачей: Определить время ПЕРВОГО (в архиве) строба начала испытания, при условии что "номер двигателя во время испытания" равен "номер двигателя текущий" и "номер испытания" в это время равен 1.

SCADAMaster
09.04.2019, 08:44
Нет, не так. Интервал времени неизвестен. Испытаний с номером один могло быть проведено сколько угодно. Запоминать для каждого время начала и конца как-то... не красивое решение.
Как раз таки это очень красивое решение, и более того - оно единственно правильное.
Можно сделать несколько по иному. В момент когда происходит запуск вашего испытания вызвать сообщение (используя Событие) определенной категории (например Запуски испытания). Сообщение попадет в журнал. В текст сообщения можно включить всю необходимую информацию - номер испытания, номер двигателя и прочее.
Настраиваем журнал, чтобы он выводил только эту категорию. Теперь у оператора будет весь необходимый механизм - можно задать интервал времени когда было испытание, можно в столбце Сообщение производить поиск (в том числе с регулярными выражениями). Затем оператор выбирает нужное ему сообщение, и его параметры попадают в специальный скрипт. Скрипт разбирает сообщение, извлекает данные Начала и Конца и выводить на выходы скрипта - после этого можно запускать формирование отчета.
Пример такого скрипта (обращение к журналу и получение выделенного сообщения) - в приложении

ks21
09.04.2019, 09:09
Спасибо за пояснения и скрипт. Буду разбираться.