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