если принципиально, то конфигурация УНФ
В конфигураторе в командном интерфейсе формы есть панель навигации, где перечислены ссылки на вызов окон, которые открываются внутри формы СписокНоменклатуры (Основное, Ед.Изм, Спецификации, Цены и так далее).

Самый главный вопрос - как узнать, какой из них является текущим? Второй, не критичный - как установить нужный.

Разбор ситуации (как пытаюсь решить, но пока безуспешно):
На процедуру ПриЗакрытии вешаю точку останова и проверяю открытые окна.

ПолучитьОкна() - возвращает реквизит типа ОкнаКлиентскогоПриложения,
являющимся неким массивом элементов типа ОкноКлиентскогоПриложения

Среди них есть элемент с заголовком "Номенклатура", у которого есть реквизит Содержимое типа ФиксированныйМассив с элементами Типа УправляемаяФорма.

Если я вообще не трогаю панель навигации, в нём один элемент - закладка "Основное".
Если нажимаю на любой пункт панели навигации, к нему добавляется ещё один элемент (но при условии, если его ранее не было).
Т.е. понажимав на разные пункты и нажав в конце на "Основное", я имею массив из нескольких элементов, где Основное находится под индексом 0. Определить, какой пункт был выбран в момент закрытия, не получается.

Сделал вспомогательную функцию

```1c
    Функция НайтиОкно(Заголовок) Экспорт
    Окна=ПолучитьОкна();
    Для Каждого Окно Из Окна Цикл
    Если Окно.Заголовок=Заголовок Тогда
    Возврат Окно
    КонецЕсли
    КонецЦикла
    КонецФункции
```

НайтиОкно("Номенклатура").Содержимое[0]=ЭтаФорма (Истина)
НайтиОкно("Номенклатура").Содержимое[1]=ЭтаФорма (Ложь)

НайтиОкно("Номенклатура").Содержимое[0].Открыта() (Истина)
НайтиОкно("Номенклатура").Содержимое[1].Открыта() (Истина)

НайтиОкно("Номенклатура").Содержимое[0].Активизировать() - устанавливает закладку "Основое"
НайтиОкно("Номенклатура").Содержимое[1].Активизировать() - устанавливает закладку, "в которую я зашёл первой"

Очень не хватает чего-нибудь типа:
НайтиОкно("Номенклатура").Содержимое[1].Активно() - Истина или Ложь
____
Задача изначально стоит такая: в случае, если пользователь стоит не в основной закладке, по ESC он должен переходить в основную. Если в основной - выходить.

В данный момент, пользователь заходит в закладку спецификации, нажимает ESC (подразумевая возврат обратно) и форма списка закрывается.
---
Однако этот вариант - работает, как положено (т.е. нужно ПЕРЕД закрытием сначала возвращать фокус туда, куда нужно):

```1c
    &НаКлиенте
    Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Если Окно.Содержимое.Количество()>1 Тогда
    Отказ = Истина;
    Пока Окно.Содержимое.Количество()>1 Цикл
    Окно.Содержимое[0].Активизировать();
    Окно.Содержимое[1].Закрыть();
    КонецЦикла;
    КонецЕсли
    //{...}
    КонецПроцедуры
```
---
это полное противоречие функциональности платформы. При нажатие Esc сначала закрывается основное окно, только потом "дочернее".
Тут только костылестроением заниматься.
---
когда закрывал основное, то в фиксированном масиве был только 1 элемент, а когда файлы, то стало 2!
Но если вернуться на основное, то все равно остается количество окон, которые были в основной форме открыты.
Единственное действие, это действительно делать переменную и писать результат каждый раз при вызове команд, которые эти окна открывают, но потом все равно нет информации о переключении окна.
---
Как вариант, если окон несколько, сначала закрыть их при попытке закрытия, тогда если пользователь находится не в основном, при нажатии Esc, закроются дочерние окна и активируется основное. Если же он вернулся в основное после открытия дочерних, придётся 2 раза нажать на Esc.

```1c
    &НаКлиенте
    Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Если Окно.Содержимое.Количество() > 1 Тогда
    Отказ = Истина;
    Для Сч = 1 По Окно.Содержимое.Количество() - 1 Цикл
    Окно.Содержимое[Сч].Закрыть();
    КонецЦикла;
    КонецЕсли;
    КонецПроцедуры
```
---
Исправил:

```1c
    &НаКлиенте
    Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Если Окно.Содержимое.Количество() > 1 Тогда
    Отказ = Истина;
    Пока Окно.Содержимое.Количество() > 1 Цикл
    Окно.Содержимое[1].Закрыть();
    КонецЦикла;
    КонецЕсли;
    КонецПроцедуры
```
---
При таком способе реализации есть два варианта поведения:

1. Если открыта закладка Основная и нажат ESC - происходит выход
2. Если открыта закладка Основная и любая другая (или несколько), последней открыта Основная - по двойному нажатию на ESC - выход.
3. Если открыта закладка Основная и любая другая (или несколько) и нажат ESC - происходит переход в закладку Основная
- при повторном нажатии ESC (любое количество раз ничего не происходит, эффект, как у "подвисания"),
 мы продолжаем "висеть" в закладке Основная
- если же после этого мы попытаемся ткнуть мышью в любое место окна - мы попадём в последнюю закрытую закладку
- далее, по нажатию ESC - повторный переход в Основная, откуда (теперь уже) можно выйти, повторно нажав ESC.

Это не рабочий механизм, увы. Но вы натолкнули меня на интересную мысль... Сейчас поковыряюсь...

