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