К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как узнать, откуда открыта форма выбора в 1С

Способы определить, откуда открыта форма выбора в 1С: ВладелецФормы, УникальныйИдентификатор, ОповещениеОВыборе, параметры формы и отладчик. Примеры кода.

Когда одна и та же форма выбора справочника или документа открывается из разных мест конфигурации — из поля ввода документа, из обработки, из другой формы списка — часто требуется понять, кто именно её открыл. Это нужно, чтобы вернуть выбранное значение именно туда, откуда пришёл вызов, применить нужный отбор или изменить поведение формы в зависимости от источника.

В платформе 1С:Предприятие 8.3 для этого есть несколько штатных механизмов: свойство ВладелецФормы, параметр УникальныйИдентификатор, передача произвольных параметров при открытии и анализ стека вызовов в отладчике. Ниже разобраны все подходы — от самого простого к универсальному.

Почему форме выбора важно знать своего «родителя»

Форма выбора в 1С редко существует сама по себе. Обычно она открывается в контексте какой-то задачи: пользователь подбирает контрагента в документ, выбирает номенклатуру в обработке загрузки прайса или указывает склад в отчёте. От источника зависит, какой отбор установить, какие колонки показать и куда вернуть результат.

Если источник не определён, типичные проблемы такие: выбранное значение «теряется» и не попадает в нужное поле, срабатывает обработчик выбора не той формы, либо одна и та же форма выбора ведёт себя одинаково там, где требуется разное поведение. Поэтому первый шаг при доработке — надёжно определить, откуда пришёл вызов.

Способ 1. Свойство ВладелецФормы

Когда форма выбора открывается стандартно — через поле ввода со связью по типу или методом ОткрытьФорму() с указанием владельца — платформа заполняет свойство ВладелецФормы. В модуле формы выбора его можно проанализировать в обработчике ПриСозданииНаСервере или ПриОткрытии.

Проверить тип владельца можно так:

&НаКлиенте

Процедура ПриОткрытии(Отказ)

Если ВладелецФормы <> Неопределено Тогда

ИмяФормыВладельца = ВладелецФормы.ИмяФормы;

// Например: "Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента"

Сообщить("Форма выбора открыта из: " + ИмяФормыВладельца);

Иначе

Сообщить("Владелец не задан — форма открыта без контекста");

КонецЕсли;

КонецПроцедуры

По значению ИмяФормы владельца уже можно строить логику: сравнивать с ожидаемыми именами форм и включать нужный режим. Учтите, что ВладелецФормы может быть как формой целиком, так и элементом формы (полем ввода, таблицей), поэтому перед обращением к свойствам проверяйте, что именно пришло.

Способ 2. Параметр УникальныйИдентификатор

При стандартном открытии формы выбора из поля ввода платформа автоматически передаёт в параметрах формы ключ УникальныйИдентификатор — это уникальный идентификатор формы-владельца. По нему можно понять, из какого именно экземпляра формы пришёл вызов, даже если открыто несколько одинаковых документов.

Проверка в модуле формы выбора:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("УникальныйИдентификатор") Тогда

ИдентификаторИсточника = Параметры.УникальныйИдентификатор;

// Можно сравнить с известным идентификатором формы

КонецЕсли;

КонецПроцедуры

Этот способ особенно полезен в обработчике ОбработкаВыбора формы-источника: там можно сравнить Параметры.УникальныйИдентификатор из оповещения с собственным УникальныйИдентификатор формы и понять, что выбор адресован именно ей, а не другой открытой копии того же документа.

Способ 3. Собственные параметры при открытии формы

Самый надёжный и управляемый вариант — явно передавать признак источника через структуру параметров. Тогда форма выбора не зависит от того, как именно её открыли, и логика не ломается при добавлении новых мест вызова.

// В месте вызова (например, в форме документа)

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("РежимВыбора", Истина);

