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

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

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

Анализ типичных ошибок при вызове формы выбора

Рассмотрим распространенную ситуацию. Разработчик пытается открыть форму выбора направления и в качестве владельца формы передает результат метода Добавить() табличной части:


// Ошибочный вариант вызова:
ОткрытьФорму("Документ.Случай.Форма.ФормаВыбораНаправления", , Объект.Назначения.Добавить());

Затем в форме выбора формируется структура с данными и вызывается метод ОповеститьОВыборе:


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

ОповеститьОВыборе(Выбор);

В такой схеме данные не попадают в строку документа. Выясним основные причины:

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

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

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

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

Передаем текущую форму в качестве владельца:


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

Шаг 2. Отправка результата из формы выбора

В форме выбора формируем структуру параметров и оповещаем владельца:


&НаКлиенте
Процедура ЗавершитьВыбор(Команда)
    
    Выбор = Новый Структура;
    Выбор.Вставить("ВидОбследования", НазначенияВидОбследования);
    Выбор.Вставить("ПрофильКойкиПриРеабилитации", НазначенияПрофильКойкиПриРеабилитации);
    Выбор.Вставить("ПрофильМедицинскойПомощи", НазначенияПрофильМедицинскойПомощи);
    Выбор.Вставить("СпециальностьВрача", НазначенияСпециальностьВрача);
    
    ОповеститьОВыборе(Выбор);
    
КонецПроцедуры

Шаг 3. Обработка выбранного значения в форме документа

В модуле формы документа создаем обработчик предопределенного события формы ОбработкаВыбора. Чтобы быстро перенести все поля из структуры в реквизиты строки, используем метод ЗаполнитьЗначенияСвойств:


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

Способ 2. Использование асинхронного описания оповещения (рекомендуемый)

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

Посмотрим на пример реализации с передачей идентификатора созданной строки:

В вызывающей форме:


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

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

В форме выбора:

В этом случае при подтверждении ввода достаточно вызвать Закрыть(Выбор) или ОповеститьОВыборе(Выбор) — переданная структура автоматически поступит в первый параметр процедуры-обработчика РезультатВыбора.

Альтернативные подходы без создания отдельной формы

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

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