Как реализовать механизм подбора в 1С: передача нескольких значений и работа без закрытия формы

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

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

Почему форма подбора закрывается автоматически и как это исправить

Рассмотрим ситуацию: вы прописали параметр ЗакрыватьПриВыборе = Ложь, но форма все равно закрывается. Давайте проанализируем возможные причины. В управляемых формах 1С 8.3 за это поведение отвечает структура параметров, передаваемая при открытии формы. Типичный код открытия выглядит так:


ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);
ПараметрыФормы.Вставить("МножественныйВыбор", Истина); // Если нужно выбирать сразу нескольких
ОткрытьФорму("Справочник.Сотрудники.ФормаВыбора", ПараметрыФормы, ЭтаФорма);

Если форма все равно закрывается, проверьте следующие моменты:

  1. Свойство таблицы в форме выбора: Перейдите в форму выбора справочника. У элемента "Список" (динамический список) проверьте свойство ИмяКомандыВыбора. Если там указана стандартная команда, она может игнорировать программные установки.
  2. Режим выбора: Убедитесь, что в форме, которую вы открываете, не прописан жесткий отказ от множественного выбора в коде ПриСозданииНаСервере.
  3. Версия платформы и тип форм: Помните, что работа с параметрами в Структура характерна для Управляемых форм. Если вы работаете в старом интерфейсе (Обычные формы), свойство устанавливается напрямую у объекта формы: Форма.ЗакрыватьПриВыборе = Ложь;.

Передача дополнительных данных (оклад, подразделение и др.)

Часто возникает вопрос: как вместе с сотрудником сразу получить его оклад, чтобы не делать лишних запросов к базе данных? Рассмотрим два подхода: "ленивый" и "профессиональный".

Ленивый способ: Получение данных в обработчике ПриИзменении в самом документе. Это кажется простым, но это плохая практика. Каждый раз, когда вы добавляете строку, система будет делать отдельный вызов к серверу, чтобы вытащить оклад. Если сотрудников в подборе много, форма начнет "подтормаживать".

Профессиональный способ: Переопределение события выбора в справочнике. Разберем его по шагам:

Шаг 1. В форме выбора справочника "Сотрудники" создадим событие СписокВыбор (или ПередЗавершениемВыбора). Вместо стандартного возврата ссылки, мы сформируем структуру со всеми нужными данными:


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

Шаг 2. Теперь в форме документа нужно правильно принять эти данные. Используем обработчик ОбработкаВыбора:


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

Реализация множественного выбора (Mass Selection)

Если пользователю нужно выбрать сразу 10-20 сотрудников, нажимать на каждого по отдельности неудобно. Для этого в 1С предусмотрен параметр МножественныйВыбор. Выясним, как его правильно обработать.

При включенном множественном выборе в процедуру ОбработкаВыбора придет не одно значение, а Массив. Проанализируем пример кода, который универсально обрабатывает и одиночный выбор, и массив:


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

Оптимизация производительности: работа с серверным контекстом

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

Не вызывайте сервер в цикле для каждого сотрудника. Вместо этого:

  1. Соберите все ссылки из массива ВыбранноеЗначение.
  2. Передайте весь массив на сервер в одну функцию.
  3. На сервере одним запросом (используя конструкцию ГДЕ Ссылка В (&МассивСсылок)) получите все оклады сразу.
  4. Верните таблицу значений или массив структур обратно на клиент и заполните документ.

Использование функции БСП ОбщегоНазначения.ЗначенияРеквизитовОбъектов() также является отличным способом быстро получить данные нескольких объектов за один вызов.

Альтернатива: Использование специализированной обработки

В типовых решениях (например, УПП, ERP или ЗУП) "Подбор" — это не просто форма справочника, а полноценная Обработка. Она обычно разделена на две части: список доступных элементов и "корзину" внизу формы. Пользователь "накидывает" сотрудников в корзину, может там же отредактировать количество или суммы, и только по кнопке "Перенести в документ" данные передаются в форму-владелец. Это наиболее эргономичный вариант для сложных документов, так как он позволяет визуально контролировать состав подбора до момента изменения данных в документе.

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

← На главную