При работе в программе 1С:Зарплата и управление персоналом 3.1 (ЗУП) пользователи и аналитики часто сталкиваются со странным поведением Универсального отчета. Например, при формировании отчета по периодическому регистру сведений Данные состояний сотрудников обнаруживается неприятная особенность: при выборе периода в шапке отчета данные реагируют исключительно на изменение года, а дата начала интервала полностью игнорируется системой. Если выставить период с 01.01.2023 по 31.12.2023 или с 01.06.2023 по 31.12.2023, результат на экране останется абсолютно одинаковым.
В этой статье мы подробно разберем, почему платформа 1С ведет себя подобным образом, как устроен этот механизм изнутри в Системе компоновки данных (СКД) и какие шаги необходимо предпринять пользователю и разработчику для решения этой проблемы.
Давайте проанализируем техническую сторону вопроса. Многие пользователи ошибочно предполагают, что проблема кроется в периодичности самого регистра сведений (например, что у регистра Данные состояний сотрудников установлена периодичность «В пределах года»). На самом деле этот регистр имеет периодичность В пределах секунды. Истинная причина кроется в архитектуре запросов СКД и логике работы Универсального отчета.
Когда мы выбираем периодический регистр сведений в Универсальном отчете, система автоматически пытается получить наиболее актуальные данные на определенный момент времени. Для этого СКД обращается не к физической таблице регистра, а к его виртуальной таблице — чаще всего это СрезПоследних.
Особенность виртуальной таблицы СрезПоследних состоит в том, что ей для работы не нужен интервал «с ... по ...». Ей требуется одна конкретная точка во времени (дата и время), на которую необходимо рассчитать срез актуальных записей. За эту точку отвечает стандартный параметр СКД &Период.
Когда в Универсальном отчете пользователь выбирает период (например, интервал с 01.01.2023 по 31.12.2023), платформа 1С должна как-то сопоставить этот интервал с одиночным параметром &Период виртуальной таблицы. Логика Универсального отчета по умолчанию транслирует в параметр &Период именно дату окончания выбранного интервала (в нашем примере это будет 31.12.2023 23:59:59).
Теперь посмотрим, что происходит при изменении даты начала периода:
&Период = 31.12.2023 23:59:59. Получаем актуальный срез на конец года.&Период = 31.12.2023 23:59:59.Поскольку параметр запроса остался прежним, виртуальная таблица возвращает абсолютно идентичный набор данных. Изменение даты начала просто игнорируется системой. Визуально у пользователя создается ощущение, что отчет «реагирует только на смену года», потому что при выборе другого года меняется и конечная дата среза.
Если вам как пользователю необходимо получить данные регистра сведений за строго определенный интервал времени (например, увидеть только те записи о состояниях сотрудников, которые были фактически внесены или действовали в период с июня по август), стандартное поле периода в шапке Универсального отчета не поможет. Нам нужно заставить систему принудительно отфильтровать записи по физическому полю периода.
Разберем по шагам, как настроить такой отчет в режиме «1С:Предприятие»:
Период (не путайте со стандартным параметром в шапке).01.06.2023 0:00:00).Период, выберите вид сравнения Меньше или равно и укажите дату окончания интервала (например, 31.08.2023 23:59:59).При таком подходе СКД применит фильтрацию непосредственно к результатам выборки физических записей регистра, и вы получите корректные данные строго за указанный промежуток времени.
Если вы являетесь разработчиком и создаете собственный отчет на базе СКД или дорабатываете Универсальный отчет на уровне конфигуратора, у вас есть два основных пути для корректного решения этой проблемы.
Чтобы предоставить пользователю возможность интерактивно управлять началом и окончанием периода, мы можем отказаться от стандартного одиночного параметра &Период и связать его с типом данных СтандартныйПериод.
Рассмотрим подробнее этот процесс:
ПериодОтчета. Задайте ему тип данных СтандартныйПериод.&НачалоПериода и &КонецПериода (или для кастомных параметров) в колонке Выражение пропишите следующие конструкции:Для начала периода:
&ПериодОтчета.ДатаНачала
Для окончания периода:
&ПериодОтчета.ДатаОкончания
После этого СКД будет автоматически разбирать выбранный пользователем интервал на две граничные даты и корректно передавать их в параметры виртуальных и физических таблиц запроса.
Если вашей задачей является вывод истории изменений (например, всех документов-отклонений, командировок или больничных сотрудников за конкретный период), использование среза последних изначально ошибочно. Вам необходимо переписать текст запроса в СКД так, чтобы он обращался к физической таблице регистра сведений.
Проанализируем пример такого запроса:
ВЫБРАТЬ
СостоянияСотрудников.Период КАК Период,
СостоянияСотрудников.Сотрудник КАК Сотрудник,
СостоянияСотрудников.Состояние КАК Состояние,
СостоянияСотрудников.ДокументОснование КАК ДокументОснование
ИЗ
РегистрСведений.ДанныеСостоянийСотрудников КАК СостоянияСотрудников
ГДЕ
СостоянияСотрудников.Период МЕЖДУ &НачалоПериода И &КонецПериода
В данном случае параметры &НачалоПериода и &КонецПериода будут жестко ограничивать выборку записей из базы данных. Пользователь, указывая даты в шапке отчета, будет получать ровно те записи, которые физически возникли в указанном интервале, без какого-либо смещения и игнорирования даты начала.
Используя предложенные методики, вы сможете легко диагностировать и устранять проблемы с фильтрацией данных по периодам в любых отчетах на платформе 1С:Предприятие 8.