Почему в Универсальном отчете 1С период меняется только по годам и как это исправить

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

При работе в программе 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).

Теперь посмотрим, что происходит при изменении даты начала периода:

  1. Пользователь указывает период с 01.01.2023 по 31.12.2023. Универсальный отчет передает в виртуальную таблицу параметр &Период = 31.12.2023 23:59:59. Получаем актуальный срез на конец года.
  2. Пользователь меняет дату начала и указывает период с 01.06.2023 по 31.12.2023. Универсальный отчет снова берет конечную дату и передает в виртуальную таблицу тот же самый параметр &Период = 31.12.2023 23:59:59.

Поскольку параметр запроса остался прежним, виртуальная таблица возвращает абсолютно идентичный набор данных. Изменение даты начала просто игнорируется системой. Визуально у пользователя создается ощущение, что отчет «реагирует только на смену года», потому что при выборе другого года меняется и конечная дата среза.

Решение для пользователя: настраиваем отборы в режиме предприятия

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

Разберем по шагам, как настроить такой отчет в режиме «1С:Предприятие»:

  1. Откройте Универсальный отчет по нужному регистру сведений и нажмите кнопку Настройки... в верхней части панели.
  2. В открывшемся окне настроек перейдите в Расширенный режим (кнопка внизу панели настроек).
  3. Перейдите на вкладку Фильтры (в некоторых конфигурациях она называется Отборы).
  4. Нажмите кнопку Добавить фильтр. В списке доступных полей найдите физическое поле регистра Период (не путайте со стандартным параметром в шапке).
  5. Установите вид сравнения Больше или равно и укажите точную дату начала интересующего вас интервала (например, 01.06.2023 0:00:00).
  6. Добавьте еще одну строку фильтра по полю Период, выберите вид сравнения Меньше или равно и укажите дату окончания интервала (например, 31.08.2023 23:59:59).
  7. Нажмите кнопку Закрыть и сформировать.

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

Решение для разработчика: оптимизация схемы компоновки данных

Если вы являетесь разработчиком и создаете собственный отчет на базе СКД или дорабатываете Универсальный отчет на уровне конфигуратора, у вас есть два основных пути для корректного решения этой проблемы.

Способ 1. Использование параметра типа «СтандартныйПериод»

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

Рассмотрим подробнее этот процесс:

  1. В схеме компоновки данных перейдите на вкладку Параметры.
  2. Добавьте новый параметр, назовем его, например, ПериодОтчета. Задайте ему тип данных СтандартныйПериод.
  3. Для стандартных параметров виртуальных таблиц &НачалоПериода и &КонецПериода (или для кастомных параметров) в колонке Выражение пропишите следующие конструкции:

Для начала периода:

&ПериодОтчета.ДатаНачала

Для окончания периода:

&ПериодОтчета.ДатаОкончания

После этого СКД будет автоматически разбирать выбранный пользователем интервал на две граничные даты и корректно передавать их в параметры виртуальных и физических таблиц запроса.

Способ 2. Запрос к физической таблице регистра

Если вашей задачей является вывод истории изменений (например, всех документов-отклонений, командировок или больничных сотрудников за конкретный период), использование среза последних изначально ошибочно. Вам необходимо переписать текст запроса в СКД так, чтобы он обращался к физической таблице регистра сведений.

Проанализируем пример такого запроса:


ВЫБРАТЬ
    СостоянияСотрудников.Период КАК Период,
    СостоянияСотрудников.Сотрудник КАК Сотрудник,
    СостоянияСотрудников.Состояние КАК Состояние,
    СостоянияСотрудников.ДокументОснование КАК ДокументОснование
ИЗ
    РегистрСведений.ДанныеСостоянийСотрудников КАК СостоянияСотрудников
ГДЕ
    СостоянияСотрудников.Период МЕЖДУ &НачалоПериода И &КонецПериода

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

Используя предложенные методики, вы сможете легко диагностировать и устранять проблемы с фильтрацией данных по периодам в любых отчетах на платформе 1С:Предприятие 8.

← На главную