IE 2018

1. getnight 42 08.08.18 11:31 Сейчас в теме

УФ. Как у списка номенклатуры узнать/установить активное окно (содержимое)

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

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

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

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

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

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

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


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

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

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

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

____
Задача изначально стоит такая: в случае, если пользователь стоит не в основной закладке, по ESC он должен переходить в основную. Если в основной - выходить.

В данный момент, пользователь заходит в закладку спецификации, нажимает ESC (подразумевая возврат обратно) и форма списка закрывается.
Прикрепленные файлы:
Вознаграждение за ответ
Показать полностью
Найденные решения
14. getnight 42 10.08.18 17:35 Сейчас в теме
Однако этот вариант - работает, как положено (т.е. нужно ПЕРЕД закрытием сначала возвращать фокус туда, куда нужно):
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	Если Окно.Содержимое.Количество()>1 Тогда
		Отказ = Истина;
		Пока Окно.Содержимое.Количество()>1 Цикл
			Окно.Содержимое[0].Активизировать();
			Окно.Содержимое[1].Закрыть();
		КонецЦикла;
	КонецЕсли
//{...}
КонецПроцедуры
Показать
Остальные ответы
Избранное Подписка Сортировка: Древо
4. spacecraft 08.08.18 16:50 Сейчас в теме
(1) это полное противоречие функциональности платформы. При нажатие Esc сначала закрывается основное окно, только потом "дочернее".
Тут только костылестроением заниматься.
9. Xershi 389 10.08.18 15:35 Сейчас в теме
(1) когда закрывал основное, то в фиксированном масиве был только 1 элемент, а когда файлы, то стало 2!
Но если вернуться на основное, то все равно остается количество окон, которые были в основной форме открыты.
Единственное действие, это действительно делать переменную и писать результат каждый раз при вызове команд, которые эти окна открывают, но потом все равно нет информации о переключении окна.
Прикрепленные файлы:
10. SlavaKron 10.08.18 15:51 Сейчас в теме
(9) Как вариант, если окон несколько, сначала закрыть их при попытке закрытия, тогда если пользователь находится не в основном, при нажатии Esc, закроются дочерние окна и активируется основное. Если же он вернулся в основное после открытия дочерних, придётся 2 раза нажать на Esc.
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	Если Окно.Содержимое.Количество() > 1 Тогда
		Отказ = Истина;
		Для Сч = 1 По Окно.Содержимое.Количество() - 1 Цикл
			Окно.Содержимое[Сч].Закрыть();
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры
Показать
11. SlavaKron 10.08.18 15:57 Сейчас в теме +1 $m
(10) Исправил:
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	Если Окно.Содержимое.Количество() > 1 Тогда
		Отказ = Истина;
		Пока Окно.Содержимое.Количество() > 1 Цикл
			Окно.Содержимое[1].Закрыть();
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры
Показать
getnight; +1 Ответить
13. getnight 42 10.08.18 17:12 Сейчас в теме
(11) При таком способе реализации есть два варианта поведения:

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

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

Да, я понял причину странного поведения 1С!
Дело в том, что когда мы закрываем окно, как в (11), 1С не может раздуплиться, куда "возвращаться" после закрытия окон и... уходит в анабиоз... Сначала я подумал, что нужно "помочь" ей понять, куда "возвращаться" и попробовал так:
Неудачная попытка


Но при таком раскладе, если пользователь не сделает паузу после первого нажатия на ESC больше секунды,
клиент опять уходит в анабиоз, только ещё более глубокий, после которого закрыть окно можно только крестиком на закладке)
12. Xershi 389 10.08.18 15:58 Сейчас в теме
(10) да выходит единственный вариант, сначала закрыть все открытое, а потом уже что осталось.
2. DarkUser 08.08.18 16:06 Сейчас в теме
Интересная задача. А если в процедуре ПриОткрытии() форм, которые вызываются из основной формы, сделать обработчик оповещения с именем формы. И ловить это оповещение в основной открываемой форме, записывая в переменную. Тогда у вас всегда будет текущее имя последней открытой формы. Правда, не факт что ПриОткрытии() будет срабатывать при повторном открытии формы (если кликнуть на раздел, потом на другой, и потом снова вернуться в отрытый ранее).
3. getnight 42 08.08.18 16:40 Сейчас в теме
Не хотелось бы идти по такому пути... ведь тогда решение обещает быть громоздким...

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

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

