Перейти к содержанию

Отчёты — Администрирование

Обзор

Домен reports охватывает настройку отчётов, фильтров, прав доступа и импорт/экспорт пакетов отчётов. Администрирование использует:

  • Кастомная SPA-страница -- 1 форма (отчёты) -- зарегистрирована в дереве автоадминки, но открывает собственную SPA-страницу
  • EntityEditor -- 3 схемы (printForms, registries, registryColumns)
  • Admin API -- 4 контроллера (CRUD отчётов, фильтры, права, экспорт/импорт)

Механизмы администрирования

Кастомная SPA-страница (в дереве автоадминки)

Alias формы Название Url Таблица БД Папка
reports Отчеты /administration/reports dbo.Reports Дополнительно

EntityEditor

Схема JSON Таблица Назначение
printForms dbo.PrintForms Печатные формы
registries dbo.Registries Реестры
registryColumns (связанная) Колонки реестров

Admin API контроллеры

Контроллер Маршрут Методы Назначение
ReportsAdminController /api/admin/reports GET, POST, PUT, DELETE CRUD отчётов, контексты
ReportFiltersController /api/admin/reports/filters GET, POST, PUT, DELETE CRUD фильтров и параметров
ReportRightsController /api/admin/reports/{reportId:Guid}/*rights* GET, POST, DELETE Права групп (view/edit/special)
ReportStatsController /api/admin/reportstats GET, POST Экспорт/импорт пакетов отчётов

Ключевые настройки

Отчёты (Reports)

Где настраивается: SPA-страница /administration/reports (пункт reports в дереве автоадминки) / Admin API -> ReportsAdminController Таблица БД: dbo.Reports

17 полей: карточка отчёта, описание, тип, шаблон.

Группа полей Что контролирует
Имя, описание Идентификация в UI
Тип отчёта FastReport / Word / Excel / реестр
Шаблон Файл шаблона отчёта
Параметры Настройки генерации

Эффект в runtime: отчёт доступен пользователям через контекстное меню задачи/категории или через раздел отчётов.

Контексты отчёта (ReportContextObject)

Где настраивается: Admin API -> ReportsAdminController -> /{id}/context Таблица БД: dbo.ReportContextObject

Привязка отчёта к контексту использования. Определяет, где отчёт будет доступен. Значения поля Reports.Context: 0=Task, 1=Subcat, 2=Category, 3=User, 4=Group (подробнее: support-guide-fastreport.md секция 3.3, 8).

Фильтры отчёта

Где настраивается: Admin API -> ReportFiltersController Таблицы БД: dbo.ReportFilterLink, таблицы Filter*

Форма фильтра: набор параметров и их порядок. Параметры определяют пользовательский ввод перед генерацией.

Права доступа

Где настраивается: Admin API -> ReportRightsController Таблицы БД: dbo.ExternalObjects* (таблицы прав)

Видимость и редактирование отчёта по группам. Без прав отчёт не виден в runtime.

Печатные формы (EntityEditor)

Где настраивается: EntityEditor -> printForms Таблица БД: dbo.PrintForms

Шаблоны документов для печати (Word/Excel), привязанные к категориям.

Реестры (EntityEditor)

Где настраивается: EntityEditor -> registries, registryColumns Таблица БД: dbo.Registries

Структура и колонки реестров, доступных для просмотра/экспорта.

Типичные ошибки настройки

Симптом Причина Где проверить SQL-диагностика
Отчёт есть в админке, но не виден пользователю Не настроены права на группу пользователя ReportRightsController select * from dbo.ExternalObjectsPermissions where ObjectId = (select ExternalObjectId from dbo.Reports where Id = {reportId})
Фильтр отчёта пустой/неверный Некорректные ReportFilterLink или порядок параметров ReportFiltersController select * from dbo.ReportFilterLink where ReportId = {reportId}
После импорта отчёт работает некорректно Частично перенесённые связи фильтров/прав Целостность связок Проверить ReportFilterLink, ExternalObjects* для импортированного отчёта
Отчёт не виден в контекстном меню Не привязан контекст ReportsAdminController -> context select * from dbo.ReportContextObject where ReportId = {reportId}

FastReport: обязательные инварианты

FastReport-отчёт — административная настройка, в которой администратор создаёт карточку отчёта, права, контекст, фильтр, шаблон и параметры экспорта. Пошаговый workflow создания отчёта и базовые источники данных уже описаны в academy-patterns.md, практический support-чеклист Win-дизайнера и runtime — в support-guide-fastreport.md.

⚠️ Критично: для новых FR-отчётов в пользовательских custom-app-settings должен быть включён параметр useNewFRReports=true. Без этой настройки новый FR-контур не открывает отчёты корректно.

⚠️ MSSQL и PostgreSQL не взаимозаменяемы: отчёт, созданный на MSSQL, содержит источник данных MSSQL. При переносе на PostgreSQL FastReport продолжит пытаться подключаться к старому источнику, что приводит к ошибкам. Для PostgreSQL нужен отдельный отчёт с отдельным источником данных; автоматического переключения SQL-диалекта нет.

⚠️ Права на данные внутри отчёта — ответственность разработчика отчёта. Права видимости отчёта и права на данные в SQL-источнике — разные уровни. CurrentUserID передаётся автоматически, но SQL отчёта должен сам применять его для фильтрации данных.

Где открывается дизайнер

Дизайнер Как открыть Ограничения
Win-дизайнер действие «Win-дизайнер» у отчёта ссылка на скачивание из интерфейса больше не предоставляется; ZIP берётся из служебной категории «Репозиторий версий приложения»; нужен .NET Framework 4.7.1; SQL-сервер должен быть доступен с машины дизайнера
Онлайн-дизайнер Task Center /MVC/ReportDesigner/{id} доступен администраторам
Онлайн-дизайнер .NET Core /reportdesigner/{id} доступен администраторам

Для сетевых требований Win-дизайнера см. support-guide-fastreport.md. Для 7-шаговой последовательности создания отчёта см. academy-patterns.md.

Контексты и автоматические параметры

CurrentUserID передаётся во все отчёты автоматически. Этот параметр нужен не для UI, а для SQL/скриптов отчёта: по нему разработчик отчёта ограничивает данные правами текущего пользователя.

Context Где доступен отчёт Автоматические параметры Особенности настройки
0 Task карточка задачи, меню «Ещё» / отчёты TaskID, SubcatID можно ограничить доступность отчёта категориями/разделами
1 Subcat контекст категории SubcatID используется для отчётов по категории
2 Category контекст раздела CategoryID в старом руководстве помечен как неиспользуемый сценарий
3 User профиль пользователя UserID список доступных значений не настраивается; доступ определяется правом просмотра отчёта
4 Group просмотр состава группы коллекция UserID + GroupID в старом руководстве помечен как неиспользуемый сценарий

Все параметры отчёта применяются совместно: контекстные параметры, CurrentUserID и параметры фильтра не отменяют друг друга.

Фильтры FR: параметры и пустые значения

Базовые фильтры «Период» и «Выпадающий список» уже разобраны в academy-patterns.md. Ниже — правила, которые критичны именно для администратора/разработчика FR-шаблона.

Именование параметров фильтра

Тип фильтра Имя в настройке фильтра Параметр в FastReport
Строка / Число / Выпадающий список / Пользователь / Группа / Категория / Оргструктура Name FilterName
Период Period FilterPeriodFrom, FilterPeriodTo

Для SQL-параметров дат обычно нужен тип DateTime. Для числовых ID, которые приходят из выпадающего списка как строка, безопасный вариант — оставить параметр запроса VarChar и дать SQL Server выполнить преобразование в запросе.

Передача пустых значений

Тип фильтра Если значение выбрано Если значение не выбрано
Строка строка null
Число число null
Дата дата null
Период две даты: Filter<Name>From, Filter<Name>To null для открытого начала/конца
Выпадающий список строка; при мультивыборе — значения через запятую без пробелов null
Пользователь / Группа / Оргструктура / Категория строка ID через запятую без пробелов пустая строка "", не null

⚠️ Фильтры Пользователь/Группа/Оргструктура/Категория всегда мультивыборные. Их нельзя штатно ограничить одним значением; SQL должен принимать строку ID.

⚠️ Фильтр по категориям не заменяет проверку прав в SQL. В самом фильтре пользователь видит только категории, где у него есть хотя бы одно из прав: «Просматривать все задачи», «Создавать задачи», «Исполнять», «Администратор задач», «Администратор категории». Если пользователь выбирает раздел, в отчёт передаётся список доступных ему категорий раздела. Но если пользователь не выбрал ни одной категории/раздела, контроль прав полностью остаётся на SQL отчёта.

Пустое значение по умолчанию

Если фильтр привязан к отчёту, FastReport создаёт параметры при открытии отчёта в дизайнере. Для пустого default параметр может не создаться автоматически. Есть два рабочих способа:

  1. вручную создать параметр в дизайнере с нужным типом и именем Filter<Имя> или Filter<Имя>From/Filter<Имя>To, затем сохранить отчёт;
  2. временно задать в фильтре непустой default, открыть отчёт в дизайнере, убедиться что параметры созданы, сохранить отчёт, затем вернуть пустой default.

Для открытого периода default SQL-параметров подбирается так, чтобы не отсечь реальные данные. Типовой нижний default:

@from = '01.01.1900'

SQL-условие для открытого периода:

WHERE (@from IS NULL OR t.Date >= @from)
  AND (@to   IS NULL OR t.Date <= @to)

Параметры фильтра в строке вызова

Для прямого вызова отчёта значения фильтров передаются в формате f{paramID}_{Name}_v=.... Значение из строки вызова имеет приоритет над default в фильтре. Имя параметра регистрозависимо.

Тип параметра Пример
строка f11_Mod_v=test
число f11_Mod_v=2
дата f11_Mod_v=25.06.2018
период f11_Mod_v=from:25.06.2018;to:20.06.2018
пользователь / оргструктура / выпадающий список / группа / категория f11_Mod_v=1,2,3
read-only режим параметра f11_r=1

ID раздела для параметра категории не передаётся: если нужно выбрать раздел, передаётся список категорий раздела.

Техники программирования в FastReport

Тернарный оператор вместо IIf()

⚠️ Не использовать IIf() для защиты от null при форматировании. IIf() вычисляет все ветки до выбора результата, поэтому форматирование null всё равно падает. Тернарный оператор вычисляет только нужную ветку.

IsNull("FilterPeriodFrom") ? "-" : FormatDateTime([FilterPeriodFrom])

Для строки периода применяйте тот же принцип отдельно к началу и окончанию периода.

Итоги в заголовке группы

Если итог по группе выводится в заголовке, а не в подвале группы:

Настройка Значение
итоговое поле ProcessAt = GroupFinished
объект Report DoublePass = True
поле названия группы ProcessAt = Default

Название группы и итог должны быть разными объектами. Название печатается на первом проходе, итог — после завершения группы.

Детальная страница и drill-down

Для перехода из основного отчёта в детальную страницу FastReport передаёт значения через гиперссылку. Если нужно передать список ID, не используйте запятую: FastReport трактует её как разделитель разных параметров. Практичный разделитель — _.

111_222_333

Название вкладки детальной страницы формируется автоматически из переданных параметров и вручную не задаётся.

Вызов отчёта с кнопки карточки задачи

Для кнопки в карточке задачи обычно используется контекст «Задача». JavaScript-выражение открывает просмотр отчёта и передаёт TaskID как contextId:

window.open('/MVC/ReportView/{reportId}/contextId/' + TaskID, '_newtab');

Восстановление шаблона из .FRX

Локальная копия шаблона FastReport сохраняется в .FRX. Восстановление через начальный экран дизайнера полностью заменяет содержимое отчёта в БД. Перед восстановлением нужно понимать, что текущий ContentXml будет перезаписан.

Преобразование типов

В рамках одного отчёта тип параметра должен быть одинаковым во всех местах использования. Числовые константы должны соответствовать ожидаемому типу: например, для Double используйте 60.0, а не 60.

SQL-паттерны для FR-источников

Базовый пример SQL-источника и гиперссылки на задачу есть в academy-patterns.md и academy-patterns.md. Ниже — паттерны, которые нужны для нетривиальных отчётов.

Гиперссылки на карточки

Способ Когда использовать Пример
Через Settings.ApplicationPath когда в отчёт добавлена таблица Settings [Settings.ApplicationPath + "/MainTaskForm.aspx?TaskID=" + ToString([Table.TaskID])]
Относительный URL из SQL-источника когда не хочется добавлять Settings как источник сформировать URL в SQL и выбрать готовое поле в настройках гиперссылки

Для профиля пользователя используется тот же подход с UserID.

Очистка HTML и служебных символов

Если в категории разрешён HTML в тексте задачи, FastReport может некорректно отрисовать неполный HTML. Для плоского текста используйте SQL-функцию очистки:

SELECT dbo.fnStripTags(T.TaskText) AS TaskText
FROM TasksInSubcat11Denormalized T

Альтернативные функции, которые встречаются в отчётах: cm_StripHTML, cm_ReplaceHTML, cm_ReplaceEverything.

Полный путь категории хранит разделитель Fraction Slash (U+2044). В SQL используйте NCHAR(8260):

SELECT REPLACE(Subcategories.FullPath, NCHAR(8260), '\\') AS SubcatName
FROM Subcategories

Служебные категории через Settings

Чтобы отчёт переносился между инсталляциями, не зашивайте ID служебных категорий. Добавьте Settings как источник данных и используйте поля:

Поле Settings Категория
CalendarSubcatID календарь
ChatSubcatID общение / чаты
PrivateSubcatID личные задачи

Для исключения задач из этих категорий передайте строку ID и проверяйте SubcatID через CHARINDEX или LIKE.

Мультивыбор в SQL

Параметр мультивыбора приходит строкой ID через запятую. Перед проверкой удобно добавить запятые в начало и конец строки: ,123,456,789,. Пустой выбор после такой нормализации даёт ,,.

WHERE (@subcat = ',,')
   OR (CHARINDEX(',' + CAST(T.SubcatID AS varchar(max)) + ',', @subcat) > 0)

Альтернативный вариант — табличная функция GetMultiValues:

WHERE (@subcat = ',,')
   OR (CAST(T.SubcatID AS varchar(max)) IN (
        SELECT [Value]
        FROM dbo.GetMultiValues(@subcat, ',')
   ))

В коде отчёта для строковых значений можно проверять вхождение через .ToString().Contains(...).

Список выбранных значений в шапке

Для вывода выбранных категорий/пользователей/групп в шапке используйте отдельный SQL-источник с FOR XML PATH('') и той же проверкой CHARINDEX:

SELECT
  (SELECT REPLACE(S.FullPath, NCHAR(8260), '\\') + '; '
   FROM Subcategories S
   WHERE CHARINDEX(',' + CAST(S.SubcatID AS varchar(max)) + ',', @subcat) > 0
   FOR XML PATH('')) AS SubcatNames
FROM Subcategories

Если нужно вывести каждый элемент с новой строки, добавьте <br/> в SQL и после FOR XML PATH верните экранированные символы обратно. Для поля FastReport должен быть включён режим HTML-тегов.

SELECT REPLACE(REPLACE(
  (SELECT G.Descr + ', <br/>'
   FROM Groups G
   WHERE CHARINDEX(',' + CAST(G.GroupID AS varchar(max)) + ',', @GroupID) > 0
   FOR XML PATH('')),
  '&lt;', '<'), '&gt;', '>') AS GroupNames
FROM Groups

Рабочие минуты и Excel-формулы

Для рабочих минут используйте SQL-функцию:

dbo.tc_DiffWorkingMinutes(StartTime, EndTime)

Для отображения результата строкой в C#-коде отчёта обычно используется функция diff_str(int WMinutes), которая берёт Settings.WorkMinutesInDay и возвращает строку вида X дн. X ч. X мин.. Таблица Settings должна быть добавлена как источник данных.

Для генерации формул Excel из FR используется вспомогательная C#-функция ColumnNumberToName(int), возвращающая имя колонки (1 -> A, 2 -> B). Если порядок пересчёта формул важен, в начало формулы добавляют цифру очереди (1=..., 2=...) и затем запускают макрос .xlam AddIn, который сортирует и применяет формулы.

Дизайн FR-шаблонов и экспорт

Подробные режимы XLSX-экспорта (Wysiwyg, DataOnly, Seamless, PrintOptimized), DTO ExportSettings и API настройки уже описаны в support-guide-fastreport.md. Здесь зафиксированы правила дизайна, которые влияют на корректность вывода.

Excel-сетка

⚠️ Для Excel элементы отчёта обязательно привязывать к сетке. Если объекты не выровнены по одной сетке или пересекаются, FastReport создаёт лишние строки/столбцы и объединённые ячейки. После завершения шаблона включите snap-to-grid и выровняйте все элементы.

Условное форматирование и матрицы

В обычных полях условное выделение может читать Value, Text или значения других ячеек. В матрицах порядок вычисления ячеек зависит от Layout (DownThenAcross / AcrossThenDown), поэтому чтение соседней ячейки в условии может быть нестабильным. Надёжнее читать исходное значение из DataSource, а не из уже отрисованной ячейки.

Скрытие строк и колонок матрицы

Для pivot/матрицы свойства Visible=false часто недостаточно. Для скрываемой колонки/строки применяйте одновременно:

Свойство Значение
Width / Height 0
Autosize False
MinWidth / MinHeight 0
Padding убрать отступы по соответствующей оси

Unlimited height/width

Unlimited height отключает вертикальную пагинацию в браузере. Unlimited width нужен для широких матриц, которые растут по горизонтали. Настройка задаётся отдельно для каждой страницы отчёта.

«Таблица в таблице» через Duplicates=Merge

FastReport не поддерживает вложенные таблицы как отдельные объекты. Для макета «таблица в таблице» используйте обычную таблицу для центральной части и текстовые поля по краям. У повторяющихся текстовых полей выставляется Duplicates=Merge, чтобы визуально получить объединённые вертикальные заголовки.

Спойлеры

Спойлер собирается из CheckBox, гиперссылки со значением группы, BeforePrint у заголовка группы и Click у чекбокса. В Click меняется список раскрытых групп и вызывается Report.Refresh().

⚠️ Клик по спойлеру полностью перезагружает отчёт. Для тяжёлых отчётов и больших наборов данных спойлеры использовать нельзя: пользователь будет ждать повторного формирования отчёта.

Изображения из файловых БД

Изображения для объекта Picture можно брать из таблицы UploadFiles файлового провайдера. Для вложений задачи используется провайдер по умолчанию (FileProviders.UseToWriteFiles = 1), для файлового ДП — провайдер из ExtParamsFileSettings или провайдер по умолчанию.

Ключевые таблицы связки:

Сценарий Таблицы
файлы задачи FileStorageFileToTaskLinks, FileStorageFileVersions, {FileProviderDb}.dbo.UploadFiles
файлы ДП FileStorageFileToExtParamLinks, FileStorageFileVersions, {FileProviderDb}.dbo.UploadFiles

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

Прочие дизайн-приёмы

Приём Правило
сортировка по клику менять DataBand.Sort в обработчике Click; работает только на главной странице отчёта, не на детальных страницах
кликабельная шапка сортировки шапка столбца должна быть текстовым полем (Label), не ячейкой таблицы
несколько страниц в документе чтобы новая страница продолжила печататься на текущей странице, включить PrintOnPreviousPage
текстовый экспорт печатных форм RTF обычно лучше сохраняет форматирование, переносы и нестандартные шрифты, чем DOCX/PDF

Импорт, экспорт и форматы выгрузки

Импорт/экспорт FR-отчётов

Экспорт отчётов создаёт ZIP-архив с XML-файлами. При импорте отчёты добавляются вместе с фильтрами; тип контекста переносится, но конкретные объекты контекста нужно указать заново. Права доступа после импорта также настраиваются заново.

⚠️ Совпадение отчётов проверяется по GUID. Если импортируемый отчёт имеет GUID уже существующего отчёта, старый отчёт заменяется новым. Привязки к объектам контекста при этом теряются.

Для локального восстановления одного шаблона используется .FRX из Win-дизайнера; это не то же самое, что пакетный экспорт/импорт отчётов через админку.

Настройки экспорта по форматам

Формат Настройки Примечания
Docx тип экспорта: табличный / послойный / абзацы; высота строки: совпадает / минимальна; Wysiwyg; оптимизированная печать табличный экспорт кладёт каждый абзац в отдельную ячейку; послойный — в текстовые поля; абзацы — форматированный текст
Xlsx см. support-guide-fastreport.md не дублируется здесь: режимы и API уже описаны в support-guide
Rtf Wysiwyg; разрывы страниц; картинки: нет / PNG / JPEG / метафайл метафайл .EMF — default и лучший вариант для качества диаграмм
Ppt картинки: PNG / JPEG используется для презентационного вывода

Готовые отчёты и ограничения прав

В поставке есть 35 типовых отчётов. Они полезны как готовый инструмент и как примеры FR-шаблонов, но имеют отдельное ограничение прав.

⚠️ В готовых отчётах права на задачи проверяются частично. Списки задач внутри отчёта могут содержать задачи, на просмотр которых у пользователя нет прав. Проверка прав сработает только при переходе по гиперссылке в карточку задачи; отдельные задачи могут не открыться.

⚠️ Совместимость: корректная работа готовых отчётов поддерживается с SQL Server 2014; SQL Server 2012 — ограниченно.

Список типовых отчётов:

Отчёт
1 Аудит доступа к задаче
2 Время активности пользователей в системе
3 Время активности пользователя в системе
4 Диаграмма Ганта по отсутствиям
5 Журнал регистрации действий пользователей
6 Задачи, не выполненные за рекомендуемый срок
7 Занятость сотрудников в группах за период
8 Информация по просроченным задачам
9 Использование дискового пространства
10 История доступа к файлам
11 Итоги дня
12 Нарушения регламентов работы с задачами
13 Общая статистика по задачам
14 Отчёт по входу сотрудников в 1Форму
15 Отчёт по переносам сроков
16 Отчёт по статусам
17 Поставленные задачи на группу
18 Просроченные задачи для пользователя
19 Работа по поставленным задачам
20 Статистика загрузки сотрудника
21 Статистика исполнения задач группой для орг.единиц
22 Статистика использования мобильных приложений
23 Статистика по акцептантам
24 Статистика по подписям
25 Статистика по просроченным задачам
26 Статистика по сотруднику за период
27 Табель трудозатрат
28 Табель трудозатрат по задаче
29 Табель трудозатрат по категории
30 Табель трудозатрат по проекту
31 Табель трудозатрат по сотруднику
32 Трудозатраты по задачам
33 Трудозатраты по задачам категории
34 Трудозатраты по задачам проекта
35 Трудозатраты по сотруднику

Логирование действий с отчётами

Действия с отчётами фиксируются в общем системном логе: изменение основных настроек отчёта, редактирование содержимого в онлайн-редакторе и Win-дизайнере, импорт/экспорт, добавление/редактирование/удаление условий фильтрации.

Что не дублируется в этом файле

Тема Где основной источник
workflow создания FR-отчёта, 3 типа источников данных, базовая гиперссылка на задачу academy-patterns.md
Win-дизайнер, сетевые требования, runtime-диагностика, API endpoints support-guide-fastreport.md
XLSX export settings, DTO и API настройки экспорта support-guide-fastreport.md
пользовательские сценарии запуска отчётов business.md
карта документов домена reports README.md

Связанные документы

  • backend.md -- backend-архитектура (контроллеры, генерация, фильтры)
  • data-flow.md -- E2E диагностика (генерация отчёта)
  • ../../platform/backend/admin-architecture.md -- общая архитектура администрирования
  • ../../reference/database/dbadmin-forms-map.md -- карта всех форм автоадминки