Как программно установить редактируемый отбор в форме выбора 1С

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

При разработке на платформе 1С:Предприятие 8.3 часто возникает задача: открыть форму выбора документа или справочника с уже предустановленным фильтром (например, по периоду), но при этом оставить пользователю возможность этот фильтр изменить или вовсе отключить. Типичная ошибка начинающего разработчика заключается в том, что установленные программно настройки «слетают» или отображаются некорректно (например, вместо вида сравнения «Больше или равно» отображается «Равно», а значение остается пустым). Рассмотрим подробнее, почему это происходит и как правильно реализовать этот механизм.

Анализ проблемы: почему настройки не сохраняются

Проанализируем ситуацию, описанную в обращении. Разработчик пытается добавить элемент отбора непосредственно в КомпоновщикНастроек.Настройки.Отбор. На первый взгляд, код выглядит логично: создается новый элемент, указывается левое значение (поле компоновки), вид сравнения и правое значение. Однако при открытии формы пользователь видит пустые поля или стандартные настройки.

Выясним причину такого поведения. В управляемых формах 1С динамические списки используют сложную систему компоновки данных. Основной секрет кроется в наличии двух разных коллекций внутри компоновщика:

  1. Настройки (Settings) — это «эталонные» настройки, которые определяют логику работы отбора.
  2. Пользовательские настройки (User Settings) — это именно те значения, которые пользователь видит в интерфейсе формы (в «быстрых настройках» или через кнопку «Настроить список»).

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

Решение №1: Синхронизация программных и пользовательских настроек

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

Рассмотрим пример кода, который решает поставленную задачу:


// 1. Открываем форму без автоматического открытия, чтобы успеть изменить настройки
СтандартнаяОбработка = Ложь;
ПараметрыФормы = Новый Структура;
Форма = ПолучитьФорму("Документ.Счет.Форма.ФормаВыбора", ПараметрыФормы, ЭтаФорма);

// 2. Создаем элемент в основных настройках компоновщика
ЭлементОтбора = Форма.Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Дата");
ЭлементОтбора.ВидСравнения   = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
ЭлементОтбора.ПравоеЗначение = ДобавитьМесяц(Объект.Дата, -2);
ЭлементОтбора.Использование  = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;

// 3. Генерируем уникальный идентификатор для связи с пользовательскими настройками
ИдентификаторНастройки = Новый УникальныйИдентификатор();
ЭлементОтбора.ИдентификаторПользовательскойНастройки = ИдентификаторНастройки;
ЭлементОтбора.ПредставлениеПользовательской Настройки = "Дата начала периода";

// 4. Обязательный шаг: синхронизация с пользовательскими настройками
// Ищем элемент в коллекции пользовательских настроек по нашему идентификатору
ПользовательскийЭлемент = Форма.Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ИдентификаторНастройки);

Если ПользовательскийЭлемент <> Неопределено Тогда
    ПользовательскийЭлемент.Использование = Истина;
    ПользовательскийЭлемент.Значение      = ЭлементОтбора.ПравоеЗначение;
    ПользовательскийЭлемент.ВидСравнения  = ЭлементОтбора.ВидСравнения;
КонецЕсли;

// 5. Теперь открываем форму
Форма.Открыть();

В этом примере мы явно указываем системе, что программно созданный отбор должен быть связан с интерфейсным элементом. Установка РежимОтображения.БыстрыйДоступ гарантирует, что пользователь увидит этот фильтр прямо над списком документов.

Решение №2: Использование фиксированных настроек (когда менять нельзя)

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

Посмотрим на пример передачи фиксированных настроек:


НастройкиКД = Новый НастройкиКомпоновкиДанных;
ЭлементОтбора = НастройкиКД.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Проведен");
ЭлементОтбора.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Истина;
ЭлементОтбора.Использование  = Истина;

ПараметрыВыбора = Новый Структура;
ПараметрыВыбора.Вставить("ФиксированныеНастройки", НастройкиКД);

ОткрытьФорму("Документ.Счет.ФормаВыбора", ПараметрыВыбора, Элемент);

Решение №3: Обработка события ПриСозданииНаСервере

Если у вас есть возможность редактировать форму выбора (целевую форму), то наиболее надежным и правильным с точки зрения архитектуры 1С способом будет перенос логики установки отборов внутрь самой формы выбора в обработчик ПриСозданииНаСервере.

Разберем, как это реализовать. Мы можем передать нужные значения через параметры формы, а в самой форме их обработать. Это позволит избежать манипуляций с объектом формы «снаружи», что часто приводит к ошибкам инициализации.

Код вызова формы:


ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ДатаНачалаОтбора", ДобавитьМесяц(Объект.Дата, -2));
ОткрытьФорму("Документ.Счет.Форма.ФормаВыбора", ПараметрыФормы, ЭтаФорма);

Код внутри формы выбора (ПриСозданииНаСервере):


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

Важные нюансы и рекомендации

Проанализируем несколько технических моментов, которые часто упускаются из виду:

Таким образом, для корректной работы динамического фильтра всегда следуйте правилу: изменяете основные настройки — не забывайте обновить пользовательские. Это обеспечит предсказуемое поведение интерфейса и удобство работы пользователя с программой.

← На главную