Как правильно получить остатки на конец дня в СКД 1С?

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

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

Рассмотрим подробно причины такого поведения платформы 1С:Предприятие и разберем по шагам проверенные способы решения этой задачи.

Выясним причину: особенности работы виртуальной таблицы «Остатки»

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

Если мы указываем в качестве периода время 23:59:59 (что является результатом функции КонецПериода(&Период, "День")), виртуальная таблица возвращает остаток на момент 23:59:59 000. Все документы, зарегистрированные ровно в 23:59:59, остаются за пределами расчета.

Решение 1: Смещение даты на 1 секунду через выражение параметра СКД

Чтобы в отчет попали все движения за текущий день, необходимо сместить границу расчета остатков на первую секунду следующего дня — 00:00:00. В этом случае остаток будет рассчитан на начало следующего дня, что физически эквивалентно концу предыдущего дня со всеми включенными документами.

Разберем вариант с разделением параметров, когда пользователь выбирает понятный период, а отчет рассчитывает данные корректно:

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

ДобавитьКДате(КонецПериода(&ПериодПользователя.ДатаОкончания, "День"), "Секунда", 1)

Если параметр ПериодПользователя имеет тип Дата, выражение примет вид:

ДобавитьКДате(КонецПериода(&ПериодПользователя, "День"), "Секунда", 1)

В тексте запроса виртуальная таблица вызывается стандартным образом:


ВЫБРАТЬ
	ТоварыВРезервеОстатки.Номенклатура КАК Номенклатура,
	ТоварыВРезервеОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
	РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&Период, ) КАК ТоварыВРезервеОстатки

Решение 2: Смещение даты непосредственно в запросе СКД

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


ВЫБРАТЬ
	ТоварыВРезервеОстатки.Номенклатура КАК Номенклатура,
	ТоварыВРезервеОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
	РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(
		ДобавитьКДате(КонецПериода(&КонДата, "День"), "Секунда", 1), 
		) КАК ТоварыВРезервеОстатки

В настройках параметров СКД для &КонДата с типом СтандартныйПериод в поле Выражение достаточно указать &Период.ДатаОкончания.

Решение 3: Использование виртуальной таблицы «ОстаткиИОбороты»

Проанализируем альтернативный метод. Виртуальная таблица ОстаткиИОбороты работает иначе: её параметр конечной даты включает указанную секунду включительно.

Если изменить запрос и обратиться к таблице остатков и оборотов, прибавлять секунду не потребуется:


ВЫБРАТЬ
	ТоварыВРезервеОстатки.Номенклатура КАК Номенклатура,
	ТоварыВРезервеОстатки.КоличествоКонечныйОстаток КАК КоличествоОстаток
ИЗ
	РегистрНакопления.ТоварыВРезервеНаСкладах.ОстаткиИОбороты(, КОНЕЦПЕРИОДА(&КонДата, "День"), , , ) КАК ТоварыВРезервеОстатки

Важное замечание: виртуальная таблица остатков и оборотов выполняет дополнительные вычисления оборотов за указанный период. На регистрах с большим объемом данных этот запрос может работать медленнее, чем прямой запрос к таблице Остатки. Для получения строго конечных остатков рекомендуется использовать Решение 1 или Решение 2.

← На главную