Как исправить ошибку "Несоответствие типов" при использовании стандартного периода в СКД?

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

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

Разберем причину возникновения ошибки

Чтобы понять суть проблемы, посмотрим на то, как платформа 1С воспринимает различные типы данных. Тип СтандартныйПериод — это не просто дата. Это сложный (составной) объект, который содержит внутри себя два отдельных свойства: ДатаНачала и ДатаОкончания.

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

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

Ошибки в синтаксисе параметров виртуальной таблицы

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


ВЫБРАТЬ 
    КадроваяИсторияСотрудниковСрезПоследних.Период КАК Период, 
    КадроваяИсторияСотрудниковСрезПоследних.Регистратор КАК Регистратор, 
    КадроваяИсторияСотрудниковСрезПоследних.Сотрудник КАК Сотрудник 
ИЗ 
    РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних( , Период > &ДатаС И Период < &ДатаПо) КАК КадроваяИсторияСотрудниковСрезПоследних

Так делать категорически нельзя. Виртуальная таблица СрезПоследних не предназначена для выборки истории за период (для этого существует основная физическая таблица регистра). Задача среза — дать одну самую актуальную запись на запрошенный момент времени. Первый параметр всегда должен быть конкретным значением. Задавать там условия вроде «Больше/Меньше» концептуально неверно.

Правильная настройка стандартного периода в СКД

Рассмотрим по шагам правильный паттерн настройки, который позволит пользователям удобно выбирать период отчета (например, «Этот месяц», «Прошлый год»), а платформе — корректно обрабатывать запросы без ошибок типов.

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

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

Как влияет флаг "Автозаполнение"

Иногда при работе с расширением языка запросов СКД (использование фигурных скобок {}) разработчики сталкиваются с мистическим исчезновением параметра Период из списка параметров схемы. Разберем, почему это происходит.

Когда в запросе СКД включен флаг «Автозаполнение», система сама анализирует текст запроса и автоматически генерирует параметры Период для таблиц срезов и НачалоПериода / КонецПериода для таблиц оборотов.

Если мы начинаем вручную переопределять параметры виртуальной таблицы (например, пишем СрезПоследних(&КонецПериода {(&КонецПериода)}, ...)), парсер СКД может решить, что стандартный параметр Период больше не нужен, и автоматически удалит его. Чтобы избежать таких "качелей", рекомендуется всегда явно прописывать имена параметров в виртуальных таблицах, если ваш запрос содержит сложную логику комбинации срезов и оборотов.

Использование типа "Граница" для точного попадания данных

Отдельно стоит рассмотреть проблему получения данных на конец дня. Если мы передадим в СрезПоследних обычную дату окончания дня (например, 31.12.2023 23:59:59), то документы или записи регистра, сделанные ровно в эту же секунду, могут не попасть в выборку. Это происходит из-за внутренней сортировки ссылок и идентификаторов внутри одной секунды.

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

ДОБАВИТЬКДАТЕ(&ПериодОтчета.ДатаОкончания, "СЕКУНДА", 1)

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

Применяя эти правила, вы сможете создавать гибкие и надежные отчеты, которые не будут выдавать системные ошибки при попытке пользователя выбрать нужный ему временной интервал.

← На главную