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

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

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

Разбор типичной ошибки обращения к полям отбора

Рассмотрим ситуацию: разработчик пытается установить отбор по наименованию родителя в обработчике события НачалоВыбора. В исходном коде часто встречается попытка обратиться к свойству через цепочку: ФормаПодбора.Отбор.Наименование.Родитель. Это приводит к ошибке «Поле объекта не обнаружено (Родитель)».

Проанализируем причину: объект Отбор в 1С содержит набор доступных полей, соответствующих реквизитам справочника. У реквизита Наименование (который является строкой) не может быть свойства Родитель. Обращение должно идти напрямую к реквизиту Родитель, если справочник иерархический.

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

Реализация для обычных форм (толстый клиент)

Для того чтобы программно открыть форму с фильтром и избежать стандартного поведения системы, выполним следующие шаги:

  1. Отключим стандартное открытие формы выбора.
  2. Найдем ссылку на нужную нам папку (группу).
  3. Создадим форму выбора программно.
  4. Настроим параметры отбора.
  5. Откроем форму.

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


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

    // 3. Получаем форму выбора
    ФормаПодбора = Справочники.ОбъектыОИС.ПолучитьФормуВыбора("ФормаСписка");
    ФормаПодбора.РежимВыбора = Истина;
    ФормаПодбора.ВладелецФормы = Элемент;
    
    // 4. Настраиваем отбор по родителю
    // Используем ВидСравнения.ВИерархии, чтобы видеть и подпапки, 
    // или ВидСравнения.Равно для строгого соответствия непосредственному родителю
    ФормаПодбора.Отбор.Родитель.ВидСравнения = ВидСравнения.Равно;
    ФормаПодбора.Отбор.Родитель.Значение = ГруппаСсылка;
    ФормаПодбора.Отбор.Родитель.Использование = Истина;
    
    // 5. Открываем форму
    ФормаПодбора.Открыть();
    
КонецПроцедуры

Важные нюансы работы с отбором

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

Вид сравнения: Если вы используете ВидСравнения.Равно, в списке отобразятся только те элементы, которые лежат непосредственно в указанной папке. Если же внутри папки «Информационные системы» есть другие вложенные папки и вы хотите видеть их содержимое тоже, используйте ВидСравнения.ВИерархии.

ТекущийРодитель: Иногда вместо жесткого фильтра (который скрывает всё остальное) нужно просто, чтобы при открытии формы пользователь «оказался» внутри определенной папки, но мог выйти из нее вверх по иерархии. Для этого в обычных формах используется свойство ФормаПодбора.ТекущийРодитель = ГруппаСсылка;.

Особенности реализации для управляемых форм (8.3)

В современном интерфейсе «Такси» и на управляемых формах подход с ПолучитьФорму и прямой модификацией объекта Отбор не используется. Вместо этого параметры отбора передаются в структуру при открытии формы. Рассмотрим, как это выглядит.

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


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

Фиксированные настройки: Если вы хотите, чтобы пользователь не мог самостоятельно отключить установленный вами программно отбор через меню «Настроить список», в управляемых формах следует использовать параметр ФиксированныеНастройки. Это гарантирует, что фильтр по родителю останется неизменным на протяжении всего сеанса выбора.

Рекомендации по поиску родителя

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

Подводя итог, отметим: для успешного решения задачи необходимо четко разделять контекст выполнения кода (Обычные или Управляемые формы) и всегда помнить об отключении СтандартнаяОбработка. Правильное манипулирование объектом Отбор или параметрами формы позволяет создавать интуитивно понятные и удобные интерфейсы для конечных пользователей.

← На главную