В процессе разработки и кастомизации конфигураций на обычных формах (таких как «1С:Управление производственным предприятием 1.3» или «1С:Управление торговлей 10.3») программисты часто сталкиваются со специфическим поведением платформы при работе с иерархическими справочниками. Одна из наиболее популярных проблем — внезапный отказ механизма подбора при попытке выбрать несколько элементов из справочника ФизическиеЛица (или любого другого иерархического справочника) после установки отбора по группе.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем поведение платформы «1С:Предприятие» изнутри и рассмотрим три эффективных способа ее решения: от быстрого исправления в коде до интерактивного обхода силами пользователя.
Рассмотрим стандартный сценарий. Разработчик программно открывает форму выбора справочника ФизическиеЛица для организации множественного подбора сотрудников в табличную часть документа. Для этого в коде формы-владельца прописываются следующие настройки:
ФормаВыбора = Справочники.ФизическиеЛица.ПолучитьФормуВыбора(, ЭтаФорма);
ФормаВыбора.РежимВыбора = Истина;
ФормаВыбора.ПараметрВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы;
ФормаВыбора.МножественныйВыбор = Истина;
ФормаВыбора.Открыть();
Пользователь открывает эту форму, интерактивно устанавливает отбор (например, по определенному подразделению или группе физических лиц) и пытается перенести всех найденных людей в документ. Чтобы не кликать по каждому человеку отдельно, пользователь нажимает комбинацию клавиш Ctrl + A (Выделить все) или выделяет диапазон строк с помощью клавиши Shift, после чего нажимает кнопку «Выбрать» или клавишу Enter. И в этот момент ничего не происходит — данные не переносятся, а кнопка выбора в форме выглядит неактивной.
Выясним причину такого поведения. Она кроется в конфликте двух свойств формы выбора:
МножественныйВыбор = Истина позволяет выделить в списке сразу несколько строк.ПараметрВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы жестко указывает платформе, что результатом выбора могут быть только конечные элементы справочника (не папки).Когда справочник отображается в виде дерева или иерархического списка, при нажатии комбинации Ctrl + A в выделение неизбежно попадает сама родительская группа (папка). Поскольку в выделенном массиве присутствует хотя бы один объект типа «Группа», а форме предписано выбирать исключительно «Элементы», срабатывает защитный механизм платформы. Система блокирует возможность выбора, делая кнопку «Выбрать» неактивной, а двойной клик или клавишу Enter — нерабочими. При этом, если пользователь выбирает элементы поодиночке с зажатым Ctrl, обходя папки стороной, подбор отрабатывает абсолютно штатно.
Проанализируем три практических способа решения этой проблемы.
Этот способ является наиболее надежным и незаметным для конечного пользователя. Мы обойдем ограничение платформы, позволив форме возвращать любые объекты (и элементы, и группы), но в процедуре обработки выбора самостоятельно отсечем все папки.
Разберем реализацию по шагам.
Шаг 1. В процедуре вызова формы подбора изменим значение параметра ПараметрВыборГруппИЭлементов. Вместо жесткого ограничения на элементы укажем значение, разрешающее выбор и групп, и элементов:
Процедура КоманднаяПанельСотрудникиОрганизацииДействие(Кнопка)
СтандартнаяОбработка = Ложь;
ФормаВыбора = Справочники.ФизическиеЛица.ПолучитьФормуВыбора(, ЭтаФорма);
ФормаВыбора.РежимВыбора = Истина;
// РАЗРЕШАЕМ ВЫБОР И ГРУПП, И ЭЛЕМЕНТОВ:
ФормаВыбора.ПараметрВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.ГруппыИЭлементы;
ФормаВыбора.МножественныйВыбор = Истина;
ФормаВыбора.ЗакрыватьПриВыборе = Ложь;
// Настройка отбора (при необходимости)
ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСпискеПоИерархии;
ФормаВыбора.Отбор.Ссылка.Использование = Истина;
ФормаВыбора.Открыть();
КонецПроцедуры
Благодаря этому изменению кнопка «Выбрать» останется активной даже в том случае, если пользователь выделит весь список вместе с родительскими папками через Ctrl + A.
Шаг 2. Теперь нам необходимо обработать полученные данные. В форме-владельце (откуда открывался подбор) найдем процедуру, отвечающую за обработку выбора (обычно это ОбработкаВыбора или вызываемая из нее процедура подбора). Добавим в нее проверку свойства ЭтоГруппа для каждого переданного объекта:
Процедура ОбработкаПодбора(ТабличнаяЧасть, ЗначениеВыбора) Экспорт
Модифицированность = Истина;
Для Каждого ВыбранныйОбъект Из ЗначениеВыбора Цикл
// ДОБАВЛЕННАЯ ПРОВЕРКА: Если объект является группой справочника, игнорируем его
Если ВыбранныйОбъект.ЭтоГруппа Тогда
Продолжить;
КонецЕсли;
// Далее следует ваш стандартный алгоритм обработки элемента
СтандартнаяОбработка = Ложь;
Физлицо = ВыбранныйОбъект;
Если ТабличнаяЧасть.НайтиСтроки(Новый Структура("Сотрудник", Физлицо)).Количество() = 0 Тогда
СтрокаТабличнойЧасти = ТабличнаяЧасть.Добавить();
СтрокаТабличнойЧасти.Сотрудник = Физлицо;
// Дополнительные действия по заполнению строки...
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот простой и изящный прием позволяет полностью сохранить привычный пользователю сценарий работы: он сможет спокойно использовать групповое выделение, а программа сама отфильтрует ненужные папки «под капотом».
Если у вас нет возможности или прав на изменение конфигурации (например, база находится на строгой поддержке, а изменения вносить запрещено), проблему можно решить исключительно силами интерфейса «1С:Предприятие».
Посмотрим, как пользователю обойти данное ограничение при работе со списком:
После переключения режима просмотра структура справочника перестает отображаться в виде папок. Перед пользователем предстанет сплошной плоский перечень физических лиц, удовлетворяющих условиям отбора. Папки (группы) в этом режиме вообще не выводятся на экран. Соответственно, при нажатии комбинации клавиш Ctrl + A будут выделены исключительно элементы (конкретные люди). Блокировка кнопки «Выбрать» не произойдет, и все физические лица успешно перенесутся в документ.
Иногда стандартного диалога выбора оказывается недостаточно, и разработчики проектируют специализированные (самописные) формы подбора. Если вы используете именно такую форму, то стандартный механизм ОповеститьОВыборе можно переопределить через обработку коллекции выделенных строк табличного поля.
Рассмотрим пример кода для обработчика нажатия кнопки «Перенести в документ» на кастомной форме подбора:
Процедура КнопкаПеренестиНажатие(Кнопка)
МассивВыбранныхЭлементов = Новый Массив;
// Обходим коллекцию выделенных строк табличного поля формы подбора
Для Каждого СтрокаИзВыделенных Из ЭлементыФормы.СправочникСписок.ВыделенныеСтроки Цикл
// Отсекаем группы на этапе формирования результирующего массива
Если Не СтрокаИзВыделенных.ЭтоГруппа Тогда
МассивВыбранныхЭлементов.Добавить(СтрокаИзВыделенных);
КонецЕсли;
КонецЦикла;
// Передаем очищенный массив элементов в форму-владелец
ОповеститьОВыборе(МассивВыбранныхЭлементов);
// При необходимости закрываем форму подбора
Закрыть();
КонецПроцедуры
Этот способ дает разработчику полный контроль над процессом. Вы можете не только отфильтровать папки, но и выполнить дополнительные проверки (например, проверить сотрудников на дубли или провести валидацию заполнения персональных данных) еще до того, как список вернется в основной документ.
Используя предложенные методики, вы навсегда избавитесь от неочевидного поведения платформы при групповом подборе физических лиц и обеспечите комфортную работу конечных пользователей в системе.