Сообщение пользователю после закрытия формы

1. velber 20.01.14 10:27 Сейчас в теме
1С:Предприятие 8.3 (8.3.4.389)
Бухгалтерия предприятия, редакция 3.0 (3.0.28.12)

Дописал в БП 3.0 подписку на событие перед запиью регистра бухгалтерии НаборЗаписей в модуле на сервере, которое информирует пользователя, т.е. выводит сообщение, в случае необходимости.
Но если пользователь в открытом документ нажимает "Провести и закрыть", то данное сообщение показывается в форме документа и закрывается тут же, поэтому прочесть его нет возможности.

Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Предупреждение!";
Сообщение.Сообщить();


Игрался с КлючДанных и ПутьКДанным ничего не получилось.

Как можно вывести сообщение не в текущую форму, а в форму списка регистра бухгалтерии или допустим в форму рабочего стола?
Ekaterina Lebedenko; Hobbit_Jedi; elga2012; +3 Ответить
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
3. oldfornit 10.05.16 17:36 Сейчас в теме
(1) velber, почему в серверном событии должно инициироваться уведомление пользователю?
4. Denis_CFO 48 10.05.16 18:59 Сейчас в теме
(1) velber, ну вызовите какую-нибудь общую форму и напишите на ней текст сообщения, который вы хотите. или этот вариант не подходит?
2. mazin2000 10.05.16 17:34 Сейчас в теме
Либо делается очень просто и все знают, либо очень сложно и никто не знает)))
Тоже столкнулся с таким вопросом.
Есть ли кто-то знает ответ на сей вопрос поделитесь пожал
Риник; +1 Ответить
6. Drivingblind 228 14.01.19 07:34 Сейчас в теме
(2)
Тоже столкнулся с таким вопросом.

ПоказатьОповещениеПользователя
Как вариант
5. марксист 10.05.16 19:15 Сейчас в теме
можно просто через оповещение сделать
7. Hobbit_Jedi 04.02.20 13:48 Сейчас в теме
Тоже столкнулся с похожей проблемой.
При записи документа выполняется проверка, которая не должна мешать записи, но которая должна сообщить пользователю о возможных неприятностях.
Проверка выполняется в серверном контексте (ПриЗаписи в модуле объекта). Следовательно, если пользователь нажимает "Записать и закрыть", то сообщение отображается в закрывающемся окне документа и исчезает вместе с ним, так и не попав в сознание пользователя.
Через ПоказатьОповещениеПользователю() - не подходит, т.к. оповещение работает только на клиенте, а сообщение нужно именно из серверного контекста отправлять (т.к. документ может и програмно записываться из других форм).

Неужели никто так и не поборол этот "подарок от разработчиков платформы"?
8. markw 04.02.20 14:48 Сейчас в теме
А цель какая? В такой реализации есть практически 100% уверенность, что пользователю будет ровно на эти уведомления. Он их и читать не будет.
Чтобы он прочитал - как минимум сделать Показать вопрос на форме. Ну и совсем странно делать это в подписке перед записью набора хозрасчетного.
9. Hobbit_Jedi 04.02.20 21:33 Сейчас в теме
(8) Цель - сообщить пользователю, что сохраненный в таком виде документ может привести (а может и не привести) к проблемам.
Никаких наборов записей нет. Есть просто сохраняемый документ. Проверка делается перед записью именно документа (поэтому показ вопросов, предупреждений и других окон - не допустим). Проверка на форме - плохой подход, т.к. если пользователь запустит какую-нибудь обработку, которая ему этих документов программно насоздает, то формы создаваемых документов и создаваться не будут, а сообщения вывестись - должны.

В-общем, я эту проблему решил следующим образом. Работает как часики - и в случае, если форма не закрывается, и при закрытии формы, и при программной записи объекта.

В реквизиты формы добавил реквизит с типом СписокЗначений. Я его назвал СообщенияПользователюПослеЗаписи.

