Реализация механизма подбора — одна из самых частых задач при разработке документов в 1С. Казалось бы, задача простая: открыть форму справочника, выбрать элемент и перенести его в таблицу. Однако на практике разработчики сталкиваются с тем, что форма закрывается после первого же выбора, а стандартный механизм возвращает только ссылку на объект, тогда как в документе могут требоваться дополнительные данные, например, оклады, артикулы или остатки. В этой статье мы подробно разберем, как сделать подбор удобным, производительным и функциональным.
Рассмотрим ситуацию: вы прописали параметр ЗакрыватьПриВыборе = Ложь, но форма все равно закрывается. Давайте проанализируем возможные причины. В управляемых формах 1С 8.3 за это поведение отвечает структура параметров, передаваемая при открытии формы. Типичный код открытия выглядит так:
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);
ПараметрыФормы.Вставить("МножественныйВыбор", Истина); // Если нужно выбирать сразу нескольких
ОткрытьФорму("Справочник.Сотрудники.ФормаВыбора", ПараметрыФормы, ЭтаФорма);
Если форма все равно закрывается, проверьте следующие моменты:
ИмяКомандыВыбора. Если там указана стандартная команда, она может игнорировать программные установки.ПриСозданииНаСервере.Структура характерна для Управляемых форм. Если вы работаете в старом интерфейсе (Обычные формы), свойство устанавливается напрямую у объекта формы: Форма.ЗакрыватьПриВыборе = Ложь;.Часто возникает вопрос: как вместе с сотрудником сразу получить его оклад, чтобы не делать лишних запросов к базе данных? Рассмотрим два подхода: "ленивый" и "профессиональный".
Ленивый способ: Получение данных в обработчике ПриИзменении в самом документе. Это кажется простым, но это плохая практика. Каждый раз, когда вы добавляете строку, система будет делать отдельный вызов к серверу, чтобы вытащить оклад. Если сотрудников в подборе много, форма начнет "подтормаживать".
Профессиональный способ: Переопределение события выбора в справочнике. Разберем его по шагам:
Шаг 1. В форме выбора справочника "Сотрудники" создадим событие СписокВыбор (или ПередЗавершениемВыбора). Вместо стандартного возврата ссылки, мы сформируем структуру со всеми нужными данными:
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отменяем стандартный выбор ссылки
// Получаем данные текущей строки
ДанныеСтроки = Элементы.Список.ТекущиеДанные;
Если ДанныеСтроки <> Неопределено Тогда
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("Сотрудник", ДанныеСтроки.Ссылка);
СтруктураРезультата.Вставить("Оклад", ДанныеСтроки.Оклад); // Предполагаем, что Оклад есть в списке
// Оповещаем владельца (форму документа) о выборе структуры
ОповеститьОВыборе(СтруктураРезультата);
КонецЕсли;
КонецПроцедуры
Шаг 2. Теперь в форме документа нужно правильно принять эти данные. Используем обработчик ОбработкаВыбора:
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
// Проверяем, что к нам пришла именно структура (наш расширенный выбор)
Если ТипЗнч(ВыбранноеЗначение) = Тип("Структура") Тогда
НоваяСтрока = Объект.БазаЗП.Добавить();
НоваяСтрока.Сотрудник = ВыбранноеЗначение.Сотрудник;
НоваяСтрока.Оклад = ВыбранноеЗначение.Оклад;
ИначеЕсли ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Сотрудники") Тогда
// На случай, если сработал стандартный выбор ссылки
НоваяСтрока = Объект.БазаЗП.Добавить();
НоваяСтрока.Сотрудник = ВыбранноеЗначение;
КонецЕсли;
КонецПроцедуры
Если пользователю нужно выбрать сразу 10-20 сотрудников, нажимать на каждого по отдельности неудобно. Для этого в 1С предусмотрен параметр МножественныйВыбор. Выясним, как его правильно обработать.
При включенном множественном выборе в процедуру ОбработкаВыбора придет не одно значение, а Массив. Проанализируем пример кода, который универсально обрабатывает и одиночный выбор, и массив:
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
МассивЗначений = Новый Массив;
Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда
МассивЗначений = ВыбранноеЗначение;
Иначе
МассивЗначений.Добавить(ВыбранноеЗначение);
КонецЕсли;
Для Каждого ЭлементИзСписка Из МассивЗначений Цикл
// Обработка каждого выбранного элемента
// Если это ссылка - добавляем строку и заполняем
// Если это структура - вынимаем данные из полей структуры
КонецЦикла;
КонецПроцедуры
Важный момент, который часто упускают начинающие разработчики: минимизация серверных вызовов. Если в форме выбора нет колонки "Оклад", и вам приходится получать его из базы в момент подбора, делайте это правильно.
Не вызывайте сервер в цикле для каждого сотрудника. Вместо этого:
ВыбранноеЗначение.ГДЕ Ссылка В (&МассивСсылок)) получите все оклады сразу.Использование функции БСП ОбщегоНазначения.ЗначенияРеквизитовОбъектов() также является отличным способом быстро получить данные нескольких объектов за один вызов.
В типовых решениях (например, УПП, ERP или ЗУП) "Подбор" — это не просто форма справочника, а полноценная Обработка. Она обычно разделена на две части: список доступных элементов и "корзину" внизу формы. Пользователь "накидывает" сотрудников в корзину, может там же отредактировать количество или суммы, и только по кнопке "Перенести в документ" данные передаются в форму-владелец. Это наиболее эргономичный вариант для сложных документов, так как он позволяет визуально контролировать состав подбора до момента изменения данных в документе.
Таким образом, для создания качественного механизма подбора нам необходимо комбинировать правильную передачу параметров открытия формы (ЗакрыватьПриВыборе, МножественныйВыбор) и грамотную обработку результата в событии ОбработкаВыбора.