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