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

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

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

Проанализируем ситуацию и выявим причину

Разберем типичный сценарий. У нас есть запрос, который соединяет обороты регистра накопления с актуальными ценами из регистра сведений. В тексте запроса это выглядит примерно так:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура,
    ТоварыНаСкладахОстаткиИОбороты.Склад КАК Склад,
    ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток,
    ЦеныНоменклатурыСрезПоследних.Цена,
    ЦеныНоменклатурыСрезПоследних.ВидЦены
ИЗ
    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(, , Авто, , ) КАК ТоварыНаСкладахОстаткиИОбороты
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
        ПО ТоварыНаСкладахОстаткиИОбороты.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура

Проблема кроется в механизме автозаполнения параметров СКД. Когда в схеме компоновки данных мы добавляем параметр с типом СтандартныйПериод и называем его, к примеру, Период, система начинает проявлять излишнюю «самостоятельность». Виртуальная таблица СрезПоследних первым параметром всегда ожидает конкретную точку на временной оси — значение с типом Дата. Однако СКД, видя совпадение имен или пытаясь сопоставить глобальные настройки, подставляет в этот параметр весь объект СтандартныйПериод (который содержит и дату начала, и дату окончания).

Именно это вызывает конфликт типов: виртуальная таблица «хочет» дату, а получает комплексный объект периода. В консоли запросов такой ошибки нет, так как там мы вручную передаем параметры и они имеют простые типы. В СКД же генератор запроса перестраивает исходный текст, что приводит к невалидному коду на уровне СУБД. Для отладки и тестирования запросов непосредственно из схемы компоновки данных подойдёт инженерная консоль запросов для 1С с поддержкой СКД.

Решение №1: Использование выражений для параметров (Рекомендуемый способ)

Этот метод считается наиболее правильным с точки зрения архитектуры 1С, так как он позволяет сохранить удобный для пользователя интерфейс выбора периода и при этом корректно передать данные в запрос. Разберем его по шагам:

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

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

Решение №2: Переименование параметров

Выясним, почему простое переименование часто решает проблему. Если мы переименуем глобальный параметр отчета из Период во что-то нейтральное, например, ПериодОтчета, то магическая связь между настройками экрана и внутренним параметром виртуальной таблицы разорвется. СКД перестанет пытаться «засунуть» объект периода в параметр среза последних.

Рассмотрим, как это реализовать:

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

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

Решение №3: Явное указание параметров в тексте запроса

Чтобы полностью контролировать поведение системы и избежать неявных подстановок, проанализируем возможность модификации текста запроса. Рекомендуется всегда явно прописывать параметры виртуальных таблиц, даже если они кажутся необязательными. Посмотрим на пример правильного оформления соединения:


ИЗ
    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК ТоварыНаСкладахОстаткиИОбороты
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаЦен, ) КАК ЦеныНоменклатурыСрезПоследних
        ПО ТоварыНаСкладахОстаткиИОбороты.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура

Здесь мы создали уникальный параметр &ДатаЦен. Теперь в настройках СКД мы можем гибко управлять им. Например, если отчет строится за период, логично ли нам видеть цены на начало периода или на конец? Явное указание параметра позволяет нам осознанно выбрать логику:

Важные нюансы при работе с «Периодичность: Авто»

Стоит также обратить внимание на использование настройки «Авто» в таблице ОстаткиИОбороты. В этом режиме СКД может добавлять в выборку дополнительные поля периодов (День, Месяц и т.д.). Если эти системные поля пересекаются с именами параметров, используемых в СрезПоследних, это также может вызвать путаницу в типах данных.

Совет: При использовании сложных соединений в СКД старайтесь избегать стандартных имен параметров типа &Период для виртуальных таблиц срезов, заменяя их на более специфичные, такие как &ДатаСрезаПоследних или &МоментВремениЦен. Это гарантирует, что генератор запросов СКД не подставит туда неподходящий объект СтандартныйПериод.

Подводя итог, можно сказать, что ошибка «несоответствие типов» в 99% случаев лечится внимательным управлением вкладкой «Параметры» и использованием выражений для приведения сложных типов (периодов) к простым (датам).

← На главную