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