какие типы отчетов позволяет сформировать модуль генератор отчетов
Генератор отчетов ActivityManager. Очередной велосипед, но в профиль
ActivityManager — это менеджер формирования отчетов, базирующийся на замене шаблонных строк.
Основными особенностями ActivityManager являются:
Глоссарий
Структура файла конфигурации
Файл конфигурации отчета представляет собой обычный xml-файл следующего вида:
Основную часть конфигурационного файла отчета занимают шаги. Шаги по сути представляют этапы формирования отчета: выборка данных, обработка данных, конфигурация отчета, источника данных и многое другое. Шаг состоит из имени плагина plugin, в котором находится действие action, которое необходимо выполнить, входных и выходных параметров и параметра repeat, указывающего сколько раз необходимо выполнить данный шаг (по умолчанию 1). Каждый входной параметр имеет имя name и значение (контент). Каждый выходной параметр имеет имя по умолчанию name указывает язык, на котором будут выводиться сообщения (по большей части об ошибках) во время формирования отчета. На данный момент поддерживается два языка: русский и английский. Языковые переводы расположены в каталоге lang\.
Несмотря на простую структуру файла конфигурации редактировать его вручную утомительно. Поэтому был разработан специальный редактор файлов конфигураций. Подробнее в разделе «Визуальный редактор файлов»
Поставляемые плагины
В поставке по умолчанию ActivityManager присутствуют 6 базовых и один custom-плагин:
Передача параметров
Параметры командной строки
При запуске генерации отчета ядру (ActivityManager.exe) необходимо передать один обязательный параметр config в виде
В результате ActivityManager.exe прочитает файл конфигурации, расположенный по пути c:\1.xml и сформирует отчет.
Помимо обязательного параметра config ActivityManager’у можно передать параметр lang — язык выводимых во время исполнения сообщений (по большей части ошибок, возникших при формировании отчета).
Кроме базовых параметров config и lang ActivityManager может принимать любое количество любых других параметров, которые будут помещены в коллекцию глобальных параметров времени исполнения и могут быть использованы во время формирования отчета. Например:
В результате выполнения данной команды в коллекцию глобальных параметров времени исполнения попадут параметры connectionString и id_process и их можно будет использовать во время установки соединения с источником данных, выборке и на любом другом шаге отчета. Как именно использовать данные параметры во время исполнения смотрите в следующем разделе.
Глобальные параметры времени исполнения
Коллекция глобальных параметров времени исполнения это перечень именованных переменных, которые могут быть использованы на любом шаге генерации отчета (при условии, что на данном шаге, параметр уже доступен).
Параметры записываются в данную коллекцию в двух случаях:
Тогда во время исполнения приложения мы можем использовать переданные аргументы командной строки следующим образом:
Как видно, на первом шаге SqlSetConnectionString (установка строки соединения) во входящем параметре указывается [connectionString], что говорит препроцессору, что необходимо взять этот параметр из коллекции глобальных параметров. В случае, если параметр, находящийся в квадратных скобках не будет найден в коллекции глобальных параметров, никаких сообщений об ошибках не будет сгенерировано. ActivityManager поймет, что данная строка не является параметром и оставит ее без изменений.
Обратите внимание на выходной параметр шага SqlSelectTable
Данная запись означает, что после исполнения запроса данные из источника будут сохранены в глобальной области параметров под именем tenancy_processes и к ним можно будет обратиться через [tenancy_processes] (что и делается на следующем шаге ReportSetTableValue)
Замена параметров простых типов (строки, числа, даты и т.д., а именно всех типов, которые можно однозначно конвертировать из строкового типа System.String в целевой при помощи Convert.ChangeType) осуществляется в режиме подстановки. Т.е. вполне допустимо задавать параметр как часть значения, а не как целое. Например:
Параметры более сложных типов, которые невозможно однозначно конвертировать из строкового представления, будут подставлены непосредственно. В таких параметрах частичная подстановка невозможна по определению.
Подстановка параметров из глобальной коллекции выполняется только во входящих параметрах действий.
Выборка данных
Результатом выборки данных из любого из описанных источников будет объект либо скалярного типа либо типа ReportTable.
SQL-источники данных
Для работы с источниками данных SQL предназначен плагин SqlDataSource.dll.
Простой примером использования данного плагина для выборки данных из ODBC-источника данных:
Здесь параметр name — это полное или краткое инвариантное имя провайдера. Нет необходимости задавать полное инвариантное имя, т.к. сопоставление имени происходит нечетко (по паттерну). Например, вместо полного инвариантного имени для MS Sql Server (System.Data.SqlClient) можно указать просто:
Полный перечень поддерживаемых провайдеров зависит от машины, на которой происходит генерация отчета и может быть получен через метод DbProviderFactories.GetFactoryClasses().
Помимо действия SqlSetProvider и SqlSelectTable в плагине SqlDataSource имеется еще 8 действий. Полный их перечень можно найти на wiki проекта
CSV-источники данных
Помимо работы с СУБД ActivityManager поддерживает выборку и модификацию данных файлов CSV. Для выборки данных из CSV-файлов помимо Microsoft Text Driver через ODBC поддерживается возможность осуществлять выборку встроенным текстовым драйвером, построенным на базе синтаксиса MySQL.
Например, предположим мы имеем два CSV-файла users.csv и user_actions.csv следующего содержания:
users.csv:
Нам необходимо выбрать количество действий для каждого пользователя.
Конфигурация шага выборки данных из CSV при этом будет выглядеть следующим образом:
Результат данного запроса будет сохранен в коллекции глобальных параметров под именем table.
Помимо действия TextSelectTable в плагине TextDataSource имеется еще 2 действия: TextSelectScalar и TextModifyQuery, подробную информацию о которых вы также можете узнать на wiki проекта.
Преобразование данных
Нередко возникает необходимость в форматировании данных уже после выборки из источника и до их записи в конечный отчет. Причин этому может быть множество от отсутствия поддержки на уровне СУБД каких-либо сложных преобразований, до нежелания «марать» SQL-запрос массой излишних условий, превращающих его в нечитабельную простыню.
Для подобных преобразований данных в ActivityManager используется плагин ConvertModule.dll.
Вот перечень того, что можно сделать с данными при помощи этого плагина:
По типу преобразуемых данных:
Преобразования целых чисел
Как уже говорилось выше для преобразования целых чисел используются действия ConvertIntToString, ConvertIntCellToString, ConvertIntColToString. Отличаются они между собой только типом входного и выходного параметра поэтому подробно рассматривать каждое из них мы не будем. Рассмотрим простой пример преобразования чисел в текстовое представление. Предположим, что нам необходимо из таблицы базы данных выбрать некоторые числовые значения, после чего привести их к текстовому виду по следующим правилам: все числа должны быть в родительском падеже, окончания текстовых представлений чисел должны быть в женском роде, числа должны быть количественными, а не порядковыми, первая буква результирующих текстовых представлений чисел должна быть большой. Для начала нам необходимо получить данные, которые мы будет преобразовывать. Ранее уже было показано как это делается:
В результате данного действия в коллекции глобальных объектов будет хранится объект типа ReportTable, содержащий один столбец int_column содержащую строки со значениями 1, 13013, 55132111, 1055132111.
Непосредственно само преобразование по определенным выше требованиям можно провести следующим образом:
В результате на выходе мы получим таблицу с именем table со следующими значениями: «Одной», «Тринадцати тысяч тринадцати», «Пятидесяти пяти миллионов ста тридцати двух тысяч ста одиннадцати», «Одного миллиарда пятидесяти пяти миллионов ста тридцати двух тысяч ста одиннадцати».
Обратите внимание, что параметры inTable и outTable имеют один тип ReportTable. Так как в данном случае выходной параметр имеет то же имя, что и входной, он просто заменит собой входной параметр в коллекции глобальных параметров. Таким образом можно легко делать цепочки преобразований.
Преобразования вещественных чисел
Для преобразований вещественных чисел используются действия ConvertFloatToString, ConvertFloatCellToString, ConvertFloatColToString. Преобразования вещественных чисел во многом схожи с преобразованиями целых за исключением того, что при преобразовании вещественных чисел нельзя задавать пол и какое это числительное (порядковое или количественное). Рассмотрим простой пример преобразования числа 3,1415926 в предложный падеж:
В результате в параметр words будет записано значение «трех целых одном миллионе четырехстах пятнадцати тысячах девятистах двадцати шести десятимиллионных». Несмотря на то, что в качестве входного параметра действий преобразования вещественного числа используется System.Double, максимальный размер вещественной части ограничен миллиардными (9 знаков после запятой). Технически ничего не мешает сделать и больше, но на практике необходимости в такой точности пока не возникало.
Преобразования даты и времени
Для преобразования даты и времени служат действия ConvertDateTimeToString, ConvertDateTimeCellToString, ConvertDateTimeColToString. Как и предыдущие группы действий описываемые в этом разделе действия работы с датой и временем между собой очень схожи. Однако в отличие от преобразований целых и вещественных чисел, эти действия не используют параметры падежа и пола. Вместо этого используется более гибкий параметр format. Рассмотрим подробнее, какие представления форматов поддерживаются действиями преобразования даты:
Во всех приведенных выше форматах буква «х» означает первую букву падежа n (Nominative), g (Genetive), d (Dative), a (Accusative), i (Instrumental), p (Prepositional).
Как видите, возможности по настройке формата представления даты огромные. Рассмотрим несколько конкретных примеров форматов и результатов. За исходное значение даты возьмем «1988-06-26 13:47:56» (или если вам больше нравится, можно записать ее в формате «26.06.1988 13:47:56», это не принципиально):
Формат: dd MMg yyyy года HHn mmn ssn
Результат: 26 июня 1988 года тринадцать часов сорок семь минут пятьдесят шесть секунд
Формат: ddn MMg yyyyg
Результат: двадцать шестое июня одна тысяча девятьсот восемьдесят восьмого года
Формат: dd.MM.yy (MMn yyyyg)
Результат: 26.06.88 (июнь одна тысяча девятьсот восемьдесят восьмого года)
В формате xml конфигурация шага для преобразования даты и времени из последнего примера будет выглядеть следующим образом:
Преобразования денежных сумм
Для преобразования представления денежных сумм в ActivityManager служат действия CurrencyToString, CurrencyCellToString и CurrencyColToString. Как и все предыдущие группы действий по преобразованию данных эти действия отличаются между собой только типами объектов, над которыми производится преобразование: скалярное значение, строка и таблица. Приведем простой пример преобразования. Предположим, что в базе данных суммы хранятся в поле типа decimal, поле имеет имя dept, и нам необходимо сформировать по ним отчет, в котором сумма будет представлена в формате числа с разделителями между тысячами, а в скобках должна быть расшифровка суммы письменно. Пропустим этап выборки данных из базы, как это делается было рассказано в разделе «Выборка данных». Непосредственно преобразование столбца по поставленной задаче будет выглядеть следующим образом:
В результате преобразования мы получим таблицу, столбец dept которой преобразован из числового формата в текстовый. Причем все значения в данном столбце будут иметь вид «3 101 203,03 (три миллиона сто одна тысяча двести три рубля три копейки)».
Рассмотрим подробнее поддерживаемые форматы преобразования сумм:
Во всех приведенных выше форматах буква «х» означает первую букву падежа n (Nominative), g (Genetive), d (Dative), a (Accusative), i (Instrumental), p (Prepositional).
Как и с форматами даты и времени в случае с денежными суммами возможно сформировать представление в самых невообразимых формах.
Преобразования ФИО
Нередкими являются ситуации, когда появляется необходимость склонения по падежам фамилии, имени и отчества в формируемом отчете. ActivityManager использует для склонений ФИО всем известную библиотеку Padeg.dll. Действия ConvertModule.dll для склонения по падежам ФИО называются ConvertNameToCase, ConvertNameCellToCase и ConvertNameColToCase. Пользоваться данными действиям не сложнее, чем всеми остальными действиями преобразования данных. Например, чтобы преобразовать ФИО «Сухов Зигмунд Эдуардович» можно воспользоваться следующей конфигурацией:
Результатом выполнения данного действия будет строка «Сухова Зигмунда Эдуардовича».
Формат преобразования format очень прост и поддерживает следующие ключевые конструкции:
К примеру, если нам необходимо преобразовать «Сухова Зигмунда Эдуардовича» для подписи документа, мы можем воспользоваться шаблоном n.p. ss (при этом указав именительный падеж в параметре textCase) и получим в результате строку «З.Э. Сухов».
Действия объединения данных
Помимо действий по преобразованию формата представления данных в плагине ConvertModule.dll имеются простые действия, позволяющие объединить ячейки объектов ReportTable и ReportRow в строку с указанием разделителей. Эти действия называются RowConcat, ColumnConcat и TableConcat. Действие RowConcat служит для объединение всех ячеек объекта ReportRow в одну строку с указанием разделителя между значениями ячеек. Действие ColumnConcat позволяет объединить все ячейки одного столбца объекта ReportTable. Действие TableConcat позволяет объединить все ячейки объекта ReportTable с указанием разделителей между ячейками одной строки и строками. Пример использования
В результате исполнения действия по представленном примеру в коллекцию глобальных параметров будет записан параметр myConcatedStr строкового типа, значением которого будут все данные из таблицы myTable, объединенные объявленными разделителями (rowSeparator — разделитель строк, cellSeparator — разделитель ячеек).
Действия выборки элементов
К действиям выборки элементов относятся GetRow и GetCell.
Действие GetRow позволяет получить объект класса ReportRow из объекта класса ReportTable по указанному номеру строки (нумерация начинается с нуля). Объект класса ReportRow необходим для задания группового сопоставления шаблонных строк и значений (подробнее смотрите в разделе «Формирование отчета»). Важно помнить, что при отсутствии в объекте ReportTable строки с указанным номером будет сгенерировано исключение выхода индекса за диапазон возможных значений. Пример использования действия GetRow:
Действие GetCell предназначено для получения скалярного значения отдельной ячейки объекта ReportTable:
Нумерация строк в действии GetCell также как и в GetRow начинается с нуля.
Формирование отчета
После выборки и преобразования данных следующим этапом является непосредственно вставка результатов в файл шаблона отчета.
ActivityManager поддерживает возможность формирования отчетов в форматы odt, ods, docx и xlsx. Работа со всеми этими форматами единообразна и с точки зрения конфигурации ничем не отличается. Отличия имеются только в пост-обработке, но об этом будет написано в соответствующем разделе. Одной из основных концепций был отказ от использования COM-технологий для формирования отчетов из-за их медлительности, зависимости от установленного текстового процессора и плохой переносимости на новые версии. В результате было принято решение формировать отчеты взаимодействуя с XML. Такой подход в жертву гибкости, которая присуща COM по форматированию данных, дает более высокую скорость работы и полную независимость от установленного текстового процессора. По сути текстовый процессор вообще может быть не установлен на компьютере, но отчет будет сформирован и открыт, к примеру, в WordPad или другом редакторе, ассоцированном с типом файла отчета.
Создание файла шаблона
Настройка конфигурации
Для работы непосредственно с самими файлами шаблонов отчетов в ActivityManager предусмотрен плагин ReportModule.dll. Этот плагин очень прост в использовании и определяет всего 5 действий.
Первым из рассматриваемых действий будет ReportSetTemplateFile. Это действие предназначено для установки пути до файла шаблона, на основании которого будет формироваться отчет. Этот файл уже должен существовать. Рассмотрим пример конфигурации для данного действия:
Здесь параметр [reportPath] определяет путь до папки, в которой хранится файл example.odt и передается в командной строке при вызове ActivityManager.exe или устанавливается на более ранних шагах. Безусловно нам ничего не мешает задать и абсолютный путь до файла шаблона и тогда никаких дополнительных параметров передавать необходимости не будет: Установка пути до файла шаблона является обязательным действием перед вызовом действия генерации отчета.
Помимо установки пути до файла шаблона до генерации отчета необходимо настроить сопоставления шаблонных строк и значений, на которые вы хотите их заменить. Для этого в плагине ReportModule.dll предназначены три действия ReportSetStringValue, ReportSetStringValues, ReportSetTableValue. Первые два действия предназначены для замены скалярных шаблонных строк. Рассмотрим их по порядку.
Действие ReportSetStringValue явно задает сопоставление шаблонной строки и значения, на которое она будет заменена. При запуске генерации отчета данное значение будет подставлено вместо заданной шаблонной строки по всему файлу шаблона. Необходимости в указании символов «$» в имени шаблонной строки при использовании данного действия нет. Приведем простой пример использования данного действия:
В результате при генерации отчета по файлу шаблона с предыдущего изображения получится следующий результат
Может быть утомительным устанавливать сопоставление каждой шаблонной строки и соответствующего значения из источника данных отдельно. Да еще и перед тем как его установить, необходимо выбрать значение из результирующего набора ReportTable при помощи действия GetCell. Хотя теоретически это возможно, делать так не рекомендуется. Это действие по большей части предназначено для установки сложных вычисляемых значений или значений, переданных в командной строке. При необходимости установки скалярных значений из источника данных (например, РСУБД), служит более удобное действие ReportSetStringValues. Этому действию передается всего один параметр типа ReportRow. Действие делает сопоставление названий столбцов(ячеек) именам шаблонных строк. Для пояснения возьмем следующий пример:
При групповой установке сопоставлений шаблонных строк действием ReportSetStringValues вовсе не обязательно чтобы всем столбцам(ячейкам) из строки ReportRow соответствовали шаблонные строки в файле. Шаблонные строки, которые не удалось найти в файле при формировании просто будут отброшены. Справедливо и обратное, если в файле шаблона имеются шаблонные строки, которым не сопоставлено ни одного значения, то они просто не будут заменены. Никаких ошибок при этом не будет.
Оба из рассмотренных действия для установки сопоставления шаблонных строк и значений служат для вставки скалярных значений. При помощи этих действий нельзя вставить табличные данные в отчет.
Для вставки табличных данных служит действие ReportSetTableValue. Сигнатура данного действия выглядит следующим образом:
Важно заметить, что сопоставление на схожесть опирается на количество найденных столбцов именно в объекте ReportTable, а не в конечном файле шаблона. Т.е., вполне допустима вставка значений из объекта ReportTable с двумя или даже одним столбцом в строку таблицы файла отчета с четырьмя шаблонными строками
Параметр xmlContractor имеет особое значение для действия ReportSetTableValue. Этот параметр определяет элементы какого типа необходимо искать в файле шаблона на соответствие объекту ReportTable. И при подстановке именно объекты этого типа будут дублироваться. Всего существует 4 вида xmlContractor: Paragraph, Table, Row, Cell. Их отличие проще продемонстрировать на примере. Рассмотрим простой файл шаблона, в котором мы хотим произвести замену значений
В нем имеется таблица и параграф. Шаблонные строки в таблице и параграфе оформлены схожим образом. При установке xmlContractor в значение Row будет производиться поиск строк в каждой из существующих таблиц файла шаблона на соответствие столбцам объекта ReportTable. При нахождении удовлетворяющего схожести элемента строки он будет взят за шаблон и продублирован столько раз, сколько строк имеется в объекте ReportTable с заменой шаблонных строк на значения из соответствующих строк ReportTable. Результат будет выглядеть как на изображении ниже
Как видим, элемент параграфа был вовсе проигнорирован, т.к. он не вложен ни в один из элементов строки таблицы в документе.
Если xmlContractor установить в значение Table, то мы получим результат, изображенный ниже
На первый взгляд может быть непонятно что именно произошло, но принцип тот же, что и со строками. Только в этот раз производится поиск элементов таблиц на соответствие объекту ReportTable и при нахождении такой таблицы производится ее копирование для каждой строки объекта ReportTable с заменой шаблонных строк. На рисунке выше мы видим три таблицы. По одной для каждой строки объекта ReportTable. Применение xmlContractor Table позволяет формировать более сложные отчеты, где данные расположены не построчно: блоки подписи, вертикальные карточки данных и многое другое. Стоит заметить, что продемонстрированное поведение xmlContractor Table характерно только для отчетов в odt и docx. При формировании отчета в ods с установленным xmlContractor Table будет произведено копирование листа (при нахождении соответствия) для каждой строки в объекте ReportTable. Также важно заметить, что на данный момент это единственный xmlContractor, который не поддерживается при формировании отчетов в xlsx.
На изображении ниже представлен результат установки xmlContractor Paragraph
Как и ожидалось в данном случае было произведено копирование параграфа для каждой строки в ReportTable. При помощи этого xmlContractor удобно создавать списки.
xmlContractor Cell имеет особое значение для файлов табличных процессоров xlsx и ods. Для файлов текстовых процессоров он не имеет смысла. Для примера возьмем следующий файл шаблона в формате ods:
После чего применим действие ReportSetTableValue, устанавливающее таблицу с одним столбцом value.
При использовании xmlContractor Row мы получим вполне ожидаемый результат:
Строки таблицы ods, в которых было найдено соответствие объекту ReportTable (в данном примере такая строка одна, но это не обязательно), были продублированы для каждой строки объекта ReportTable.
А вот так будет выглядеть результат, если установить xmlContractor Cell:
В данном случае искались на схожесть и дублировались не строки, а ячейки. Так как технически в файлах табличных процессоров элементы ячеек находятся внутри элементов строк, то и дублирование производится в пределах той строки, которой они принадлежат. Это свойство позволяет формировать в табличных процессорах отчеты с переменным числом столбцов.
И, наконец, последнее не рассмотренное действие в плагине ReportModule.dll — это ReportGenerate. Пример использования данного действия был приведен ранее
Это действие предназначено для формирования отчета. Дело в том, что все до этого рассмотренные действия плагина ReportModule.dll конфигурируют генератор отчета, но не производят непосредственно генерацию. Генерация отчета происходит при вызове действия ReportGenerate. Именно поэтому это действие необходимо вызывать после всех настроек. Выходящим параметром действия ReportGenerate является путь до сформированного файла отчета. ReportGenerate не производит открытие файла отчета после формирования, это следует помнить. Причиной такого поведения является модульность. Генератор отчета не может знать, что вы планируете делать со сформированным отчетом. Возможно вы захотите написать плагин для отправки отчета по электронной почте после формирования или для записи его на FTP-сервер или еще что-то. Для выполнения самого ожидаемого действия со сформированным отчетом (его открытия) в ActivityManager предусмотрено действие. Оно называется IOOpenFile и как можно догадаться из названия расположено в плагине IOModule. Пример его использования приведен ниже:
При выполнение этого действия файл будет открыт в программе, ассоциированной с расширением файла. Т.е., если мы формируем отчет, а на компьютере не установлено ни OpenOffice, ни LibreOffice, ни MS Word, ничего кроме WordPad, то файл скорее всего откроется именно в нем.
Порядок установки сопоставлений шаблонных строк
При установке сопоставлений шаблонных строк значениям действиями ReportSetStringValue, ReportSetStringValues, ReportSetTableValue важно понимать, что замена во время генерации отчета производится каскадно в порядке их объявления. Это значит, что значения параметров на раннем шаге могут служить шаблонными строками параметров на более позднем шаге. Рассмотрим на примере.
Пост-обработка файла шаблона
Под пост-обработкой понимается процесс форматирования представления текста уже после заполнения файла шаблона данными. Это необходимо, если перед нами стоит задача, к примеру, выделить жирным часть текста уже после вставки. В качестве конкретного примера рассмотрим договор мены жилья. По договору количество участников может быть неограниченным, но в перечне участников с каждой из сторон необходимо вывести их всех одним абзацем (не списком), причем известно, что в информацию по каждому участнику включается его ФИО и паспортные данные, НО только ФИО необходимо выделить жирным. Если бы для решения этой задачи можно было использовать списки, то мы бы воспользовались ReportSetTableValue с установленным xmlContractor = Paragraph и заранее настроили бы стили в файле шаблона для каждого параметра. Но так как вывести всех участников необходимо одним абзацем мы можем воспользоваться тэгами пост-обработки. При выборке данных мы объединяем всех участников и их паспортные данные в одну строку при помощи GROUP_CONCAT в MySQL, или FOR XML в MSSQL, или TableConcat плагина ConvertModule.dll, или каким-то другим более привычным для вас образом.
Действия условного перенаправления и JS макросы
Условия
ActivityManager поддерживает два действия для условного перенаправления порядка исполнения. Оба этих действия расположены в плагине IOModule.dll. К ним относятся IOIfConditionToStep и IOIfConditionExit. Как можно понять из названия действий IOIfConditionToStep позволяет перейти на указанный шаг, если условие true, а IOIfConditionExit завершает обработку шагов конфигурационного файла, если условие true. Рассмотрим конкретный пример. Предположим, что нам необходимо сформировать соглашения по социальному, коммерческому и специализированному найму жилья. Все три отчета имеют схожу структуру и одинаковые (ну или почти одинаковые, это не принципиально) шаблонные строки, и отличаются лишь немного текстом соглашения. По этой причине нам нет необходимости создавать несколько файлов конфигурации. Достаточно создать несколько файлов шаблона, а в файле конфигурации добавить условие: если тип найма — социальный, то использовать файл шаблона социального найма, если тип найма — коммерческий, то использовать файл шаблона коммерческого найма и т.д.
Вся представленная выше конфигурация на диаграмме будет иметь примерно следующий вид:
В приведенной выше конфигурации помимо уже упоминавшихся действий IOIfConditionToStep и IOIfConditionExit есть еще одно действие, требующее особого внимания. Это действие JSRun плагина JSModule.dll. Это действие позволяет реализовывать микровычисления (инкременты, проверку значений и прочее) в виде JavaScript-макросов. В первом параметре действия JSRun передается обычный скрипт на языке JavaScript. Так как этот скрипт является обычным текстом с точки зрения ядра ActivityManger, в нем можно делать любые подстановки через [параметры]. JSRun является надстройкой над известной библиотекой Noesis.Javascript и поддерживает все синтаксические конструкции, поддерживаемые данной библиотекой. Для получения результата из скрипта его необходимо вернуть инструкцией return или присвоив значение специальной переменной окружения скрипта с именем result.
Циклы
Помимо условий при помощи действия IOIfConditionToStep совместно с JSRun можно реализовывать и циклы. Предположим мы имеем в базе данных информацию по пользователям, их платежам и датам внесения платежа в следующем виде
и нам необходимо сформировать отчет вида
При этом заранее не известно количество лет, а соответственно и таблиц. В данном отчете платежи сгруппированы по годам и разнесены по разным таблицам. Приступим.
Чтобы сформировать этот отчет нам понадобится вот такой простой файл шаблона
Первым делом необходимо будет выбрать из таблицы базы данных количество годов, именно столько таблиц будет сформировано во время генерации отчета. Само значение будет необходимо для инкремента цикла.
После этого необходимо выбрать список годов и сопоставлений шаблонов. Так эти данные будут выглядит в объекте ReportTable (назовем эту таблицу yearsTable):
Представленные выше данные необходимо вставить действием ReportSetTableValue с xmlClouser = Table в шаблонный файл. В результате получится заготовка, изображенная ниже (вы ее не увидите во время формирования отчета)
И наконец, после этого необходимо пройтись по всем строкам таблицы yearsTable, выбрать из них действием GetCell значение года (назовем его currentYear) и для каждой строки таблицы yearsTable выполнить запрос к базе данных, представленный ниже (пример для MySQL)
После чего необходимо результат этого запроса (на каждой итерации) установить действием ReportSetTableValue с xmlClouser = Row в шаблонный файл.
Полный листинг конфигурационного файла для данной задачи представлен ниже:
Визуальный редактор файлов конфигураций
Как можно было убедиться из предыдущих разделов, а особенно из раздела «Действия условного перенаправления и JS макросы», писать xml-конфигурацию вручную не только утомительно, но и чревато ошибками. Помимо этого в голове необходимо держать массу информации: какие имена у параметров, сколько их, какой они имеют тип, какие есть действия и в каких плагинах они расположены, какой порядковый номер у текущего шага и многое другое. Для облегчения создания файлов конфигурации отчетов был разработан визуальный редактор. На изображении ниже можно увидеть как выглядит этот редактор с открытым файлом конфигурации, демонстрирующим работу с циклами из предыдущего раздела
В левой части окна редактора расположен список шагов и их порядковых номеров (что очень удобно при работе с условным перенаправлением). Именно в таком порядке шаги будут располагаться в xml-файле. Снизу расположено 4 кнопки, назначение которых интуитивно понятно (слева направо): добавить шаг в текущую позицию, удалить текущий выделенный шаг, переместить выделенный шаг на одну позицию вверх, переместить выделенный шаг на одну позицию вниз. Для перемещения шагов не обязательно пользоваться кнопками, поддерживается drag’n’drop.
В правой части окна редактора расположены два выпадающих списка: «Плагины» (с перечнем подключенных на данный момент плагинов) и «Действия» (со списком действий доступных из данного плагина). Также в правой части расположена таблица с перечнем входных и выходных параметров. У каждого параметра отображается имя, тип, направление (входной или выходной) и значение. Первые три столбца задавать нет необходимости, они автоматически рефлексией формируются из сборок плагинов. В данной таблице необходимо указывать только значения. Чуть ниже, под таблицей с параметрами, расположено подробное описание выбранного действия. Эти описания берутся из xml-файлов документации, расположенных вместе с плагинами в папке plugins/. Подробнее о том, как формируются эти файлы можно почитать, например, тут.
Начало работы
На этом начальная настройка заканчивается. После этого можно приступать к созданию шагов конфигурационного файла. После добавления нового шага необходимо выбрать плагин и действие в этом плагине, которое вы хотите исполнить на этом шаге. После этого в таблице параметров появится список параметров данного действия. Чтобы задать значение параметру действия необходимо дважды кликнуть на нем.
Для задания параметров существует два редактора. Какой именно редактор будет вызван определяется автоматически по типу параметра.
Для параметров с ограниченным кортежем возможных значений (перечисления, логический тип данных) и чисел, а также для задания имен выходных параметров вызывается упрощенный редактор
В выпадающем списке этого редактора можно выбрать одно из видимых на данном этапе возможных значений либо можно задать произвольное значение вручную. В списке будут представлены все возможные значения перечисления (подгружаются рефлексией из сборки плагина), все параметры командной строки и те выходные параметры предыдущих шагов исполнения, которые совпадают по типу с задаваемым параметром.
Для параметров типа данных Sytem.String и сложных типов данных вызывается редактор на базе ScintillaNET с поддержкой подсветки синтаксиса JavaScript и SQL.
В этом редакторе также как и в упрощенном есть выпадающий список с видимыми на данном шаге параметрами из глобальной коллекции. Кнопка «Вставить» вставляет выбранный в списке параметр в место расположения курсора в редакторе.
Возможности отладки
Визуальный редактор поддерживает несколько простых возможностей, позволяющих отлаживать работоспособность файлов конфигураций без необходимости запуска ядра ActivityManager.exe из консоли или своего приложения.
Настоятельно рекомендуется по возможности при создании файлов конфигурации отчетов пользоваться визуальным редактором, а не править xml-файлы вручную.
Написание собственных плагинов
Вот и все. После компиляции остается положить этот плагин в каталог plugins\ и ActivityManager с AMEditor автоматически его найдут. Использовать действие MyAction данного плагина можно будет через следующую конфигурацию:
Чуть более сложный пример custom-плагина можно посмотреть в файле MenaModule.cs
Примечание: чтобы работать в своих плагинах с объектами классов ReportTable и ReportRow необходимо добавить в проект ссылку на сборку ExtendedTypes.dll.
Заключение
Проект развивается уже около года и и используется на боевых задачах нашей организации. Как и у любого генератора отчетов у ActivityManager есть как достоинства так недостатки. О достоинствах было рассказано во введении, теперь же хотелось отметить недостатки: