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