УФ. ПоказатьВопрос() в ПередЗаписью(). Как определить закрывать форму или нет

1. SeiOkami 3434 03.10.14 09:07 Сейчас в теме
Здравия всем!
Такой вопрос. Может баян, но я как-то не нашёл решения.

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

Создавал тему на мисте, но предложение добавить свою команду взамен стардартной мне не нравится. http://www.forum.mista.ru/topic.php?id=721810

Есть адекватные способы?
Вознаграждение за ответ
Показать полностью
Найденные решения
8. alexx2510 38 03.10.14 11:44 Сейчас в теме
(1) SeiOkami, ответ 1С на твой вопрос - "красиво это никак не сделать":

http://its.1c.ru/docs/v8nonmodal/#25


Вопрос в обработчике формы ПередЗаписью

В обработчике события формы ПередЗаписью также может возникнуть потребность задать вопрос. Как и в предыдущем примере. Однако здесь вопрос так просто не решается. Отличие заключается в следующем.

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

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

Поэтому тут можно предложить три варианта, но все они, к сожалению, обладают недостатками:

Изменить логику прикладного решения так, чтобы не было диалога с пользователем в этом обработчике. Это не всегда возможно;
В обработке оповещения с помощью собственной блокирующей формы задавать пользователю развернутый вопрос, предполагающий точное описание дальнейших действий: Отказаться?, Только записать?, Записать и закрыть? Это может выглядеть не очень красиво, ведь пользователь уже нажал "Записать и закрыть", а его опять об этом спрашивают;
Не использовать стандартные команды формы Записать, "Записать и закрыть". Вместо них создать собственные команды, в которых и выполнять необходимые алгоритмы. Создание собственных команд потребует дополнительных трудозатрат.
Показать
Hogyoku; MonteCriZto; adhocprog; magdeevik; unichkin; kostik_love; vardeg; tradeagent; Lotar; +9 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Lotar 03.10.14 09:30 Сейчас в теме
(1) SeiOkami, можно поступить так: Добавить реквизит формы ФлагВопроса - Булево. В ПередЗаписью поставить вашу проверку, которая будет отрабатывать пока ФлагВопроса = Ложь. В случае если найдены недопустимые символы выставляем Отказ в истину, реквизит ФлагВопроса в Истину и вызываем ваш ПоказатьВопрос, в обработчике оповещения которого в случае ответа "Да" вы вызовите запись повторно.
Чуть позже выложу код.
3. SeiOkami 3434 03.10.14 09:33 Сейчас в теме
(2), прочтите внимательнее, пожалуйста, вопрос. Проблема не в том, как спросить пользователя. И не в том как записать. А в том, как определить, закрывать форму после записи, аль нет.
4. Lotar 03.10.14 09:44 Сейчас в теме
(3) SeiOkami, прошу прощения. Утренний кофе не успел подействовать.
7. alexx2510 38 03.10.14 11:11 Сейчас в теме
(1) SeiOkami,
upd: написал вариант, но после внимательно прочтения понял, что это не то что нужно )))
подумаем )
8. alexx2510 38 03.10.14 11:44 Сейчас в теме
(1) SeiOkami, ответ 1С на твой вопрос - "красиво это никак не сделать":

http://its.1c.ru/docs/v8nonmodal/#25


Вопрос в обработчике формы ПередЗаписью

В обработчике события формы ПередЗаписью также может возникнуть потребность задать вопрос. Как и в предыдущем примере. Однако здесь вопрос так просто не решается. Отличие заключается в следующем.

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

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

Поэтому тут можно предложить три варианта, но все они, к сожалению, обладают недостатками:

