Как программно изменить текст запроса динамического списка в 1С?

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

Работа с динамическими списками в 1С:Предприятие — одна из самых частых задач при разработке интерфейсов управляемых форм. Однако попытка изменить текст запроса «на лету» часто оборачивается для разработчика рядом ошибок: от простых проблем с контекстом до сложных диагностических сообщений о неверной основной таблице. В этой статье мы подробно разберем, как правильно модифицировать запрос динамического списка, какие ограничения накладывает платформа и как избежать типичных ошибок.

Разбор первой ошибки: Клиент или Сервер?

Проанализируем ситуацию: часто разработчики пытаются изменить свойство ТекстЗапроса непосредственно в процедуре ПриИзменении на клиенте. Рассмотрим, почему это приводит к ошибке. Согласно синтакс-помощнику, свойство ТекстЗапроса объекта ДинамическийСписок доступно для записи только на сервере.

Выясним причину ошибки «Параметр не найден» при установке значения. Когда вы пытаетесь установить параметр на клиенте, обращаясь к списку, платформа может не видеть изменений в тексте запроса, так как сама запись текста не произошла. Следовательно, структура параметров не обновилась.

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


&НаКлиенте
Процедура ФильтрПриИзменении(Элемент)
    УстановитьЗапросНаСервере();
КонецПроцедуры

&НаСервере
Процедура УстановитьЗапросНаСервере()
    // Здесь мы можем безопасно менять текст и параметры
    Список.ТекстЗапроса = "ВЫБРАТЬ * ИЗ Документ.ЗаказНаВнутреннееПотребление ГДЕ Ссылка = &Ссылка";
    Список.Параметры.УстановитьЗначениеПараметра("Ссылка", Объект.Ссылка);
КонецПроцедуры

Проблема «Основная таблица задана неверно»

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

  1. Проверим свойство «Произвольный запрос»: Если изначально в конфигураторе список был привязан просто к таблице (не был установлен флаг произвольного запроса), то при попытке программно присвоить строку с кодом ВЫБРАТЬ... система выдаст ошибку. Перед сменой текста обязательно установим: Список.ПроизвольныйЗапрос = Истина;.
  2. Соответствие полей: Убедимся, что в новом запросе присутствует ключевое поле (обычно это Ссылка) и оно принадлежит именно той таблице, которая указана в свойстве ОсновнаяТаблица.
  3. Уникальность псевдонимов: Если вы используете соединения, убедитесь, что поле Ссылка основной таблицы не перекрывается ссылками из других таблиц с похожими именами.

Использование временных таблиц в динамическом списке

Рассмотрим ситуацию, когда требуется сложный фильтр, например, по табличной части документа. Многие разработчики сомневаются, можно ли использовать пакетные запросы (временные таблицы) в динамических списках. Ответ: да, можно, начиная с версии платформы 8.3.5.

Посмотрим на пример правильного формирования запроса с временной таблицей:


&НаСервере
Функция ПолучитьТекстЗапросаСФильтром()
    Возврат 
    "ВЫБРАТЬ
    |    ТЧ.Ссылка КАК Ссылка
    |ПОМЕСТИТЬ ВТ_Фильтр
    |ИЗ
    |    Документ.ЗаказНаВнутреннееПотребление.Товары КАК ТЧ
    |ГДЕ
    |    ТЧ.ЦФУ = &ЦФУ;
    |
    |//////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    Док.Ссылка,
    |    Док.Дата,
    |    Док.Номер
    |ИЗ
    |    Документ.ЗаказНаВнутреннееПотребление КАК Док
    |ГДЕ
    |    Док.Ссылка В (ВЫБРАТЬ Ссылка ИЗ ВТ_Фильтр)";
КонецФункции

Важное примечание: Использование временных таблиц в динамических списках может замедлить работу интерфейса при больших объемах данных, так как временная таблица будет пересоздаваться при каждом обновлении списка (например, при прокрутке). Проанализируем ситуацию: если ваша задача — просто наложить фильтр, возможно, лучше воспользоваться стандартным компоновщиком настроек.

Использование инструментов БСП (Библиотека стандартных подсистем)

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

Рассмотрим пример кода, который делает изменение запроса элегантным и безопасным:


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

Этот метод самостоятельно управляет параметрами и обновлением отображения, что значительно упрощает разработку.

Ошибки при передаче динамического списка в общие модули

Разберем типичную техническую ошибку: «Ошибка преобразования данных XDTO: Отсутствует отображение для типа ДинамическийСписок». Она возникает, когда вы пытаетесь передать объект ДинамическийСписок как параметр с клиента в серверную процедуру общего модуля.

Почему это происходит? ДинамическийСписок — это объект контекста формы. Он не может быть сериализован для передачи между клиентом и сервером в качестве независимого значения. Решение задачи: вызывайте серверный метод самой формы, а внутри него уже работайте со списком напрямую, либо передавайте в общий модуль имя списка строкой и саму форму.

Альтернатива: изменение отборов без смены текста

Прежде чем менять весь ТекстЗапроса, проанализируем ситуацию: действительно ли это необходимо? Если цель — просто добавить сложное условие, мы можем заранее подготовить запрос с параметрами в конфигураторе, а программно лишь управлять ими.

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

ГДЕ (&ИспользоватьФильтр = ЛОЖЬ ИЛИ Поле В (ВЫБРАТЬ...))

Такой подход работает быстрее, не требует перегенерации схемы списка и позволяет избежать ошибок с «Основной таблицей».

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

← На главную