При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда во втором наборе данных виртуальная таблица СрезПоследних возвращает данные на текущую дату или конец периода отчета, несмотря на то что связь наборов настроена по полю Дата через параметр &Дата. Проанализируем причину такого поведения и рассмотрим проверенные способы решения этой проблемы.
Основная причина заключается в работе механизма автозаполнения СКД. Когда в схеме компоновки данных используется виртуальная таблица среза последних (например, РегистрСведений.КурсыВалют.СрезПоследних), компоновщик макета по умолчанию связывает период виртуальной таблицы со стандартным параметром Период.
Даже если в связях наборов данных явно указана передача даты документа в параметр &Дата второго набора данных, включенный механизм автозаполнения может переопределять значение этого параметра системной датой или значением по умолчанию. В результате параметр &Дата в тексте запроса физически получает нужную дату, но сама виртуальная таблица СрезПоследних рассчитывается на текущий период.
Для того чтобы зафиксировать передачу конкретного параметра в виртуальную таблицу и исключить его переопределение автозаполнением, необходимо использовать фигурные скобки для параметров виртуальной таблицы в тексте запроса второго набора данных.
Разберем по шагам, как правильно оформить запрос во втором наборе данных:
{(&Дата)}.Посмотрим на пример текста запроса для второго набора данных с использованием расширения языка СКД:
ВЫБРАТЬ
&Дата КАК Дата,
КурсыВалютСрезПоследних.Валюта КАК Валюта,
КурсыВалютСрезПоследних.Курс КАК Курс,
КурсыВалютСрезПоследних.Кратность КАК Кратность
{ВЫБРАТЬ
Дата,
Валюта.*,
Курс,
Кратность}
ИЗ
РегистрСведений.КурсыВалют.СрезПоследних({(&Дата)}, Валюта = &Валюта) КАК КурсыВалютСрезПоследних
{ГДЕ
КурсыВалютСрезПоследних.Курс,
КурсыВалютСрезПоследних.Кратность}
Конструкция {(&Дата)} явно указывает СКД, что период виртуальной таблицы жестко привязан к параметру &Дата, который передается из первого набора данных через связи наборов.
Также проверим настройки на вкладке Связи наборов данных:
Дата или ДокументОприходования.Дата).Дата (а для валюты — отдельной строкой параметр Валюта).Связь наборов данных через параметры в СКД выполняет запрос второго набора итеративно (отдельным запросом на каждую уникальную строку первого набора). На больших объемах документов это может приводить к снижению производительности.
Более эффективным решением является отказ от двух наборов данных в пользу одного набора данных с пакетным запросом.
Рассмотрим алгоритм получения среза последних на каждую дату в рамках одного запроса:
РегистрСведений.КурсыВалют по условию Период <= ВТ.Дата и сгруппируем по документу, выбрав МАКСИМУМ(Период).Проанализируем пример такого пакетного запроса:
ВЫБРАТЬ
Партии.ДокументОприходования КАК Документ,
Партии.ДокументОприходования.Дата КАК Дата,
Партии.ДокументОприходования.Валюта КАК Валюта
ПОМЕСТИТЬ ВТ_Документы
ИЗ
РегистрНакопления.ТоварыВРознице КАК Партии;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ.Документ КАК Документ,
ВТ.Валюта КАК Валюта,
МАКСИМУМ(Курсы.Период) КАК Период
ПОМЕСТИТЬ ВТ_МаксДаты
ИЗ
ВТ_Документы КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Курсы
ПО Курсы.Валюта = ВТ.Валюта
И Курсы.Период <= ВТ.Дата
СГРУППИРОВАТЬ ПО
ВТ.Документ,
ВТ.Валюта;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ.Документ КАК Документ,
ВТ.Дата КАК Дата,
ВТ.Валюта КАК Валюта,
ЕСТЬNULL(Курсы.Курс, 1) КАК Курс,
ЕСТЬNULL(Курсы.Кратность, 1) КАК Кратность
ИЗ
ВТ_Документы КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_МаксДаты КАК МаксДаты
ПО МаксДаты.Документ = ВТ.Документ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Курсы
ПО Курсы.Валюта = МаксДаты.Валюта
И Курсы.Период = МаксДаты.Период
Такой подход работает существенно быстрее связи наборов данных, гарантированно выбирает срез последних на каждую дату и полностью исключает влияние автозаполнения СКД.