Почему после обновления ЗУП 3.1 до версии 3.1.9+ отчеты выводятся пустыми и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При обновлении конфигурации «1С:Зарплата и управление персоналом» (ЗУП 3.1) со старых версий (например, ветки 3.1.5) на новые релизы (3.1.9, 3.1.10 и выше) разработчики и администраторы часто сталкиваются с крайне неприятной проблемой. Все доработанные, скопированные или внешние отчеты, которые раньше прекрасно работали, внезапно перестают выводить данные. При этом сам отчет запускается без видимых ошибок, шкала выполнения доходит до конца, но на выходе пользователь видит абсолютно пустой бланк или пустую таблицу.

В рамках этой статьи мы подробно разберем, почему произошли столь радикальные изменения в поведении системы, как устроен новый механизм формирования отчетов в современных версиях ЗУП 3.1, и пошагово восстановим работоспособность ваших отчетов с помощью правильной адаптации программного кода.

Выясним причину этой проблемы, проанализируем внутреннее устройство подсистемы отчетности и рассмотрим практические примеры кода для исправления ситуации.

Архитектурные изменения: переход на механизм представлений

Чтобы понять, почему отчеты выводятся пустыми, нам необходимо заглянуть внутрь схемы компоновки данных (СКД) любого типового отчета в новых версиях ЗУП. Ранее, в старых релизах конфигурации, запросы в СКД обращались напрямую к физическим таблицам базы данных — регистрам накопления, регистрам расчета или регистрам сведений (таким как КадроваяИсторияСотрудников или НачисленияУдержанияПоСотрудникам).

Начиная с версии ЗУП 3.1.9, компания «1С» практически полностью перешла на так называемый «механизм представлений» (динамическое переформирование запросов препроцессором).

Разберем подробнее, как это работает теперь:

  1. Запросы-заглушки в СКД: Если вы откроете схему компоновки данных типового отчета в конфигураторе, то в конструкторе запроса вы больше не найдете прямых связей с реальными таблицами данных. Вместо этого там описаны виртуальные таблицы с префиксами Представления_... или ОбщиеЗапросы_.... Поля этих таблиц заполнены фиктивными «нулевыми» значениями. Например: ЗНАЧЕНИЕ(Справочник.Сотрудники.ПустаяСсылка) КАК Сотрудник, пустые строки "" или пустые даты.
  2. Зачем это сделано: Такая схема позволяет колоссально оптимизировать производительность системы. Вместо того чтобы выполнять один огромный, жестко заданный SQL-запрос, система анализирует, какие именно поля пользователь выбрал в настройках отчета, какие установил отборы и группировки. На основе этого анализа специальный программный препроцессор «на лету» заменяет пустые таблицы-заглушки на оптимальный SQL-запрос, который выбирает только необходимые в данный момент данные. Также это упростило поддержку конфигурации разработчиками «1С» при изменении структуры метаданных и механизмов разграничения прав доступа на уровне записей (RLS).
  3. Почему старый отчет выводится пустым: Если запустить отчет без предварительной обработки этого запроса-пустышки, СКД выполнит его буквально — то есть выберет пустые ссылки и нулевые значения. Чтобы отчет заполнился реальной информацией из базы данных, этот запрос должен быть обязательно перехвачен программным кодом перед выводом и заменен на настоящий динамический запрос.

В старых версиях ЗУП вызовы для подмены запросов могли осуществляться неявно, или использовались устаревшие обработчики событий (например, ПередНачаломКомпоновкиРезультата). В новых релизах эти обработчики были унифицированы и перенесены в другие модули, из-за чего в старых кастомных отчетах подмена просто перестала срабатывать.

Пошаговое решение: восстанавливаем инициализацию отчета

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

Выполним адаптацию программного кода по шагам.

Шаг 1. Объявление процедуры инициализации

В первую очередь в модуле объекта нашего отчета должна быть объявлена экспортная процедура ИнициализироватьОтчет. Именно в ней происходит обращение к общему модулю ЗУП, который отвечает за парсинг СКД и подмену источников данных.

Добавим в модуль объекта отчета следующий код:


Процедура ИнициализироватьОтчет() Экспорт
    // Вызываем общий модуль, который выполнит подмену виртуальных таблиц-представлений на реальные SQL-запросы
    ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(ЭтотОбъект);
КонецПроцедуры

Проанализируем этот вызов: метод ЗаполнитьОбщиеИсточникиДанныхОтчета принимает в качестве параметра контекст нашего отчета (ЭтотОбъект), анализирует настройки компоновки данных, находит все таблицы с префиксами представлений и генерирует для них реальные наборы данных.

Шаг 2. Настройка обработчика события компоновки результата

Теперь нам необходимо связать инициализацию с событием формирования отчета. Вся логика должна быть сосредоточена в предопределенной процедуре ПриКомпоновкеРезультата модуля объекта отчета.

