Разработка и Конфигурация · 13 мин
Как передать выбранное значение в другую форму 1С
Как передать выбранное значение в другую форму 1С: параметры формы, ОповеститьОВыборе, обработка выбора, передача через структуру. Примеры кода и типичные ошибки.
Передача выбранного значения из одной формы в другую — одна из базовых задач при разработке на платформе 1С:Предприятие. Типичный сценарий: пользователь открывает форму выбора справочника, отмечает элемент, и это значение должно попасть в поле исходной формы, в табличную часть документа или в параметр отчёта. Платформа предлагает несколько штатных механизмов для этого, и выбор конкретного зависит от того, как открывается форма и кто является получателем данных.
Основные способы передачи: стандартный механизм выбора через ОповеститьОВыборе, обработчик ОбработкаВыбора на стороне получателя, передача параметров при открытии формы и использование метода Оповестить для произвольного обмена данными между открытыми формами. Каждый вариант имеет свои условия применения и ограничения.
Важно понимать разницу между двумя направлениями передачи: данные можно передать в открываемую форму (через параметры при открытии) и из открытой формы обратно (через оповещение о выборе или закрытие с возвратом значения). В статье разобраны оба направления с примерами кода для управляемых форм.
Как устроен механизм выбора в управляемых формах
В управляемом приложении формы не имеют прямого доступа к реквизитам друг друга — клиентский контекст каждой формы изолирован. Поэтому прямое присваивание вида Форма2.Реквизит = Значение между формами невозможно. Вместо этого платформа использует асинхронную модель обмена: одна форма генерирует событие (оповещение), а другая — обрабатывает его в специальном обработчике.
Стандартная цепочка выбора выглядит так: поле ввода связано с данными ссылочного типа, пользователь нажимает кнопку выбора, открывается форма выбора с установленным свойством РежимВыбора = Истина, при двойном щелчке или нажатии «Выбрать» платформа сама формирует оповещение о выборе, и поле ввода получает значение без единой строки кода. Ручная работа требуется, когда стандартной цепочки недостаточно — например, нужно передать не одно значение, а структуру данных, или выбор происходит из нестандартной формы.
Передача значения через ОповеститьОВыборе
Самый распространённый способ вернуть значение из формы выбора — вызвать в ней метод ОповеститьОВыборе(ВыбранноеЗначение). Этот метод доступен только в форме, открытой в режиме выбора или как подчинённая другой форме/элементу. После вызова платформа передаёт значение владельцу формы.
Пример кода в форме выбора (например, в обработчике команды «Выбрать»):
&НаКлиенте
Процедура Выбрать(Команда)
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ОповеститьОВыборе(ТекущиеДанные.Ссылка);
КонецПроцедуры
На стороне формы-получателя нужно добавить обработчик события ОбработкаВыбора. Он вызывается автоматически, когда подчинённая форма сообщает о выборе:
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда
Объект.Номенклатура = ВыбранноеЗначение;
Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Проверка типа значения важна: одна форма может получать оповещения от нескольких форм выбора, и без фильтрации значение попадёт не в тот реквизит. Дополнительно можно анализировать параметр ИсточникВыбора, чтобы различать отправителей.
Передача значения через Закрыть с возвратом результата
Альтернативный подход — открыть форму модально (блокируя владельца) и вернуть значение при закрытии. Для этого форму открывают методом ОткрытьФорму с передачей описания оповещения, которое сработает после закрытия:
&НаКлиенте
Процедура ПодборНажатие(Команда)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораКонтрагента", ЭтотОбъект);
ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , ,
ОписаниеОповещения, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораКонтрагента(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
Объект.Контрагент = Результат;
КонецЕсли;
КонецПроцедуры
В форме выбора достаточно при закрытии передать значение: Закрыть(ВыбраннаяСсылка). Если форма закрыта крестиком или по Escape, в обработчик придёт Неопределено — это нужно обязательно проверять, иначе реквизит очистится пустым значением.
Этот способ удобен, когда логика обработки результата должна находиться рядом с местом открытия формы, а не в общем обработчике ОбработкаВыбора. Также он единственный надёжный вариант, когда форма открывается не в режиме выбора, но должна вернуть данные.
Сравнение способов возврата значения
Стандартный механизм, работает с полями ввода автоматически. Требует режима выбора или владельца формы.
Гибкий вариант для любых форм, обработка результата в отдельной процедуре. Требует проверки на Неопределено.
Широковещательное сообщение всем открытым формам. Подходит для обновления списков, но требует фильтрации по имени события.
Передача параметров в открываемую форму
Обратное направление — передать данные в форму при её открытии. Для этого вторым параметром ОткрытьФорму передаётся структура или объект ПараметрыФормы. Значения с ключами, совпадающими с именами параметров формы, попадут в эти параметры и будут доступны в обработчике ПриСозданииНаСервере:
&НаКлиенте
Процедура ОткрытьПодбор(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Организация", Объект.Организация);
ПараметрыФормы.Вставить("ОтборПоСкладу", Объект.Склад);
ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, ЭтотОбъект);
КонецПроцедуры
В открываемой форме параметры объявляются в конфигураторе на закладке «Параметры» формы, либо читаются напрямую из коллекции Параметры в ПриСозданииНаСервере. Ключевой параметр Отбор позволяет передать структуру отбора динамического списка — так форма выбора откроется уже отфильтрованной по нужному условию.
Учтите ограничение: через параметры формы можно передавать только сериализуемые данные — примитивные типы, ссылки, структуры, массивы из них. Таблицу значений или результат запроса напрямую передать нельзя; их нужно преобразовать, например, в массив структур, либо поместить во временное хранилище и передать адрес.
Множественный выбор и передача списка значений
Когда пользователь должен выбрать несколько элементов (подбор товаров в документ), форма выбора открывается с параметрами МножественныйВыбор = Истина и ЗакрыватьПриВыборе = Ложь. Тогда при каждом выборе форма остаётся открытой, а в форму-владельца приходят оповещения по одному значению или массивом — в зависимости от настроек.
Обработчик на стороне документа должен уметь принимать массив и добавлять строки в табличную часть:
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда
Для Каждого Элемент Из ВыбранноеЗначение Цикл
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = Элемент;
КонецЦикла;
Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Практический нюанс: добавление строк табличной части в клиентском обработчике допустимо, но если при добавлении нужен расчёт цен, остатков или других серверных данных — вызывайте серверную процедуру, передавая ей массив выбранных ссылок. Это сократит число серверных вызовов по сравнению с обработкой каждой строки отдельно.
- 1Определите направление: в открываемую форму (параметры) или обратно (оповещение о выборе)
- 2Для возврата значения откройте форму с указанием владельца или в режиме выбора
- 3В форме выбора вызовите ОповеститьОВыборе(Значение) или Закрыть(Значение)
- 4В форме-получателе добавьте ОбработкаВыбора с проверкой типа значения
- 5Протестируйте сценарий, включая отмену выбора и закрытие формы без выбора
Передача данных между независимыми формами через Оповестить
Если формы не связаны отношением «владелец — подчинённая» (например, нужно обновить открытый список документов после записи элемента в отдельном окне), используется метод Оповестить(ИмяСобытия, Параметр, Источник). Это широковещательное сообщение: его получают все открытые формы, у которых есть обработчик ОбработкаОповещения.
// Отправитель
Оповестить("ЗаписанКонтрагент", КонтрагентСсылка, ЭтотОбъект);
// Получатель
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ЗаписанКонтрагент" Тогда
Элементы.Список.Обновить();
КонецЕсли;
КонецПроцедуры
Имя события — произвольная строка, и именно она служит фильтром. Выбирайте уникальные осмысленные имена, чтобы не пересечься с системными событиями платформы (например, Запись_Номенклатура — системное). Для стандартных случаев есть готовые события: ОповеститьОбИзменении(Ссылка) заставит все открытые формы, показывающие этот объект, обновиться автоматически.
Проверка результата и типичные ошибки
После внедрения механизма проверьте полный цикл: открытие формы выбора, выбор значения, отмену выбора, повторный выбор другого значения, закрытие формы крестиком. Каждый сценарий должен давать предсказуемый результат — либо заполнение реквизита, либо отсутствие изменений.
Отдельная группа проблем связана с обычными (неуправляемыми) формами в старых конфигурациях: там механизм другой — используются ОповеститьОВыборе совместно с обработчиком ОбработкаВыбора у поля ввода, а модальное открытие через ОткрытьМодально напрямую возвращает значение. При смешении подходов в одной конфигурации легко запутаться, поэтому сверяйтесь с режимом совместимости прикладного решения.
Что важно запомнить
Для возврата выбранного значения используйте ОповеститьОВыборе + ОбработкаВыбора либо Закрыть(Значение) + ОписаниеОповещения. Для передачи данных в открываемую форму — структуру параметров. Всегда проверяйте тип значения и случай отмены выбора, а объёмные данные передавайте через временное хранилище.
Частые вопросы
Почему ОповеститьОВыборе не срабатывает и обработчик не вызывается?
Чаще всего форма выбора открыта без указания владельца и не в режиме выбора — у неё просто нет получателя оповещения. Проверьте, что при ОткрытьФорму третьим параметром передан владелец (форма или элемент), либо открывайте форму штатно из поля ввода. Также убедитесь, что обработчик ОбработкаВыбора назначен именно форме, а не элементу.
Как передать в другую форму сразу несколько значений разных типов?
Соберите значения в структуру и передайте её одним параметром: ОповеститьОВыборе(СтруктураДанных) или Закрыть(СтруктураДанных). На стороне получателя проверьте ТипЗнч(ВыбранноеЗначение) = Тип("Структура") и извлеките поля по ключам. Для надёжности добавьте в структуру служебный ключ-идентификатор, чтобы отличать это сообщение от других.
Можно ли передать таблицу значений в другую форму?
Напрямую через параметры формы — нет, таблица значений не сериализуется. Варианты: преобразовать таблицу в массив структур и передать его, либо поместить таблицу во временное хранилище на сервере (ПоместитьВоВременноеХранилище) и передать в форму только адрес хранилища, где данные будут загружены обратно.
Чем отличается ОбработкаВыбора от ОбработкаОповещения?
ОбработкаВыбора вызывается только при оповещении о выборе от подчинённой формы (ОповеститьОВыборе или штатный выбор в поле ввода) и получает значение и источник. ОбработкаОповещения реагирует на широковещательные сообщения Оповестить от любых форм и фильтрует их по имени события. Для возврата выбранного значения правильнее первый обработчик.
Как открыть форму выбора уже отфильтрованной по текущему значению?
Передайте в параметрах формы ключ Отбор со структурой отбора, например: ПараметрыФормы.Вставить("Отбор", Новый Структура("Владелец", Объект.Контрагент)). Динамический список формы выбора применит отбор автоматически. Дополнительно можно передать ТекущаяСтрока, чтобы курсор встал на нужный элемент.
Работает ли этот механизм в обычных формах (толстый клиент)?
Да, но с отличиями: в обычных формах ОбработкаВыбора часто назначается элементу формы (полю ввода), а модальное открытие через ОткрытьМодально возвращает значение напрямую, без описания оповещения. При переходе на управляемые формы такой код требует переработки, так как модальные вызовы в управляемом приложении запрещены по умолчанию.