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

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

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

Почему выполнение кода не останавливается при открытии формы?

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

Следовательно, попытка написать код в одну процедуру «открыл — получил — обработал» без специальных инструментов приведет к тому, что обработка начнется до того, как пользователь успеет что-то выбрать. Для этой задачи есть инструмент для отладки кода на управляемых формах.

Способ 1: Использование ОписанияОповещения (Классический метод)

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

Рассмотрим по шагам, как это реализовать:

  1. Создаем объект ОписаниеОповещения, указывая процедуру, которая должна выполниться ПОСЛЕ закрытия формы.
  2. Передаем этот объект в метод открытия формы или назначаем свойству формы ОписаниеОповещенияОЗакрытии.
  3. В вызываемой форме обеспечиваем возврат значения через метод Закрыть().

Пример кода в вызывающей форме:


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

&НаКлиенте
Процедура ПослеВыбораТипаФайла(Результат, ДополнительныеПараметры) Экспорт
    
    // Сюда управление попадет только после того, как форма закроется
    Если Результат <> Неопределено Тогда
        Сообщить("Пользователь выбрал: " + Результат);
        // Здесь продолжаем логику создания элемента справочника
    КонецЕсли;
    
КонецПроцедуры

В самой общей форме (которую открываем) обязательно должен быть код возврата:


&НаКлиенте
Процедура ВыбратьИЗакрыть(Команда)
    РезультатВыбора = "Тип_PDF"; // Условно выбранное значение
    Закрыть(РезультатВыбора); // Параметр попадет в 'Результат' обработчика
КонецПроцедуры

Способ 2: Современный подход через Асинхронные функции (платформа 8.3.18+)

Если ваша конфигурация работает на платформе версии 8.3.18 и выше, мы можем использовать механизмы Асинх и Ждать. Это позволяет писать код, который выглядит синхронно, но работает по асинхронным правилам. Это значительно упрощает чтение кода, так как логика не "разрывается" на разные процедуры.

Выясним, как это работает на практике:


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

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

Способ 3: Механизм «ОбработкаВыбора» через владельца

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

  1. При открытии формы в параметре Владелец передаем текущую форму или конкретный элемент управления.
  2. В вызываемой форме используем метод ОповеститьОВыборе(Значение).
  3. В вызывающей форме переопределяем событие ОбработкаВыбора.

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

Как не потерять контекст при возврате значения?

Частая проблема: в первой процедуре у нас были локальные переменные, данные которых нужны во второй процедуре (обработчике оповещения). Так как это разные процедуры, локальные переменные первой будут очищены. Чтобы этого избежать, используйте третий параметр конструктора ОписаниеОповещения.

Посмотрим на пример передачи структуры данных:


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

&НаКлиенте
Процедура ЗавершениеРаботы(Результат, ДополнительныеПараметры) Экспорт
    // ДополнительныеПараметры — это и есть наша структура "Контекст"
    Имя = ДополнительныеПараметры.ИмяОбъекта; 
    // Теперь у нас есть доступ к данным, которые были в первой процедуре
КонецПроцедуры

Разница между Закрыть() и ОповеститьОВыборе()

Многие разработчики путают эти методы. Выясним разницу:

Рекомендации по реализации в Общих формах

При создании собственной ОбщейФормы, предназначенной для возврата значения, убедитесь, что:

  1. У формы нет жестких привязок к конкретным объектам (она универсальна).
  2. В коде формы на кнопках "ОК" или "Выбрать" прописан вызов Закрыть(ВыбранноеЗначение).
  3. Если форма предполагает выбор из списка, свойство РежимВыбора установлено в значение Истина, либо логика выбора прописана вручную.

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

← На главную