Заменим старый код обработчика или напишем новый по следующему шаблону:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // 1. Обязательно инициализируем отчет для замены пустых представлений реальными данными
    ИнициализироватьОтчет(); 
    
    // 2. Если мы дорабатываем сложный зарплатный отчет (например, "Анализ начислений и удержаний"),
    // необходимо вызвать специализированный обработчик из общего модуля конфигурации:
    УчетНачисленнойЗарплаты.ПриКомпоновкеОтчетаАнализНачисленийИУдержаний(ЭтотОбъект, ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка);
    
    // 3. Вызываем локальную процедуру компоновки, если в отчете реализована собственная специфическая логика
    ПриКомпоновкеОтчета(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка);
    
    // 4. Корректно завершаем компоновку через стандартные механизмы подсистемы "Зарплата Кадры"
    ЗарплатаКадрыОтчеты.ПриЗавершенииКомпоновкиРезультата(ЭтотОбъект);
    
КонецПроцедуры

Важное примечание: Обратите внимание на закомментированные строки в старых версиях отчетов, на которые жалуются разработчики (например, //- ПередНачаломКомпоновкиРезультата;). В версиях ЗУП 3.1.9+ старые механизмы БСП больше не вызывают эти события автоматически в том формате, в котором они вызывались раньше. Нам необходимо жестко и последовательно определить структуру вызовов, как показано в примере выше.

Дополнительные важные нюансы при работе с отчетами в ЗУП 3.1.9+

Процесс адаптации отчетов не всегда ограничивается лишь изменением двух процедур. Рассмотрим еще три критически важных аспекта, с которыми вы можете столкнуться при обновлении.

1. Ошибки при копировании типовых отчетов внутри конфигурации

Очень часто разработчики создают новые отчеты путем копирования существующих типовых отчетов (например, копируют «Расчетный листок» или «Анализ начислений») прямо в дереве метаданных конфигурации, чтобы внести туда свои правки.

После обновления до версии 3.1.9+ такие скопированные отчеты могут перестать работать вовсе, даже если вы прописали в них код инициализации. Это связано с работой подсистемы БСП «Варианты отчетов». При открытии отчета система проверяет его имя по внутреннему справочнику зарегистрированных вариантов. Так как ваш скопированный отчет имеет уникальное имя, которого нет в реестре типовых отчетов ЗУП, механизмы инициализации могут отрабатывать некорректно или игнорироваться формой отчета.

Как решить эту проблему:

2. Ошибка «В настройку отчета внесены критичные изменения»

Иногда после обновления внешнего отчета при его формировании пользователи видят предупреждение: «В настройку отчета внесены критичные изменения. Отчет не будет сформирован». Это встроенный механизм защиты СКД.

Причина кроется в том, что в новых релизах ЗУП 3.1.9+ разработчики «1С» могли переименовать, удалить или изменить типы некоторых полей в препроцессоре представлений (например, изменилась структура данных полей физических лиц или кадровых состояний). Поскольку ваш старый внешний отчет содержит в настройках (компоновщике настроек) обращения к старым, ныне несуществующим полям, система блокирует вывод во избежание аварийного завершения работы платформы.

Как решить эту проблему:

  1. Откройте схему компоновки данных вашего отчета в конфигураторе.
  2. Сравните структуру набора данных и полей с аналогичным типовым отчетом из обновленной конфигурации ЗУП.
  3. Замените устаревшие пути к полям на новые актуальные реквизиты.
  4. Сбросьте настройки отчета в режиме «1С:Предприятие» у пользователей (кнопка Еще — Установить стандартные настройки в форме отчета), чтобы очистить кэшированные старые настройки компоновщика.

3. Права доступа и ограничения на уровне записей (RLS)

Новый механизм представлений напрямую завязан на подсистему разграничения прав доступа. Если отчет запускается под правами обычного пользователя (например, расчетчика или кадровика), динамический запрос будет автоматически модифицирован с учетом ограничений RLS (ограничения по группам доступа физических лиц, подразделениям или организациям).

Если в коде инициализации вашего отчета допущена ошибка или вы используете устаревшие методы ручного построения запросов, система может вернуть пустой результат для обычного пользователя, в то время как под полными правами (Администратор) отчет будет заполняться данными.

Рекомендация: Всегда проводите финальное тестирование доработанных и адаптированных отчетов под учетными записями тех пользователей, которые непосредственно будут с ними работать, чтобы исключить влияние ограничений RLS на результат компоновки.

Мы подробно разобрали причины возникновения пустых отчетов после перехода на ЗУП 3.1.9+ и рассмотрели универсальный программный механизм восстановления их работоспособности. Придерживаясь этих правил разработки, вы сможете быстро адаптировать любые кастомные отчеты под современные стандарты платформы «1С:Предприятие».

← На главную