Изменить логику прикладного решения так, чтобы не было диалога с пользователем в этом обработчике. Это не всегда возможно;
В обработке оповещения с помощью собственной блокирующей формы задавать пользователю развернутый вопрос, предполагающий точное описание дальнейших действий: Отказаться?, Только записать?, Записать и закрыть? Это может выглядеть не очень красиво, ведь пользователь уже нажал "Записать и закрыть", а его опять об этом спрашивают;
Не использовать стандартные команды формы Записать, "Записать и закрыть". Вместо них создать собственные команды, в которых и выполнять необходимые алгоритмы. Создание собственных команд потребует дополнительных трудозатрат.
Показать
Hogyoku; MonteCriZto; adhocprog; magdeevik; unichkin; kostik_love; vardeg; tradeagent; Lotar; +9 Ответить
9. SeiOkami 3434 03.10.14 12:13 Сейчас в теме
(8) alexx2510, жалько... Очень жалько. Но благодарю за официальный ответ со ссылкой на ИТС.
12. Xershi 1484 27.03.18 13:53 Сейчас в теме
(1) в 8.3.11 вот такой код использую:
Если Не ПараметрыЗаписи.ПринудительноЗакрытьФорму Тогда

Если пользователь нажал провести или записать документ, то там ложь, а вот если провести и закрыть, то там истина!
5. fokin 03.10.14 09:56 Сейчас в теме
Сталкивался с подобной задачей.
Мне предлагали убрать кнопку "Записать и закрыть" и оставить только "Записать" и "Закрыть".
И в вашем случае для "закрыть" свой обработчик
6. SeiOkami 3434 03.10.14 10:10 Сейчас в теме
(5) fokin, да есть такой вариант, я написал об это в (0), но всё же надеюсь на то, что есть что-то получше =(
10. caponid 03.10.14 14:13 Сейчас в теме
что мешает добавить пару реквизитов ДалиОтвет и КодВозврата формы,
проверять потом в ПриЗаписи на клиенте в цикле ДалиОтвет и делать отказ если отказались?
11. malcev82 21.09.16 07:50 Сейчас в теме
После записи программно (при ответе пользователя "Да") Можно вставить следующий код:
Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
	Закрыть();	
КонецЕсли;
, где "ПараметрыЗаписи" параметр процедуры "ПередЗаписью".
При нажатии на кнопку "Записать" режим записи будет
ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Запись
, и закрывать, следовательно, не нужно.

P.S. Если, конечно, документ не был проведен до этого.
13. KroVladS 34 08.09.18 12:15 Сейчас в теме
Мой костыль, работает на 8.3.10.2753

&НаКлиенте
Перем ВыполняетсяЗакрытие;
&НаКлиенте
Перем _МодифицированностьФормы;

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
	Если Модифицированность Тогда 
		
		_МодифицированностьФормы = Истина;		

		//При закрытии форма этого вопроса оказывается под формой вопроса вызваной из ПередЗакрытием и закрывается вместе с формой
		Режим = РежимДиалогаВопрос.ДаНет;
		Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтаФорма, "ПередЗаписью");
		ПоказатьВопрос(Оповещение, НСтр("ru = 'Обновить значения?';"), Режим, 0);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	Если _МодифицированностьФормы 
		И НЕ ВыполняетсяЗакрытие Тогда 
		
		Отказ = Истина;
		Режим = РежимДиалогаВопрос.ДаНет;
		Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтаФорма, "ПередЗакрытием");
		ПоказатьВопрос(Оповещение, НСтр("ru = 'Обновить значения?';"), Режим, 0); 		
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, Параметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        Объект.ДатаОбновления = ТекущаяДата();
		Записать();
		Если Параметры = "ПередЗакрытием" Тогда
			ВыполняетсяЗакрытие = Истина;
			Закрыть();
		КонецЕсли;
	КонецЕсли; 
КонецПроцедуры

