Как использовать дату из временной таблицы в параметрах виртуальной таблицы запроса 1С?

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

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

Ограничение платформы: почему нельзя передать поле таблицы в параметр виртуальной таблицы

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

  1. Параметры запроса (обозначаемые символом &, например, &НачалоПериода).
  2. Литералы и константы (например, дата, число или Булево).

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

Способ 1. Получение остатков на каждый день через соединение таблицы дат и таблицы итогов

Рассмотрим стандартный алгоритм построения остатков на каждую дату периода. Для этого мы сначала создаем таблицу дат (календарь), а затем соединяем ее с данными регистра.

Разберем по шагам логику построения такого запроса:

  1. Формирование таблицы дат: Выбираем все дни из производственного календаря за нужный период и помещаем их во временную таблицу Дни.
  2. Получение движений и остатков: Выбираем данные из виртуальной таблицы ОстаткиИОбороты с периодичностью День.
  3. Соединение и накопление: Соединяем таблицу дат с остатками и оборотами по условию Период <= Дата и суммируем показатели.

Рассмотрим пример готового запроса для расчета остатков по счету расчетов:


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Дни.Дата КАК Дата,
	ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Контрагент,
	ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Договор,
	СУММА(ВЫБОР
		КОГДА ХозрасчетныйОстаткиИОбороты.Период = &НачалоПериода
			ТОГДА ХозрасчетныйОстаткиИОбороты.СуммаНачальныйОстаток
		ИНАЧЕ ВЫБОР
			КОГДА ХозрасчетныйОстаткиИОбороты.Период <= Дни.Дата
				ТОГДА ХозрасчетныйОстаткиИОбороты.СуммаОборот
			ИНАЧЕ 0
		КОНЕЦ
	КОНЕЦ) КАК СуммаОстаток
ИЗ
	Дни КАК Дни,
	РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , Счет = &Счет, , ) КАК ХозрасчетныйОстаткиИОбороты
СГРУППИРОВАТЬ ПО
	Дни.Дата,
	ХозрасчетныйОстаткиИОбороты.Субконто1,
	ХозрасчетныйОстаткиИОбороты.Субконто2
УПОРЯДОЧИТЬ ПО
	Контрагент,
	Договор,
	Дата

Важные детали реализации:

Инструкция ИНДЕКСИРОВАТЬ ПО Дата при создании временной таблицы критически важна для производительности, так как соединение выполняется по условию неравенства (<=).

Способ 2. Использование Системы компоновки данных (СКД)

Если отчет разрабатывается на Системе компоновки данных, решать задачу соединения таблиц вручную в запросе не требуется. В СКД есть два встроенных механизма для работы с остатками на каждый день:

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

Типичные ошибки при составлении запросов с датами

Выясним основные причины, из-за которых расчет остатков по датам может выводить некорректные данные:

  1. Использование `ПРАВОЕ` или `ЛЕВОЕ` соединение без сгруппированных итогов: Связывание таблицы дат с виртуальной таблицей по условию равенства Период = Дата приводит к тому, что дни без оборотов выпадают из выборки или содержат пустые остатки.
  2. Отсутствие группировки при связи `Период <= Дата`: При декартовом произведении или связи по неравенству без агрегатной функции СУММА() строки дублируются, а остатки умножаются на количество совпавших дат.
  3. Игнорирование начального остатка: Если учитывать только обороты за период, входящий остаток на дату начала отчета будет потерян. Необходимо отдельно учитывать начальный остаток на &НачалоПериода и прибавлять к нему обороты последующих дней.
← На главную