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