INFOSTART EVENT 2018 EDUCATION

Второй тур голосования за доклады.
Окончание 5 сентября.

Зябликов Дмитрий | Senior ios developer | ЦРПТ

«Модуль ЭДО для 1С»

Полностью удаленный проект от прототипа до продакшна: - специфика законодательства - командная работа - интеграционные фишки (лайфхаки) Итог: довольный заказчик

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 385 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 385 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С
Санкт-Петербург
Временный (на проект)

Программист 1С
Москва
Полный день

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

Аналитик 1С
Москва
зарплата от 80 000 руб. до 120 000 руб.
Полный день