Как решить конфликт параметров при использовании Среза последних и Стандартного периода в СКД?

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

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

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

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

Решение №1: Использование расширения языка запросов (фигурные скобки)

Самый быстрый и эффективный способ, который мы рассмотрим, — это явное указание параметров в тексте запроса с использованием фигурных скобок. Это позволяет "перехватить" управление параметром у автоматических механизмов СКД.

В конструкторе запроса для виртуальной таблицы СрезПоследних в поле "Период" необходимо прописать имя своего параметра внутри фигурных скобок. Посмотрим на пример синтаксиса:


ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних({(&КонецПериода)}, ) КАК ЦеныНоменклатурыСрезПоследних

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

Решение №2: Переименование параметров и использование выражений

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

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

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

Решение №3: Работа с объектом Граница (Boundary)

Проанализируем тонкий технический момент: если запись в регистре сведений была сделана ровно в ту же секунду, которая указана в параметре &Период, она может не попасть в результат из-за особенностей работы виртуальных таблиц. Чтобы гарантированно включить данные на последнюю секунду периода, рекомендуется использовать объект Граница.

Выясним, как это реализовать в СКД. В поле "Выражение" для параметра даты можно написать специальный вызов:

Вычислить("Новый Граница(&Период.ДатаОкончания, ВидГраницы.Включая)")

Или, если вы предпочитаете более простой вариант через добавление секунды, можно использовать стандартные функции языка выражений СКД:


ДобавитьКДате(КонецПериода(&СтандартныйПериод.ДатаОкончания, "День"), "Секунда", 1)

Важно: Первый вариант с объектом Граница является более методологически верным в архитектуре 1С.

Решение №4: Разные периоды для разных таблиц

Иногда возникают ситуации, когда в одном отчете нужно соединить данные из нескольких регистров на разные даты. Например, остатки товаров на конец периода, а курсы валют — на дату начала. В этом случае автоматическое заполнение параметров только мешает.

Рассмотрим, как прописать разные имена параметров непосредственно в определении виртуальных таблиц:


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

После написания такого запроса СКД создаст два независимых параметра: &ДатаОстатков и &ДатаЦен. Вы сможете связать их с разными частями СтандартногоПериода. В более сложных архитектурных задачах может потребоваться использование двух разных схем в одном отчете или разработка подсистем уровня универсального отчета для ЗУП, где логика получения данных выходит за рамки простых виртуальных таблиц.

Особенности программного вывода отчета

Если ваш отчет формируется программно через модуль (например, в типовых конфигурациях типа 1С:ERP или 1С:УТ 11), будьте осторожны при переименовании параметров. Проанализируем код формирования: если в модуле присутствует прямое обращение к параметру по имени Период, то после его переименования в схеме (СКД) код выдаст ошибку.

Пример кода, который может сломаться:


// Опасно, если в СКД параметр переименован в &ДатаОтчета
ПараметрДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Период");
Если ПараметрДанных <> Неопределено Тогда
    ПараметрДанных.Value = ТекущаяДата();
    ПараметрДанных.Использование = Истина;
КонецЕсли;

В таких случаях лучше использовать Решение №1 (фигурные скобки). А чтобы сократить количество рутинного кода при программной работе с компоновкой, можно применить СКДБилдер: инструмент для упрощения программного создания СКД, который делает код более читаемым и компактным.

Подведем итоги

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

← На главную