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