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