Как правильно использовать Граница.Исключая в СКД для получения остатков?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет Финансы и профессиональные услуги
← На главную

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

Различие между Датой и Границей

В платформе 1С:Предприятие существует фундаментальное различие в том, как система воспринимает обычный тип Дата и объект Граница. Проанализируем стандартное поведение: когда мы передаем просто дату в параметры виртуальной таблицы (например, 01.01.2023 00:00:00), система по умолчанию интерпретирует её как Граница.Включая. Это означает, что в результат запроса попадут все движения, совершенные в ту же самую секунду.

Рассмотрим ситуацию: документ «Операция (бухгалтерский учет)» записан ровно в 00:00:00 первого числа месяца. Если мы формируем остатки на начало этого месяца, используя обычную дату, этот документ попадет во входящее сальдо. Однако с точки зрения бухгалтерской логики, движения этого дня должны относиться к оборотам периода, а не к начальному остатку. Чтобы «отсечь» движения этой конкретной секунды, нам и необходим объект Граница с параметром ВидГраницы.Исключая.

Почему добавление или вычитание секунды — плохая практика?

В старых методиках часто советовали использовать конструкции вида ДобавитьКДате(КонецПериода(&ДатаКон, "ДЕНЬ"), "Секунда", 1). Выясним, почему в современных конфигурациях это может привести к ошибкам:

  1. Документы в ту же секунду: Если в одну секунду (например, 23:59:59) записано несколько документов, манипуляции с секундами не позволяют выбрать состояние регистра «между» ними.
  2. Позиция документа: Объект Граница позволяет инициализироваться не только по времени, но и по ссылке на конкретный документ или МоментВремени. Это дает возможность получить остаток строго перед определенным документом, даже если в этой же секунде их было десять.
  3. Прозрачность кода: Использование встроенных типов платформы делает код более читаемым и соответствующим стандартам разработки 1С.

Реализация в СКД через выражения параметров

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

Допустим, у нас есть стандартный параметр &НачалоПериода. Нам нужно создать внутренний параметр для виртуальной таблицы остатков, назовем его &НачПериодаГраница. В колонке «Выражение» для этого параметра пропишем следующую конструкцию:

Новый Граница(&НачалоПериода, ВидГраницы.Исключая)

Теперь в настройках виртуальной таблицы РегистрБухгалтерии.Хозрасчетный.Остатки в поле «Период» мы указываем именно наш параметр &НачПериодаГраница. Это гарантирует, что начальный остаток будет рассчитан на момент времени ДО совершения любых операций в первую секунду периода.

Программная установка параметров

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


// Установка границы для начала периода (исключая движения начала дня)
ГраницаНачала = Новый Граница(НачалоДня(ПараметрыОтчета.НачалоПериода), ВидГраницы.Исключая);
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "НачПериодаОстатков", ГраницаНачала);

// Установка границы для конца периода (включая движения конца дня)
ГраницаКонца = Новый Граница(КонецДня(ПараметрыОтчета.КонецПериода), ВидГраницы.Включая);
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "КонПериодаОстатков", ГраницаКонца);

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

Методология бухгалтерских отчетов

Важно понимать, почему в типовых решениях (например, в ОСВ) используется именно такой подход. Бухгалтерская методология 1С разделяет данные следующим образом:

Такой подход исключает риск «двойного счета», когда одна и та же операция попадает и в остаток, и в обороты.

Нюансы работы с виртуальными таблицами «ОстаткиИОбороты»

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

Производительность на уровне СУБД

Выясним, как наши манипуляции выглядят «под капотом» SQL. Когда платформа 1С формирует запрос к базе данных:

С точки зрения производительности СУБД разницы между этими операциями практически нет, так как оба они эффективно используют индексы таблиц итогов. Однако с точки зрения бизнес-логики — это два принципиально разных отчета.

Таким образом, использование объекта Граница в СКД является не просто «хорошим тоном», а технической необходимостью для получения достоверных бухгалтерских данных. Разберем и запомним: если нужен остаток на момент открытия периода — используем Исключая, если на момент закрытия — Включая.

← На главную