Далее, в обработчике формы ПослеЗаписиНаСервере, пока, после выполнения записи объекта на сервере, управление еще не вернулось на клиента, и выведенные пользователю сообщения еще не отображены на клиенте, я снимаю копию очереди сообщений пользователю и сохраняю ее в добавленном реквизите СообщенияПользователюПослеЗаписи:

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	// Если в процессе записи пользователю выдавались какие-либо сообщения,
	// то перед отображением их ему, сохраним их копии,
	// чтобы в случае записи во время закрытия формы, отобразить их ему
	// (т.к. после закрытия формы он их уже не увидит).
	СообщенияПользователюПослеЗаписи.Очистить();
	Сообщения = ПолучитьСообщенияПользователю(Истина);
	Для Каждого Сообщение Из Сообщения Цикл
		КопияСообщения = Новый СообщениеПользователю;
		ЗаполнитьЗначенияСвойств(КопияСообщения, Сообщение);
		СообщенияПользователюПослеЗаписи.Добавить(КопияСообщения);
		Сообщение.Сообщить();
	КонецЦикла;
КонецПроцедуры
Показать


Подозреваю, что можно было вызывать ПолучитьСообщенияПользователю(...) с аргументом Ложь, и тогда можно было бы прямо полученные сообщения и добавлять в реквизит СообщенияПользователюПослеЗаписи, не делая их копии... Но опробовать эту "оптимизацию" еще не успел, поэтому привел работающий вариант кода.

Потом, в конце обработчика формы ПослеЗаписи, подключаю обработчик ожидания, который должен вызваться сразу после завершения цепочки вызовов других обработчиков.

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
	//....
	
	// Подключим обработчик очистки собранных сообщений пользователю,
	// который будет выполнен только в случае, если запись выполнялась без закрытия формы.
	ПодключитьОбработчикОжидания("ОбработчикОжиданияОчисткиСобранныхПриЗаписиСообщенийПользов­ателю", 0.1, Истина);
КонецПроцедуры
Показать


Сам обработчик выглядит вот так

// Обработчик ожидания, который подключается после записи объекта,
// и вызывается однократно, если запись объекта выполнялась без закрытия формы.
// Очищает список собранных во время записи объекта сообщений пользователю.
//
//Параметры:
// НЕТ
//
&НаКлиенте
Процедура ОбработчикОжиданияОчисткиСобранныхПриЗаписиСообщенийПользова­телю()
	СообщенияПользователюПослеЗаписи.Очистить();
КонецПроцедуры
Показать


Тут хитрость заключается в том, что данный обработчик вызывается только, если форма осталась открытой (т.е. была запись объекта без закрытия формы).
Если же форма после записи закрывается (пользователь нажал кнопку "Записать и закрыть"), то данный обработчик уже не будет вызван никогда.

Вообще, эта очистка очереди сообщений нужна для того, чтобы в случае, если пользователь получил свои сообщения при записи объекта, то чтобы ему не выводились эти же сообщения еще раз при закрытии формы, если он ее закрывает без записи. Такая ситуация может возникнуть, например, если пользователь нажал "Записать", прочитал сообщения, и нажимает "Закрыть" (без записи). В таком случае вывод сообщений будет "странным" с точки зрения пользователя.

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

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
	Если НЕ ЗавершениеРаботы Тогда
		// Перенаправим собранные при записи объекта,
		// и еще не отображенные пользователю, сообщения в форму,
		// которая станет активной после закрытия этой формы
		// (т.к. в противном случае окно задачи будет закрыто и пользователь не увидит этих сообщений).
		ПустойУИД = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000");
		Для Каждого Элемент Из СообщенияПользователюПослеЗаписи Цикл
			Сообщение = Элемент.Значение;
			Сообщение.ИдентификаторНазначения = ПустойУИД;
			Сообщение.Сообщить();
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры
Показать


В этом обработчике, мы все собранные в реквизите формы сообщения пользователю выводим, перепривязывая их (с помощью свойства ИдентификаторНазначения) к текущей активной форме (которая уже не наша закрываемая форма). Делаем мы это только в том случае, если окно закрывается не "при завершении работы", т.к. при завершении работы закрыты будут все окна 1С, и пользователь все-равно ничего не успеет прочитать.


