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