Как передать данные из вспомогательной формы обратно в форму документа в 1С:УПП

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

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

Почему метод ОткрытьМодально() возвращает Неопределенность

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


Процедура ТоварыСтатьиДДСНачалоВыбора(Элемент, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Форма = ПолучитьФорму("ОбщаяФорма.СКС_СтатьиДДС",, Элемент);
    Результат = Форма.ОткрытьМодально();
КонецПроцедуры

Метод ОткрытьМодально() возвращает значение Неопределенность в следующих случаях:

  1. Форма закрыта пользователем с помощью стандартной кнопки с крестиком или системной комбинации клавиш, когда значение закрытия не передавалось.
  2. В коде вспомогательной формы вызван метод ЭтаФорма.Закрыть() без передачи возвращаемого параметра.
  3. Для кнопок на форме не переопределены стандартные действия закрытия.

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

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


Процедура КнопкаОКНажатие(Элемент)
    // Формируем результат, например, таблицу значений или структуру
    РезультатВыбора = Новый Структура("СтатьяДДС, Процент", Статья, ПроцентИспользования);
    
    // Закрываем форму с передачей значения
    ЭтаФорма.Закрыть(РезультатВыбора);
КонецПроцедуры

В форме документа принимаем переданное значение и заполняем текущую строку табличной части:


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

Способ 2. Использование метода ОповеститьОВыборе

Разберем стандартный механизм платформы 1С для форм подбора и выбора. Метод ОповеститьОВыборе() закрывает открытую форму и вызывает событие ОбработкаВыбора у владельца формы.

В коде открытия формы документа передаем элемент управления табличного поля третьим параметром функции ПолучитьФорму:


Процедура ТоварыСтатьиДДСНачалоВыбора(Элемент, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    Форма = ПолучитьФорму("ОбщаяФорма.СКС_СтатьиДДС",, Элемент);
    Форма.Открыть();
КонецПроцедуры

Во вспомогательной форме при завершении выбора вызываем:


Процедура КнопкаВыбратьНажатие(Элемент)
    ОповеститьОВыборе(СформированныеДанные);
КонецПроцедуры

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


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

Способ 3. Передача данных через глобальное оповещение

Посмотрим на универсальный механизм обмена данными между не связанными напрямую формами с помощью метода Оповестить().

Во вспомогательной форме отправляем оповещение и закрываем окно:


Процедура КнопкаПрименитьНажатие(Элемент)
    Оповестить("ЗаполненыСтатьиДДС", ТаблицаРаспределения, ЭтаФорма);
    ЭтаФорма.Закрыть();
КонецПроцедуры

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


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

Способ 4. Прямое обращение через свойство ВладелецФормы

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


// Во вспомогательной форме:
Процедура КнопкаСохранитьНажатие(Элемент)
    Если ВладелецФормы <> Неопределенность Тогда
        ВладелецФормы.ОбновитьДанныеПоСтатьям(ТаблицаДанных);
    КонецЕсли;
    ЭтаФорма.Закрыть();
КонецПроцедуры

Особенности хранения сложных структур в табличной части

Важно учитывать: реквизит табличной части документа в 1С не может иметь тип ТаблицаЗначений или СписокЗначений для постоянного сохранения в базе данных.

Если по одной строке требуется хранить несколько записей (распределение по статьям и процентам), применяются следующие подходы:

  1. Сериализация набора данных в строку (например, XML или JSON) и сохранение в строковый реквизит или реквизит с типом ХранилищеЗначения.
  2. Использование подчиненного регистра сведений, связанного с документом и номером строки.
  3. Создание отдельной дополнительной табличной части документа с колонками для связи с основной строкой.
← На главную