В процессе разработки интерфейсов на платформе 1С:Предприятие 8.3 (особенно в решениях для розничной торговли, таких как РМК — рабочее место кассира), программисты часто сталкиваются с необходимостью не просто открыть форму, а переключиться на уже существующее окно. На первый взгляд, стандартный метод ОткрытьФорму с передачей идентификатора должен решать эту задачу, но на практике возникают нюансы, когда система вместо активации старого окна открывает новое.
В этой статье мы подробно разберем, почему так происходит, проанализируем механизм работы КлючаУникальности и изучим способы гарантированной активации нужного окна приложения.
Рассмотрим классическую ситуацию: у нас есть открытая форма документа (например, ЧекККМ). Мы пытаемся найти её идентификатор через перебор окон и снова вызвать ОткрытьФорму, ожидая, что система просто «поднимет» окно на передний план. Однако, как только документ в этой форме записывается (что неизбежно происходит при пробитии чека), старый механизм поиска перестает работать.
Проанализируем причину этого поведения. В управляемом приложении 1С для форм документов существует стандартная логика: если при открытии формы не был явно указан КлючУникальности, платформа автоматически использует Ссылку документа в качестве этого ключа.
Записать() или объект записывается программно, у документа появляется уникальная ссылка в базе данных.В итоге, если ваш код ищет форму по старому УникальномуИдентификатору или пустому ключу, 1С не находит совпадений и открывает абсолютно новое окно. Рассмотрим, как это исправить.
Для таких форм, как РМК, которые должны существовать в единственном экземпляре в течение всего сеанса работы пользователя, самым надежным способом является использование жестко заданного строкового ключа. Это гарантирует, что форма будет найдена системой независимо от того, какой объект в ней сейчас редактируется и был ли он записан.
Рассмотрим пример кода для открытия формы со стабильным ключом:
&НаКлиенте
Процедура ОткрытьРМК(Команда)
// Задаем произвольную уникальную строку для идентификации нашего окна
КлючУникальностиРМК = "МоеУникальноеРабочееМестоКассира";
// Параметры формы (если нужны)
ПараметрыФормы = Новый Структура;
// При вызове ОткрытьФорму платформа сначала проверит,
// нет ли уже открытой формы с таким КлючомУникальности
ОткрытьФорму("Документ.ЧекККМ.Форма.ФормаДокумента_РМК", ПараметрыФормы, , КлючУникальностиРМК);
КонецПроцедуры
При таком подходе даже после вызова ЗначениеВДанныеФормы или записи документа, повторный вызов ОткрытьФорму с тем же ключом "МоеУникальноеРабочееМестоКассира" просто активирует уже открытое окно.
Если по каким-то причинам вы не можете заранее задать ключ уникальности (например, работаете с типовой конфигурацией без возможности её изменения), можно воспользоваться методом перебора всех открытых окон приложения. Выясним, как правильно реализовать этот поиск.
Основная ошибка многих разработчиков заключается в попытке достать идентификатор из найденного окна и снова передать его в ОткрытьФорму. Вместо этого следует использовать встроенный метод окна Активизировать(). Разберем по шагам правильный алгоритм:
&НаКлиенте
Процедура АктивизироватьОкноРМК()
ИмяНужнойФормы = "Документ.ЧекККМ.Форма.ФормаДокумента_РМК";
ВсеОкна = ПолучитьОкна();
Для Каждого ТекущееОкно Из ВсеОкна Цикл
// Проверяем, что окно не пустое и в нем есть содержимое
Если ТекущееОкно.Содержимое.Количество() > 0 Тогда
// Проверяем имя формы первого элемента содержимого
Если ТекущееОкно.Содержимое[0].ИмяФормы = ИмяНужнойФормы Тогда
// Вместо открытия новой формы просто активируем существующее окно
ТекущееОкно.Активизировать();
Возврат;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Если окно не найдено в цикле, открываем его стандартно
ОткрытьФорму(ИмяНужнойФормы);
КонецПроцедуры
Важный момент: использование метода Активизировать() объекта ОкноКлиентскогоПриложения является самым «чистым» способом, так как он не инициирует серверные вызовы и не требует проверки прав на открытие формы. Вы просто принудительно выводите уже созданный визуальный компонент на передний план.
Проанализируем ситуацию, упомянутую в обсуждении, когда после выполнения процедуры ИнициализироватьНовыйЧек() форма теряет связь с предыдущим идентификатором. В этой процедуре часто используется метод ЗначениеВДанныеФормы.
Когда вы создаете новый объект на сервере (Документы.ЧекККМ.СоздатьДокумент()) и подкладываете его в данные формы (Объект), платформа обновляет внутреннее состояние формы. Если при этом форма была открыта без явного КлючаУникальности, она начинает ориентироваться на Объект.Ссылка. Поскольку у нового документа ссылка пустая, форма становится «новой». Как только вы записываете документ, ссылка заполняется, и ключ формы снова меняется.
Именно поэтому использование статического строкового ключа (как в Решении №1) является приоритетным для стабильной работы РМК и аналогичных интерфейсов.
Подводя итоги, дадим несколько практических советов для работы с управляемыми формами:
КлючУникальности при вызове ОткрытьФорму, если предполагается работа с формой в режиме «синглтон» (одно окно на сеанс).УникальныйИдентификатор формы — это GUID конкретного экземпляра в памяти, а КлючУникальности — это параметр для поиска этого экземпляра.ПолучитьОкна() и метод Активизировать().эл.Содержимое[0] всегда делайте проверку на количество элементов, чтобы избежать ошибки обращения к пустому массиву.Применяя эти методы, вы обеспечите отзывчивость интерфейса и избавите пользователей от путаницы с множеством открытых копий одних и тех же рабочих столов или документов.