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

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

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

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

Анализ исходной проблемы

Рассмотрим типовой запрос, который часто пишут начинающие разработчики и который приводит к ошибкам при выполнении отчета:


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

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

---

Причина 1: Несоответствие типов данных в параметре периода

Основная причина возникновения ошибки «Несоответствие типов» кроется в том, как СКД обрабатывает параметры периода, выводимые на форму отчета.

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

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

Решение: Правильная настройка параметров на вкладке «Параметры» СКД

Для того чтобы избежать конфликтов типов и обеспечить корректную передачу даты в виртуальную таблицу, выполним следующие шаги:

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

Такой подход гарантирует, что в виртуальную таблицу всегда будет передаваться очищенное значение типа Дата, приведенное к концу дня (23:59:59), независимо от того, какой период выбрал пользователь.

---

Причина 2: Критическая ошибка производительности при фильтрации в предложении ГДЕ

Обратим внимание на конструкцию в исходном запросе:


ГДЕ
    КадроваяИсторияСотрудниковСрезПоследних.Организация = &Организация

С технической точки зрения наложение отборов на виртуальную таблицу через секцию ГДЕ — это грубейшая ошибка проектирования, которая на больших базах данных гарантированно приведет к зависанию отчета и избыточной нагрузке на сервер SQL.

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

Решение: Перенос условий в параметры виртуальной таблицы

Чтобы СУБД работала максимально эффективно, любые отборы по измерениям регистра необходимо передавать непосредственно внутрь параметров виртуальной таблицы. Изменим наш запрос следующим образом:


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

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

---

Применение расширения языка запросов СКД (Фигурные скобки)

Еще один важный нюанс работы с параметрами виртуальных таблиц в СКД — использование фигурных скобок {}.

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

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


РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних({&КонецПериода}, Организация = &Организация)

Если значение параметра &КонецПериода не будет передано, СКД автоматически проигнорирует его в итоговом SQL-запросе и получит срез последних на текущий момент времени (настоящую дату и время), предотвратив падение отчета.

---

Профессиональный подход: Использование встроенного механизма параметров СКД

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

Рассмотрим этот элегантный метод по шагам:

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

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

Настройка параметров через вкладку «Компоновка данных» в конструкторе запроса

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

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

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

← На главную