УФ. Как у списка номенклатуры узнать/установить активное окно (содержимое)
если принципиально, то конфигурация УНФ
В конфигураторе в командном интерфейсе формы есть панель навигации, где перечислены ссылки на вызов окон, которые открываются внутри формы СписокНоменклатуры (Основное, Ед.Изм, Спецификации, Цены и так далее).
Самый главный вопрос - как узнать, какой из них является текущим? Второй, не критичный - как установить нужный.
Разбор ситуации (как пытаюсь решить, но пока безуспешно):
На процедуру ПриЗакрытии вешаю точку останова и проверяю открытые окна.
ПолучитьОкна() - возвращает реквизит типа ОкнаКлиентскогоПриложения,
являющимся неким массивом элементов типа ОкноКлиентскогоПриложения
Среди них есть элемент с заголовком "Номенклатура", у которого есть реквизит Содержимое типа ФиксированныйМассив с элементами Типа УправляемаяФорма.
Если я вообще не трогаю панель навигации, в нём один элемент - закладка "Основное".
Если нажимаю на любой пункт панели навигации, к нему добавляется ещё один элемент (но при условии, если его ранее не было).
Т.е. понажимав на разные пункты и нажав в конце на "Основное", я имею массив из нескольких элементов, где Основное находится под индексом 0. Определить, какой пункт был выбран в момент закрытия, не получается.
Сделал вспомогательную функцию
НайтиОкно("Номенклатура").Содержимое[0]=ЭтаФорма (Истина)
НайтиОкно("Номенклатура").Содержимое[1]=ЭтаФорма (Ложь)
НайтиОкно("Номенклатура").Содержимое[0].Открыта() (Истина)
НайтиОкно("Номенклатура").Содержимое[1].Открыта() (Истина)
НайтиОкно("Номенклатура").Содержимое[0].Активизировать() - устанавливает закладку "Основое"
НайтиОкно("Номенклатура").Содержимое[1].Активизировать() - устанавливает закладку, "в которую я зашёл первой"
Очень не хватает чего-нибудь типа:
НайтиОкно("Номенклатура").Содержимое[1].Активно() - Истина или Ложь
____
Задача изначально стоит такая: в случае, если пользователь стоит не в основной закладке, по ESC он должен переходить в основную. Если в основной - выходить.
В данный момент, пользователь заходит в закладку спецификации, нажимает ESC (подразумевая возврат обратно) и форма списка закрывается.
В конфигураторе в командном интерфейсе формы есть панель навигации, где перечислены ссылки на вызов окон, которые открываются внутри формы СписокНоменклатуры (Основное, Ед.Изм, Спецификации, Цены и так далее).
Самый главный вопрос - как узнать, какой из них является текущим? Второй, не критичный - как установить нужный.
Разбор ситуации (как пытаюсь решить, но пока безуспешно):
На процедуру ПриЗакрытии вешаю точку останова и проверяю открытые окна.
ПолучитьОкна() - возвращает реквизит типа ОкнаКлиентскогоПриложения,
являющимся неким массивом элементов типа ОкноКлиентскогоПриложения
Среди них есть элемент с заголовком "Номенклатура", у которого есть реквизит Содержимое типа ФиксированныйМассив с элементами Типа УправляемаяФорма.
Если я вообще не трогаю панель навигации, в нём один элемент - закладка "Основное".
Если нажимаю на любой пункт панели навигации, к нему добавляется ещё один элемент (но при условии, если его ранее не было).
Т.е. понажимав на разные пункты и нажав в конце на "Основное", я имею массив из нескольких элементов, где Основное находится под индексом 0. Определить, какой пункт был выбран в момент закрытия, не получается.
Сделал вспомогательную функцию
Функция НайтиОкно(Заголовок) Экспорт
Окна=ПолучитьОкна();
Для Каждого Окно Из Окна Цикл
Если Окно.Заголовок=Заголовок Тогда
Возврат Окно
КонецЕсли
КонецЦикла
КонецФункции
ПоказатьНайтиОкно("Номенклатура").Содержимое[0]=ЭтаФорма (Истина)
НайтиОкно("Номенклатура").Содержимое[1]=ЭтаФорма (Ложь)
НайтиОкно("Номенклатура").Содержимое[0].Открыта() (Истина)
НайтиОкно("Номенклатура").Содержимое[1].Открыта() (Истина)
НайтиОкно("Номенклатура").Содержимое[0].Активизировать() - устанавливает закладку "Основое"
НайтиОкно("Номенклатура").Содержимое[1].Активизировать() - устанавливает закладку, "в которую я зашёл первой"
Очень не хватает чего-нибудь типа:
НайтиОкно("Номенклатура").Содержимое[1].Активно() - Истина или Ложь
____
Задача изначально стоит такая: в случае, если пользователь стоит не в основной закладке, по ESC он должен переходить в основную. Если в основной - выходить.
В данный момент, пользователь заходит в закладку спецификации, нажимает ESC (подразумевая возврат обратно) и форма списка закрывается.
Прикрепленные файлы:
Найденные решения
Однако этот вариант - работает, как положено (т.е. нужно ПЕРЕД закрытием сначала возвращать фокус туда, куда нужно):
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если Окно.Содержимое.Количество()>1 Тогда
Отказ = Истина;
Пока Окно.Содержимое.Количество()>1 Цикл
Окно.Содержимое[0].Активизировать();
Окно.Содержимое[1].Закрыть();
КонецЦикла;
КонецЕсли
//{...}
КонецПроцедуры
ПоказатьОстальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) когда закрывал основное, то в фиксированном масиве был только 1 элемент, а когда файлы, то стало 2!
Но если вернуться на основное, то все равно остается количество окон, которые были в основной форме открыты.
Единственное действие, это действительно делать переменную и писать результат каждый раз при вызове команд, которые эти окна открывают, но потом все равно нет информации о переключении окна.
Но если вернуться на основное, то все равно остается количество окон, которые были в основной форме открыты.
Единственное действие, это действительно делать переменную и писать результат каждый раз при вызове команд, которые эти окна открывают, но потом все равно нет информации о переключении окна.
Прикрепленные файлы:
(9) Как вариант, если окон несколько, сначала закрыть их при попытке закрытия, тогда если пользователь находится не в основном, при нажатии Esc, закроются дочерние окна и активируется основное. Если же он вернулся в основное после открытия дочерних, придётся 2 раза нажать на Esc.
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если Окно.Содержимое.Количество() > 1 Тогда
Отказ = Истина;
Для Сч = 1 По Окно.Содержимое.Количество() - 1 Цикл
Окно.Содержимое[Сч].Закрыть();
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Показать
(10) Исправил:
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если Окно.Содержимое.Количество() > 1 Тогда
Отказ = Истина;
Пока Окно.Содержимое.Количество() > 1 Цикл
Окно.Содержимое[1].Закрыть();
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Показать
(11) При таком способе реализации есть два варианта поведения:
1. Если открыта закладка Основная и нажат ESC - происходит выход
2. Если открыта закладка Основная и любая другая (или несколько), последней открыта Основная - по двойному нажатию на ESC - выход.
3. Если открыта закладка Основная и любая другая (или несколько) и нажат ESC - происходит переход в закладку Основная
- при повторном нажатии ESC (любое количество раз ничего не происходит, эффект, как у "подвисания"),
мы продолжаем "висеть" в закладке Основная
- если же после этого мы попытаемся ткнуть мышью в любое место окна - мы попадём в последнюю закрытую закладку
- далее, по нажатию ESC - повторный переход в Основная, откуда (теперь уже) можно выйти, повторно нажав ESC.
Это не рабочий механизм, увы. Но вы натолкнули меня на интересную мысль... Сейчас поковыряюсь...
Да, я понял причину странного поведения 1С!
Дело в том, что когда мы закрываем окно, как в (11), 1С не может раздуплиться, куда "возвращаться" после закрытия окон и... уходит в анабиоз... Сначала я подумал, что нужно "помочь" ей понять, куда "возвращаться" и попробовал так:
Но при таком раскладе, если пользователь не сделает паузу после первого нажатия на ESC больше секунды,
клиент опять уходит в анабиоз, только ещё более глубокий, после которого закрыть окно можно только крестиком на закладке)
1. Если открыта закладка Основная и нажат ESC - происходит выход
2. Если открыта закладка Основная и любая другая (или несколько), последней открыта Основная - по двойному нажатию на ESC - выход.
3. Если открыта закладка Основная и любая другая (или несколько) и нажат ESC - происходит переход в закладку Основная
- при повторном нажатии ESC (любое количество раз ничего не происходит, эффект, как у "подвисания"),
мы продолжаем "висеть" в закладке Основная
- если же после этого мы попытаемся ткнуть мышью в любое место окна - мы попадём в последнюю закрытую закладку
- далее, по нажатию ESC - повторный переход в Основная, откуда (теперь уже) можно выйти, повторно нажав ESC.
Это не рабочий механизм, увы. Но вы натолкнули меня на интересную мысль... Сейчас поковыряюсь...
Да, я понял причину странного поведения 1С!
Дело в том, что когда мы закрываем окно, как в (11), 1С не может раздуплиться, куда "возвращаться" после закрытия окон и... уходит в анабиоз... Сначала я подумал, что нужно "помочь" ей понять, куда "возвращаться" и попробовал так:
Неудачная попытка |
---|
Если Окно.Содержимое.Количество()>1 Тогда
Отказ = Истина;
Пока Окно.Содержимое.Количество()>1 Цикл
Окно.Содержимое[1].Закрыть();
Окно.Содержимое[0].Активизировать();
КонецЦикла;
КонецЕсли
|
Но при таком раскладе, если пользователь не сделает паузу после первого нажатия на ESC больше секунды,
клиент опять уходит в анабиоз, только ещё более глубокий, после которого закрыть окно можно только крестиком на закладке)
Интересная задача. А если в процедуре ПриОткрытии() форм, которые вызываются из основной формы, сделать обработчик оповещения с именем формы. И ловить это оповещение в основной открываемой форме, записывая в переменную. Тогда у вас всегда будет текущее имя последней открытой формы. Правда, не факт что ПриОткрытии() будет срабатывать при повторном открытии формы (если кликнуть на раздел, потом на другой, и потом снова вернуться в отрытый ранее).
Не хотелось бы идти по такому пути... ведь тогда решение обещает быть громоздким...
ПриОткрытии() действительно не будет срабатывать, т.к. форма остаётся открытой (даже текущие строки остаются прежними и введённые данные).
Не верится, что невозможно проверить активность окна. Может, какая-нибудь недокументированная возможность?..
ПриОткрытии() действительно не будет срабатывать, т.к. форма остаётся открытой (даже текущие строки остаются прежними и введённые данные).
Не верится, что невозможно проверить активность окна. Может, какая-нибудь недокументированная возможность?..
Если повиснуть на ПередЗакрытием() основного окна, то можно переиграть базовый функционал.
Во огромном количестве случаев он сам является костылём самого себя.
Т.е. я бы запросто переиграл его, в случае, если бы узнал, как определить, активно ли указанное окно.
Если это невозможно - то недоработка разрабов. Но даже в таких случаях думаю, это возможно.
Просто я ещё пока не нашёл, как)
Во огромном количестве случаев он сам является костылём самого себя.
Т.е. я бы запросто переиграл его, в случае, если бы узнал, как определить, активно ли указанное окно.
Если это невозможно - то недоработка разрабов. Но даже в таких случаях думаю, это возможно.
Просто я ещё пока не нашёл, как)
Однако этот вариант - работает, как положено (т.е. нужно ПЕРЕД закрытием сначала возвращать фокус туда, куда нужно):
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если Окно.Содержимое.Количество()>1 Тогда
Отказ = Истина;
Пока Окно.Содержимое.Количество()>1 Цикл
Окно.Содержимое[0].Активизировать();
Окно.Содержимое[1].Закрыть();
КонецЦикла;
КонецЕсли
//{...}
КонецПроцедуры
Показать
Если кому интересно, вчера реализовал другой вариант, но (14) мне нравится больше)
Там суть сводилась к тому, что для выхода из номенклатуры нужно произвести в течение секунды два нажатия ESC.
В противном случае мы переходили в закладку Основное (или оставались в ней).
Для этого я добавлял на форму реквизит МоментВыхода типа Дата.
Там суть сводилась к тому, что для выхода из номенклатуры нужно произвести в течение секунды два нажатия ESC.
В противном случае мы переходили в закладку Основное (или оставались в ней).
Для этого я добавлял на форму реквизит МоментВыхода типа Дата.
Вариант с засеканием момента нажатия |
---|
Если Окно.Содержимое.Количество()>1 Тогда
Если ЗначениеЗаполнено(МоментВыхода) и ТекущаяДата()-МоментВыхода<2 Тогда
Возврат;
Иначе
Отказ=Истина;
Окно.Содержимое[0].Активизировать();
МоментВыхода=ТекущаяДата()
КонецЕсли
КонецЕсли Показать |
(21)
1. пользователь не привыкнет к двойному нажатию, по причине того, что такая потребность будет возникать у него в крайне редких случаях, более того, в этих случаях второе нажатие никак не заставит его думать, что нужно нажимать два раза в принципе.
2. в 99% случаев все будет работать так, как нужно.
тот самый случай, когда решение облегчает жизнь пользователю ЗНАЧИТЕЛЬНО,
а взамен крайне незначительно и крайне редко добавляет минизаминку
1. пользователь не привыкнет к двойному нажатию, по причине того, что такая потребность будет возникать у него в крайне редких случаях, более того, в этих случаях второе нажатие никак не заставит его думать, что нужно нажимать два раза в принципе.
2. в 99% случаев все будет работать так, как нужно.
тот самый случай, когда решение облегчает жизнь пользователю ЗНАЧИТЕЛЬНО,
а взамен крайне незначительно и крайне редко добавляет минизаминку
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот