Почему не срабатывает ОповеститьОВыборе при подборе номенклатуры в 1С?

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

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

Анализ проблемы: как работает механизм оповещения о выборе

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

Рассмотрим типовые ошибки, которые приводят к сбою передачи данных:

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

Вариант 1. Назначение владельцем табличного поля документа (рекомендуемый подход)

Разберем классическую схему, когда форма подбора открывается с указанием конкретного табличного поля в качестве владельца.

Шаг 1. Открытие формы подбора из документа

В модуле формы документа при нажатии на кнопку командной панели открываем форму подбора и передаем табличное поле ЭлементыФормы.Товары вторым параметром:


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

Шаг 2. Формирование структуры данных и отправка выбора

В форме подбора при выборе строки списка (или после модального ввода количества) вызываем стандартный метод ОповеститьОВыборе:


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

Шаг 3. Обработка полученных данных в документе

В свойствах табличного поля Товары в строке события ОбработкаВыбора привязываем процедуру ТоварыОбработкаВыбора:


Процедура ТоварыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    
    СтрокаТЧ = Товары.Добавить();
    СтрокаТЧ.Номенклатура = ВыбранноеЗначение.Номенклатура;
    СтрокаТЧ.ЕдиницаИзмерения = ВыбранноеЗначение.ЕдиницаИзмерения;
    СтрокаТЧ.Количество = ВыбранноеЗначение.Количество;
    СтрокаТЧ.Цена = УзнатьЦену(СтрокаТЧ);
    СтрокаТЧ.Сумма = СтрокаТЧ.Цена * СтрокаТЧ.Количество;
    
КонецПроцедуры

Вариант 2. Назначение владельцем самой формы документа

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

При открытии передаем форму:


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

В модуле формы документа описываем стандартную процедуру события формы ОбработкаВыбора:


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

Нюансы работы с модальными окнами ввода количества

Если в процессе подбора открывается дополнительное окно для запроса количества, цены или коэффициента, необходимо помнить о правилах возврата значений:

  1. Метод Форма.ОткрытьМодально() возвращает значение только в том случае, если форма закрывается с передачей параметра: ЭтаФорма.Закрыть(СтруктураДанных).
  2. Если пользователь закрыл окно крестиком или нажатием кнопки «Отмена», функция вернет Неопределено. Поэтому перед вызовом ОповеститьОВыборе обязательно проверяем результат на заполненность:

ФормаВвода = ПолучитьФорму("ФормаВводаПараметров");
ФормаВвода.Номенклатура = ТекСтрока.Ссылка;
СтруктураДанных = ФормаВвода.ОткрытьМодально();

Если СтруктураДанных <> Неопределено Тогда
    ОповеститьОВыборе(СтруктураДанных);
КонецЕсли;

Соблюдение соответствия между переданным объектом-владельцем и обработчиком события гарантирует безошибочную передачу данных из подбора в табличную часть.

← На главную