[Из песочницы] Генератор отчетов ActivityManager. Очередной велосипед, но в профиль11.12.2014 21:48
ActivityManager — это менеджер формирования отчетов, базирующийся на замене шаблонных строк.Основными особенностями ActivityManager являются: Независимость от источника данных: поддерживаются все СУБД, для которых существуют провайдеры .Net, и не только;
Формирование шаблонов без использования COM: все отчеты формируются непосредственно в XML;
Поддержка форматов отчетов ods, odt, docx, xlsx. Независимость от наличия текстового процессора на конечном компьютере пользователя: эта особенность вытекает из предыдущей;
Наличие механизмов пред-обработки данных: изменение формата представления ФИО, денежных сумм, целых, вещественных чисел и дат, в том числе и возможность изменения падежа, в котором должны быть представлены конечные данные;
Наличие механизмов пост-форматирования данных;
Простота использования и расширения благодаря наличию редактора конфигурации отчетов и простой плагинной архитектуре.
Конфигурацию отчета при помощи ActivityManager можно условно разделить на 3 части: выборка данных, их обработка и непосредственно формирование отчета. Подробную информацию по каждому из этапов смотри в соответствующих разделах.ГлоссарийФайл шаблона — файл формата odt, ods, docx или xlsx, служащий в качестве заготовки для будущего отчета
Шаблонная строка — элемент строки вида $variable$ в файле шаблона, который при формировании отчета будет заменен на подставляемые данные
Плагин — обычная сборка .Net, реализующая специальный интерфейс IPlug.
Действие (action) — с технической точки зрения это публичный метод класса, реализующего интерфейс IPlug и видимый через этот интерфейс
Шаг (step) — этап исполнения последовательности действий, описанный в конфигурационном файле отчета. Шаг отличается от действия тем, что действие — это описание сигнатуры того, что необходимо сделать на данном шаге, а шаг — это оболочка, связывающая сигнатуру с конкретными значениями параметров
Структура файла конфигурации
Файл конфигурации отчета представляет собой обычный xml-файл следующего вида: Пример
ConvertModule.dll
…
rudsn=registrySELECT * FROM executors;
…
Основную часть конфигурационного файла отчета занимают шаги. Шаги по сути представляют этапы формирования отчета: выборка данных, обработка данных, конфигурация отчета, источника данных и многое другое. Шаг состоит из имени плагина plugin, в котором находится действие action, которое необходимо выполнить, входных и выходных параметров и параметра repeat, указывающего сколько раз необходимо выполнить данный шаг (по умолчанию 1). Каждый входной параметр имеет имя name и значение (контент). Каждый выходной параметр имеет имя по умолчанию nameВ верхней части файла конфигурация находится блок . В данном блоке расположен перечень загружаемых плагинов во время исполнения. Плагины по умолчанию расположены в каталоге plugins\. Блок указывает язык, на котором будут выводиться сообщения (по большей части об ошибках) во время формирования отчета. На данный момент поддерживается два языка: русский и английский. Языковые переводы расположены в каталоге lang\.Несмотря на простую структуру файла конфигурации редактировать его вручную утомительно. Поэтому был разработан специальный редактор файлов конфигураций. Подробнее в разделе «Визуальный редактор файлов»
Поставляемые плагины
В поставке по умолчанию ActivityManager присутствуют 6 базовых и один custom-плагин: SqlDataSource.dll — плагин доступа к источникам данных SQL;
TextDataSource.dll — плагин доступа к источникам данных CSV через SQL;
ConvertModule.dll — Плагин преобразования данных. В этом плагине находятся действия преобразования формата представления данных, падежей, действия объединения в единую строку отчета целых таблиц, столбцов и строк, а также выбора отдельных строк, ячеек из таблицы источника данных;
ReportModule.dll — непосредственно сам плагин формирования отчетов;
IOModule.dll — данный плагин предназначен для операций ввода/вывода и управления порядком исполнения шагов. В данном модуле находятся действия запуска сформированного отчета в текстовом процессоре (и любого другого файла или приложения), вывода отладочной информации на консоль и в MessageBox, действия условного перехода, благодаря которым становится возможно делать в отчете ветвления и циклы (подробнее об этом смотрите в разделе «Действия условного перенаправления и JS макросы»);
JSModule.dll — данный плагин предназначен для написание достаточно простых JavaScript-макросов. Первоначальное назначение данного плагина — вычисление условий переходов, реализованных в модуле IOModule.dll. Но данным функционалом этот плагин конечно же не ограничен;
MenaModule.dll — это custom-модуль, который был разработан как специфичное расширение функционала для конкретной программы по мене жилья в нашей организации. Плагин демонстрирует, как легко можно добавить в генератор отчета свою функциональность, если базовой не хватает для решения поставленных задач.
Передача параметров
Параметры командной строки
При запуске генерации отчета ядру (ActivityManager.exe) необходимо передать один обязательный параметр config в виде
ActivityManager.exe config=«c:\1.xml»
В результате ActivityManager.exe прочитает файл конфигурации, расположенный по пути c:\1.xml и сформирует отчет.Помимо обязательного параметра config ActivityManager’у можно передать параметр lang — язык выводимых во время исполнения сообщений (по большей части ошибок, возникших при формировании отчета).Кроме базовых параметров config и lang ActivityManager может принимать любое количество любых других параметров, которые будут помещены в коллекцию глобальных параметров времени исполнения и могут быть использованы во время формирования отчета. Например:
ActivityManager.exe config=«c:\1.xml» connectionString=«dsn=registry» id_process=318
В результате выполнения данной команды в коллекцию глобальных параметров времени исполнения попадут параметры connectionString и id_process и их можно будет использовать во время установки соединения с источником данных, выборке и на любом другом шаге отчета. Как именно использовать данные параметры во время исполнения смотрите в следующем разделе.Глобальные параметры времени исполнения
Коллекция глобальных параметров времени исполнения это перечень именованных переменных, которые могут быть использованы на любом шаге генерации отчета (при условии, что на данном шаге, параметр уже доступен).Параметры записываются в данную коллекцию в двух случаях: При передаче в командной строке (см. предыдущий пункт)
Как результат исполнения предыдущих шагов формирования отчета.
Для использования глобальных параметров, необходимо заключить название параметра в квадратные скобки. Препроцессор перед передачей значения параметра на исполнение проверит соответствие шаблона с квадратными скобками параметрам в коллекции и если найдет соответствие по имени, то произведет замену.Например, предположим, что мы запустили генерацию отчета следующим образом
ActivityManager.exe config=«c:\1.xml» connectionString=«dsn=registry» id_process=318
Тогда во время исполнения приложения мы можем использовать переданные аргументы командной строки следующим образом: Пример
[connectionString]SELECT * FROM tenancy_processes WHERE id_process = [id_process][tenancy_processes]Row
Как видно, на первом шаге SqlSetConnectionString (установка строки соединения) во входящем параметре указывается [connectionString], что говорит препроцессору, что необходимо взять этот параметр из коллекции глобальных параметров. В случае, если параметр, находящийся в квадратных скобках не будет найден в коллекции глобальных параметров, никаких сообщений об ошибках не будет сгенерировано. ActivityManager поймет, что данная строка не является параметром и оставит ее без изменений.Обратите внимание на выходной параметр шага SqlSelectTable
Данная запись означает, что после исполнения запроса данные из источника будут сохранены в глобальной области параметров под именем tenancy_processes и к ним можно будет обратиться через [tenancy_processes] (что и делается на следующем шаге ReportSetTableValue)
[tenancy_processes]Row
Замена параметров простых типов (строки, числа, даты и т.д., а именно всех типов, которые можно однозначно конвертировать из строкового типа System.String в целевой при помощи Convert.ChangeType) осуществляется в режиме подстановки. Т.е. вполне допустимо задавать параметр как часть значения, а не как целое. Например:
SELECT * FROM tenancy_processes WHERE id_process = [id_process]
Параметры более сложных типов, которые невозможно однозначно конвертировать из строкового представления, будут подставлены непосредственно. В таких параметрах частичная подстановка невозможна по определению.Подстановка параметров из глобальной коллекции выполняется только во входящих параметрах действий.
Выборка данных
Прежде чем сформировать отчет, необходимо получить данные. На данный момент источниками данных для ActivityManager могут служить СУБД, для которых существует .Net-провайдер, а также текстовые файлы в формате CSV. К сожалению пока нет нативного источника данных для XML.Результатом выборки данных из любого из описанных источников будет объект либо скалярного типа либо типа ReportTable.
SQL-источники данных
Для работы с источниками данных SQL предназначен плагин SqlDataSource.dll.Простой примером использования данного плагина для выборки данных из ODBC-источника данных: Пример
dsn=registrySELECT * FROM executors;
На первом шаге данного примера устанавливается строка соединения. На втором производится выборка данных из таблицы executors, данные записываются в таблицу с именем new_table. После чего мы можем производить над ними различные модификации через плагин ConvertModule.dll или отправить непосредственно в отчет.В качестве провайдера по умолчанию в SqlDataSource используется ODBC, но допускается установка любого поддерживаемого в .Net провайдера. Для установки провайдера используется функция SqlSetProvider. Например, вот так можно установить провайдер OLE DB:
OLE
Здесь параметр name — это полное или краткое инвариантное имя провайдера. Нет необходимости задавать полное инвариантное имя, т.к. сопоставление имени происходит нечетко (по паттерну). Например, вместо полного инвариантного имени для MS Sql Server (System.Data.SqlClient) можно указать просто:
SQL
или, например
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:
id|surname|name|patronymic
1|Игнатов|Василий|Васильевич
2|Иванов|Иван|Иванович
user_actions.csv:
id_user|action
1|действие1
1|действие2
1|действие3
2|действие4
Нам необходимо выбрать количество действий для каждого пользователя.Конфигурация шага выборки данных из CSV при этом будет выглядеть следующим образом: Пример
SELECT a.surname, a.name, a.patronymic, COUNT (*) AS record_count
FROM [csv_path]users.csv a
LEFT JOIN [csv_path]user_actions.csv b ON a.id = b.id_user GROUP BY a.id
|truetrue
Результат данного запроса будет сохранен в коллекции глобальных параметров под именем table.Помимо действия TextSelectTable в плагине TextDataSource имеется еще 2 действия: TextSelectScalar и TextModifyQuery, подробную информацию о которых вы также можете узнать на wiki проекта.Преобразование данных
Нередко возникает необходимость в форматировании данных уже после выборки из источника и до их записи в конечный отчет. Причин этому может быть множество от отсутствия поддержки на уровне СУБД каких-либо сложных преобразований, до нежелания «марать» SQL-запрос массой излишних условий, превращающих его в нечитабельную простыню.Для подобных преобразований данных в ActivityManager используется плагин ConvertModule.dll.Вот перечень того, что можно сделать с данными при помощи этого плагина: Получить из таблицы источника данных отдельную строку по ее номеру. В дальнейшем данные в этой строке также можно подвергнуть преобразованиям и отправить в качестве коллекции автоматически именованных параметров в отчет;
Получить из таблицу источника данных значение отдельной ячейки;
Провести объединение в одну строку таблицы, столбца или строки источника данных в текстовую переменную. Чтобы было более понятно, это некоторый аналог GROUP_CONCAT из MySQL;
Преобразовать целые и вещественные числа, а также дату и время в сложное текстовое или комбинированное представление с возможностью склонения по падежам;
Преобразовать ФИО русского языка из именительного падежа в любую падежную форму;
Преобразовать число в представление денежной единицы, в том числе (при необходимости) и в текстовом виде с возможностью склонения по падежам.
Рассмотрим функции преобразования формата данных подробнее. Все функции преобразования данных можно классифицироватьПо типу преобразуемых данных:
Представления целых чисел: ConvertIntToString, ConvertIntCellToString, ConvertIntColToString;
Представления вещественных чисел: ConvertFloatToString, ConvertFloatCellToString, ConvertFloatColToString;
Представления даты и времени: ConvertDateTimeToString, ConvertDateTimeCellToString, ConvertDateTimeColToString;
Представления денежных сумм: ConvertCurrencyToString, ConvertCurrencyCellToString, ConvertCurrencyColToString;
Представления ФИО: ConvertNameToCase, ConvertNameCellToCase, ConvertNameColToCase;
По типу входных и выходных параметров: Преобразования над скалярными величинами: ConvertIntToString, ConvertFloatToString, ConvertDateTimeToString, ConvertCurrencyToString, ConverNameToCase;
Преобразования над ячейками объекта типа ReportRow (данный объект является результатом выполнения действия GetRow плагина ConvertModule.dll): ConvertIntCellToString, ConvertFloatCellToString, ConvertDateTimeCellToString, ConvertCurrencyCellToString, ConvertNameCellToCase;
Преобразования над столбцами объекта типа ReportTable (данный объект является результатом выполнения действий SqlSelectTable и TextSelectTable плагинов SqlDataSource.dll и TextDataSource.dll соответственно): ConvertIntColToString, ConvertFloatColToString, ConvertDateTimeColToString, ConvertCurrencyColToString, ConvertNameColToCase;
Преобразования целых чисел
Как уже говорилось выше для преобразования целых чисел используются действия ConvertIntToString, ConvertIntCellToString, ConvertIntColToString. Отличаются они между собой только типом входного и выходного параметра поэтому подробно рассматривать каждое из них мы не будем. Рассмотрим простой пример преобразования чисел в текстовое представление. Предположим, что нам необходимо из таблицы базы данных выбрать некоторые числовые значения, после чего привести их к текстовому виду по следующим правилам: все числа должны быть в родительском падеже, окончания текстовых представлений чисел должны быть в женском роде, числа должны быть количественными, а не порядковыми, первая буква результирующих текстовых представлений чисел должна быть большой. Для начала нам необходимо получить данные, которые мы будет преобразовывать. Ранее уже было показано как это делается: Пример
SELECT 1 AS int_column
UNION
SELECT 13013
UNION
SELECT 55132111
UNION
SELECT 1055132111
В результате данного действия в коллекции глобальных объектов будет хранится объект типа ReportTable, содержащий один столбец int_column содержащую строки со значениями 1, 13013, 55132111, 1055132111.Непосредственно само преобразование по определенным выше требованиям можно провести следующим образом:
Пример
[table]int_columnGenitiveFemaletruefalse
В результате на выходе мы получим таблицу с именем table со следующими значениями: «Одной», «Тринадцати тысяч тринадцати», «Пятидесяти пяти миллионов ста тридцати двух тысяч ста одиннадцати», «Одного миллиарда пятидесяти пяти миллионов ста тридцати двух тысяч ста одиннадцати».Обратите внимание, что параметры inTable и outTable имеют один тип ReportTable. Так как в данном случае выходной параметр имеет то же имя, что и входной, он просто заменит собой входной параметр в коллекции глобальных параметров. Таким образом можно легко делать цепочки преобразований.
Преобразования вещественных чисел
Для преобразований вещественных чисел используются действия ConvertFloatToString, ConvertFloatCellToString, ConvertFloatColToString. Преобразования вещественных чисел во многом схожи с преобразованиями целых за исключением того, что при преобразовании вещественных чисел нельзя задавать пол и какое это числительное (порядковое или количественное). Рассмотрим простой пример преобразования числа 3,1415926 в предложный падеж: Пример
3,1415926Prepositionalfalse
В результате в параметр words будет записано значение «трех целых одном миллионе четырехстах пятнадцати тысячах девятистах двадцати шести десятимиллионных». Несмотря на то, что в качестве входного параметра действий преобразования вещественного числа используется System.Double, максимальный размер вещественной части ограничен миллиардными (9 знаков после запятой). Технически ничего не мешает сделать и больше, но на практике необходимости в такой точности пока не возникало.Преобразования даты и времени
Для преобразования даты и времени служат действия ConvertDateTimeToString, ConvertDateTimeCellToString, ConvertDateTimeColToString. Как и предыдущие группы действий описываемые в этом разделе действия работы с датой и временем между собой очень схожи. Однако в отличие от преобразований целых и вещественных чисел, эти действия не используют параметры падежа и пола. Вместо этого используется более гибкий параметр format. Рассмотрим подробнее, какие представления форматов поддерживаются действиями преобразования даты: Форматы
dd — день месяца в виде числа
ddx — день месяца в виде текста
MM — месяц в виде числа
MMx — месяц в виде текста
yy — год в формате двухзначного числа
yyx — год в формате двухзначного числа в виде текста
yyyy — год в формате четырехзначного числа
yyyyx — год в формате четырехзначного числа в виде текста
hh — время от 1 до 12 в виде числа
hhx — время от 1 до 12 в виде текста
HH — время от 0 до 23 в виде числа
HHx — время от 0 до 23 в виде текста
mm — минуты в виде числа
mmx — минуты в виде текста
ss — секунды в виде числа
ssx — секунды в виде текста
Во всех приведенных выше форматах буква «х» означает первую букву падежа 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 конфигурация шага для преобразования даты и времени из последнего примера будет выглядеть следующим образом:
Пример
26.06.1988 13:47:56dd.MM.yy (MMn yyyyg)false
Преобразования денежных сумм
Для преобразования представления денежных сумм в ActivityManager служат действия CurrencyToString, CurrencyCellToString и CurrencyColToString. Как и все предыдущие группы действий по преобразованию данных эти действия отличаются между собой только типами объектов, над которыми производится преобразование: скалярное значение, строка и таблица. Приведем простой пример преобразования. Предположим, что в базе данных суммы хранятся в поле типа decimal, поле имеет имя dept, и нам необходимо сформировать по ним отчет, в котором сумма будет представлена в формате числа с разделителями между тысячами, а в скобках должна быть расшифровка суммы письменно. Пропустим этап выборки данных из базы, как это делается было рассказано в разделе «Выборка данных». Непосредственно преобразование столбца по поставленной задаче будет выглядеть следующим образом: Пример
[table]deptRublenii, ff (nniin rn ffn kn)falsefalse
В результате преобразования мы получим таблицу, столбец dept которой преобразован из числового формата в текстовый. Причем все значения в данном столбце будут иметь вид »3 101 203,03 (три миллиона сто одна тысяча двести три рубля три копейки)».Рассмотрим подробнее поддерживаемые форматы преобразования сумм: Форматы
ii — рубли (доллары, евро) в виде числа
ff — копейки (центы) в виде числа
iix — рубли (доллары, евро) в виде строки
ffx — копейки (центы) в виде строки
rx — слово «рубль» («доллар», «евро») — какое именно слово будет выбрано зависит от параметра currencyType
kx — слово «копейка» («цент») — какое именно слово будет выбрано зависит от параметра currencyType
nn — слово «минус », если число отрицательное. Если число положительное, то пустая строка. Пробел после слова минус ставится автоматически.
n — знак »-», если число отрицательное. Если число положительное, то знак не ставится. Пробел после знака »-» автоматически НЕ ставится.
Во всех приведенных выше форматах буква «х» означает первую букву падежа n (Nominative), g (Genetive), d (Dative), a (Accusative), i (Instrumental), p (Prepositional).Как и с форматами даты и времени в случае с денежными суммами возможно сформировать представление в самых невообразимых формах.
Преобразования ФИО
Нередкими являются ситуации, когда появляется необходимость склонения по падежам фамилии, имени и отчества в формируемом отчете. ActivityManager использует для склонений ФИО всем известную библиотеку Padeg.dll. Действия ConvertModule.dll для склонения по падежам ФИО называются ConvertNameToCase, ConvertNameCellToCase и ConvertNameColToCase. Пользоваться данными действиям не сложнее, чем всеми остальными действиями преобразования данных. Например, чтобы преобразовать ФИО «Сухов Зигмунд Эдуардович» можно воспользоваться следующей конфигурацией: Пример
Сухов Зигмунд Эдуардовичss nn ppGenitive
Результатом выполнения данного действия будет строка «Сухова Зигмунда Эдуардовича».Формат преобразования format очень прост и поддерживает следующие ключевые конструкции: Форматы
ss — полное представление фамилии
s — первая буква фамилии
nn — полное представление имени
n — первая буква имени
pp — полное представление отчества
p — первая буква отчества
К примеру, если нам необходимо преобразовать «Сухова Зигмунда Эдуардовича» для подписи документа, мы можем воспользоваться шаблоном n.p. ss (при этом указав именительный падеж в параметре textCase) и получим в результате строку «З.Э. Сухов».Действия объединения данных
Помимо действий по преобразованию формата представления данных в плагине ConvertModule.dll имеются простые действия, позволяющие объединить ячейки объектов ReportTable и ReportRow в строку с указанием разделителей. Эти действия называются RowConcat, ColumnConcat и TableConcat. Действие RowConcat служит для объединение всех ячеек объекта ReportRow в одну строку с указанием разделителя между значениями ячеек. Действие ColumnConcat позволяет объединить все ячейки одного столбца объекта ReportTable. Действие TableConcat позволяет объединить все ячейки объекта ReportTable с указанием разделителей между ячейками одной строки и строками. Пример использованияПример
[myTable]; ,
В результате исполнения действия по представленном примеру в коллекцию глобальных параметров будет записан параметр myConcatedStr строкового типа, значением которого будут все данные из таблицы myTable, объединенные объявленными разделителями (rowSeparator — разделитель строк, cellSeparator — разделитель ячеек).Действия выборки элементов
К действиям выборки элементов относятся GetRow и GetCell.Действие GetRow позволяет получить объект класса ReportRow из объекта класса ReportTable по указанному номеру строки (нумерация начинается с нуля). Объект класса ReportRow необходим для задания группового сопоставления шаблонных строк и значений (подробнее смотрите в разделе «Формирование отчета»). Важно помнить, что при отсутствии в объекте ReportTable строки с указанным номером будет сгенерировано исключение выхода индекса за диапазон возможных значений. Пример использования действия GetRow:
Пример
[table]0
Действие GetCell предназначено для получения скалярного значения отдельной ячейки объекта ReportTable: Пример
[table]0myColumn
Нумерация строк в действии GetCell также как и в GetRow начинается с нуля.Формирование отчета
После выборки и преобразования данных следующим этапом является непосредственно вставка результатов в файл шаблона отчета.ActivityManager поддерживает возможность формирования отчетов в форматы odt, ods, docx и xlsx. Работа со всеми этими форматами единообразна и с точки зрения конфигурации ничем не отличается. Отличия имеются только в пост-обработке, но об этом будет написано в соответствующем разделе. Одной из основных концепций был отказ от использования COM-технологий для формирования отчетов из-за их медлительности, зависимости от установленного текстового процессора и плохой переносимости на новые версии. В результате было принято решение формировать отчеты взаимодействуя с XML. Такой подход в жертву гибкости, которая присуща COM по форматированию данных, дает более высокую скорость работы и полную независимость от установленного текстового процессора. По сути текстовый процессор вообще может быть не установлен на компьютере, но отчет будет сформирован и открыт, к примеру, в WordPad или другом редакторе, ассоцированном с типом файла отчета.Создание файла шаблона
Прежде чем приступить к настройке файла конфигурации для генерации отчета необходимо создать файл шаблона отчета. Файл шаблона отчета — это обычный файл формата odt, ods, docx или xlsx с заданной заранее конструкцией и форматированием и указанными шаблонными строками. Подставляемые значения в файле шаблона экранируются символами доллара. Например: $variable$, где variable — имя шаблонной строки. Чтобы было более понятно, посмотрите на изображение ниже.
В данном файле шаблона определено 6 шаблонных строк: $title$, $date$, $n$, $snp$, $money$, $date$. Как именно данные шаблонные строки будут заменяться в файле шаблона зависит от конфигурации.
Настройка конфигурации
Для работы непосредственно с самими файлами шаблонов отчетов в ActivityManager предусмотрен плагин ReportModule.dll. Этот плагин очень прост в использовании и определяет всего 5 действий.Первым из рассматриваемых действий будет ReportSetTemplateFile. Это действие предназначено для установки пути до файла шаблона, на основании которого будет формироваться отчет. Этот файл уже должен существовать. Рассмотрим пример конфигурации для данного действия:
Пример
[reportPath]example.odt
Здесь параметр [reportPath] определяет путь до папки, в которой хранится файл example.odt и передается в командной строке при вызове ActivityManager.exe или устанавливается на более ранних шагах. Безусловно нам ничего не мешает задать и абсолютный путь до файла шаблона и тогда никаких дополнительных параметров передавать необходимости не будет: Установка пути до файла шаблона является обязательным действием перед вызовом действия генерации отчета.Помимо установки пути до файла шаблона до генерации отчета необходимо настроить сопоставления шаблонных строк и значений, на которые вы хотите их заменить. Для этого в плагине ReportModule.dll предназначены три действия ReportSetStringValue, ReportSetStringValues, ReportSetTableValue. Первые два действия предназначены для замены скалярных шаблонных строк. Рассмотрим их по порядку.
Действие ReportSetStringValue явно задает сопоставление шаблонной строки и значения, на которое она будет заменена. При запуске генерации отчета данное значение будет подставлено вместо заданной шаблонной строки по всему файлу шаблона. Необходимости в указании символов »$» в имени шаблонной строки при использовании данного действия нет. Приведем простой пример использования данного действия:
Пример
titleЗаголовок 123
В результате при генерации отчета по файлу шаблона с предыдущего изображения получится следующий результат
Может быть утомительным устанавливать сопоставление каждой шаблонной строки и соответствующего значения из источника данных отдельно. Да еще и перед тем как его установить, необходимо выбрать значение из результирующего набора ReportTable при помощи действия GetCell. Хотя теоретически это возможно, делать так не рекомендуется. Это действие по большей части предназначено для установки сложных вычисляемых значений или значений, переданных в командной строке. При необходимости установки скалярных значений из источника данных (например, РСУБД), служит более удобное действие ReportSetStringValues. Этому действию передается всего один параметр типа ReportRow. Действие делает сопоставление названий столбцов (ячеек) именам шаблонных строк. Для пояснения возьмем следующий пример:
Пример
dsn=registrySELECT 'Заголовок 321' AS title, NOW () AS date[table]0[row]C:\example.odt[fileName]
На первых двух шагах примера выше мы устанавливаем строку соединения и делаем выборку объекта ReportTable в коллекцию глобальных параметров. Этот объект имеет имя table и представляет собой таблицу с одной строкой и столбцом с именами title и date. После этого мы при помощи действия GetRow выбираем из объекта ReportTable объект ReportRow, представляющий собой строку по индексу 0 (первая строка) объекта ReportTable. После чего устанавливаем объект ReportRow в качестве перечня сопоставлений значений и шаблонных строк в действии ReportSetStringValues. В результате всех этих действий будет сформирована конфигурация, которая «говорит», что необходимо искать в файле шаблона строки $title$ и $date$ и менять их на значения из соответствующих столбцов (ячеек) строки ReportRow. После формирования отчета по рассмотренной выше конфигурации для ранее созданного файла шаблона example.odt мы получим результат, представленный на рисунке ниже
Обратите внимание, что во время вставки скалярных значений в четвертом столбце таблицы произошла замена одноименной шаблонной строки $date$. Дело в том, что действия сопоставления шаблонных строк значениям ReportSetStringValue и ReportSetStringValues не делают никаких предположений о том, где расположены данные: в таблице, в колонтитуле, в плавающем текстовом блоке или где-то еще, они просто производят замену по шаблону. Одним из решений данной проблемы может служить переименование одной из шаблонных строк. Другой способ будет рассказан ниже в разделе «Порядок установки сопоставлений шаблонных строк».
При групповой установке сопоставлений шаблонных строк действием ReportSetStringValues вовсе не обязательно чтобы всем столбцам (ячейкам) из строки ReportRow соответствовали шаблонные строки в файле. Шаблонные строки, которые не удалось найти в файле при формировании просто будут отброшены. Справедливо и обратное, если в файле шаблона имеются шаблонные строки, которым не сопоставлено ни одного значения, то они просто не будут заменены. Никаких ошибок при этом не будет.
Оба из рассмотренных действия для установки сопоставления шаблонных строк и значений служат для вставки скалярных значений. При помощи этих действий нельзя вставить табличные данные в отчет.
Для вставки табличных данных служит действие ReportSetTableValue. Сигнатура данного действия выглядит следующим образом:
Пример
[table]Row
Параметр table представляет собой объект типа ReportTable, данные из которого планируется вставить в файл шаблона. Поиск соответствия в файле шаблона производится по названиям столбцов объекта ReportTable. Порядок столбцов значения не имеет, но имеет значение их наличие. Важным моментом в замене т