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