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