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