Да, я понял причину странного поведения 1С!
Дело в том, что когда мы закрываем окно, как в (11), 1С не может раздуплиться, куда "возвращаться" после закрытия окон и... уходит в анабиоз... Сначала я подумал, что нужно "помочь" ей понять, куда "возвращаться" и попробовал так:
Неудачная попытка
```1c
    Если Окно.Содержимое.Количество()>1 Тогда
    Отказ = Истина;
    Пока Окно.Содержимое.Количество()>1 Цикл
    Окно.Содержимое[1].Закрыть();
    Окно.Содержимое[0].Активизировать();
    КонецЦикла;
    КонецЕсли
```

Но при таком раскладе, если пользователь не сделает паузу после первого нажатия на ESC больше секунды,
клиент опять уходит в анабиоз, только ещё более глубокий, после которого закрыть окно можно только крестиком на закладке)
---
да выходит единственный вариант, сначала закрыть все открытое, а потом уже что осталось.
---
Интересная задача. А если в процедуре ПриОткрытии() форм, которые вызываются из основной формы, сделать обработчик оповещения с именем формы. И ловить это оповещение в основной открываемой форме, записывая в переменную. Тогда у вас всегда будет текущее имя последней открытой формы. Правда, не факт что ПриОткрытии() будет срабатывать при повторном открытии формы (если кликнуть на раздел, потом на другой, и потом снова вернуться в отрытый ранее).
---
Не хотелось бы идти по такому пути... ведь тогда решение обещает быть громоздким...

ПриОткрытии() действительно не будет срабатывать, т.к. форма остаётся открытой (даже текущие строки остаются прежними и введённые данные).

Не верится, что невозможно проверить активность окна. Может, какая-нибудь недокументированная возможность?..
---
Если повиснуть на ПередЗакрытием() основного окна, то можно переиграть базовый функционал.
Во огромном количестве случаев он сам является костылём самого себя.

Т.е. я бы запросто переиграл его, в случае, если бы узнал, как определить, активно ли указанное окно.
Если это невозможно - то недоработка разрабов. Но даже в таких случаях думаю, это возможно.
Просто я ещё пока не нашёл, как)
---
проблема в том, что это функционал MDI. И да, доступ к функциональности ограничен.
---
Мне было бы достаточно просто подтвердить или опровергнуть нахождение в закладке Основное (как на первом скрине).
---
Есть ли тут кто-нибудь, кто глубоко познал процесс работы с окнами в 1С?..
---
Однако этот вариант - работает, как положено (т.е. нужно ПЕРЕД закрытием сначала возвращать фокус туда, куда нужно):

```1c
    &НаКлиенте
    Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Если Окно.Содержимое.Количество()>1 Тогда
    Отказ = Истина;
    Пока Окно.Содержимое.Количество()>1 Цикл
    Окно.Содержимое[0].Активизировать();
    Окно.Содержимое[1].Закрыть();
    КонецЦикла;
    КонецЕсли
    //{...}
    КонецПроцедуры
```
---
Если кому интересно, вчера реализовал другой вариант, но (14) мне нравится больше)
Там суть сводилась к тому, что для выхода из номенклатуры нужно произвести в течение секунды два нажатия ESC.
В противном случае мы переходили в закладку Основное (или оставались в ней).
Для этого я добавлял на форму реквизит МоментВыхода типа Дата.

Вариант с засеканием момента нажатия
```1c
    Если Окно.Содержимое.Количество()>1 Тогда
    Если ЗначениеЗаполнено(МоментВыхода) и ТекущаяДата()-МоментВыхода<2 Тогда
    Возврат;
    Иначе
    Отказ=Истина;
    Окно.Содержимое[0].Активизировать();
    МоментВыхода=ТекущаяДата()
    КонецЕсли
    КонецЕсли
```
---
На моей платформе, закрытие дочернего автоматически вызывает активизацию основного, поэтому специально его не прописал.
---
в таком случае теряется фокус. Дальнейшее закрытие не происходит.
---
а что за платформа? У меня 1С:Предприятие 8.3 (8.3.12.1412)
---
8.3.10.2580 такси, режим совместимости отключён. Проверял на расходном ордере, конфа Бит.Финанс. Возможно с формой документа поведение другое.
---
это разве решает задачу закрытия, если пользователь сам вернулся на основное окно?
---
Второе нажатие ESC мгновенно решает вопрос. Проверил на практике - не напрягает, выглядит естественным.
В отличие от предыдущих вариантов, когда 1С начинала вести себя не совсем адекватно.
Решение выглядит уверенно на 11/12 баллов.
---
как сказать. Пользователю нужно будет быть очень внимательным. Если он привыкнет к двойному нажатию ESC, то просто при открытии будет получать закрытия и другого открытого окна. Остается только гадать о его мысленных позывах разработчику.
---
Попробуйте на практике... Мой вариант с засеканием времени действительно меня в некоторых случаях напрягал.
Этот - выглядит естественно, крайне прост в реализации и действительно эффективен.
---
1. пользователь не привыкнет к двойному нажатию, по причине того, что такая потребность будет возникать у него в крайне редких случаях, более того, в этих случаях второе нажатие никак не заставит его думать, что нужно нажимать два раза в принципе.
2. в 99% случаев все будет работать так, как нужно.

тот самый случай, когда решение облегчает жизнь пользователю ЗНАЧИТЕЛЬНО,
а взамен крайне незначительно и крайне редко добавляет минизаминку