Т.е. я бы запросто переиграл его, в случае, если бы узнал, как определить, активно ли указанное окно.
Если это невозможно - то недоработка разрабов. Но даже в таких случаях думаю, это возможно.
Просто я ещё пока не нашёл, как)
6. spacecraft 08.08.18 17:03 Сейчас в теме
(5) проблема в том, что это функционал MDI. И да, доступ к функциональности ограничен.
7. getnight 42 08.08.18 17:22 Сейчас в теме
Мне было бы достаточно просто подтвердить или опровергнуть нахождение в закладке Основное (как на первом скрине).
8. getnight 42 10.08.18 15:07 Сейчас в теме
Есть ли тут кто-нибудь, кто глубоко познал процесс работы с окнами в 1С?..
14. getnight 42 10.08.18 17:35 Сейчас в теме
Однако этот вариант - работает, как положено (т.е. нужно ПЕРЕД закрытием сначала возвращать фокус туда, куда нужно):
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	Если Окно.Содержимое.Количество()>1 Тогда
		Отказ = Истина;
		Пока Окно.Содержимое.Количество()>1 Цикл
			Окно.Содержимое[0].Активизировать();
			Окно.Содержимое[1].Закрыть();
		КонецЦикла;
	КонецЕсли
//{...}
КонецПроцедуры
Показать
15. getnight 42 10.08.18 17:42 Сейчас в теме
Если кому интересно, вчера реализовал другой вариант, но (14) мне нравится больше)
Там суть сводилась к тому, что для выхода из номенклатуры нужно произвести в течение секунды два нажатия ESC.
В противном случае мы переходили в закладку Основное (или оставались в ней).
Для этого я добавлял на форму реквизит МоментВыхода типа Дата.

Вариант с засеканием момента нажатия
16. SlavaKron 10.08.18 17:43 Сейчас в теме
(14) На моей платформе, закрытие дочернего автоматически вызывает активизацию основного, поэтому специально его не прописал.
17. spacecraft 10.08.18 17:44 Сейчас в теме
(16) в таком случае теряется фокус. Дальнейшее закрытие не происходит.
18. getnight 42 10.08.18 17:44 Сейчас в теме
(16) а что за платформа? У меня 1С:Предприятие 8.3 (8.3.12.1412)
23. SlavaKron 10.08.18 18:17 Сейчас в теме
(18) 8.3.10.2580 такси, режим совместимости отключён. Проверял на расходном ордере, конфа Бит.Финанс. Возможно с формой документа поведение другое.
19. spacecraft 10.08.18 17:45 Сейчас в теме
(14) это разве решает задачу закрытия, если пользователь сам вернулся на основное окно?
20. getnight 42 10.08.18 17:48 Сейчас в теме
(19) Второе нажатие ESC мгновенно решает вопрос. Проверил на практике - не напрягает, выглядит естественным.
В отличие от предыдущих вариантов, когда 1С начинала вести себя не совсем адекватно.
Решение выглядит уверенно на 11/12 баллов.
21. spacecraft 10.08.18 17:50 Сейчас в теме
(20) как сказать. Пользователю нужно будет быть очень внимательным. Если он привыкнет к двойному нажатию ESC, то просто при открытии будет получать закрытия и другого открытого окна. Остается только гадать о его мысленных позывах разработчику.
22. getnight 42 10.08.18 17:53 Сейчас в теме
(21) Попробуйте на практике... Мой вариант с засеканием времени действительно меня в некоторых случаях напрягал.
Этот - выглядит естественно, крайне прост в реализации и действительно эффективен.
24. getnight 42 13.08.18 09:46 Сейчас в теме
(21)
1. пользователь не привыкнет к двойному нажатию, по причине того, что такая потребность будет возникать у него в крайне редких случаях, более того, в этих случаях второе нажатие никак не заставит его думать, что нужно нажимать два раза в принципе.
2. в 99% случаев все будет работать так, как нужно.

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

Вакансии

Программист 1С
Нижний Новгород
зарплата от 120 000 руб.
Полный день

Программист 1С
Санкт-Петербург
зарплата от 120 000 руб.
Полный день

Программист 1С
Новосибирск
зарплата от 80 000 руб. до 100 000 руб.
Полный день

Системный аналитик
Новосибирск
зарплата от 80 000 руб. до 100 000 руб.
Полный день

Программист 1С
Казань
Полный день