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