ПараметрыФормы.Вставить("ИсточникВызова", "ДокументРеализация_ТабЧастьТовары");

ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, ЭтотОбъект);

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Источник = "";

Если Параметры.Свойство("ИсточникВызова", Источник) Тогда

Если Источник = "ДокументРеализация_ТабЧастьТовары" Тогда

// Своя логика: отбор, колонки, заголовок

КонецЕсли;

КонецЕсли;

КонецПроцедуры

Чтобы параметр был доступен в форме, его нужно объявить в редакторе формы на закладке «Параметры» либо анализировать через Параметры.Свойство(). Второй вариант проще при доработках без изменения структуры формы.

Порядок действий
  1. 1
    Откройте модуль формы выбора и найдите обработчик ПриСозданииНаСервере
  2. 2
    Добавьте проверку Параметры.Свойство("ИсточникВызова") или анализ ВладелецФормы
  3. 3
    В местах вызова формы передайте свой параметр-идентификатор источника через структуру параметров
  4. 4
    Проверьте результат: откройте форму из каждого места вызова и убедитесь, что источник определяется правильно
  5. 5
    Обработайте случай, когда источник не определён — задайте поведение по умолчанию

Способ 4. Отладчик и стек вызовов

Если форма открывается из типового кода или места вызова неизвестны, быстрее всего найти источник через отладчик. Поставьте точку останова в обработчике ПриСозданииНаСервере формы выбора, воспроизведите открытие формы и посмотрите стек вызовов (окно «Стек вызовов» в конфигураторе).

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

Дополнительно в отладчике можно посмотреть содержимое Параметры и значение ВладелецФормы через табло — это сразу покажет, что именно платформа передала в форму при конкретном сценарии.

В типовых конфигурациях выбор часто идёт через общие команды и подключаемые обработчики БСП, поэтому прямого вызова ОткрытьФорму в модуле документа может не быть. В таких случаях стек вызовов в отладчике находит реальную точку входа быстрее, чем глобальный поиск по конфигурации.
ПЗ
Практическое замечание

Как вернуть выбранное значение именно источнику

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

Оповещение о выборе

Если форма открыта с владельцем, то при выборе значения платформа вызывает метод ОповеститьОВыборе(), и у формы-владельца срабатывает обработчик ОбработкаВыбора. В нём доступен ИсточникВыбора — ссылка на форму выбора, а значение передаётся параметром:

&НаКлиенте

Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)

Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда

Объект.Номенклатура = ВыбранноеЗначение;

КонецЕсли;

КонецПроцедуры

Описание оповещения

Современный вариант — передавать в ОткрытьФорму() описание оповещения с именем процедуры-обработчика. Тогда не важно, кто владелец формы: результат придёт строго в указанную процедуру. Этот способ предпочтителен, когда одна форма-источник открывает несколько разных форм выбора, и ответы нужно разводить по разным обработчикам.

Сравнение вариантов

ВладелецФормы

Подходит для быстрой диагностики и простых случаев; ограничение — владелец может быть не задан или уже закрыт

УникальныйИдентификатор

Позволяет различить несколько одинаковых открытых форм; ограничение — не говорит, из какого именно элемента или сценария пришёл вызов

Свой параметр в структуре

Самый управляемый способ, работает всегда; ограничение — требует доработки всех мест вызова

Отладчик и стек вызовов

Идеален для поиска неизвестных мест вызова в типовом коде; ограничение — это инструмент анализа, а не механизм для рабочего кода

Типичные ошибки при определении источника

Первая частая ошибка — сравнение ВладелецФормы.ИмяФормы без учёта того, что одна форма может открываться в разных ролях. Если из одной формы документа выбор делается в шапку и в табличную часть, имени формы недостаточно — нужен дополнительный параметр, указывающий целевое поле.

Вторая ошибка — попытка использовать ВладелецФормы на сервере после закрытия формы-владельца. В управляемом приложении контекст владельца живёт ограниченное время; надёжнее при открытии сразу сохранить нужные данные источника в реквизиты формы выбора.

