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

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Понятие режима выбора и его ключевые свойства

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

  1. РежимВыбора (ChoiceMode): Это булево свойство. Если оно установлено в значение Истина, форма понимает, что ее открыли для того, чтобы пользователь что-то выбрал. Это влияет на поведение стандартных обработчиков.
  2. ЗакрыватьПриВыборе (CloseOnChoice): Если вы реализуете множественный подбор (когда пользователь выбирает несколько товаров подряд, не закрывая окно), это свойство обязательно нужно установить в значение Ложь.

Разберем, где найти эти настройки. В конфигураторе, открыв вашу форму, перейдите в палитру свойств (F4). В разделе "Использование" вы увидите эти флаги. Однако опытные разработчики предпочитают контролировать это программно при открытии формы, чтобы гарантировать правильное поведение в разных контекстах.

Программное открытие формы подбора

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

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

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

Посмотрим на пример кода открытия формы из документа:


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

Здесь ЭтаФорма передается вторым параметром — это и есть назначение владельца. Без этого вызов методов оповещения не достигнет цели.

Реализация передачи данных через ОповеститьОВыборе

Когда пользователь выполняет действие в форме подбора (например, двойной клик по строке списка), нам нужно передать данные обратно. Основным инструментом здесь выступает метод ОповеститьОВыборе(). Разберем по шагам, как это реализовать в модуле вашей формы подбора.

Предположим, у вас есть элемент управления ТабличноеПоле, в котором отображаются данные. Нам нужно создать обработчик события Выбор:


Процедура ТабличноеПолеВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
    
    // Отменяем стандартное действие платформы
    СтандартнаяОбработка = Ложь;
    
    // Формируем данные, которые хотим передать. 
    // Это может быть просто ссылка или целая структура данных.
    ВыбранноеЗначение = ВыбраннаяСтрока.Ссылка;
    
    // Самый важный метод:
    ЭтаФорма.ОповеститьОВыборе(ВыбранноеЗначение);
    
КонецПроцедуры

Проанализируем ситуацию: метод ОповеститьОВыборе посылает сигнал владельцу формы. В форме документа-владельца при этом автоматически срабатывает событие ОбработкаВыбора.

Передача сложных структур данных

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

Рассмотрим пример формирования сложного результата:


ДанныеДляДокумента = Новый Структура;
ДанныеДляДокумента.Вставить("Номенклатура", ТекущаяСтрока.Номенклатура);
ДанныеДляДокумента.Вставить("Характеристика", ТекущаяСтрока.Характеристика);
ДанныеДляДокумента.Вставить("Цена", ТекущаяСтрока.Цена);
ДанныеДляДокумента.Вставить("Количество", 1); // Значение по умолчанию

ОповеститьОВыборе(ДанныеДляДокумента);

Теперь в документе, в процедуре ОбработкаВыбора, мы получим не ссылку, а этот объект Структура, что позволит мгновенно заполнить строку табличной части.

Обработка результата в документе

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


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

Альтернативный метод: Глобальное оповещение

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

В форме подбора мы пишем:

Оповестить("ТоварВыбранВПодборе", ДанныеТовара);

А в форме документа создаем обработчик ОбработкаОповещения:


Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ТоварВыбранВПодборе" Тогда
        // Обрабатываем данные из переменной Параметр
    КонецЕсли;
КонецПроцедуры

Этот способ считается более гибким, так как позволяет передавать данные сразу в несколько открытых окон, если они "подписаны" на это событие. Однако для стандартного подбора в УТ 10.3 чаще всего используется именно ОповеститьОВыборе, так как это штатный механизм взаимодействия с владельцем формы.

Важные нюансы оптимизации

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

Соблюдение этих правил позволит создать отзывчивый и удобный инструмент для пользователей, который будет работать так же стабильно, как и типовые механизмы системы 1С.

← На главную