Почему в отчетах СКД не учитываются данные за последнюю секунду?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

При построении отчетов на основе виртуальных таблиц остатков в Системе Компоновки Данных (СКД) многие разработчики сталкиваются с тем, что движения, совершенные в последнюю секунду выбранного периода (например, 23:59:59), не попадают в итоговый результат. Давайте разберемся, почему это происходит и как правильно настроить параметры, чтобы обеспечить корректный расчет остатков.

Выясняем причину проблемы

Основная причина заключается в принципе работы виртуальных таблиц в 1С:Предприятии. Запрос к виртуальной таблице Остатки(&Период, ) возвращает данные на начало указанной даты. Если вы передаете дату 31.12.2023 23:59:59, платформа интерпретирует это как получение данных на момент перед наступлением этой секунды. Таким образом, все документы, проведенные в эту секунду, игнорируются системой. Использование стандартного типа данных СтандартныйПериод в параметрах СКД не решает эту проблему автоматически, так как он лишь позволяет пользователю выбрать интервал, но не меняет логику работы виртуальной таблицы с границами времени.

Решение 1: Программная установка границы в модуле

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

Рассмотрим пошагово, как это реализовать:

  1. В схеме компоновки данных (СКД) создайте параметр (например, ПериодОтчета), который будет использоваться в запросе.
  2. В модуле отчета, где выполняется компоновка, перехватите настройки и установите значение параметра программно.

// В обработчике ПриКомпоновкеРезультата
ПериодДляГраницы = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПериодОтчета"));
Если ПериодДляГраницы <> Неопределено Тогда
    ДатаОкончания = КонецДня(ПериодДляГраницы.Значение.ДатаОкончания);
    ЗначениеГраницы = Новый Граница(ДатаОкончания, ВидГраницы.Включая);
    КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("ПериодОтчета", ЗначениеГраницы);
КонецЕсли;

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

Решение 2: Использование функции общего модуля

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

  1. Создайте в общем серверном модуле функцию, которая возвращает тип Граница.
  2. В поле «Выражение» параметра СКД вызовите эту функцию, передав ей дату окончания из стандартного периода.

Пример вызова в выражении параметра СКД:

МойОбщийМодуль.ПолучитьГраницуВключая(&ПериодОтчета.ДатаОкончания)

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

Решение 3: «Хаки» и их риски

Часто в профессиональных обсуждениях можно встретить совет просто добавлять одну секунду к дате окончания:

ДОБАВИТЬКДАТЕ(&ДатаОкончания, "СЕКУНДА", 1)

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

Рекомендации по настройке СКД

Чтобы отчет работал корректно и был удобен для пользователя, воспользуйтесь следующими рекомендациями:

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

← На главную