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