При обновлении конфигурации «1С:Зарплата и управление персоналом» (ЗУП 3.1) со старых версий (например, ветки 3.1.5) на новые релизы (3.1.9, 3.1.10 и выше) разработчики и администраторы часто сталкиваются с крайне неприятной проблемой. Все доработанные, скопированные или внешние отчеты, которые раньше прекрасно работали, внезапно перестают выводить данные. При этом сам отчет запускается без видимых ошибок, шкала выполнения доходит до конца, но на выходе пользователь видит абсолютно пустой бланк или пустую таблицу.
В рамках этой статьи мы подробно разберем, почему произошли столь радикальные изменения в поведении системы, как устроен новый механизм формирования отчетов в современных версиях ЗУП 3.1, и пошагово восстановим работоспособность ваших отчетов с помощью правильной адаптации программного кода.
Выясним причину этой проблемы, проанализируем внутреннее устройство подсистемы отчетности и рассмотрим практические примеры кода для исправления ситуации.
Чтобы понять, почему отчеты выводятся пустыми, нам необходимо заглянуть внутрь схемы компоновки данных (СКД) любого типового отчета в новых версиях ЗУП. Ранее, в старых релизах конфигурации, запросы в СКД обращались напрямую к физическим таблицам базы данных — регистрам накопления, регистрам расчета или регистрам сведений (таким как КадроваяИсторияСотрудников или НачисленияУдержанияПоСотрудникам).
Начиная с версии ЗУП 3.1.9, компания «1С» практически полностью перешла на так называемый «механизм представлений» (динамическое переформирование запросов препроцессором).
Разберем подробнее, как это работает теперь:
Представления_... или ОбщиеЗапросы_.... Поля этих таблиц заполнены фиктивными «нулевыми» значениями. Например: ЗНАЧЕНИЕ(Справочник.Сотрудники.ПустаяСсылка) КАК Сотрудник, пустые строки "" или пустые даты.В старых версиях ЗУП вызовы для подмены запросов могли осуществляться неявно, или использовались устаревшие обработчики событий (например, ПередНачаломКомпоновкиРезультата). В новых релизах эти обработчики были унифицированы и перенесены в другие модули, из-за чего в старых кастомных отчетах подмена просто перестала срабатывать.
Для того чтобы вернуть отчету работоспособность, нам потребуется внести изменения в модуль объекта отчета. Нам нужно гарантировать, что перед компоновкой результата система выполнит процедуру инициализации и подменит виртуальные таблицы представлений реальными данными.
Выполним адаптацию программного кода по шагам.
В первую очередь в модуле объекта нашего отчета должна быть объявлена экспортная процедура ИнициализироватьОтчет. Именно в ней происходит обращение к общему модулю ЗУП, который отвечает за парсинг СКД и подмену источников данных.
Добавим в модуль объекта отчета следующий код:
Процедура ИнициализироватьОтчет() Экспорт
// Вызываем общий модуль, который выполнит подмену виртуальных таблиц-представлений на реальные SQL-запросы
ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(ЭтотОбъект);
КонецПроцедуры
Проанализируем этот вызов: метод ЗаполнитьОбщиеИсточникиДанныхОтчета принимает в качестве параметра контекст нашего отчета (ЭтотОбъект), анализирует настройки компоновки данных, находит все таблицы с префиксами представлений и генерирует для них реальные наборы данных.
Теперь нам необходимо связать инициализацию с событием формирования отчета. Вся логика должна быть сосредоточена в предопределенной процедуре ПриКомпоновкеРезультата модуля объекта отчета.
Заменим старый код обработчика или напишем новый по следующему шаблону:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// 1. Обязательно инициализируем отчет для замены пустых представлений реальными данными
ИнициализироватьОтчет();
// 2. Если мы дорабатываем сложный зарплатный отчет (например, "Анализ начислений и удержаний"),
// необходимо вызвать специализированный обработчик из общего модуля конфигурации:
УчетНачисленнойЗарплаты.ПриКомпоновкеОтчетаАнализНачисленийИУдержаний(ЭтотОбъект, ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка);
// 3. Вызываем локальную процедуру компоновки, если в отчете реализована собственная специфическая логика
ПриКомпоновкеОтчета(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка);
// 4. Корректно завершаем компоновку через стандартные механизмы подсистемы "Зарплата Кадры"
ЗарплатаКадрыОтчеты.ПриЗавершенииКомпоновкиРезультата(ЭтотОбъект);
КонецПроцедуры
Важное примечание: Обратите внимание на закомментированные строки в старых версиях отчетов, на которые жалуются разработчики (например, //- ПередНачаломКомпоновкиРезультата;). В версиях ЗУП 3.1.9+ старые механизмы БСП больше не вызывают эти события автоматически в том формате, в котором они вызывались раньше. Нам необходимо жестко и последовательно определить структуру вызовов, как показано в примере выше.
Процесс адаптации отчетов не всегда ограничивается лишь изменением двух процедур. Рассмотрим еще три критически важных аспекта, с которыми вы можете столкнуться при обновлении.
Очень часто разработчики создают новые отчеты путем копирования существующих типовых отчетов (например, копируют «Расчетный листок» или «Анализ начислений») прямо в дереве метаданных конфигурации, чтобы внести туда свои правки.
После обновления до версии 3.1.9+ такие скопированные отчеты могут перестать работать вовсе, даже если вы прописали в них код инициализации. Это связано с работой подсистемы БСП «Варианты отчетов». При открытии отчета система проверяет его имя по внутреннему справочнику зарегистрированных вариантов. Так как ваш скопированный отчет имеет уникальное имя, которого нет в реестре типовых отчетов ЗУП, механизмы инициализации могут отрабатывать некорректно или игнорироваться формой отчета.
Как решить эту проблему:
Администрирование — Печатные формы, отчеты и обработки — Дополнительные отчеты и обработки. Внешние отчеты корректно обрабатываются библиотекой стандартных подсистем при условии правильного заполнения сведений о внешней обработке.Иногда после обновления внешнего отчета при его формировании пользователи видят предупреждение: «В настройку отчета внесены критичные изменения. Отчет не будет сформирован». Это встроенный механизм защиты СКД.
Причина кроется в том, что в новых релизах ЗУП 3.1.9+ разработчики «1С» могли переименовать, удалить или изменить типы некоторых полей в препроцессоре представлений (например, изменилась структура данных полей физических лиц или кадровых состояний). Поскольку ваш старый внешний отчет содержит в настройках (компоновщике настроек) обращения к старым, ныне несуществующим полям, система блокирует вывод во избежание аварийного завершения работы платформы.
Как решить эту проблему:
Еще — Установить стандартные настройки в форме отчета), чтобы очистить кэшированные старые настройки компоновщика.Новый механизм представлений напрямую завязан на подсистему разграничения прав доступа. Если отчет запускается под правами обычного пользователя (например, расчетчика или кадровика), динамический запрос будет автоматически модифицирован с учетом ограничений RLS (ограничения по группам доступа физических лиц, подразделениям или организациям).
Если в коде инициализации вашего отчета допущена ошибка или вы используете устаревшие методы ручного построения запросов, система может вернуть пустой результат для обычного пользователя, в то время как под полными правами (Администратор) отчет будет заполняться данными.
Рекомендация: Всегда проводите финальное тестирование доработанных и адаптированных отчетов под учетными записями тех пользователей, которые непосредственно будут с ними работать, чтобы исключить влияние ограничений RLS на результат компоновки.
Мы подробно разобрали причины возникновения пустых отчетов после перехода на ЗУП 3.1.9+ и рассмотрели универсальный программный механизм восстановления их работоспособности. Придерживаясь этих правил разработки, вы сможете быстро адаптировать любые кастомные отчеты под современные стандарты платформы «1С:Предприятие».