ВыполняетсяЗакрытие = Ложь;
_МодифицированностьФормы = Ложь;
Показать
14. agdam_m 6 03.12.18 10:09 Сейчас в теме
&НаКлиенте
Перем мЗакрытьФорму;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	мЗакрытьФорму = Ложь;
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
	Если мЗакрытьФорму= Ложь Тогда
		Отказ=Истина;
		ТекстВопроса = НСтр("ru = 'Закрыть форму?");
		ДополнительныеПараметры = Новый Структура;
		Обработчик = Новый ОписаниеОповещения("ПередЗакрытиемЗавершение", ЭтаФорма, ДополнительныеПараметры);
		ПоказатьВопрос(Обработчик, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 60, КодВозвратаДиалога.Да);		
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытиемЗавершение(Ответ, ДополнительныеПараметры) Экспорт
	Если Ответ = КодВозвратаДиалога.Да Тогда
		мЗакрытьФорму = Истина;
		ЭтаФорма.Закрыть();
	КонецЕсли;	
КонецПроцедуры
Показать
15. Natalex95 18.04.20 06:59 Сейчас в теме
Приведу пример с проведением документа, та же самая задача - в событии ПередЗаписью узнать что форма будет закрываться. Пример является наброском и требует более внимательной проработки кода написанного в обработчике события.

1. В форме необходимо добавить команду "ПровестиИЗакрыть", ее свойства должны быть максимально схожи с оригинальной командой (Синоним, картинки, подписи и т.д.). Кнопку при этом создавать не нужно.

2. Описать действия на данную команду. Примерно такие:
&НаКлиенте
Процедура ПровестиИЗакрыть(Команда)
	ПровестиДокумент(Истина, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ПровестиДокумент(ЗакрыватьПослеПроведения = Истина, ЗадаватьВопрос = Истина)
	сткПараметры = Новый Структура();
	сткПараметры.Вставить("ПослеЗаписиЗакрытьФорму", ЗакрыватьПослеПроведения);
	сткПараметры.Вставить("ЗадаватьВопрос", ЗадаватьВопрос);
	сткПараметры.Вставить("РежимЗаписи", РежимЗаписиДокумента.Проведение);
	сткПараметры.Вставить("РежимПроведения", РежимПроведенияДокумента.Неоперативный);
	
	Результат = ЭтотОбъект.Записать(сткПараметры);
	Если Результат и ЗакрыватьПослеПроведения Тогда
		Закрыть();
	КонецЕсли;
КонецПроцедуры
Показать


3. При создании формы на сервере у стандартной кнопки переопределить действие
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ЭтотОбъект.Элементы.ФормаПровестиИЗакрыть.ИмяКоманды = "ПровестиИЗакрыть";
КонецПроцедуры


4. Теперь в событие ПередЗаписью, вы получите необходимые свойства в параметрах. И можете уже обрабатывать вопрос согласно рекомендаций от 1С. Можно аналогичную команду создать и для кнопки Провести
Естественно при создании формы на сервере необходимо проконтролировать, что пользователь может выполнять данные действия.
pavluha_vrn; +1 Ответить
16. welder 10 03.11.22 14:38 Сейчас в теме
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
	Если Не ПараметрыЗаписи.Свойство("ВопросУжеЗадан") Тогда
		Отказ = истина;
		Оповещение = Новый ОписаниеОповещения(
	    	     "ПередЗаписьюЗавершение",
	    	     ЭтотОбъект,ПараметрыЗаписи);
		ПоказатьВопрос(Оповещение, "Документ будет записан, продолжить?", РежимДиалогаВопрос.ДаНет);
	КонецЕсли;	
КонецПроцедуры

&НаКлиенте
Процедура ПередЗаписьюЗавершение(Результат, Параметры) ЭКСПОРТ
	  
	Если Результат = КодВозвратаДиалога.Да Тогда
		Параметры.Вставить("ВопросУжеЗадан",Истина);
		Записать(Параметры);
	КонецЕсли;
	
КонецПроцедуры
Показать
17. gosizo 38 19.05.23 15:50 Сейчас в теме
(16) Спасибо! Интересное решение, только думаю стоит добавить в ПередЗаписьюЗавершение после записи:
Если Параметры.ПринудительноЗакрытьФорму Тогда
		  Закрыть();
КонецЕсли; 
 

Иначе при нажатии Провести и Закрыть - не закроется
Оставьте свое сообщение

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