Как правильно установить период в динамическом списке для виртуальных таблиц и избежать ошибок отбора

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

При разработке интерфейсов на управляемых формах часто возникает задача динамического изменения периода в списках, построенных на виртуальных таблицах (например, ОстаткиИОбороты или Обороты). Одной из самых распространенных проблем является ошибка: «Невозможно применить элемент отбора в наборе данных "Параметры.НачалоПериода"». В этой статье мы разберем природу этой ошибки, выясним, почему стандартные методы отбора не работают в данном случае, и рассмотрим несколько эффективных способов решения задачи.

Почему возникает ошибка при установке отбора

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

Проанализируем причину подробнее. Виртуальные таблицы в 1С (такие как РегистрНакопления.Продажи.ОстаткиИОбороты) принимают НачалоПериода и КонецПериода как входящие параметры функции, а не как поля результата запроса. Коллекция Отбор предназначена для фильтрации уже полученных строк данных по их полям. Платформа не может применить фильтр «Равно» или «Больше» к параметру функции на этапе получения данных через механизм отборов, так как значение параметра должно быть определено ДО выполнения запроса к базе данных.

Способ 1. Установка параметров через коллекцию Параметры (Рекомендуемый)

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


ВЫБРАТЬ
    Регистр.Период,
    Регистр.Номенклатура,
    Регистр.КоличествоОборот
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Регистр

Теперь рассмотрим программный код на встроенном языке, который изменит эти даты (например, при нажатии кнопки или изменении реквизита формы):


&НаСервере
Процедура ОбновитьПериодСпискаНаСервере(НоваяДатаНачала, НоваяДатаКонца)
    
    // Прямая установка значений параметров динамического списка
    Список.Параметры.УстановитьЗначениеПараметра("НачалоПериода", НоваяДатаНачала);
    Список.Параметры.УстановитьЗначениеПараметра("КонецПериода", НоваяДатаКонца);
    
КонецПроцедуры

Этот метод работает мгновенно, не требует перестроения схемы компоновки и является наиболее производительным для сервера.

Способ 2. Использование компоновщика настроек (SettingsComposer)

Если ваша задача требует, чтобы параметры были видны пользователю в настройках списка или вы используете более сложную логику СКД, следует работать через КомпоновщикНастроек. В отличие от коллекции Отбор, мы будем работать с коллекцией ЗначенияПараметровДанных.

Выполним следующие шаги для реализации этого метода:

  1. Найдем нужный параметр в настройках компоновщика по его имени.
  2. Установим значение и обязательно взведем флаг использования.

Посмотрим на пример кода:


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

Важно помнить: если вы меняете параметры через КомпоновщикНастроек.Настройки, эти изменения затронут текущий сеанс работы пользователя, но могут быть перекрыты пользовательскими настройками, если они сохранены.

Способ 3. Стандартный период платформы и фигурные скобки

Платформа 1С:Предприятие 8.3 предоставляет встроенный механизм управления периодом для динамических списков. Чтобы он работал корректно с виртуальными таблицами, в тексте запроса ДС необходимо использовать фигурные скобки — это синтаксис расширения языка запросов для СКД.

Проанализируем правильное написание запроса:


ВЫБРАТЬ
    Регистр.Номенклатура,
    Регистр.СуммаОборот
ИЗ
    РегистрНакопления.Продажи.Обороты({&НачалоПериода}, {&КонецПериода}, , ) КАК Регистр

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

Анализ использования временных таблиц (метод из обсуждения)

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

Поэтому использование временных таблиц для обхода ошибки параметров — это крайняя мера, которую стоит избегать в пользу методов, описанных выше.

Важные нюансы и советы

При работе с периодами в виртуальных таблицах Остатки и ОстаткиИОбороты обратите внимание на следующие моменты:

1. Использование типа Граница (Boundary): Чтобы данные за последнюю секунду периода (например, 23:59:59) гарантированно попадали в отчет, рекомендуется передавать дату конца периода в виде объекта Граница с видом Включая.


КонецДняГраница = Новый Граница(КонецДня(ДатаКонца), ВидГраницы.Включая);
Список.Параметры.УстановитьЗначениеПараметра("КонецПериода", КонецДняГраница);

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

3. Сброс настроек: Если вы программно меняете период, а список не обновляется, попробуйте вызвать метод Элементы.Список.Обновить(), хотя при использовании УстановитьЗначениеПараметра обновление обычно происходит автоматически.

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

← На главную