А! Ну а сами сообщения выдаются в обработчиках модуля объекта (ПередЗаписью, ПриЗаписи, ОбработкаПроверкиЗаполнения и т.п.) с помощью классического метода Сообщить или через объект СообщениеПользователю. Кстати, в последнем случае можно даже привязать сообщения к конкретным реквизитам записываемого объекта, и тогда, после записи и закрытия формы объекта, можно будет двойным щелчком по сообщению обратно открыть объект и перейти к редактированию "стремного" реквизита. Что уже приобретает смысл "удобства пользователя".
user1671936; dimanich70; user1779799; Teplotrassamen; Dali; user1826519; warrior1985; ZDmitry83; vl-sher1; Омский Домовой; adamx; user1004898; soularise; RomanKod; Риник; LimarenkoA; al2578; KAPACEB.AA; +18 Ответить
10. KAPACEB.AA 460 25.02.20 16:45 Сейчас в теме
(9) Спасибо, пригодилось.
В своей версии для отображения сообщений использовал ПоказатьПредупреждение(, ТекстВсехСообщений). Окно сообщений пользователи часто игнорируют.
Irwin; Hobbit_Jedi; +2 Ответить
11. LimarenkoA 20.02.21 11:19 Сейчас в теме
(9)Спасибо тоже пригодилось! быстрое и по моему красивое решение,
Hobbit_Jedi; +1 Ответить
12. Hobbit_Jedi 21.02.21 19:58 Сейчас в теме
(9)
Подозреваю, что можно было вызывать ПолучитьСообщенияПользователю(...) с аргументом Ложь, и тогда можно было бы прямо полученные сообщения и добавлять в реквизит СообщенияПользователюПослеЗаписи, не делая их копии... Но опробовать эту "оптимизацию" еще не успел, поэтому привел работающий вариант кода.

Опробовал эту идею - все сработало.
Финальную версию можно у меня на сайте посмотреть: http://hj.net.ua/bounties/1%D0%A1/MessageFromClosingForm/MessageFromClosin­gForm.html
soularise; NoRazum; +2 Ответить
15. rinik88 31 16.08.22 11:25 Сейчас в теме
18. dimanich70 623 05.03.24 15:45 Сейчас в теме
13. Омский Домовой 408 17.11.21 23:51 Сейчас в теме
Спасибо , избавило от взрыва мозга.
14. vl-sher1 43 22.02.22 16:15 Сейчас в теме
У меня работает так (БП 3.0.52.36, платформа 8.3.19.1467, тонкий и толстый клиент):
// Модуль "закрываемой" формы:
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи) 
	Если ПараметрыЗаписи.Свойство("Сообщения") Тогда 
		ПустойУИД = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000");
		Для Каждого Элемент Из ПараметрыЗаписи.Сообщения Цикл
		    Сообщение = Элемент;
		    Сообщение.ИдентификаторНазначения = ПустойУИД;
		    Сообщение.Сообщить();
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	ПараметрыЗаписи.Вставить("Сообщения", ПолучитьСообщенияПользователю(Истина)); // удаляем после получения
КонецПроцедуры

// Код вывода сообщения (в серверных процедурах)
// ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Сообщение");
Показать
katena-p; Mihamak; Samarin; +3 1 Ответить
16. ledidinka 12.05.23 13:37 Сейчас в теме
Спасибо! Вспомнив об описанной проблеме - использовала приведенное решение для выполнения рабочей задачи. Оказалось зря :)

1С:Предприятие 8.3 (8.3.21.1674) - работает без лишних действий: в расширении вывожу сообщение в процедуре ПередЗакрытиемПосле и ПередЗаписьюПосле. Оно успешно выводится на экран после закрытия формы.
krenchik; BushNik; +2 Ответить
17. Ekaterina Lebedenko 05.10.23 14:49 Сейчас в теме
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот