Как исправить ошибку «Несоответствие типов (Параметр номер "1")» при получении среза последних в СКД?

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

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

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

Выясняем причину: почему СКД генерирует ошибку соответствия типов?

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


ВЫБРАТЬ
    ДокументыФизическихЛицСрезПоследних.Физлицо,
    ДокументыФизическихЛицСрезПоследних.ФинКод
ПОМЕСТИТЬ ВТ_ФинКод
ИЗ
    РегистрСведений.ДокументыФизическихЛиц.СрезПоследних(&НачПериода, ) КАК ДокументыФизическихЛицСрезПоследних

Если в схеме компоновки данных включена стандартная опция «Автозаполнение», система пытается самостоятельно оптимизировать запрос и связать параметры виртуальных таблиц с доступными параметрами схемы. Однако в процессе компоновки макета СКД может переопределить имя нашего параметра &НачПериода на свое внутреннее имя (например, &П3).

Ошибка соответствия типов в первом параметре возникает в следующих случаях:

  1. Несоответствие типов данных: Первый параметр виртуальной таблицы СрезПоследних строго ожидает типы данных Дата, Граница или МоментВремени. Если СКД передает туда значение типа Неопределено, Null или объект другого типа, платформа генерирует исключение.
  2. Конфликт со «Стандартным периодом»: Очень часто на форму отчета выводится удобный для пользователя параметр с типом СтандартныйПериод. Если разработчик по ошибке передает этот сложный объект напрямую в виртуальную таблицу, СКД не может автоматически преобразовать его в конкретную дату, что приводит к падению запроса.
  3. Связи наборов данных: При получении среза последних на каждую дату из таблицы другого набора данных (например, получение курса валюты на дату каждого документа), СКД динамически подставляет параметры связи. Если связь настроена некорректно или типы связываемых полей не совпадают, возникает рассматриваемая ошибка.

Рассмотрим подробнее четыре практических способа решения этой проблемы.

Способ 1. Использование расширения языка запросов СКД (Фигурные скобки)

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

Изменим наш запрос следующим образом:


ВЫБРАТЬ
    ДокументыФизическихЛицСрезПоследних.Физлицо,
    ДокументыФизическихЛицСрезПоследних.ФинКод
ПОМЕСТИТЬ ВТ_ФинКод
ИЗ
    РегистрСведений.ДокументыФизическихЛиц.СрезПоследних({&НачПериода}, ) КАК ДокументыФизическихЛицСрезПоследних

Синтаксис {&НачПериода} сообщает системе компоновки, что параметр не является жестко обязательным для выполнения СУБД-запроса «как есть». Если параметр окажется незаполненным, СКД не передаст туда пустое значение, ломающее запрос, а просто проигнорирует его на уровне генерации SQL-текста, выполнив срез на актуальную дату. Это страхует разработчика от ошибок несоответствия типов при инициализации отчета.

Способ 2. Правильная передача даты из «Стандартного периода»

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

Разберем этот процесс по шагам:

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

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

Способ 3. Перенос параметров на вкладку «Компоновка данных» в Конструкторе запросов

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

Посмотрим на пример реализации этого подхода:

  1. В основном тексте запроса мы полностью очищаем круглые скобки у виртуальной таблицы:
    
    ИЗ
        РегистрСведений.ДокументыФизическихЛиц.СрезПоследних КАК ДокументыФизическихЛицСрезПоследних
    
  2. Открываем Конструктор запроса и переходим на вкладку «Компоновка данных».
  3. Переходим на вложенную вкладку «Таблицы».
  4. В списке таблиц находим наш срез последних, дважды кликаем по нему или нажимаем кнопку редактирования параметров таблицы.
  5. В появившемся окне в поле «Период» указываем наш параметр &НачПериода.

При такой настройке СКД сама сгенерирует корректный SQL-код, подставив условия в нужные секции запроса, избегая при этом конфликтов типов данных и переименования параметров в &П3.

Способ 4. Отключение автозаполнения схемы

Если СКД продолжает вести себя непредсказуемо и переименовывать параметры, можно прибегнуть к радикальному, но крайне надежному способу — отключению флага «Автозаполнение» у набора данных-запроса.

Для этого снимем галочку «Автозаполнение» на вкладке «Наборы данных». Однако помните о важном нюансе: при отключении автозаполнения СКД перестанет автоматически вытягивать доступные поля и параметры из текста запроса. Нам придется вручную определить все используемые поля набора данных и параметры на соответствующих вкладках СКД. Это трудоемкий процесс, но он дает разработчику стопроцентный контроль над итоговым SQL-запросом.

Способ 5. Исправление ошибки при связи наборов данных

Если ошибка &П3 возникает при попытке соединить два набора данных (например, когда мы делаем срез последних цен на дату каждой продажи из первого набора), важно правильно настроить параметры связи.

Проанализируем правильный алгоритм настройки:

  1. В запросе подчиненного набора данных (где выбирается срез последних) обязательно оборачиваем параметр даты в фигурные скобки:
    
    ВЫБРАТЬ
        ЦеныНоменклатурыСрезПоследних.Номенклатура,
        ЦеныНоменклатурыСрезПоследних.Цена
    ИЗ
        РегистрСведений.ЦеныНоменклатуры.СрезПоследних({&ДатаСреза}, Номенклатура = &Номенклатура) КАК ЦеныНоменклатурыСрезПоследних
    
  2. Переходим на вкладку «Связи наборов данных».
  3. В качестве выражения источника выбираем поле даты из первого набора данных (например, ДатаДокумента).
  4. В колонке «Параметр» обязательно указываем имя нашего параметра из подчиненного запроса — ДатаСреза.

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

← На главную