Третья ошибка — обработка выбора не в том обработчике. Если форма выбора открыта с описанием оповещения, а разработчик ждёт результат в ОбработкаВыбора, значение туда не придёт. Механизм возврата определяется тем, как форма была открыта, и это тоже часть ответа на вопрос «откуда открыта форма».

Типичные ошибки
01
Обращение к ВладелецФормы без проверки на Неопределено — ошибка при открытии формы без владельца
02
Сравнение только по ИмяФормы владельца — невозможно различить разные поля одной формы
03
Ожидание результата в ОбработкаВыбора, когда форма открыта с ОписаниеОповещения — выбор не попадает в обработчик
04
Хранение ссылки на владельца вместо копии нужных данных — обращение к закрытой форме вызывает исключение

Как проверить, что источник определяется правильно

После доработки пройдите все сценарии открытия формы выбора: из поля ввода документа, из обработки, из командного интерфейса. В каждом случае выведите диагностическое сообщение или запись в журнал регистрации с определённым источником.

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

Контрольные точки

Как проверить результат

Открытие из поля ввода документа
Норма

Источник определён, выбор возвращается в нужное поле

Тревожный признак

Источник пуст или значение попадает не в тот реквизит

Открытие из обработки или другой формы
Норма

Параметр источника передан и распознан

Тревожный признак

Форма работает в режиме по умолчанию, отборы не применяются

Открытие без контекста
Норма

Форма открывается в штатном режиме без ошибок

Тревожный признак

Ошибка обращения к ВладелецФормы или параметрам

Частые вопросы

Можно ли узнать, из какого именно элемента формы открыта форма выбора?

Да, но не через ВладелецФормы напрямую — он не всегда указывает на конкретный элемент. Надёжный способ — при открытии передавать собственный параметр, например ИмяПоля или ИсточникВызова, и заполнять его в обработчике НачалоВыбора нужного поля.

Почему ВладелецФормы равен Неопределено?

Форма была открыта без указания владельца: из командного интерфейса, методом ОткрытьФорму() без третьего параметра или программно из кода, где владелец не задан. Всегда проверяйте ВладелецФормы на Неопределено перед использованием.

Чем отличается ОбработкаВыбора от ОписаниеОповещения?

ОбработкаВыбора — стандартный обработчик формы-владельца, срабатывает при ОповеститьОВыборе(). ОписаниеОповещения — явно переданный обработчик, который вызывается при закрытии формы выбора. Второй способ гибче: позволяет назначить разные обработчики для разных форм выбора из одной формы-источника.

Как найти все места, откуда открывается конкретная форма выбора?

Используйте глобальный поиск по конфигурации (Ctrl+Shift+F) по имени формы, например "Справочник.Номенклатура.ФормаВыбора". Учтите, что стандартные вызовы из полей ввода поиск не покажет — их видно только в отладчике через стек вызовов.

Работает ли ВладелецФормы в обычном приложении?

В обычных формах есть аналогичное свойство ВладелецФормы, и принцип тот же. Однако механизм оповещений там отличается: вместо ОписаниеОповещения используется ОповеститьОВыборе и обработчик ОбработкаВыбора у формы-владельца.

Можно ли запретить открытие формы выбора из «чужого» источника?

Да. В ПриСозданииНаСервере проверьте параметр источника или ВладелецФормы и при несоответствии ожиданиям установите Отказ = Истина. При этом предусмотрите понятное сообщение пользователю, иначе форма просто не откроется без объяснений.

Итог

Что важно запомнить

Источник открытия формы выбора определяется через ВладелецФормы, параметр УникальныйИдентификатор или собственный параметр в структуре при вызове ОткрытьФорму. Самый надёжный путь — явная передача параметра-идентификатора источника; для поиска неизвестных мест вызова используйте стек вызовов в отладчике. Всегда обрабатывайте случай открытия формы без контекста.