///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ПрограммныйИнтерфейс

// Устанавливает заголовок главного окна приложения, используя значение константы
// ЗаголовокПриложения и заголовок приложения по умолчанию.
//
// Параметры:
//   ПриЗапуске - Булево - Истина, если вызывается при начале работы программы.
//
Процедура УстановитьРасширенныйЗаголовокПриложения(ПриЗапуске = Ложь) Экспорт
	
	ПараметрыКлиента = ?(ПриЗапуске, ПараметрыРаботыКлиентаПриЗапуске(),
		ПараметрыРаботыКлиента());
		
	Если ОбщегоНазначенияКлиент.ДоступноИспользованиеРазделенныхДанных() Тогда
		ПредставлениеЗаголовка = ПараметрыКлиента.ЗаголовокПриложения;
		ПредставлениеКонфигурации = ПараметрыКлиента.ПодробнаяИнформация;
		
		Если ПустаяСтрока(СокрЛП(ПредставлениеЗаголовка)) Тогда
			Если ПараметрыКлиента.Свойство("ПредставлениеОбластиДанных") Тогда
				ШаблонЗаголовка = "%1 / %2";
				ЗаголовокПриложения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка, ПараметрыКлиента.ПредставлениеОбластиДанных,
					ПредставлениеКонфигурации);
			Иначе
				ШаблонЗаголовка = "%1";
				ЗаголовокПриложения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка, ПредставлениеКонфигурации);
			КонецЕсли;
		Иначе
			ШаблонЗаголовка = "%1 / %2";
			ЗаголовокПриложения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка,
				СокрЛП(ПредставлениеЗаголовка), ПредставлениеКонфигурации);
		КонецЕсли;
	Иначе
		ШаблонЗаголовка = "%1 / %2";
		ЗаголовокПриложения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка, НСтр("ru = 'Не установлены разделители'"), ПараметрыКлиента.ПодробнаяИнформация);
	КонецЕсли;
	
	Если Не ОбщегоНазначенияКлиент.РазделениеВключено()
	   И ПараметрыКлиента.Свойство("РаботаСВнешнимиРесурсамиЗаблокирована") Тогда
		ЗаголовокПриложения = "[" + НСтр("ru = 'КОПИЯ'") + "]" + " " + ЗаголовокПриложения;
	КонецЕсли;
	
	ОбщегоНазначенияКлиентПереопределяемый.ПриУстановкеЗаголовкаКлиентскогоПриложения(ЗаголовокПриложения, ПриЗапуске);
	
	КлиентскоеПриложение.УстановитьЗаголовок(ЗаголовокПриложения);
	
КонецПроцедуры

// Показать форму вопроса.
//
// Параметры:
//   ОписаниеОповещенияОЗавершении - ОписаниеОповещения - описание процедуры, которая будет вызвана после закрытия окна
//                                                        вопроса со следующими параметрами:
//                                                          РезультатВопроса - Структура:
//                                                            Значение - результат выбора пользователя: значение
//                                                                       системного перечисления или значение,
//                                                                       связанное с нажатой кнопкой. В случае закрытия
//                                                                       диалога по истечении времени - значение
//                                                                       Таймаут.
//                                                            БольшеНеЗадаватьЭтотВопрос - Булево - результат выбора
//                                                                                                  пользователя в
//                                                                                                  одноименном флажке.
//                                                          ДополнительныеПараметры - Структура 
//   ТекстВопроса                  - Строка, ФорматированнаяСтрока - текст задаваемого вопроса. 
//   Кнопки                        - РежимДиалогаВопрос
//                                 - СписокЗначений     - может быть задан список значений, в котором:
//                                       Значение - содержит значение, связанное с кнопкой и возвращаемое при 
//                                                  ее нажатии. В качестве значения может использоваться значение
//                                                  перечисления КодВозвратаДиалога, а также другие значения,
//                                                  поддерживающее XDTO-сериализацию.
//                                       Представление - текст кнопки.
//
//   ДополнительныеПараметры       - см. СтандартныеПодсистемыКлиент.ПараметрыВопросаПользователю.
//
Процедура ПоказатьВопросПользователю(ОписаниеОповещенияОЗавершении, ТекстВопроса, Кнопки, ДополнительныеПараметры = Неопределено) Экспорт
	
	Параметры = ПараметрыВопросаПользователю();
	Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда
		ЗаполнитьЗначенияСвойств(Параметры, ДополнительныеПараметры);
	КонецЕсли;
	
	КодыВозвратаДиалога = Новый Соответствие;
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.Да, "КодВозвратаДиалога.Да");
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.Нет, "КодВозвратаДиалога.Нет");
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.ОК, "КодВозвратаДиалога.ОК");
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.Отмена, "КодВозвратаДиалога.Отмена");
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.Повторить, "КодВозвратаДиалога.Повторить");
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.Прервать, "КодВозвратаДиалога.Прервать");
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.Пропустить, "КодВозвратаДиалога.Пропустить");
	КодыВозвратаДиалога.Вставить(КодВозвратаДиалога.Таймаут, "КодВозвратаДиалога.Таймаут");
	
	ПредставленияКнопок = Новый Соответствие;
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.Да, НСтр("ru = 'Да'"));
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.Нет, НСтр("ru = 'Нет'"));
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.ОК, НСтр("ru = 'ОК'"));
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.Отмена, НСтр("ru = 'Отмена'"));
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.Повторить, НСтр("ru = 'Повторить'"));
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.Прервать, НСтр("ru = 'Прервать'"));
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.Пропустить, НСтр("ru = 'Пропустить'"));
	ПредставленияКнопок.Вставить(КодВозвратаДиалога.Таймаут, НСтр("ru = 'Таймаут'"));
	
	РежимыДиалогаВопрос = Новый Соответствие;
	РежимыДиалогаВопрос.Вставить(РежимДиалогаВопрос.ДаНет, "РежимДиалогаВопрос.ДаНет");
	РежимыДиалогаВопрос.Вставить(РежимДиалогаВопрос.ДаНетОтмена, "РежимДиалогаВопрос.ДаНетОтмена");
	РежимыДиалогаВопрос.Вставить(РежимДиалогаВопрос.ОК, "РежимДиалогаВопрос.ОК");
	РежимыДиалогаВопрос.Вставить(РежимДиалогаВопрос.ОКОтмена, "РежимДиалогаВопрос.ОКОтмена");
	РежимыДиалогаВопрос.Вставить(РежимДиалогаВопрос.ПовторитьОтмена, "РежимДиалогаВопрос.ПовторитьОтмена");
	РежимыДиалогаВопрос.Вставить(РежимДиалогаВопрос.ПрерватьПовторитьПропустить, "РежимДиалогаВопрос.ПрерватьПовторитьПропустить");
	
	КнопкиДиалога = Кнопки;
	
	Если ТипЗнч(Кнопки) = Тип("СписокЗначений") Тогда
		КнопкиДиалога = ОбщегоНазначенияКлиент.СкопироватьРекурсивно(Кнопки);
		Для Каждого Кнопка Из КнопкиДиалога Цикл
			Если Кнопка.Представление = "" Тогда
				Кнопка.Представление = ПредставленияКнопок[Кнопка.Значение];
			КонецЕсли;
			Если ТипЗнч(Кнопка.Значение) = Тип("КодВозвратаДиалога") Тогда
				Кнопка.Значение = КодыВозвратаДиалога[Кнопка.Значение];
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если ТипЗнч(Кнопки) = Тип("РежимДиалогаВопрос") Тогда
		КнопкиДиалога = РежимыДиалогаВопрос[Кнопки];
	КонецЕсли;
	
	Если ТипЗнч(Параметры.КнопкаПоУмолчанию) = Тип("КодВозвратаДиалога") Тогда
		Параметры.КнопкаПоУмолчанию = КодыВозвратаДиалога[Параметры.КнопкаПоУмолчанию];
	КонецЕсли;
	
	Если ТипЗнч(Параметры.КнопкаТаймаута) = Тип("КодВозвратаДиалога") Тогда
		Параметры.КнопкаТаймаута = КодыВозвратаДиалога[Параметры.КнопкаТаймаута];
	КонецЕсли;
	
	Параметры.Вставить("Кнопки", КнопкиДиалога);
	Параметры.Вставить("ТекстСообщения", ТекстВопроса);
	
	ОткрытьФорму("ОбщаяФорма.Вопрос", Параметры, , , , , ОписаниеОповещенияОЗавершении);
	
КонецПроцедуры

// Возвращает новую структуру дополнительных параметров для процедуры ПоказатьВопросПользователю.
//
// Возвращаемое значение:
//  Структура:
//    * КнопкаПоУмолчанию             - Произвольный - определяет кнопку по умолчанию по типу кнопки или по связанному
//                                                     с ней значению.
//    * Таймаут                       - Число        - интервал времени в секундах до автоматического закрытия окна
//                                                     вопроса.
//    * КнопкаТаймаута                - Произвольный - кнопка (по типу кнопки или по связанному с ней значению), 
//                                                     на которой отображается количество секунд, оставшихся до
//                                                     истечения таймаута.
//    * Заголовок                     - Строка       - заголовок вопроса. 
//    * ПредлагатьБольшеНеЗадаватьЭтотВопрос - Булево - если Истина, то в окне вопроса будет доступен одноименный флажок.
//    * БольшеНеЗадаватьЭтотВопрос    - Булево       - принимает значение, выбранное пользователем в соответствующем
//                                                     флажке.
//    * БлокироватьВесьИнтерфейс      - Булево       - если Истина, форма вопроса открывается, блокируя работу всех
//                                                     остальных открытых окон, включая главное окно.
//    * Картинка                      - Картинка     - картинка, выводимая в окне вопроса.
//    * ТекстФлажка                   - Строка       - текст флажка "Больше не спрашивать".
//
Функция ПараметрыВопросаПользователю() Экспорт
	
	Параметры = Новый Структура;
	Параметры.Вставить("КнопкаПоУмолчанию", Неопределено);
	Параметры.Вставить("Таймаут", 0);
	Параметры.Вставить("КнопкаТаймаута", Неопределено);
	Параметры.Вставить("Заголовок", КлиентскоеПриложение.ПолучитьЗаголовок());
	Параметры.Вставить("ПредлагатьБольшеНеЗадаватьЭтотВопрос", Истина);
	Параметры.Вставить("БольшеНеЗадаватьЭтотВопрос", Ложь);
	Параметры.Вставить("БлокироватьВесьИнтерфейс", Ложь);
	Параметры.Вставить("Картинка", БиблиотекаКартинок.ДиалогВопрос);
	Параметры.Вставить("ТекстФлажка", "");
	
	Возврат Параметры;
	
КонецФункции	

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

// Открыть выбор объектов метаданных.
// 
// Параметры:
//  ПараметрыФормы - см. СтандартныеПодсистемыКлиентСервер.ПараметрыВыбораОбъектовМетаданных
//  ОписаниеОповещенияОЗакрытии - ОписаниеОповещения - оповещение, вызываемое при закрытии формы с параметрами: 
//			# ВыбранныеОбъектыМетаданных - СписокЗначений - полные имена выбранных объектов метаданных,
//				или ссылки на идентификаторы объектов метаданных, если параметр ВыбиратьСсылки установлен в Истина. 
//			# ДополнительныеПараметры - Произвольный - дополнительные параметры, переданные при создании оповещения. 
//		Если ОписаниеОповещенияОЗакрытии не указано, то будет вызвано оповещение, которое можно получить 
//		с помощью обработчика ОбработкаОповещения:
//			# ИмяСобытия - Строка - "ВыборОбъектовМетаданных"
//			# Параметр - СписокЗначений - выбранные объекты метаданных.
//			# Источник - см. СтандартныеПодсистемыКлиентСервер.ПараметрыВыбораОбъектовМетаданных.УникальныйИдентификаторИсточник
//
Процедура ВыбратьОбъектыМетаданных(ПараметрыФормы, ОписаниеОповещенияОЗакрытии = Неопределено) Экспорт
	ОткрытьФорму("ОбщаяФорма.ВыборОбъектовМетаданных", ПараметрыФормы,,,,, ОписаниеОповещенияОЗакрытии);
КонецПроцедуры

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

// Параметры редактора табличного документа для СтандартныеПодсистемыКлиент.ПоказатьРедакторТабличногоДокумента.
// 
// Возвращаемое значение:
//  Структура:
//   * ИмяДокумента - Строка - наименование табличного документа, выводимое в заголовке редактора. 
//   * ТабличныйДокумент - ТабличныйДокумент, Строка - отображаемый или редактируемый табличный документ.
//                         Также может быть указан адрес табличного документа во временном хранилище.
//   * ПутьКФайлу - Строка - полный путь к файлу табличного документа, опционально.
//   * Редактирование - Булево - если Истина, то табличный документ можно отредактировать. По умолчанию Ложь.
//
Функция ПараметрыРедактораТабличногоДокумента() Экспорт
	
	Результат = Новый Структура;
	Результат.Вставить("ИмяДокумента", "");
	Результат.Вставить("ТабличныйДокумент", Неопределено);
	Результат.Вставить("ПутьКФайлу", "");
	Результат.Вставить("Редактирование", Ложь);
	Возврат Результат;
	
КонецФункции

// Отрыть форму сравнения табличных документов, в которой можно посмотреть их отличия.
// 
// Параметры:
//  ТабличныйДокументЛевый - ТабличныйДокумент - первый сравниваемый табличный документ.
//  ТабличныйДокументПравый - ТабличныйДокумент - второй сравниваемый табличный документ.
//  Параметры - см. ПараметрыСравненияТабличныхДокументов
//
Процедура ПоказатьСравнениеТабличныхДокументов(ТабличныйДокументЛевый, ТабличныйДокументПравый, Параметры) Экспорт
	
	Если ТабличныйДокументЛевый <> Неопределено Тогда
		ПараметрыФормы = ПараметрыСравненияТабличныхДокументов();
		ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(ПараметрыФормы, Параметры, Истина);
		СравниваемыеДокументы = Новый Структура("Левый, Правый", ТабличныйДокументЛевый, ТабличныйДокументПравый);
		ПараметрыФормы.АдресТабличныхДокументов = ПоместитьВоВременноеХранилище(СравниваемыеДокументы, Неопределено);
	Иначе
		ПараметрыФормы = Параметры;
	КонецЕсли;
	ОткрытьФорму("ОбщаяФорма.СравнениеТабличныхДокументов", ПараметрыФормы);
	
КонецПроцедуры

// Параметры сравнения табличных документов для процедуры ПоказатьСравнениеТабличныхДокументов.
// 
// Возвращаемое значение:
//  Структура:
//    * АдресТабличныхДокументов - Строка - адрес сравниваемых табличных документов во временном хранилище.
//    * Заголовок - Строка - заголовок формы. Если не задано, то "Сравнение табличных документов".
//    * ЗаголовокЛевый - Строка - заголовок первого табличного документа (слева).
//    * ЗаголовокПравый - Строка - заголовок правого табличного документа (справа).
//
Функция ПараметрыСравненияТабличныхДокументов() Экспорт
	
	Результат = Новый Структура;
	Результат.Вставить("АдресТабличныхДокументов", "");
	Результат.Вставить("Заголовок", "");
	Результат.Вставить("ЗаголовокЛевый", "");
	Результат.Вставить("ЗаголовокПравый", "");
	Возврат Результат;
	
КонецФункции

// См. СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации
Функция ЭтоБазоваяВерсияКонфигурации() Экспорт
	
	Возврат ПараметрКлиента("ЭтоБазоваяВерсияКонфигурации");
	
КонецФункции

// См. СтандартныеПодсистемыСервер.ЭтоУчебнаяПлатформа
Функция ЭтоУчебнаяПлатформа() Экспорт
	
	Возврат ПараметрКлиента("ЭтоУчебнаяПлатформа");
	
КонецФункции

#Область ОбработкаОшибок

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

// Отключает видимость указанному элементу, если ошибка
// не подходит по категории с учетом параметра ОшибкаТребуетЗавершениеРаботы.
// Устанавливает в заголовок текст обязательной отправки,
// если администратор настроил Отправлять в объекте
// РежимОтправкиИнформацииОбОшибке, в противном случае
// (СпрашиватьПользователя или Авто) текст необязательной отправки.
// Рекомендуется вызывать ПриОткрытии своей формы ошибки.
//
// Параметры:
//  Элемент - ПолеФормы, КнопкаФормы - элемент которому будет установлена видимость и заголовок.
//  ИнформацияОбОшибке  - ИнформацияОбОшибке - ошибка по категории которой уточняется необходимость отправки отчета.
//  ОшибкаТребуетЗавершениеРаботы - Булево - учитывается при настройке видимости ссылки. По ошибкам,
//    из-за которых требуется завершение работы или перезапуск, как правило обязательно отправляется отчет.
//
// Пример:
//	#Область ОписаниеПеременных
//	&НаКлиенте
//	Перем ОтчетОбОшибке, ОтчетИнформацияОбОшибке;
//	#КонецОбласти
//	#Область ОбработчикиСобытийФормы
//	&НаКлиенте
//	Процедура ПриОткрытии(Отказ)
//		Если Параметры.ИнформацияОбОшибке <> Неопределено Тогда
//			ОтчетИнформацияОбОшибке = Параметры.ИнформацияОбОшибке;
//			ОтчетОбОшибке = Новый ОтчетОбОшибке(ОтчетИнформацияОбОшибке);
//			СтандартныеПодсистемыКлиент.НастроитьВидимостьИЗаголовокСсылкиОтправкиОтчетаОбОшибке(
//				Элементы.СформироватьОтчетОбОшибке, ОтчетИнформацияОбОшибке);
//		КонецЕсли;
//	КонецПроцедуры
//	&НаКлиенте
//	Процедура ПриЗакрытии(ЗавершениеРаботы)
//		Если ОтчетОбОшибке <> Неопределено Тогда
//			СтандартныеПодсистемыКлиент.ОтправитьОтчетОбОшибке(ОтчетОбОшибке, ОтчетИнформацияОбОшибке);
//		КонецЕсли;
//	КонецПроцедуры
//	#КонецОбласти
//	#Область ОбработчикиСобытийЭлементовШапкиФормы
//	&НаКлиенте
//	Процедура СформироватьОтчетОбОшибкеНажатие(Элемент)
//		СтандартныеПодсистемыКлиент.ПоказатьОтчетОбОшибке(ОтчетОбОшибке);
//	КонецПроцедуры
//	#КонецОбласти
//
Процедура НастроитьВидимостьИЗаголовокСсылкиОтправкиОтчетаОбОшибке(Элемент, ИнформацияОбОшибке, ОшибкаТребуетЗавершениеРаботы = Ложь) Экспорт
	
	Настройки = ПараметрКлиента("НастройкиОтправкиИнформацииОбОшибке");
	КатегорияДляПользователя = ОбработкаОшибок.КатегорияОшибкиДляПользователя(ИнформацияОбОшибке);
	
	Элемент.Видимость =
		    Не ОшибкаТребуетЗавершениеРаботы И КатегорияДляПользователя = КатегорияОшибки.ПрочаяОшибка
		Или Не ОшибкаТребуетЗавершениеРаботы И КатегорияДляПользователя = КатегорияОшибки.ОшибкаКонфигурации
		Или    ОшибкаТребуетЗавершениеРаботы И КатегорияДляПользователя <> КатегорияОшибки.ОшибкаСеанса;
	
	Если Настройки.РежимОтправки = РежимОтправкиИнформацииОбОшибке.Отправлять Тогда
		Элемент.Заголовок = НСтр("ru = 'Отчет об ошибке будет отправлен автоматически.
			|Настроить отчет...'");
	Иначе
		Элемент.Заголовок = НСтр("ru = 'Сформировать отчет об ошибке'");
	КонецЕсли;
	
КонецПроцедуры

// Открывает отчет об ошибке для проверки и настройки состава отчета,
// либо в режиме отправки (если указан адрес сервиса для отправки и администратор
// не настроил НеОтправлять в объекте РежимОтправкиИнформацииОбОшибке)
// либо в режиме записи в файл в противном случае.
//
// Параметры:
//  ОтчетДляОтправки - ОтчетОбОшибке
//
// Пример:
//	#Область ОписаниеПеременных
//	&НаКлиенте
//	Перем ОтчетОбОшибке, ОтчетИнформацияОбОшибке;
//	#КонецОбласти
//	#Область ОбработчикиСобытийФормы
//	&НаКлиенте
//	Процедура ПриОткрытии(Отказ)
//		Если Параметры.ИнформацияОбОшибке <> Неопределено Тогда
//			ОтчетИнформацияОбОшибке = Параметры.ИнформацияОбОшибке;
//			ОтчетОбОшибке = Новый ОтчетОбОшибке(ОтчетИнформацияОбОшибке);
//			СтандартныеПодсистемыКлиент.НастроитьВидимостьИЗаголовокСсылкиОтправкиОтчетаОбОшибке(
//				Элементы.СформироватьОтчетОбОшибке, ОтчетИнформацияОбОшибке);
//		КонецЕсли;
//	КонецПроцедуры
//	&НаКлиенте
//	Процедура ПриЗакрытии(ЗавершениеРаботы)
//		Если ОтчетОбОшибке <> Неопределено Тогда
//			СтандартныеПодсистемыКлиент.ОтправитьОтчетОбОшибке(ОтчетОбОшибке, ОтчетИнформацияОбОшибке);
//		КонецЕсли;
//	КонецПроцедуры
//	#КонецОбласти
//	#Область ОбработчикиСобытийЭлементовШапкиФормы
//	&НаКлиенте
//	Процедура СформироватьОтчетОбОшибкеНажатие(Элемент)
//		СтандартныеПодсистемыКлиент.ПоказатьОтчетОбОшибке(ОтчетОбОшибке);
//	КонецПроцедуры
//	#КонецОбласти
//
Процедура ПоказатьОтчетОбОшибке(ОтчетДляОтправки) Экспорт
	
	Настройки = ПараметрКлиента("НастройкиОтправкиИнформацииОбОшибке");
	
	Если ЗначениеЗаполнено(Настройки.АдресОтправки)
	   И Настройки.РежимОтправки <> РежимОтправкиИнформацииОбОшибке.НеОтправлять Тогда
		
		ОтчетДляОтправки.Отправить(Истина);
	Иначе
		ОтчетДляОтправки.Записать(, Истина);
	КонецЕсли;
	
КонецПроцедуры

// Неинтерактивно отправляет отчет об ошибке, если ошибка подходит
// по категории для отправки с учетом параметра ЗавершениеРаботы и
// администратор настроил Отправлять в объекте РежимОтправкиИнформацииОбОшибке.
// Рекомендуется вызывать ПриЗакрытии своей формы ошибки.
//
// Параметры:
//  ОтчетДляОтправки - ОтчетОбОшибке
//  ИнформацияОбОшибке  - ИнформацияОбОшибке - ошибка по категории которой уточняется необходимость отправки отчета.
//  ОшибкаТребуетЗавершениеРаботы - Булево - учитывается при отправке отчета. По ошибкам,
//    из-за которых требуется завершение работы или перезапуск, как правило обязательно отправляется отчет.
//    Нужно передать то же значение, что и в процедуру НастроитьВидимостьИЗаголовокСсылкиОтправкиОтчетаОбОшибке.
//
// Пример:
//	#Область ОписаниеПеременных
//	&НаКлиенте
//	Перем ОтчетОбОшибке, ОтчетИнформацияОбОшибке;
//	#КонецОбласти
//	#Область ОбработчикиСобытийФормы
//	&НаКлиенте
//	Процедура ПриОткрытии(Отказ)
//		Если Параметры.ИнформацияОбОшибке <> Неопределено Тогда
//			ОтчетИнформацияОбОшибке = Параметры.ИнформацияОбОшибке;
//			ОтчетОбОшибке = Новый ОтчетОбОшибке(ОтчетИнформацияОбОшибке);
//			СтандартныеПодсистемыКлиент.НастроитьВидимостьИЗаголовокСсылкиОтправкиОтчетаОбОшибке(
//				Элементы.СформироватьОтчетОбОшибке, ОтчетИнформацияОбОшибке);
//		КонецЕсли;
//	КонецПроцедуры
//	&НаКлиенте
//	Процедура ПриЗакрытии(ЗавершениеРаботы)
//		Если ОтчетОбОшибке <> Неопределено Тогда
//			СтандартныеПодсистемыКлиент.ОтправитьОтчетОбОшибке(ОтчетОбОшибке, ОтчетИнформацияОбОшибке);
//		КонецЕсли;
//	КонецПроцедуры
//	#КонецОбласти
//	#Область ОбработчикиСобытийЭлементовШапкиФормы
//	&НаКлиенте
//	Процедура СформироватьОтчетОбОшибкеНажатие(Элемент)
//		СтандартныеПодсистемыКлиент.ПоказатьОтчетОбОшибке(ОтчетОбОшибке);
//	КонецПроцедуры
//	#КонецОбласти
//
Процедура ОтправитьОтчетОбОшибке(ОтчетДляОтправки, ИнформацияОбОшибке, ОшибкаТребуетЗавершениеРаботы = Ложь) Экспорт
	
	Настройки = ПараметрКлиента("НастройкиОтправкиИнформацииОбОшибке");
	
	Если Не ЗначениеЗаполнено(Настройки.АдресОтправки)
	 Или Настройки.РежимОтправки <> РежимОтправкиИнформацииОбОшибке.Отправлять Тогда
		Возврат;
	КонецЕсли;
	
	КатегорияДляПользователя = ОбработкаОшибок.КатегорияОшибкиДляПользователя(ИнформацияОбОшибке);
	
	Если ОшибкаТребуетЗавершениеРаботы И КатегорияДляПользователя <> КатегорияОшибки.ОшибкаСеанса
	 Или Не ОшибкаТребуетЗавершениеРаботы
	   И (    КатегорияДляПользователя = КатегорияОшибки.ПрочаяОшибка
	      Или КатегорияДляПользователя = КатегорияОшибки.ОшибкаКонфигурации) Тогда
		
		ОтчетДляОтправки.Отправить(Ложь);
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработкаСобытийПриложения

// Отключает выдачу предупреждения пользователю при завершении работы программы.
//
Процедура ПропуститьПредупреждениеПередЗавершениемРаботыСистемы() Экспорт
	
	ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ПропуститьПредупреждениеПередЗавершениемРаботыСистемы", Истина);
	
КонецПроцедуры

// Выполнить стандартные действия перед началом работы пользователя
// с областью данных, либо в локальном режиме работы.
//
// Предназначена для вызова из обработчика ПередНачаломРаботыСистемы модулей управляемого и обычного приложения.
//
// Параметры:
//  ОповещениеЗавершения - ОписаниеОповещения - не задается при вызове из обработчика ПередНачаломРаботыСистемы 
//                         модулей управляемого и обычного приложения. В других случаях, после запуска будет вызвано
//                         оповещение с параметром типа Структура со свойствами:
//                         > Отказ - Булево - Ложь, если запуск выполнен успешно, или Истина, если вход в программу не
//                         выполнен;
//                         > Перезапустить - Булево - если требуется перезапуск программы;
//                         > ДополнительныеПараметрыКоманднойСтроки - Строка - для перезапуска.
//
Процедура ПередНачаломРаботыСистемы(Знач ОповещениеЗавершения = Неопределено) Экспорт
	
	ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	Если ПараметрыПриложения = Неопределено Тогда
		ПараметрыПриложения = Новый Соответствие;
	КонецЕсли;
	
	ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ОценкаПроизводительности.ВремяНачалаЗапуска", ВремяНачала);
	
	Если ОповещениеЗавершения <> Неопределено Тогда
		ОбщегоНазначенияКлиентСервер.ПроверитьПараметр("СтандартныеПодсистемыКлиент.ПередНачаломРаботыСистемы", 
			"ОповещениеЗавершения", ОповещениеЗавершения, Тип("ОписаниеОповещения"));
	КонецЕсли;
	
	ВойтиВОбластьДанных();
	
	ДействияПередНачаломРаботыСистемы(ОповещениеЗавершения);
	
	Если Не ОтключенаЛогикаНачалаРаботыСистемы()
	   И Не ОбщегоНазначенияКлиент.ПодсистемаСуществует("ИнтернетПоддержкаПользователей.БазоваяФункциональностьБИП") Тогда
		Возврат;
	КонецЕсли;
	
	Попытка
		МодульИнтернетПоддержкаПользователейКлиентСервер =
			ОбщегоНазначенияКлиент.ОбщийМодуль("ИнтернетПоддержкаПользователейКлиентСервер");
		ВерсияБИП = МодульИнтернетПоддержкаПользователейКлиентСервер.ВерсияБиблиотеки();
		// Подключение обработчика запроса настроек клиента лицензирования
		// для корректной проверки легальности обновления.
		Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияБИП, "2.7.1.0") > 0 Тогда
			МодульКлиентЛицензированияКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("КлиентЛицензированияКлиент");
			МодульКлиентЛицензированияКлиент.ПодключитьЗапросНастроекКлиентаЛицензирования();
		КонецЕсли;
	Исключение
		Если ОтключенаЛогикаНачалаРаботыСистемы() Тогда
			Возврат;
		КонецЕсли;
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

// Выполнить стандартные действия при начале работы пользователя
// с областью данных, либо в локальном режиме работы.
//
// Предназначена для вызова из обработчика ПриНачалеРаботыСистемы модулей управляемого и обычного приложения.
//
// Параметры:
//  ОповещениеЗавершения - ОписаниеОповещения - не задается при вызове из обработчика ПриНачалеРаботыСистемы 
//                         модулей управляемого и обычного приложения. В других случаях, после запуска будет вызвано
//                         оповещение с параметром типа Структура со свойствами:
//                         > Отказ - Булево - Ложь, если запуск выполнен успешно, или Истина, если вход в программу не
//                         выполнен;
//                         > Перезапустить - Булево - если требуется перезапуск программы;
//                         > ДополнительныеПараметрыКоманднойСтроки - Строка - для перезапуска.
//
//  НепрерывноеВыполнение - Булево - только для внутреннего использования.
//                          Для перехода из обработчика ПередНачаломРаботыСистемы
//                          выполненного в режиме интерактивной обработки.
//
Процедура ПриНачалеРаботыСистемы(Знач ОповещениеЗавершения = Неопределено, НепрерывноеВыполнение = Истина) Экспорт
	
	Если ВыполняетсяИнтерактивнаяОбработкаПередНачаломРаботыСистемы() Тогда
		Возврат;
	КонецЕсли;
	
	Если ОтключенаЛогикаНачалаРаботыСистемы() Тогда
		Возврат;
	КонецЕсли;
	
	Если ОповещениеЗавершения <> Неопределено Тогда
		ОбщегоНазначенияКлиентСервер.ПроверитьПараметр("СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы", 
			"ОповещениеЗавершения", ОповещениеЗавершения, Тип("ОписаниеОповещения"));
	КонецЕсли;
	ОбщегоНазначенияКлиентСервер.ПроверитьПараметр("СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы", 
		"НепрерывноеВыполнение", НепрерывноеВыполнение, Тип("Булево"));
	
	ДействияПриНачалеРаботыСистемы(ОповещениеЗавершения, НепрерывноеВыполнение);
	
КонецПроцедуры

// Выполнить стандартные действия перед завершением работы пользователя
// с областью данных, либо в локальном режиме работы.
//
// Предназначена для вызова из обработчика ПередЗавершениемРаботыСистемы модулей управляемого и обычного приложения.
//
// Параметры:
//  Отказ                - Булево - возвращаемое значение. Признак отказа от завершения работы 
//                         для обработчика события ПередЗавершениемРаботыСистемы, либо программного отказа,
//                         либо того, что потребовалась интерактивная обработка. В случае успешного взаимодействия
//                         с пользователем завершение работы будет продолжено.
//  ТекстПредупреждения  - Строка - см. ПередЗавершениемРаботыСистемы() в синтакс-помощнике.
//
Процедура ПередЗавершениемРаботыСистемы(Отказ = Ложь, ТекстПредупреждения = "") Экспорт
	
	Если Не ВыводитьПредупрежденияПередЗавершениемРаботыСистемы(Отказ) Тогда
		Возврат;
	КонецЕсли;
	
	Предупреждения = ПредупрежденияПередЗавершениемРаботыСистемы(Отказ);
	Если Предупреждения.Количество() = 0 Тогда
		Если Не ПараметрКлиента("ЗапрашиватьПодтверждениеПриЗавершенииПрограммы") Тогда
			Возврат;
		КонецЕсли;
		ТекстПредупреждения = НСтр("ru = 'Завершить работу с приложением?'");
		Отказ = Истина;
	Иначе
		Отказ = Истина;
		МассивПредупреждений = Новый Массив;
		Для Каждого Предупреждение Из Предупреждения Цикл
			МассивПредупреждений.Добавить(Предупреждение.ТекстПредупреждения);
		КонецЦикла;
		Если Не ПустаяСтрока(ТекстПредупреждения) Тогда
			ТекстПредупреждения = ТекстПредупреждения + Символы.ПС;
		КонецЕсли;
		МассивПредупреждений.Добавить(Символы.ПС);
		МассивПредупреждений.Добавить(НСтр("ru = 'Для этого выберите ""Продолжить работу"" и затем нажмите на всплывающее оповещение.'"));
		ТекстПредупреждения = ТекстПредупреждения + СтрСоединить(МассивПредупреждений, Символы.ПС);
		
		ПодключитьОбработчикОжидания("ПоказатьПредупрежденияПриЗавершенииРаботы", 0.1, Истина);
	КонецЕсли;
	УстановитьПараметрКлиента("ПредупрежденияПриЗавершенииРаботы", Предупреждения);
	
КонецПроцедуры

// Выполнить стандартные действия при обработке получения формы выбора пользователей системы взаимодействия.
//
// Параметры:
//  НазначениеВыбора - НазначениеВыбораПользователейСистемыВзаимодействия
//  Форма - ФормаКлиентскогоПриложения
//  ИдентификаторОбсуждения - ИдентификаторОбсужденияСистемыВзаимодействия
//  Параметры - Структура
//  ВыбраннаяФорма - Строка
//  СтандартнаяОбработка - Булево
//
Процедура ОбработкаПолученияФормыВыбораПользователейСистемыВзаимодействия(НазначениеВыбора,
			Форма, ИдентификаторОбсуждения, Параметры, ВыбраннаяФорма, СтандартнаяОбработка) Экспорт
	
	// СтандартныеПодсистемы.Обсуждения
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.Обсуждения") Тогда
		МодульОбсужденияСлужебныйКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ОбсужденияСлужебныйКлиент");
		МодульОбсужденияСлужебныйКлиент.ПриПолученииФормыВыбораПользователейСистемыВзаимодействия(НазначениеВыбора,
			Форма, ИдентификаторОбсуждения, Параметры, ВыбраннаяФорма, СтандартнаяОбработка);
	КонецЕсли;
	// Конец СтандартныеПодсистемы.Обсуждения
		
КонецПроцедуры

// Возвращает новую структуру параметров для вывода предупреждения перед завершением работы программы.
// Для использования в ОбщегоНазначенияКлиентПереопределяемый.ПередЗавершениемРаботыСистемы.
//
// Возвращаемое значение:
//  Структура:
//    ТекстПредупреждения  - Строка - текст, выводимый в окне веб-браузера (или тонкого клиента) при завершении работы.
//                                    Например, "Имеются редактируемые файлы, которые не помещены в приложение".
//                                    Остальные параметры определяют внешний вид формы предупреждений,
//                                    открываемой после подтверждения в окне веб-браузера (или тонкого клиента).
//    ТекстФлажка          - Строка - если задан, то в форме предупреждений выводится флажок с указанным текстом. 
//                                    Например, "Завершить редактирование файлов (5)".
//    ПоясняющийТекст      - Строка - текст, выводимый в форме сверху управляющего элемента (флажок или гиперссылка).
//                                    Например, "Редактируемые файлы, не помещенные в приложение".
//    ТекстГиперссылки     - Строка - если задан, то выводится гиперссылка с указанным текстом.
//                                    Например, "Редактируемые файлы (5)".
//    РасширеннаяПодсказка - Строка - текст подсказки, выводимый по кнопке справа от управляющего элемента (флажок или
//                                    гиперссылка). Например, "Нажмите для перехода к списку файлов, 
//                                    открытых для редактирования".
//    Приоритет            - Число  - относительный порядок в списке предупреждений на форме (чем больше, тем выше).
//    ВывестиОдноПредупреждение - Булево - если Истина, то в списке предупреждений выводится только одно это
//                                         предупреждение. Т.е. такое предупреждение не совместимо с любыми другими.
//    ДействиеПриУстановленномФлажке - Структура:
//      * Форма          - Строка    - если пользователь установил флажок, то следует открыть указанную форму.
//                                     Например, "Обработка.Файлы.РедактируемыеФайлы".
//      * ПараметрыФормы - Структура - произвольная структура параметров для открытия формы. 
//    ДействиеПриНажатииГиперссылки - Структура:
//      * Форма          - Строка    - путь к форме, которая должна открываться по нажатию на гиперссылку.
//                                     Например, "Обработка.Файлы.РедактируемыеФайлы".
//      * ПараметрыФормы - Структура - произвольная структура параметров для открываемой формы.
//      * ПрикладнаяФормаПредупреждения - Строка - путь к форме, которая должна открываться сразу
//                                        вместо универсальной формы в случае, когда в списке 
//                                        предупреждений оказывается только одно данное предупреждение.
//                                        Например, "Обработка.Файлы.РедактируемыеФайлы".
//      * ПараметрыПрикладнойФормыПредупреждения - Структура - произвольная структура
//                                                 параметров для вышеописанной формы.
//      * РежимОткрытияОкна - РежимОткрытияОкнаФормы - режим открытия форм Форма или ПрикладнаяФормаПредупреждения.
// 
Функция ПредупреждениеПриЗавершенииРаботы() Экспорт
	
	ДействиеПриУстановленномФлажке = Новый Структура;
	ДействиеПриУстановленномФлажке.Вставить("Форма", "");
	ДействиеПриУстановленномФлажке.Вставить("ПараметрыФормы", Неопределено);
	
	ДействиеПриНажатииГиперссылки = Новый Структура;
	ДействиеПриНажатииГиперссылки.Вставить("Форма", "");
	ДействиеПриНажатииГиперссылки.Вставить("ПараметрыФормы", Неопределено);
	ДействиеПриНажатииГиперссылки.Вставить("ПрикладнаяФормаПредупреждения", "");
	ДействиеПриНажатииГиперссылки.Вставить("ПараметрыПрикладнойФормыПредупреждения", Неопределено);
	ДействиеПриНажатииГиперссылки.Вставить("РежимОткрытияОкна", Неопределено);
	
	ПараметрыПредупреждения = Новый Структура;
	ПараметрыПредупреждения.Вставить("ТекстФлажка", "");
	ПараметрыПредупреждения.Вставить("ПоясняющийТекст", "");
	ПараметрыПредупреждения.Вставить("ТекстПредупреждения", "");
	ПараметрыПредупреждения.Вставить("РасширеннаяПодсказка", "");
	ПараметрыПредупреждения.Вставить("ТекстГиперссылки", "");
	ПараметрыПредупреждения.Вставить("ДействиеПриУстановленномФлажке", ДействиеПриУстановленномФлажке);
	ПараметрыПредупреждения.Вставить("ДействиеПриНажатииГиперссылки", ДействиеПриНажатииГиперссылки);
	ПараметрыПредупреждения.Вставить("Приоритет", 0);
	ПараметрыПредупреждения.Вставить("ВывестиОдноПредупреждение", Ложь);
	
	Возврат ПараметрыПредупреждения;
	
КонецФункции

// Возвращает значения параметров, необходимых для работы клиентского кода
// при запуске конфигурации за один серверный вызов (для минимизации клиент-серверного взаимодействия
// и снижения времени запуска). 
// С помощью этой функции можно обращаться к параметрам в клиентском коде, вызываемым из обработчиков событий:
// - ПередНачаломРаботыСистемы,
// - ПриНачалеРаботыСистемы.
//
// В этих обработчиках при запуске недопустимо использовать команды сброса кэша
// повторно используемых модулей, иначе запуск может привести
// к непредсказуемым ошибкам и лишним серверным вызовам.
// 
// Возвращаемое значение:
//   ФиксированнаяСтруктура - параметры работы клиента при запуске. 
//                            См. в ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиентаПриЗапуске.
//
//
Функция ПараметрыРаботыКлиентаПриЗапуске() Экспорт
	
	Возврат СтандартныеПодсистемыКлиентПовтИсп.ПараметрыРаботыКлиентаПриЗапуске();
	
КонецФункции

// Возвращает значения параметров, необходимых для работы клиентского кода конфигурации
// без дополнительных серверных вызовов.
// 
// Возвращаемое значение:
//   ФиксированнаяСтруктура - параметры работы клиента.
//                            Состав свойств см. в ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиента.
//
Функция ПараметрыРаботыКлиента() Экспорт
	
	Возврат СтандартныеПодсистемыКлиентПовтИсп.ПараметрыРаботыКлиента();
	
КонецФункции

// См. ОбщегоНазначенияКлиентПереопределяемый.ПриГлобальномПоиске
Процедура ПриГлобальномПоиске(СтрокаПоиска, ПланПоиска) Экспорт
	
	ИнтеграцияПодсистемБСПКлиент.ПриГлобальномПоиске(СтрокаПоиска, ПланПоиска);
	ОбщегоНазначенияКлиентПереопределяемый.ПриГлобальномПоиске(СтрокаПоиска, ПланПоиска);
	
КонецПроцедуры

// См. ОбщегоНазначенияКлиентПереопределяемый.ПриВыбореРезультатаГлобальногоПоиска
Процедура ПриВыбореРезультатаГлобальногоПоиска(ЭлементРезультата, СтандартнаяОбработка) Экспорт
	
	ИнтеграцияПодсистемБСПКлиент.ПриВыбореРезультатаГлобальногоПоиска(
		ЭлементРезультата,
		СтандартнаяОбработка);
	ОбщегоНазначенияКлиентПереопределяемый.ПриВыбореРезультатаГлобальногоПоиска(
		ЭлементРезультата,
		СтандартнаяОбработка);
	
КонецПроцедуры

// См. ОбщегоНазначенияКлиентПереопределяемый.ПриВыбореДействияРезультатаГлобальногоПоиска
Процедура ПриВыбореДействияРезультатаГлобальногоПоиска(ЭлементРезультата, Действие) Экспорт
	
	ИнтеграцияПодсистемБСПКлиент.ПриВыбореДействияРезультатаГлобальногоПоиска(
		ЭлементРезультата,
		Действие);
	ОбщегоНазначенияКлиентПереопределяемый.ПриВыбореДействияРезультатаГлобальногоПоиска(
		ЭлементРезультата,
		Действие);
	
КонецПроцедуры

// См. ОбщегоНазначенияКлиентПереопределяемый.ОбработкаПереходаПоНавигационнойСсылке
Процедура ОбработкаПереходаПоНавигационнойСсылке(ДанныеПереходаПоНавигационнойСсылке,
	СтандартнаяОбработка) Экспорт
	
	ИнтеграцияПодсистемБСПКлиент.ОбработкаПереходаПоНавигационнойСсылке(
		ДанныеПереходаПоНавигационнойСсылке,
		СтандартнаяОбработка);
	ОбщегоНазначенияКлиентПереопределяемый.ОбработкаПереходаПоНавигационнойСсылке(
		ДанныеПереходаПоНавигационнойСсылке,
		СтандартнаяОбработка);
	
КонецПроцедуры

#КонецОбласти

#Область ДляВызоваИзДругихПодсистем

// Вызывается при получении оповещений от сервера.
// Оповещения отправляются на сервере в процедурах ПриОтправкеСерверногоОповещения.
// Список оповещений смотри в ОбщегоНазначенияПереопределяемый.ПриДобавленииСерверныхОповещений.
// 
// Параметры:
//  ИмяОповещения - см. СерверныеОповещения.ОтправитьСерверноеОповещение.ИмяОповещения
//  Результат     - см. СерверныеОповещения.ОтправитьСерверноеОповещение.Результат
//
// Пример:
//	Если ИмяОповещения <> "СтандартныеПодсистемы.ЗавершениеРаботыПользователей.БлокировкаСеансов" Тогда
//		Возврат;
//	КонецЕсли;
//	Если РаботаПользователейЗавершается() Тогда
//		ЗавершитьРаботуПользователей(Результат);
//	ИначеЕсли ВключенКонтрольЗавершенияРаботыПользователей() Тогда
//		КонтрольРежимаЗавершенияРаботыПользователей(Результат);
//	КонецЕсли;
//
Процедура ПриПолученииСерверногоОповещения(ИмяОповещения, Результат) Экспорт
	
	Если ИмяОповещения = "СтандартныеПодсистемы.БазоваяФункциональность.ФункциональныеОпцииИзменены" Тогда
		ОтключитьОбработчикОжидания("ОбновитьИнтерфейсПриИзмененииФункциональныхОпций");
		ПодключитьОбработчикОжидания("ОбновитьИнтерфейсПриИзмененииФункциональныхОпций", 5*60, Истина);
		
	ИначеЕсли ИмяОповещения = "СтандартныеПодсистемы.БазоваяФункциональность.ПовторноИспользуемыеЗначенияУстарели" Тогда
		ОбновитьПовторноИспользуемыеЗначения();
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область СлужебныйПрограммныйИнтерфейс

Функция ЗапускПрограммыЗавершен() Экспорт
	
	ИмяПараметра = "СтандартныеПодсистемы.ЗапускПрограммыЗавершен";
	Если ПараметрыПриложения[ИмяПараметра] = Истина Тогда
		Возврат Истина;
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

Функция ПараметрКлиента(ИмяПараметра = Неопределено) Экспорт
	
	ИмяГлобальногоПараметра = "СтандартныеПодсистемы.ПараметрыКлиента";
	ПараметрыКлиента = ПараметрыПриложения[ИмяГлобальногоПараметра];
	
	Если ПараметрыКлиента = Неопределено Тогда
		// Заполнение постоянных параметров клиента.
		СтандартныеПодсистемыКлиентПовтИсп.ПараметрыРаботыКлиентаПриЗапуске();
		ПараметрыКлиента = ПараметрыПриложения[ИмяГлобальногоПараметра];
	КонецЕсли;
	
	Если ИмяПараметра = Неопределено Тогда
		Возврат ПараметрыКлиента;
	Иначе
		Возврат ПараметрыКлиента[ИмяПараметра];
	КонецЕсли;
	
КонецФункции

Процедура УстановитьПараметрКлиента(ИмяПараметра, Значение) Экспорт
	ИмяГлобальногоПараметра = "СтандартныеПодсистемы.ПараметрыКлиента";
	ПараметрыПриложения[ИмяГлобальногоПараметра].Вставить(ИмяПараметра, Значение);
КонецПроцедуры

Процедура ЗаполнитьПараметрыКлиента(ПараметрыКлиента) Экспорт
	
	ИмяПараметра = "СтандартныеПодсистемы.ПараметрыКлиента";
	Если ТипЗнч(ПараметрыПриложения[ИмяПараметра]) <> Тип("Структура") Тогда
		ПараметрыПриложения[ИмяПараметра] = Новый Структура;
		ПараметрыПриложения[ИмяПараметра].Вставить("РазделениеВключено");
		ПараметрыПриложения[ИмяПараметра].Вставить("ИнформационнаяБазаФайловая");
		ПараметрыПриложения[ИмяПараметра].Вставить("ЭтоБазоваяВерсияКонфигурации");
		ПараметрыПриложения[ИмяПараметра].Вставить("ЭтоУчебнаяПлатформа");
		ПараметрыПриложения[ИмяПараметра].Вставить("ЭтоСеансВнешнегоПользователя");
		ПараметрыПриложения[ИмяПараметра].Вставить("ЭтоПолноправныйПользователь");
		ПараметрыПриложения[ИмяПараметра].Вставить("ЭтоАдминистраторСистемы");
		ПараметрыПриложения[ИмяПараметра].Вставить("АвторизованныйПользователь");
		ПараметрыПриложения[ИмяПараметра].Вставить("ЗапрашиватьПодтверждениеПриЗавершенииПрограммы");
		ПараметрыПриложения[ИмяПараметра].Вставить("ДоступноИспользованиеРазделенныхДанных");
		ПараметрыПриложения[ИмяПараметра].Вставить("ПараметрыАвтономнойРаботы");
		ПараметрыПриложения[ИмяПараметра].Вставить("ПерсональныеНастройкиРаботыСФайлами");
		ПараметрыПриложения[ИмяПараметра].Вставить("КоличествоЗанятыхФайлов");
		ПараметрыПриложения[ИмяПараметра].Вставить("РезервноеКопированиеИБПриЗавершенииРаботы");
		ПараметрыПриложения[ИмяПараметра].Вставить("ОтображатьПомощникНастройкиРазрешений");
		ПараметрыПриложения[ИмяПараметра].Вставить("ПоправкаКВремениСеанса");
		ПараметрыПриложения[ИмяПараметра].Вставить("ПоправкаКУниверсальномуВремени");
		ПараметрыПриложения[ИмяПараметра].Вставить("СмещениеСтандартногоВремени");
		ПараметрыПриложения[ИмяПараметра].Вставить("СмещениеДатыКлиента");
		ПараметрыПриложения[ИмяПараметра].Вставить("КодОсновногоЯзыка");
		ПараметрыПриложения[ИмяПараметра].Вставить("КоличествоДополнительныхЯзыков");
		ПараметрыПриложения[ИмяПараметра].Вставить("НастройкиОтправкиИнформацииОбОшибке");
	КонецЕсли;
	Если Не ПараметрыПриложения[ИмяПараметра].Свойство("ОценкаПроизводительности")
	   И ПараметрыКлиента.Свойство("ОценкаПроизводительности") Тогда
		ПараметрыПриложения[ИмяПараметра].Вставить("ОценкаПроизводительности");
	КонецЕсли;
	
	ЗаполнитьЗначенияСвойств(ПараметрыПриложения[ИмяПараметра], ПараметрыКлиента);
	
КонецПроцедуры

// После предупреждения вызывает процедуру с параметрами Результат, ДополнительныеПараметры.
//
// Параметры:
//  Параметры           - Структура - которая содержит свойство:
//                          ОбработкаПродолжения - ОписаниеОповещения - которое
//                          содержит процедуру с двумя параметрами:
//                            Результат, ДополнительныеПараметры.
//
//  ОписаниеПредупреждения - Неопределено - предупреждение не требуется.
//  ОписаниеПредупреждения - Строка - текст предупреждения, который нужно показать.
//  ОписаниеПредупреждения - Структура:
//       * ТекстПредупреждения - Строка - текст предупреждения, который нужно показать.
//       * Кнопки              - СписокЗначений - для процедуры ПоказатьВопросПользователю.
//       * ПараметрыВопроса    - Структура - содержит подмножество свойств,
//                                 которые нужно переопределить, из числа
//                                 возвращаемых функцией ПараметрыВопросаПользователю.
//
Процедура ПоказатьПредупреждениеИПродолжить(Параметры, ОписаниеПредупреждения) Экспорт
	
	ОповещениеСРезультатом = Параметры.ОбработкаПродолжения;
	
	Если ОписаниеПредупреждения = Неопределено Тогда
		ВыполнитьОбработкуОповещения(ОповещениеСРезультатом);
		Возврат;
	КонецЕсли;
	
	Кнопки = Новый СписокЗначений;
	ПараметрыВопроса = ПараметрыВопросаПользователю();
	ПараметрыВопроса.ПредлагатьБольшеНеЗадаватьЭтотВопрос = Ложь;
	ПараметрыВопроса.БлокироватьВесьИнтерфейс = Истина;
	ПараметрыВопроса.Картинка = БиблиотекаКартинок.ДиалогВосклицание;
	
	Если Параметры.Отказ Тогда
		Кнопки.Добавить("Завершить", НСтр("ru = 'Завершить работу'"));
		ПараметрыВопроса.КнопкаПоУмолчанию = "Завершить";
	Иначе
		Кнопки.Добавить("Продолжить", НСтр("ru = 'Продолжить'"));
		Кнопки.Добавить("Завершить",  НСтр("ru = 'Завершить работу'"));
		ПараметрыВопроса.КнопкаПоУмолчанию = "Продолжить";
	КонецЕсли;
	
	Если ТипЗнч(ОписаниеПредупреждения) = Тип("Структура") Тогда
		ТекстПредупреждения = ОписаниеПредупреждения.ТекстПредупреждения;
		Кнопки = ОписаниеПредупреждения.Кнопки;
		ЗаполнитьЗначенияСвойств(ПараметрыВопроса, ОписаниеПредупреждения.ПараметрыВопроса);
	Иначе
		ТекстПредупреждения = ОписаниеПредупреждения;
	КонецЕсли;
	
	ОповещениеОЗакрытии = Новый ОписаниеОповещения("ПоказатьПредупреждениеИПродолжитьЗавершение", ЭтотОбъект, Параметры);
	ПоказатьВопросПользователю(ОповещениеОЗакрытии, ТекстПредупреждения, Кнопки, ПараметрыВопроса);
	
КонецПроцедуры

// Возвращает имя исполняемого файла в зависимости от вида клиента.
//
// Возвращаемое значение:
//  Строка
//
Функция ИмяИсполняемогоФайлаПриложения(ПолучитьИмяФайлаКонфигуратора = Ложь) Экспорт
	
	ШаблонИмениФайла = "1cv8[УчебнаяПлатформа].exe";
	
#Если ТонкийКлиент Тогда
	Если Не ПолучитьИмяФайлаКонфигуратора Тогда
		ШаблонИмениФайла = "1cv8c[УчебнаяПлатформа].exe";
	КонецЕсли;	
#КонецЕсли
	
	Возврат СтрЗаменить(ШаблонИмениФайла, "[УчебнаяПлатформа]", ?(ЭтоУчебнаяПлатформа(), "t", ""));
	
КонецФункции

// Устанавливает / отменяет хранение ссылки на управляемую форму в глобальной переменной.
// Требуется для случаев, когда ссылка на форму передается через ДополнительныеПараметры
// в объекте ОписаниеОповещения, который не блокирует освобождение закрытой формы.
//
Процедура УстановитьХранениеФормы(Форма, Хранение) Экспорт
	
	Хранилище = ПараметрыПриложения["СтандартныеПодсистемы.ВременноеХранилищеСсылокНаУправляемыеФормы"];
	Если Хранилище = Неопределено Тогда
		Хранилище = Новый Соответствие;
		ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ВременноеХранилищеСсылокНаУправляемыеФормы", Хранилище);
	КонецЕсли;
	
	Если Хранение Тогда
		Хранилище.Вставить(Форма, Новый Структура("Форма", Форма));
	ИначеЕсли Хранилище.Получить(Форма) <> Неопределено Тогда
		Хранилище.Удалить(Форма);
	КонецЕсли;
	
КонецПроцедуры

// Проверяет, что текущие данные определены и не являются группировкой.
// Предназначена для обработчиков таблиц формы динамических списков.
//
// Параметры:
//  ТаблицаИлиТекущиеДанные - ТаблицаФормы - таблица формы динамического списка для проверки текущих данных.
//                          - Неопределено
//                          - ДанныеФормыСтруктура
//                          - Структура - текущие данные для проверки.
//
// Возвращаемое значение:
//  Булево
//
Функция ЭтоЭлементДинамическогоСписка(ТаблицаИлиТекущиеДанные) Экспорт
	
	Если ТипЗнч(ТаблицаИлиТекущиеДанные) = Тип("ТаблицаФормы") Тогда
		ТекущиеДанные = ТаблицаИлиТекущиеДанные.ТекущиеДанные;
	Иначе
		ТекущиеДанные = ТаблицаИлиТекущиеДанные;
	КонецЕсли;
	
	Если ТипЗнч(ТекущиеДанные) <> Тип("ДанныеФормыСтруктура")
	   И ТипЗнч(ТекущиеДанные) <> Тип("Структура") Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если ТекущиеДанные.Свойство("ГруппировкаСтроки") Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

// Проверяет, выполнено ли опасное отключение процедур запуска для целей автоматического тестирования.
//
// Возвращаемое значение:
//  Булево
//
Функция ОтключенаЛогикаНачалаРаботыСистемы() Экспорт
	Возврат СтрНайти(ПараметрЗапуска, "ОтключитьЛогикуНачалаРаботыСистемы") > 0;
КонецФункции

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

// Переадресует оповещение без результата на оповещение с результатом.
//
// Возвращаемое значение:
//  ОписаниеОповещения
//
Функция ОповещениеБезРезультата(ОповещениеСРезультатом) Экспорт
	
	Возврат Новый ОписаниеОповещения("ВыполнитьОповещениеСПустымРезультатом", ЭтотОбъект, ОповещениеСРезультатом);
	
КонецФункции

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

#Область ТехническаяПоддержка

// Возвращает информацию для технической поддержки, содержащая основную, системную и дополнительную информацию.
//
// Системная информация содержит описание технических характеристик клиентского компьютера.
// Серверный аналог: см. СтандартныеПодсистемыСервер.ИнформацияДляПоддержки.
//
// Пример:
//  Демонстрационная конфигурация, редакция Х.Х, Х.Х.ХХ.ХХ
//  Платформа 1С:Предприятие: Х.Х.ХХ.ХХХХ
//  Библиотека стандартных подсистем: Х.Х.ХХ.ХХ
//
//  Системная информация
//  Версия ОС: ХХХ
//  Процессор: ХХХ
//  Оперативная память: ХХХ
//  Приложение: ХХХ
//
//  Дополнительная информация
//  Имя COM-соединителя: ХХХ
//  Базовая конфигурация: Нет
//  Полноправный пользователь: Нет
//  Учебная платформа: Нет
//  Конфигурация изменена: Нет
//
// Возвращаемое значение:
//  Строка - информация для технической поддержки.
//
Функция ИнформацияДляПоддержки() Экспорт
	
	ИнформацияДляПоддержки = СтандартныеПодсистемыКлиентСервер.НоваяИнформацияДляПоддержки();
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	ЗаполнитьЗначенияСвойств(ИнформацияДляПоддержки, СистемнаяИнформация);
	
	Если ЗапускПрограммыЗавершен() Тогда
		ПараметрыКонфигурации = ПараметрыРаботыКлиента();
	Иначе
		ПараметрыКонфигурации = ПараметрыРаботыКлиентаПриЗапуске();
	КонецЕсли;
	
	ПараметрНедоступен = НСтр("ru = 'недоступно'");
	
	// АПК:1417-выкл Динамический состав свойств.
	ИнформацияДляПоддержки.НазваниеПрограммы = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		ПараметрыКонфигурации,
		"ПодробнаяИнформация",
		ПараметрНедоступен);
	// АПК:1417-вкл
	
	// АПК:1417-выкл Динамический состав свойств.
	ИнформацияДляПоддержки.ВерсияПрограммы = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		ПараметрыКонфигурации,
		"ВерсияКонфигурации",
		ПараметрНедоступен);
	// АПК:1417-вкл
	
	ИнформацияДляПоддержки.ВерсияБСП = СтандартныеПодсистемыВызовСервера.ВерсияБиблиотеки();
	ИнформацияДляПоддержки.ИмяCOMСоединителя = ОбщегоНазначенияКлиентСервер.ИмяCOMСоединителя();
	ИнформацияДляПоддержки.ЭтоБазоваяКонфигурация = ЭтоБазоваяВерсияКонфигурации();
	ИнформацияДляПоддержки.ЭтоПолноправныйПользователь = ПользователиКлиент.ЭтоПолноправныйПользователь();
	ИнформацияДляПоддержки.ЭтоУчебнаяПлатформа = ЭтоУчебнаяПлатформа();
	
	// АПК:1417-выкл Динамический состав свойств.
	НастройкиОбновления = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		ПараметрыКонфигурации,
		"НастройкиОбновления");
	// АПК:1417-вкл
	
	// АПК:1417-выкл Динамический состав свойств.
	ИнформацияДляПоддержки.КонфигурацияИзменена = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		НастройкиОбновления,
		"КонфигурацияИзменена",
		ПараметрНедоступен);
	// АПК:1417-вкл
	
	Возврат СтандартныеПодсистемыКлиентСервер.ТекстИнформацииДляПоддержки(ИнформацияДляПоддержки);
	
КонецФункции

#КонецОбласти

#Область ОбработчикиСобытийПодсистемКонфигурации

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

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

#КонецОбласти

#Область ВыводРезультатаВыполнения

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

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

// Открывает форму списка объекта с позиционированием на объекте.
//
// Параметры:
//   Ссылка - ЛюбаяСсылка - объект, который необходимо показать в списке.
//   ИмяФормыСписка - Строка - имя формы списка.
//       Если передать Неопределено то будет определена автоматически (потребуется вызов сервера).
//   ПараметрыФормы - Структура - дополнительные параметры открытия формы списка.
//
Процедура ПоказатьВСписке(Ссылка, ИмяФормыСписка, ПараметрыФормы = Неопределено) Экспорт
	Если Ссылка = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ИмяФормыСписка = Неопределено Тогда
		ПолноеИмя = СтандартныеПодсистемыВызовСервера.ПолноеИмяОбъектаМетаданных(ТипЗнч(Ссылка));
		Если ПолноеИмя = Неопределено Тогда
			Возврат;
		КонецЕсли;
		ИмяФормыСписка = ПолноеИмя + ".ФормаСписка";
	КонецЕсли;
	
	Если ПараметрыФормы = Неопределено Тогда
		ПараметрыФормы = Новый Структура;
	КонецЕсли;
	
	ПараметрыФормы.Вставить("ТекущаяСтрока", Ссылка);
	
	Форма = ПолучитьФорму(ИмяФормыСписка, ПараметрыФормы, , Истина);
	Форма.Открыть();
	Форма.ВыполнитьПереход(Ссылка);
КонецПроцедуры

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

#Если Не ВебКлиент И Не МобильныйКлиент Тогда

// Каталог системных приложений, например, "C:\Windows\System32".
// Используется только в ОС Windows.
//
// Возвращаемое значение:
//  Строка
//
Функция КаталогСистемныхПриложений() Экспорт
	
	ОбъектShell = Новый COMОбъект("Shell.Application");
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 Тогда 
		// Для 32-битной системы "C:\Windows\System32".
		// Для 64-битной системы "C:\Windows\SysWOW64".
		ОбъектFolder = ОбъектShell.Namespace(41);
	ИначеЕсли СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64 Тогда 
		// Для любой системы "C:\Windows\System32".
		ОбъектFolder = ОбъектShell.Namespace(37);
	КонецЕсли;
	
	Возврат ОбъектFolder.Self.Path + "\";
	
КонецФункции

#КонецЕсли

// Асинхронный аналог метода платформы ВыполнитьОбработкуОповещения.
// Выполняет обработку оповещения асинхронно, подобно методам платформы, например НачатьПолучениеФайла.
// Используется, когда обработку оповещения нужно выполнить после синхронного завершения вызова,
// то есть с некоторой минимальной задержкой.
// 
// Параметры:
//  ОписаниеОповещения - ОписаниеОповещения - оповещение, которое нужно выполнить.
//  Результат  - Произвольный - значение, которое передается в параметр Результат
//               метода платформы ВыполнитьОбработкуОповещения.
//
Процедура НачатьВыполнениеОбработкиОповещения(ОписаниеОповещения, Результат = Неопределено) Экспорт
	
	Контекст = Новый Структура;
	Контекст.Вставить("Оповещение", ОписаниеОповещения);
	Контекст.Вставить("Результат", Результат);
	
	Поток = Новый ПотокВПамяти;
	Поток.НачатьПолучениеРазмера(Новый ОписаниеОповещения(
		"НачатьВыполнениеОбработкиОповещенияЗавершение", ЭтотОбъект, Контекст));
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

#Область ПередНачаломРаботыСистемы

// Продолжение процедуры ПередНачаломРаботыСистемы.
Процедура ДействияПередНачаломРаботыСистемы(ОповещениеЗавершения)
	
	Параметры = ПараметрыОбработкиПередНачаломРаботыСистемы();
	
	// Внешние параметры описания результата.
	Параметры.Вставить("Отказ", Ложь);
	Параметры.Вставить("Перезапустить", Ложь);
	Параметры.Вставить("ДополнительныеПараметрыКоманднойСтроки", "");
	
	// Внешние параметры управления выполнением.
	Параметры.Вставить("ИнтерактивнаяОбработка", Неопределено); // ОписаниеОповещения.
	Параметры.Вставить("ОбработкаПродолжения",   Неопределено); // ОписаниеОповещения.
	Параметры.Вставить("НепрерывноеВыполнение", Истина);
	Параметры.Вставить("ПолученныеПараметрыКлиента", Новый Структура);
	Параметры.Вставить("ВызванныеПроцедуры", Новый Массив);
	УстановитьПоследнююПроцедуру(Параметры, "СтандартныеПодсистемыКлиент", "ПередНачаломРаботыСистемы");
	
	// Внутренние параметры.
	Параметры.Вставить("ОповещениеЗавершения", ОповещениеЗавершения);
	Параметры.Вставить("ОбработкаЗавершения", Новый ОписаниеОповещения(
		"ДействияПередНачаломРаботыСистемыОбработкаЗавершения", ЭтотОбъект));
	
	ОбновитьПараметрыРаботыКлиента(Параметры, Истина, ОповещениеЗавершения <> Неопределено);
	
	// Подготовка перехода к следующей процедуре.
	Параметры.Вставить("ОбработкаПродолжения", Новый ОписаниеОповещения(
		"ДействияПередНачаломРаботыСистемыВИнтеграционнойПроцедуре", ЭтотОбъект));
	
	Если ОтключенаЛогикаНачалаРаботыСистемы() Тогда
		Попытка
			// Проверка права отключения и заполнение параметров работы клиента на сервере.
			СвойстваКлиента = Новый Структура;
			ЗаполнитьПараметрыРаботыКлиентаНаСервере(СвойстваКлиента);
			СтандартныеПодсистемыВызовСервера.ПроверитьПравоОтключитьЛогикуНачалаРаботыСистемы(СвойстваКлиента);
			Если СвойстваКлиента.Свойство("ОшибкаНетПраваОтключитьЛогикуНачалаРаботыСистемы") Тогда
				ПользователиСлужебныйКлиент.УстановитьИнтерактивнуюОбработкуПриОшибкеНедостаточноПравДляВходаВПрограмму(
					Параметры, СвойстваКлиента.ОшибкаНетПраваОтключитьЛогикуНачалаРаботыСистемы);
				УстановитьПоследнююПроцедуру(Параметры, "ПользователиСлужебныйКлиент",
					"УстановитьИнтерактивнуюОбработкуПриОшибкеНедостаточноПравДляВходаВПрограмму");
			КонецЕсли;
		Исключение
			ТекстОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
			СтандартныеПодсистемыВызовСервера.ЗаписатьОшибкуВЖурналРегистрацииПриЗапускеИлиЗавершении(
				Ложь, "Запуск", ТекстОшибки);
			ПользователиСлужебныйКлиент.УстановитьИнтерактивнуюОбработкуПриОшибкеНедостаточноПравДляВходаВПрограмму(
				Параметры, ТекстОшибки);
			УстановитьПоследнююПроцедуру(Параметры, "ПользователиСлужебныйКлиент",
				"УстановитьИнтерактивнуюОбработкуПриОшибкеНедостаточноПравДляВходаВПрограмму");
		КонецПопытки;
		Если ИнтерактивнаяОбработкаПередНачаломРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		СкрытьРабочийСтолПриНачалеРаботыСистемы(Истина, Истина);
		Возврат;
	КонецЕсли;
	
	// Стандартный первый серверный вызов с целью предварительного
	// заполнения параметров работы клиента на сервере.
	Попытка
		ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.БазоваяФункциональность");
	Исключение
		ОбработатьОшибкуПередНачаломРаботыСистемы(Параметры, ИнформацияОбОшибке(), Истина);
	КонецПопытки;
	УстановитьПоследнююПроцедуру(Параметры, "ОбщегоНазначенияКлиент", "ПодсистемаСуществует");
	Если ИнтерактивнаяОбработкаПередНачаломРаботыСистемы(Параметры) Тогда
		Возврат;
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Параметры.ОбработкаПродолжения);
	
КонецПроцедуры

// Только для внутреннего использования. Продолжение процедуры ПередНачаломРаботыСистемы.
Процедура ДействияПередНачаломРаботыСистемыВИнтеграционнойПроцедуре(Неопределен, Контекст) Экспорт
	
	Параметры = ПараметрыОбработкиПередНачаломРаботыСистемы();
	УстановитьПоследнююПроцедуру(Параметры, "СтандартныеПодсистемыКлиент",
		"ДействияПередНачаломРаботыСистемыВИнтеграционнойПроцедуре");
	
	Если Не ПродолжитьДействияПередНачаломРаботыСистемы(Параметры) Тогда
		Возврат;
	КонецЕсли;
	
	Параметры.Вставить("ОбработкаПродолжения", Новый ОписаниеОповещения(
		"ДействияПередНачаломРаботыСистемыВМодуляхИнтеграционнойПроцедуры", ЭтотОбъект));
	
	Параметры.Вставить("ИндексТекущегоМодуля", 0);
	Параметры.Вставить("ДобавленныеМодули", Новый Массив);
	Попытка
		Параметры.Вставить("Модули", Новый Массив);
		ИнтеграцияПодсистемБСПКлиент.ПередНачаломРаботыСистемы(Параметры);
		УстановитьПоследнююПроцедуру(Параметры, "ИнтеграцияПодсистемБСПКлиент", "ПередНачаломРаботыСистемы");
		Параметры.Вставить("ДобавленныеМодули", Параметры.Модули);
		Параметры.Удалить("Модули");
	Исключение
		ОбработатьОшибкуПередНачаломРаботыСистемы(Параметры, ИнформацияОбОшибке(), Истина);
	КонецПопытки;
	Если ИнтерактивнаяОбработкаПередНачаломРаботыСистемы(Параметры) Тогда
		Возврат;
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Параметры.ОбработкаПродолжения);
	
КонецПроцедуры

// Только для внутреннего использования. Продолжение процедуры ПередНачаломРаботыСистемы.
Процедура ДействияПередНачаломРаботыСистемыВМодуляхИнтеграционнойПроцедуры(Неопределен, Контекст) Экспорт
	
	Пока Истина Цикл
		
		Параметры = ПараметрыОбработкиПередНачаломРаботыСистемы();
		УстановитьПоследнююПроцедуру(Параметры, "СтандартныеПодсистемыКлиент",
			"ДействияПередНачаломРаботыСистемыВМодуляхИнтеграционнойПроцедуры");
		
		Если Не ПродолжитьДействияПередНачаломРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
		Если Параметры.ИндексТекущегоМодуля >= Параметры.ДобавленныеМодули.Количество() Тогда
			ДействияПередНачаломРаботыСистемыВПереопределяемойПроцедуре(Неопределено, Неопределено);
			Возврат;
		КонецЕсли;
	
		ОписаниеМодуля = Параметры.ДобавленныеМодули[Параметры.ИндексТекущегоМодуля];
		Параметры.ИндексТекущегоМодуля = Параметры.ИндексТекущегоМодуля + 1;
		
		Попытка
			Если ТипЗнч(ОписаниеМодуля) <> Тип("Структура") Тогда
				ТекущийМодуль = ОписаниеМодуля;
				ТекущийМодуль.ПередНачаломРаботыСистемы(Параметры);
				УстановитьПоследнююПроцедуру(Параметры, ТекущийМодуль, "ПередНачаломРаботыСистемы");
			Иначе
				ТекущийМодуль = ОписаниеМодуля.Модуль;
				Если ОписаниеМодуля.Номер = 2 Тогда
					ТекущийМодуль.ПередНачаломРаботыСистемы2(Параметры);
					УстановитьПоследнююПроцедуру(Параметры, ТекущийМодуль, "ПередНачаломРаботыСистемы2");
				ИначеЕсли ОписаниеМодуля.Номер = 3 Тогда
					ТекущийМодуль.ПередНачаломРаботыСистемы3(Параметры);
					УстановитьПоследнююПроцедуру(Параметры, ТекущийМодуль, "ПередНачаломРаботыСистемы3");
				ИначеЕсли ОписаниеМодуля.Номер = 4 Тогда
					ТекущийМодуль.ПередНачаломРаботыСистемы4(Параметры);
					УстановитьПоследнююПроцедуру(Параметры, ТекущийМодуль, "ПередНачаломРаботыСистемы4");
				ИначеЕсли ОписаниеМодуля.Номер = 5 Тогда
					ТекущийМодуль.ПередНачаломРаботыСистемы5(Параметры);
					УстановитьПоследнююПроцедуру(Параметры, ТекущийМодуль, "ПередНачаломРаботыСистемы5");
				КонецЕсли;
			КонецЕсли;
		Исключение
			ОбработатьОшибкуПередНачаломРаботыСистемы(Параметры, ИнформацияОбОшибке(), Истина);
		КонецПопытки;
		Если ИнтерактивнаяОбработкаПередНачаломРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

// Только для внутреннего использования. Продолжение процедуры ПередНачаломРаботыСистемы.
Процедура ДействияПередНачаломРаботыСистемыВМодуляхПереопределяемойПроцедуры(Неопределен, Контекст) Экспорт
	
	Пока Истина Цикл
		
		Параметры = ПараметрыОбработкиПередНачаломРаботыСистемы();
		УстановитьПоследнююПроцедуру(Параметры, "СтандартныеПодсистемыКлиент",
			"ДействияПередНачаломРаботыСистемыВМодуляхПереопределяемойПроцедуры");
		
		Если Не ПродолжитьДействияПередНачаломРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
		Если Параметры.ИндексТекущегоМодуля >= Параметры.ДобавленныеМодули.Количество() Тогда
			ДействияПередНачаломРаботыСистемыПослеВсехПроцедур(Неопределено, Неопределено);
			Возврат;
		КонецЕсли;
		
		ТекущийМодуль = Параметры.ДобавленныеМодули[Параметры.ИндексТекущегоМодуля];
		Параметры.ИндексТекущегоМодуля = Параметры.ИндексТекущегоМодуля + 1;
		
		Попытка
			ТекущийМодуль.ПередНачаломРаботыСистемы(Параметры);
			УстановитьПоследнююПроцедуру(Параметры, ТекущийМодуль, "ПередНачаломРаботыСистемы");
		Исключение
			ОбработатьОшибкуПередНачаломРаботыСистемы(Параметры, ИнформацияОбОшибке());
		КонецПопытки;
		Если ИнтерактивнаяОбработкаПередНачаломРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

// Только для внутреннего использования. Завершение процедуры ПередНачаломРаботыСистемы.
Процедура ДействияПередНачаломРаботыСистемыОбработкаЗавершения(Неопределен, Контекст) Экспорт
	
	Параметры = ПараметрыОбработкиПередНачаломРаботыСистемы(Истина);
	
	Параметры.ОбработкаПродолжения = Неопределено;
	Параметры.ОбработкаЗавершения  = Неопределено;
	
	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
	ПараметрыПриЗапускеПрограммы.Удалить("ПолученныеПараметрыКлиента");
	ПараметрыПриложения["СтандартныеПодсистемы.ЗапускПрограммыЗавершен"] = Истина;
	
	Если Параметры.ОповещениеЗавершения <> Неопределено Тогда
		Результат = Новый Структура;
		Результат.Вставить("Отказ", Параметры.Отказ);
		Результат.Вставить("Перезапустить", Параметры.Перезапустить);
		Результат.Вставить("ДополнительныеПараметрыКоманднойСтроки", Параметры.ДополнительныеПараметрыКоманднойСтроки);
		ВыполнитьОбработкуОповещения(Параметры.ОповещениеЗавершения, Результат);
		Возврат;
	КонецЕсли;
	
	Если Параметры.Отказ Тогда
		Если Параметры.Перезапустить <> Истина Тогда
			ПрекратитьРаботуСистемы();
		ИначеЕсли ЗначениеЗаполнено(Параметры.ДополнительныеПараметрыКоманднойСтроки) Тогда
			ПрекратитьРаботуСистемы(Параметры.Перезапустить, Параметры.ДополнительныеПараметрыКоманднойСтроки);
		Иначе
			ПрекратитьРаботуСистемы(Параметры.Перезапустить);
		КонецЕсли;
		
	ИначеЕсли Не Параметры.НепрерывноеВыполнение Тогда
		Если ПараметрыПриЗапускеПрограммы.Свойство("ПараметрыОбработки") Тогда
			ПараметрыПриЗапускеПрограммы.Удалить("ПараметрыОбработки");
		КонецЕсли;
		ПодключитьОбработчикОжидания("ОбработчикОжиданияПриНачалеРаботыСистемы", 0.1, Истина);
	КонецЕсли;
	
КонецПроцедуры

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

#КонецОбласти

#Область ПриНачалеРаботыСистемы

// Продолжение процедуры ПриНачалеРаботыСистемы.
Процедура ДействияПриНачалеРаботыСистемы(ОповещениеЗавершения, НепрерывноеВыполнение)
	
	Параметры = ПараметрыОбработкиПриНачалеРаботыСистемы();
	
	// Внешние параметры описания результата.
	Параметры.Вставить("Отказ", Ложь);
	Параметры.Вставить("Перезапустить", Ложь);
	Параметры.Вставить("ДополнительныеПараметрыКоманднойСтроки", "");
	
	// Внешние параметры управления выполнением.
	Параметры.Вставить("ИнтерактивнаяОбработка", Неопределено); // ОписаниеОповещения.
	Параметры.Вставить("ОбработкаПродолжения",   Неопределено); // ОписаниеОповещения.
	Параметры.Вставить("НепрерывноеВыполнение", НепрерывноеВыполнение);
	
	// Внутренние параметры.
	Параметры.Вставить("ОповещениеЗавершения", ОповещениеЗавершения);
	Параметры.Вставить("ОбработкаЗавершения", Новый ОписаниеОповещения(
		"ДействияПриНачалеРаботыСистемыОбработкаЗавершения", ЭтотОбъект));
	
	// Подготовка перехода к следующей процедуре.
	Параметры.Вставить("ОбработкаПродолжения", Новый ОписаниеОповещения(
		"ДействияПриНачалеРаботыСистемыВИнтеграционнойПроцедуре", ЭтотОбъект));
	
	Если Не ЗапускПрограммыЗавершен() Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Возникла непредвиденная ситуация при запуске приложения.
			           |
			           |Техническая информация:
			           |Недопустимый вызов %1 при запуске приложения. Сначала должна быть завершена процедура %2.
			           |Предположительно, один из обработчиков события не вызвал оповещение для продолжения.
			           |Вызванные процедуры (в обратном порядке):
			           |%3'"),
			"СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы",
			"СтандартныеПодсистемыКлиент.ПередНачаломРаботыСистемы",
			ВызванныеПроцедурыПередНачаломРаботыСистемы());
		Попытка
			ВызватьИсключение ТекстОшибки;
		Исключение
			ОбработатьОшибкуПриНачалеРаботыСистемы(Параметры, ИнформацияОбОшибке(), Истина);
		КонецПопытки;
		Если ИнтерактивнаяОбработкаПриНачалеРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	Попытка
		УстановитьРасширенныйЗаголовокПриложения(Истина); // Для главного окна.
		
		Если НЕ ОбработатьПараметрыЗапуска() Тогда
			Параметры.Отказ = Истина;
			ВыполнитьОбработкуОповещения(Параметры.ОбработкаЗавершения);
			Возврат;
		КонецЕсли;
	Исключение
		ОбработатьОшибкуПриНачалеРаботыСистемы(Параметры, ИнформацияОбОшибке(), Истина);
	КонецПопытки;
	Если ИнтерактивнаяОбработкаПриНачалеРаботыСистемы(Параметры) Тогда
		Возврат;
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Параметры.ОбработкаПродолжения);
	
КонецПроцедуры

// Только для внутреннего использования. Продолжение процедуры ПриНачалеРаботыСистемы.
Процедура ДействияПриНачалеРаботыСистемыВИнтеграционнойПроцедуре(Неопределен, Контекст) Экспорт
	
	Параметры = ПараметрыОбработкиПриНачалеРаботыСистемы();
	
	Если Не ПродолжитьДействияПриНачалеРаботыСистемы(Параметры) Тогда
		Возврат;
	КонецЕсли;
	
	Параметры.Вставить("ОбработкаПродолжения", Новый ОписаниеОповещения(
		"ДействияПриНачалеРаботыСистемыВМодуляхИнтеграционнойПроцедуры", ЭтотОбъект));
	
	Параметры.Вставить("ИндексТекущегоМодуля", 0);
	Параметры.Вставить("ДобавленныеМодули", Новый Массив);
	Попытка
		Параметры.Вставить("Модули", Новый Массив);
		ИнтеграцияПодсистемБСПКлиент.ПриНачалеРаботыСистемы(Параметры);
		Параметры.Вставить("ДобавленныеМодули", Параметры.Модули);
		Параметры.Удалить("Модули");
	Исключение
		ОбработатьОшибкуПриНачалеРаботыСистемы(Параметры, ИнформацияОбОшибке());
	КонецПопытки;
	Если ИнтерактивнаяОбработкаПриНачалеРаботыСистемы(Параметры) Тогда
		Возврат;
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Параметры.ОбработкаПродолжения);
	
КонецПроцедуры

// Только для внутреннего использования. Продолжение процедуры ПриНачалеРаботыСистемы.
Процедура ДействияПриНачалеРаботыСистемыВМодуляхИнтеграционнойПроцедуры(Неопределен, Контекст) Экспорт
	
	Пока Истина Цикл
		Параметры = ПараметрыОбработкиПриНачалеРаботыСистемы();
		
		Если Не ПродолжитьДействияПриНачалеРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
		Если Параметры.ИндексТекущегоМодуля >= Параметры.ДобавленныеМодули.Количество() Тогда
			ДействияПриНачалеРаботыСистемыВПереопределяемойПроцедуре(Неопределено, Неопределено);
			Возврат;
		КонецЕсли;
		
		ОписаниеМодуля = Параметры.ДобавленныеМодули[Параметры.ИндексТекущегоМодуля];
		Параметры.ИндексТекущегоМодуля = Параметры.ИндексТекущегоМодуля + 1;
		
		Попытка
			Если ТипЗнч(ОписаниеМодуля) <> Тип("Структура") Тогда
				ТекущийМодуль = ОписаниеМодуля;
				ТекущийМодуль.ПриНачалеРаботыСистемы(Параметры);
			Иначе
				ТекущийМодуль = ОписаниеМодуля.Модуль;
				Если ОписаниеМодуля.Номер = 2 Тогда
					ТекущийМодуль.ПриНачалеРаботыСистемы2(Параметры);
				ИначеЕсли ОписаниеМодуля.Номер = 3 Тогда
					ТекущийМодуль.ПриНачалеРаботыСистемы3(Параметры);
				ИначеЕсли ОписаниеМодуля.Номер = 4 Тогда
					ТекущийМодуль.ПриНачалеРаботыСистемы4(Параметры);
				КонецЕсли;
			КонецЕсли;
		Исключение
			ОбработатьОшибкуПриНачалеРаботыСистемы(Параметры, ИнформацияОбОшибке());
		КонецПопытки;
		Если ИнтерактивнаяОбработкаПриНачалеРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

// Только для внутреннего использования. Продолжение процедуры ПриНачалеРаботыСистемы.
Процедура ДействияПриНачалеРаботыСистемыВМодуляхПереопределяемойПроцедуры(Неопределен, Контекст) Экспорт
	
	Пока Истина Цикл
		
		Параметры = ПараметрыОбработкиПриНачалеРаботыСистемы();
		
		Если Не ПродолжитьДействияПриНачалеРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
		Если Параметры.ИндексТекущегоМодуля >= Параметры.ДобавленныеМодули.Количество() Тогда
			ДействияПриНачалеРаботыСистемыПослеВсехПроцедур(Неопределено, Неопределено);
			Возврат;
		КонецЕсли;
		
		ТекущийМодуль = Параметры.ДобавленныеМодули[Параметры.ИндексТекущегоМодуля];
		Параметры.ИндексТекущегоМодуля = Параметры.ИндексТекущегоМодуля + 1;
		
		Попытка
			ТекущийМодуль.ПриНачалеРаботыСистемы(Параметры);
		Исключение
			ОбработатьОшибкуПриНачалеРаботыСистемы(Параметры, ИнформацияОбОшибке());
		КонецПопытки;
		Если ИнтерактивнаяОбработкаПриНачалеРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

// Только для внутреннего использования. Завершение процедуры ПриНачалеРаботыСистемы.
Процедура ДействияПриНачалеРаботыСистемыОбработкаЗавершения(Неопределен, Контекст) Экспорт
	
	Параметры = ПараметрыОбработкиПриНачалеРаботыСистемы(Истина);
	
	Параметры.ОбработкаПродолжения = Неопределено;
	Параметры.ОбработкаЗавершения  = Неопределено;
	
	Если НЕ Параметры.Отказ Тогда
		ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
		Если ПараметрыПриЗапускеПрограммы.Свойство("ПропуститьОчисткуСкрытияРабочегоСтола") Тогда
			ПараметрыПриЗапускеПрограммы.Удалить("ПропуститьОчисткуСкрытияРабочегоСтола");
		КонецЕсли;
		СкрытьРабочийСтолПриНачалеРаботыСистемы(Ложь);
	КонецЕсли;
	
	Если Параметры.ОповещениеЗавершения <> Неопределено Тогда
		
		Результат = Новый Структура;
		Результат.Вставить("Отказ", Параметры.Отказ);
		Результат.Вставить("Перезапустить", Параметры.Перезапустить);
		Результат.Вставить("ДополнительныеПараметрыКоманднойСтроки", Параметры.ДополнительныеПараметрыКоманднойСтроки);
		ВыполнитьОбработкуОповещения(Параметры.ОповещениеЗавершения, Результат);
		Возврат;
		
	Иначе
		Если Параметры.Отказ Тогда
			Если Параметры.Перезапустить <> Истина Тогда
				ПрекратитьРаботуСистемы();
				
			ИначеЕсли ЗначениеЗаполнено(Параметры.ДополнительныеПараметрыКоманднойСтроки) Тогда
				ПрекратитьРаботуСистемы(Параметры.Перезапустить, Параметры.ДополнительныеПараметрыКоманднойСтроки);
			Иначе
				ПрекратитьРаботуСистемы(Параметры.Перезапустить);
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

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

// Обработать параметры запуска программы.
//
// Возвращаемое значение:
//   Булево   - Истина, если необходимо прервать выполнение процедуры ПриНачалеРаботыСистемы.
//
Функция ОбработатьПараметрыЗапуска()

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

#КонецОбласти

#Область ПередЗавершениемРаботыСистемы

// Только для внутреннего использования. 
// 
// Параметры:
//  Пересоздать - Булево
//
// Возвращаемое значение:
//   Структура:
//     Отказ - Булево
//     Предупреждения - Массив из см. СтандартныеПодсистемыКлиент.ПредупреждениеПриЗавершенииРаботы.
//     ИнтерактивнаяОбработка - ОписаниеОповещения, Неопределено
//     ОбработкаПродолжения - ОписаниеОповещения, Неопределено
//     НепрерывноеВыполнение - Булево
//     ОбработкаЗавершения - ОписаниеОповещения
//
Функция ПараметрыДействийПередЗавершениемРаботыСистемы(Пересоздать = Ложь) Экспорт
	
	ИмяПараметра = "СтандартныеПодсистемы.ПараметрыДействийПередЗавершениемРаботыСистемы";
	Если Пересоздать Или ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
		ПараметрыПриложения.Вставить(ИмяПараметра, Новый Структура);
	КонецЕсли;
	Параметры = ПараметрыПриложения[ИмяПараметра];
	
	Если Не Пересоздать Тогда
		Возврат Параметры;
	КонецЕсли;
	
	// Внешние параметры описания результата.
	Параметры.Вставить("Отказ", Ложь);
	Параметры.Вставить("Предупреждения", ПараметрКлиента("ПредупрежденияПриЗавершенииРаботы"));
	
	// Внешние параметры управления выполнением.
	Параметры.Вставить("ИнтерактивнаяОбработка", Неопределено); // ОписаниеОповещения.
	Параметры.Вставить("ОбработкаПродолжения",   Неопределено); // ОписаниеОповещения.
	Параметры.Вставить("НепрерывноеВыполнение", Истина);
	
	// Внутренние параметры.
	Параметры.Вставить("ОбработкаЗавершения", Новый ОписаниеОповещения(
		"ДействияПередЗавершениемРаботыСистемыОбработкаЗавершения", СтандартныеПодсистемыКлиент));
	Возврат Параметры;
	
КонецФункции	
	
// Только для внутреннего использования. Продолжение процедуры ПередЗавершениемРаботыСистемы.
//
// Параметры:
//   Параметры - см. СтандартныеПодсистемыКлиент.ПараметрыДействийПередЗавершениемРаботыСистемы
//
Процедура ДействияПередЗавершениемРаботыСистемы(Параметры) Экспорт
	
	Параметры.Вставить("ОбработкаПродолжения", Параметры.ОбработкаЗавершения);
	
	Если ОбщегоНазначенияКлиент.ДоступноИспользованиеРазделенныхДанных() Тогда
		Попытка
			ОткрытьФормуПредупрежденийПриЗавершенииРаботы(Параметры);
		Исключение
			ОбработатьОшибкуПриЗапускеИлиЗавершении(Параметры, ИнформацияОбОшибке(), "Завершение");
		КонецПопытки;
		Если ИнтерактивнаяОбработкаПередЗавершениемРаботыСистемы(Параметры) Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Параметры.ОбработкаПродолжения);
	
КонецПроцедуры

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

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

#КонецОбласти

#Область ПрочиеПроцедурыИФункцииДляЗапускаИЗавершенияРаботыПрограммы

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

// Только для внутреннего использования. Продолжение процедуры ПередНачаломРаботыСистемы2.
Процедура ПроверитьВерсиюПлатформыПриЗапуске(Параметры, Контекст) Экспорт
	
	ПараметрыКлиента = ПараметрыРаботыКлиентаПриЗапуске();
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Текущая             = СистемнаяИнформация.ВерсияПриложения;
	Минимальная         = ПараметрыКлиента.МинимальнаяВерсияПлатформы;
	Если СтрНайти(ПараметрЗапуска, "ВыполнитьОбновлениеИЗавершитьРаботу") > 0
		И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Текущая, Минимальная) < 0
		И ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.ОбновлениеКонфигурации") Тогда
		ТекстСообщения = НСтр("ru = 'Обновление приложения на новую версию невозможно.
			|Предварительно обновите версию платформы 1С:Предприятие.
			|Используемая версия платформы - %1.
			|Минимально необходимая версия платформы - %2'");
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщения, Текущая, Минимальная);
		МодульОбновлениеКонфигурацииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ОбновлениеКонфигурацииКлиент");
		МодульОбновлениеКонфигурацииКлиент.ЗаписатьОшибкуНеобходимостиОбновленияПлатформы(ТекстСообщения);
	КонецЕсли;
	
	ОповещениеОЗакрытии = Новый ОписаниеОповещения("ПослеЗакрытияФормыНерекомендуемойВерсииПлатформы", ЭтотОбъект, Параметры);
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("ИнтернетПоддержкаПользователей.ПолучениеОбновленийПрограммы") Тогда
		СтандартнаяОбработка = Истина;
		МодульПолучениеОбновленийПрограммыКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ПолучениеОбновленийПрограммыКлиент");
		МодульПолучениеОбновленийПрограммыКлиент.ПриПроверкеВерсииПлатформыПриЗапуске(ОповещениеОЗакрытии, СтандартнаяОбработка);
		Если Не СтандартнаяОбработка Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Текущая, Минимальная) < 0 Тогда
		Если ПользователиКлиент.ЭтоПолноправныйПользователь(Истина) Тогда
			ТекстСообщения =
				НСтр("ru = 'Вход в приложение невозможен.
				           |Предварительно обновите версию платформы 1С:Предприятие.'");
		Иначе
			ТекстСообщения =
				НСтр("ru = 'Вход в приложение невозможен.
				           |Обратитесь к администратору для обновления версии платформы 1С:Предприятие.'");
		КонецЕсли;
	Иначе
		Если ПользователиКлиент.ЭтоПолноправныйПользователь(Истина) Тогда
			ТекстСообщения =
				НСтр("ru = 'Рекомендуется завершить работу приложения и обновить версию платформы 1С:Предприятия.
				         |Новая версия платформы содержит исправления ошибок, которые позволят приложению работать более стабильно.
				         |Вы также можете продолжить работу на текущей версии.
				         |Минимально необходимая версия платформы %1.'");
		Иначе
			ТекстСообщения = 
				НСтр("ru = 'Рекомендуется завершить работу приложения и обратиться к администратору для обновления версии платформы 1С:Предприятия.
				         |Новая версия платформы содержит исправления ошибок, которые позволят приложению работать более стабильно.
				         |Вы также можете продолжить работу на текущей версии.
				         |Минимально необходимая версия платформы %1.'");
		КонецЕсли;
	КонецЕсли;
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("ТекстСообщения", ТекстСообщения);
	ПараметрыФормы.Вставить("РекомендуемаяВерсияПлатформы", ПараметрыКлиента.РекомендуемаяВерсияПлатформы);
	ПараметрыФормы.Вставить("МинимальнаяВерсияПлатформы", ПараметрыКлиента.МинимальнаяВерсияПлатформы);
	ПараметрыФормы.Вставить("ОткрытаПоСценарию", Истина);
	ПараметрыФормы.Вставить("ПропуститьЗавершениеРаботы", Истина);
	
	Форма = ОткрытьФорму("Обработка.НерекомендуемаяВерсияПлатформы.Форма.НерекомендуемаяВерсияПлатформы", ПараметрыФормы,
		, , , , ОповещениеОЗакрытии);	
	Если Форма = Неопределено Тогда
		ПослеЗакрытияФормыНерекомендуемойВерсииПлатформы("Продолжить", Параметры);
	КонецЕсли;
	
КонецПроцедуры

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

// Только для внутреннего использования. Продолжение процедуры ПередНачаломРаботыСистемы2.
Процедура ПредупредитьОНедопустимойВерсииПлатформы(Параметры, Контекст) Экспорт

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

// Только для внутреннего использования. Продолжение процедуры ПроверитьВерсиюПлатформыПриЗапуске.
Процедура ПослеЗакрытияФормыНедопустимойВерсииПлатформы(Результат, Параметры) Экспорт
	
	ВыполнитьОбработкуОповещения(Параметры.ОбработкаПродолжения);
	
КонецПроцедуры

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

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

// Только для внутреннего использования. Продолжение процедуры ПроверитьНеобходимостьВосстановленияСвязиСГлавнымУзлом.
Процедура ИнтерактивнаяОбработкаВосстановленияСвязиСГлавнымУзлом(Параметры, Контекст) Экспорт
	
	ПараметрыКлиента = ПараметрыРаботыКлиентаПриЗапуске();
	
	Если ПараметрыКлиента.ВосстановитьСвязьСГлавнымУзлом = Ложь Тогда
		Параметры.Отказ = Истина;
		ПоказатьПредупреждение(
			ОповещениеБезРезультата(Параметры.ОбработкаПродолжения),
			НСтр("ru = 'Вход в приложение временно невозможен до восстановления связи с главным узлом.
			           |Обратитесь к администратору за подробностями.'"),
			15);
		Возврат;
	КонецЕсли;
	
	Форма = ОткрытьФорму("ОбщаяФорма.ВосстановлениеСвязиСГлавнымУзлом",,,,,,
		Новый ОписаниеОповещения("ПослеЗакрытияФормыВосстановленияСвязиСГлавнымУзлом", ЭтотОбъект, Параметры));
	
	Если Форма = Неопределено Тогда
		ПослеЗакрытияФормыВосстановленияСвязиСГлавнымУзлом(Новый Структура("Отказ", Истина), Параметры);
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования. Продолжение процедуры ПередНачаломРаботыСистемы4.
Процедура ИнтерактивнаяОбработкаНачальныхРегиональныхНастроекИБ(Параметры, Контекст) Экспорт
	
	ПараметрыКлиента = ПараметрыРаботыКлиентаПриЗапуске();
	
	Если ПараметрыКлиента.ВыбратьНачальныеРегиональныеНастройкиИБ = Ложь Тогда
		Параметры.Отказ = Истина;
		ПоказатьПредупреждение(
			ОповещениеБезРезультата(Параметры.ОбработкаПродолжения),
			НСтр("ru = 'Вход в приложение невозможен до установки начальных региональных настроек.
			           |Обратитесь к администратору за подробностями.'"),
			15);
		Возврат;
	КонецЕсли;
	
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
		МодульМультиязычностьКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("МультиязычностьКлиент");
		
		ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияФормыВыбораНачальныхРегиональныхНастроекИБ", ЭтотОбъект, Параметры);
		ПараметрыОткрытия  = Новый Структура("Источник", "НачальноеЗаполнение");
		МодульМультиязычностьКлиент.ОткрытьФормуРегиональныхНастроек(ОписаниеОповещения, ПараметрыОткрытия);
		
	Иначе
		ПослеЗакрытияФормыВыбораНачальныхРегиональныхНастроекИБ(Новый Структура("Отказ", Истина), Параметры);
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования. Продолжение процедуры ПроверитьНеобходимостьВосстановленияСвязиСГлавнымУзлом.
Процедура ПослеЗакрытияФормыВосстановленияСвязиСГлавнымУзлом(Результат, Параметры) Экспорт
	
	Если ТипЗнч(Результат) <> Тип("Структура") Или Результат.Отказ Тогда
		Параметры.Отказ = Истина;
	Иначе
		Параметры.ПолученныеПараметрыКлиента.Вставить("ВосстановитьСвязьСГлавнымУзлом");
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Параметры.ОбработкаПродолжения);
	
КонецПроцедуры

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

// Устанавливает флаг скрытия рабочего стола при начале работы системы,
// который блокирует создание форм на рабочем столе.
// Снимает флаг скрытия и обновляет рабочий стол, когда это станет возможным,
// если скрытие выполнялось.
//
// Параметры:
//  Скрыть - Булево - если передать Ложь, тогда при условии скрытия рабочего
//           стола он будет вновь показан.
//
//  УжеВыполненоНаСервере - Булево - если передать Истина, тогда уже был вызван
//           метод в модуле СтандартныеПодсистемыВызовСервера, и его не требуется
//           вызвать, а требуется только установить на клиенте, что рабочий стол
//           был скрыт и позднее его требуется показать.
//
Процедура СкрытьРабочийСтолПриНачалеРаботыСистемы(Скрыть = Истина, УжеВыполненоНаСервере = Ложь) Экспорт
	
	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
	
	Если Скрыть Тогда
		Если НЕ ПараметрыПриЗапускеПрограммы.Свойство("СкрытьРабочийСтолПриНачалеРаботыСистемы") Тогда
			ПараметрыПриЗапускеПрограммы.Вставить("СкрытьРабочийСтолПриНачалеРаботыСистемы");
			Если НЕ УжеВыполненоНаСервере Тогда
				СтандартныеПодсистемыВызовСервера.СкрытьРабочийСтолПриНачалеРаботыСистемы();
			КонецЕсли;
			ОбновитьИнтерфейс();
		КонецЕсли;
	Иначе
		Если ПараметрыПриЗапускеПрограммы.Свойство("СкрытьРабочийСтолПриНачалеРаботыСистемы") Тогда
			ПараметрыПриЗапускеПрограммы.Удалить("СкрытьРабочийСтолПриНачалеРаботыСистемы");
			Если НЕ УжеВыполненоНаСервере Тогда
				СтандартныеПодсистемыВызовСервера.СкрытьРабочийСтолПриНачалеРаботыСистемы(Ложь);
			КонецЕсли;
			ОбщегоНазначенияКлиент.ОбновитьИнтерфейсПрограммы();
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ВыполнитьОповещениеСПустымРезультатом(ОповещениеСРезультатом) Экспорт
	
	ВыполнитьОбработкуОповещения(ОповещениеСРезультатом);
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура НачатьИнтерактивнуюОбработкуПередЗавершениемРаботыСистемы() Экспорт
	
	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
	Если НЕ ПараметрыПриЗапускеПрограммы.Свойство("ПараметрыОбработкиЗавершения") Тогда
		Возврат;
	КонецЕсли;
	
	Параметры = ПараметрыПриЗапускеПрограммы.ПараметрыОбработкиЗавершения;
	ПараметрыПриЗапускеПрограммы.Удалить("ПараметрыОбработкиЗавершения");
	
	ИнтерактивнаяОбработка = Параметры.ИнтерактивнаяОбработка;
	Параметры.ИнтерактивнаяОбработка = Неопределено;
	ВыполнитьОбработкуОповещения(ИнтерактивнаяОбработка, Параметры);
	
КонецПроцедуры

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

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

Функция ВыводитьПредупрежденияПередЗавершениемРаботыСистемы(Отказ)
	
	Если ОтключенаЛогикаНачалаРаботыСистемы() Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
	
	Если ПараметрыПриЗапускеПрограммы.Свойство("СкрытьРабочийСтолПриНачалеРаботыСистемы") Тогда
		// Произошла попытка закрытия до окончания запуска.
		// В веб-клиенте это возможно в штатном случае (при закрытии страницы в целом),
		// поэтому закрытие блокируется, так как его все равно можно выполнить принудительно,
		// а в случае случайного закрытия у пользователя должна быть возможность остаться на странице.
		// Не в веб-клиенте это возможно в случае ошибок в немодальной последовательности запуска.
		// То есть нет ни одного окна блокирующего весь интерфейс. Закрытие нужно разрешить,
		// но без стандартных процедур перед завершение работы системы, так как они могут
		// привести к ошибке в процессе закрытия из-за незавершенного запуска.
#Если Не ВебКлиент Тогда
		Отказ = Истина;
#КонецЕсли
		Возврат Ложь;
	КонецЕсли;
	
	// В режиме работы толстый клиент (обычное приложение) не выводится список предупреждений.
#Если ТолстыйКлиентОбычноеПриложение Тогда
	Возврат Ложь;
#КонецЕсли
	
	Если ПараметрыПриложения["СтандартныеПодсистемы.ПропуститьПредупреждениеПередЗавершениемРаботыСистемы"] = Истина Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если Не ОбщегоНазначенияКлиент.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат Ложь;
	КонецЕсли;
	Возврат Истина;
	
КонецФункции
	
Функция ПредупрежденияПередЗавершениемРаботыСистемы(Отказ)
	
	Предупреждения = Новый Массив;
	ИнтеграцияПодсистемБСПКлиент.ПередЗавершениемРаботыСистемы(Отказ, Предупреждения);
	ОбщегоНазначенияКлиентПереопределяемый.ПередЗавершениемРаботыСистемы(Отказ, Предупреждения);
	Возврат Предупреждения;

КонецФункции

#КонецОбласти

#Область ДляСправочникаИдентификаторыОбъектовМетаданных

// Только для внутреннего использования.
Процедура ИдентификаторыОбъектовМетаданныхФормаСпискаСписокВыборЗначения(Форма, Элемент, Значение, СтандартнаяОбработка) Экспорт
	
	Если Не Форма.ВыбиратьГруппыОбъектовМетаданных
	   И Элемент.ТекущиеДанные <> Неопределено
	   И Не Элемент.ТекущиеДанные.ПометкаУдаления
	   И Не ЗначениеЗаполнено(Элемент.ТекущиеДанные.Родитель) Тогда
		
		СтандартнаяОбработка = Ложь;
		
		Если Элемент.Отображение = ОтображениеТаблицы.Дерево Тогда
			Если Элемент.Развернут(Элемент.ТекущаяСтрока) Тогда
				Элемент.Свернуть(Элемент.ТекущаяСтрока);
			Иначе
				Элемент.Развернуть(Элемент.ТекущаяСтрока);
			КонецЕсли;
			
		ИначеЕсли Элемент.Отображение = ОтображениеТаблицы.ИерархическийСписок Тогда
			
			Если Элемент.ТекущийРодитель <> Элемент.ТекущаяСтрока Тогда
				Элемент.ТекущийРодитель = Элемент.ТекущаяСтрока;
			Иначе
				ТекущаяСтрока = Элемент.ТекущаяСтрока;
				Элемент.ТекущийРодитель = Неопределено;
				Элемент.ТекущаяСтрока = ТекущаяСтрока;
			КонецЕсли;
		Иначе
			ПоказатьПредупреждение(,
				НСтр("ru = 'Невозможно выбрать группу объектов метаданных.
				           |Выберите объект метаданных.'"));
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ПараметрыРаботыКлиентаНаСервере

Процедура ЗаполнитьПараметрыРаботыКлиентаНаСервере(Параметры) Экспорт
	
	Параметры.Вставить("ПараметрЗапуска", ПараметрЗапуска);
	Параметры.Вставить("СтрокаСоединенияИнформационнойБазы", СтрокаСоединенияИнформационнойБазы());
	Параметры.Вставить("ЭтоВебКлиент", ЭтоВебКлиент());
	Параметры.Вставить("ЭтоLinuxКлиент", ОбщегоНазначенияКлиент.ЭтоLinuxКлиент());
	Параметры.Вставить("ЭтоMacOSКлиент", ОбщегоНазначенияКлиент.ЭтоMacOSКлиент());
	Параметры.Вставить("ЭтоWindowsКлиент", ОбщегоНазначенияКлиент.ЭтоWindowsКлиент());
	Параметры.Вставить("ЭтоМобильныйКлиент", ЭтоМобильныйКлиент());
	Параметры.Вставить("ИспользуемыйКлиент", ИспользуемыйКлиент());
	Параметры.Вставить("КаталогПрограммы", ТекущийКаталогПрограммы());
	Параметры.Вставить("ИдентификаторКлиента", ИдентификаторКлиента());
	Параметры.Вставить("СкрытьРабочийСтолПриНачалеРаботыСистемы", Ложь);
	Параметры.Вставить("ОперативнаяПамять", ОбщегоНазначенияКлиент.ОперативнаяПамятьДоступнаяКлиентскомуПриложению());
	Параметры.Вставить("РазрешениеОсновногоЭкрана", РазрешениеОсновногоЭкрана());
	Параметры.Вставить("СистемнаяИнформация", СистемнаяИнформацияКлиента());
	
	// Установка даты клиента непосредственно перед вызовом, чтобы уменьшить погрешность.
	Параметры.Вставить("ТекущаяДатаНаКлиенте", ТекущаяДата()); // АПК:143 Требуется ТекущаяДата() для расчета ПоправкаКВремениСеанса
	Параметры.Вставить("ТекущаяУниверсальнаяДатаВМиллисекундахНаКлиенте", ТекущаяУниверсальнаяДатаВМиллисекундах());
	
КонецПроцедуры

// Возвращаемое значение:
//   см. ОбщегоНазначения.ИспользуемыйКлиент
//
Функция ИспользуемыйКлиент()
	
	ИспользуемыйКлиент = "";
#Если ТонкийКлиент Тогда
		ИспользуемыйКлиент = "ТонкийКлиент";
#ИначеЕсли ТолстыйКлиентУправляемоеПриложение Тогда
		ИспользуемыйКлиент = "ТолстыйКлиентУправляемоеПриложение";
#ИначеЕсли ТолстыйКлиентОбычноеПриложение Тогда
		ИспользуемыйКлиент = "ТолстыйКлиентОбычноеПриложение";
#ИначеЕсли ВебКлиент Тогда
		ОписаниеБраузера = ТекущийБраузер();
		Если ПустаяСтрока(ОписаниеБраузера.Версия) Тогда
			ИспользуемыйКлиент = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("ВебКлиент.%1", ОписаниеБраузера.Название);
		Иначе
			ИспользуемыйКлиент = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("ВебКлиент.%1.%2", ОписаниеБраузера.Название, СтрРазделить(ОписаниеБраузера.Версия, ".")[0]);
		КонецЕсли;
#КонецЕсли
	
	Возврат ИспользуемыйКлиент;
	
КонецФункции

Функция ТекущийБраузер()
	
	Результат = Новый Структура("Название,Версия", "Другой", "");
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Строка = СистемнаяИнформация.ИнформацияПрограммыПросмотра;
	Строка = СтрЗаменить(Строка, ",", ";");

	// Opera
	Идентификатор = "Opera";
	Позиция = СтрНайти(Строка, Идентификатор, НаправлениеПоиска.СКонца);
	Если Позиция > 0 Тогда
		Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
		Результат.Название = "Opera";
		Идентификатор = "Version/";
		Позиция = СтрНайти(Строка, Идентификатор);
		Если Позиция > 0 Тогда
			Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
			Результат.Версия = СокрЛП(Строка);
		Иначе
			Строка = СокрЛП(Строка);
			Если СтрНачинаетсяС(Строка, "/") Тогда
				Строка = Сред(Строка, 2);
			КонецЕсли;
			Результат.Версия = СокрЛ(Строка);
		КонецЕсли;
		Возврат Результат;
	КонецЕсли;

	// IE
	Идентификатор = "MSIE"; // v11-
	Позиция = СтрНайти(Строка, Идентификатор);
	Если Позиция > 0 Тогда
		Результат.Название = "IE";
		Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
		Позиция = СтрНайти(Строка, ";");
		Если Позиция > 0 Тогда
			Строка = СокрЛ(Лев(Строка, Позиция - 1));
			Результат.Версия = Строка;
		КонецЕсли;
		Возврат Результат;
	КонецЕсли;

	Идентификатор = "Trident"; // v11+
	Позиция = СтрНайти(Строка, Идентификатор);
	Если Позиция > 0 Тогда
		Результат.Название = "IE";
		Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
		
		Идентификатор = "rv:";
		Позиция = СтрНайти(Строка, Идентификатор);
		Если Позиция > 0 Тогда
			Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
			Позиция = СтрНайти(Строка, ")");
			Если Позиция > 0 Тогда
				Строка = СокрЛ(Лев(Строка, Позиция - 1));
				Результат.Версия = Строка;
			КонецЕсли;
		КонецЕсли;
		Возврат Результат;
	КонецЕсли;

	// Chrome
	Идентификатор = "Chrome/";
	Позиция = СтрНайти(Строка, Идентификатор);
	Если Позиция > 0 Тогда
		Результат.Название = "Chrome";
		Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
		Позиция = СтрНайти(Строка, " ");
		Если Позиция > 0 Тогда
			Строка = СокрЛ(Лев(Строка, Позиция - 1));
			Результат.Версия = Строка;
		КонецЕсли;
		Возврат Результат;
	КонецЕсли;

	// Safari
	Идентификатор = "Safari/";
	Если СтрНайти(Строка, Идентификатор) > 0 Тогда
		Результат.Название = "Safari";
		Идентификатор = "Version/";
		Позиция = СтрНайти(Строка, Идентификатор);
		Если Позиция > 0 Тогда
			Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
			Позиция = СтрНайти(Строка, " ");
			Если Позиция > 0 Тогда
				Результат.Версия = СокрЛП(Лев(Строка, Позиция - 1));
			КонецЕсли;
		КонецЕсли;
		Возврат Результат;
	КонецЕсли;

	// Firefox
	Идентификатор = "Firefox/";
	Позиция = СтрНайти(Строка, Идентификатор);
	Если Позиция > 0 Тогда
		Результат.Название = "Firefox";
		Строка = Сред(Строка, Позиция + СтрДлина(Идентификатор));
		Если Не ПустаяСтрока(Строка) Тогда
			Результат.Версия = СокрЛП(Строка);
		КонецЕсли;
		Возврат Результат;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ТекущийКаталогПрограммы()
	
#Если ВебКлиент Или МобильныйКлиент Тогда
	КаталогПрограммы = "";
#Иначе
	КаталогПрограммы = КаталогПрограммы();
#КонецЕсли
	
	Возврат КаталогПрограммы;
	
КонецФункции

Функция РазрешениеОсновногоЭкрана()
	
	ИнформациюЭкрановКлиента = ПолучитьИнформациюЭкрановКлиента();
	Если ИнформациюЭкрановКлиента.Количество() > 0 Тогда
		DPI = ИнформациюЭкрановКлиента[0].DPI; // АПК:1353 - не требуется перевод на русский язык.
		РазрешениеОсновногоЭкрана = ?(DPI = 0, 72, DPI);
	Иначе
		РазрешениеОсновногоЭкрана = 72;
	КонецЕсли;
	
	Возврат РазрешениеОсновногоЭкрана;
	
КонецФункции

Функция ИдентификаторКлиента()
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Возврат СистемнаяИнформация.ИдентификаторКлиента;
	
КонецФункции

Функция ЭтоВебКлиент()
	
#Если ВебКлиент Тогда
	Возврат Истина;
#Иначе
	Возврат Ложь;
#КонецЕсли
	
КонецФункции

Функция ЭтоМобильныйКлиент()
	
#Если МобильныйКлиент Тогда
	Возврат Истина;
#Иначе
	Возврат Ложь;
#КонецЕсли
	
КонецФункции

// Возвращаемое значение:
//   см. ОбщегоНазначения.СистемнаяИнформацияКлиента
//
Функция СистемнаяИнформацияКлиента()
	
	Результат = Новый Структура(
		"ВерсияОС,
		|ВерсияПриложения,
		|ИдентификаторКлиента,
		|ИнформацияПрограммыПросмотра,
		|ОперативнаяПамять,
		|Процессор,
		|ТипПлатформы");
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	ЗаполнитьЗначенияСвойств(Результат, СистемнаяИнформация);
	Результат.ТипПлатформы = ОбщегоНазначенияКлиентСервер.ИмяТипаПлатформы(СистемнаяИнформация.ТипПлатформы);
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

#КонецОбласти

// Продолжение процедуры НачатьВыполнениеОбработкиОповещения.
//
// Параметры:
//  Размер - Число
//  Контекст - Структура:
//   * Оповещение - ОписаниеОповещения
//   * Результат  - Произвольный
//
Процедура НачатьВыполнениеОбработкиОповещенияЗавершение(Размер, Контекст) Экспорт
	
	ВыполнитьОбработкуОповещения(Контекст.Оповещение, Контекст.Результат);
	
КонецПроцедуры

#Область ВспомогательныеПроцедурыИФункции

Процедура ВойтиВОбластьДанных()
	
	Если ПустаяСтрока(ПараметрЗапуска) Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыЗапуска = СтрРазделить(ПараметрЗапуска, ";", Ложь);
	
	Если ПараметрыЗапуска.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ЗначениеПараметраЗапуска = ВРег(ПараметрыЗапуска[0]);
	
	Если ЗначениеПараметраЗапуска <> ВРег("ВойтиВОбластьДанных") Тогда
		Возврат;
	КонецЕсли;
	
	Если ПараметрыЗапуска.Количество() < 2 Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'В параметре запуска %1 дополнительно укажите значение разделителя (число).'"),
			"ВойтиВОбластьДанных");
	КонецЕсли;
	
	Попытка
		ЗначениеРазделителя = Число(ПараметрыЗапуска[1]);
	Исключение
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Значением разделителя в параметре %1 должно быть число.'"),
			"ВойтиВОбластьДанных");
	КонецПопытки;
	
	СтандартныеПодсистемыВызовСервера.ВойтиВОбластьДанных(ЗначениеРазделителя);
	
КонецПроцедуры

// Обновляет параметры работы клиента после очередной интерактивной обработки при запуске.
Процедура ОбновитьПараметрыРаботыКлиента(Параметры, ПервыйВызов = Ложь, ОбновитьПовторноИспользуемыеЗначения = Истина)
	
	Если ПервыйВызов Тогда
		ИмяПараметра = "СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы";
		Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
			ПараметрыПриложения.Вставить(ИмяПараметра, Новый Структура);
		КонецЕсли;
		ИмяПараметра = "СтандартныеПодсистемы.ЗапускПрограммыЗавершен";
		Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
			ПараметрыПриложения.Вставить(ИмяПараметра, Ложь);
		КонецЕсли;
	ИначеЕсли Параметры.КоличествоПолученныхПараметровКлиента = Параметры.ПолученныеПараметрыКлиента.Количество() Тогда
		Возврат;
	КонецЕсли;
	
	Параметры.Вставить("КоличествоПолученныхПараметровКлиента", Параметры.ПолученныеПараметрыКлиента.Количество());
	
	ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"].Вставить(
		"ПолученныеПараметрыКлиента", Параметры.ПолученныеПараметрыКлиента);
	
	Если ОбновитьПовторноИспользуемыеЗначения Тогда
		ОбновитьПовторноИспользуемыеЗначения();
	КонецЕсли;
	
КонецПроцедуры

// Проверяет результат интерактивной обработки, если Отказ, тогда вызывает обработку завершения.
// Если добавлен новый полученный параметр клиента, обновляет параметры работы клиента.
//
// Параметры:
//   Параметры - см. ОбщегоНазначенияКлиентПереопределяемый.ПередНачаломРаботыСистемы.Параметры.
//
// Возвращаемое значение:
//   Булево - Истина, если можно продолжить выполнения, и соответственно, не выполнялся
//            обработчик оповещения, указанный в свойствах ОбработкаЗавершения.
//
Функция ПродолжитьДействияПередНачаломРаботыСистемы(Параметры)
	
	Если Параметры.Отказ Тогда
		ВыполнитьОбработкуОповещения(Параметры.ОбработкаЗавершения);
		Возврат Ложь;
	КонецЕсли;
	
	ОбновитьПараметрыРаботыКлиента(Параметры);
	
	Возврат Истина;
	
КонецФункции

// Обрабатывает ошибку, найденную при вызове обработчика события ПриНачалеРаботыСистемы.
//
// Параметры:
//   Параметры          - см. ОбщегоНазначенияКлиентПереопределяемый.ПриНачалеРаботыСистемы.Параметры.
//   ИнформацияОбОшибке - ИнформацияОбОшибке - информация об ошибке.
//   ПрекратитьРаботу   - Булево - если указано Истина, то при ошибке запуска не будет возможности продолжить работу.
//
Процедура ОбработатьОшибкуПередНачаломРаботыСистемы(Параметры, ИнформацияОбОшибке, ПрекратитьРаботу = Ложь)
	
	ОбработатьОшибкуПриЗапускеИлиЗавершении(Параметры, ИнформацияОбОшибке, "Запуск", ПрекратитьРаботу);
	
КонецПроцедуры

// Проверяет результат обработчика события ПередНачаломРаботыСистемы и выполняет обработчик оповещения.
//
// Параметры:
//   Параметры - см. ОбщегоНазначенияКлиентПереопределяемый.ПередНачаломРаботыСистемы.Параметры.
//
// Возвращаемое значение:
//   Булево - Истина, если был выполнен обработчик оповещения, указанный
//            ОбработкаЗавершения ОбработкаЗавершения или запланирован переход к выполнению
//            интерактивной обработке, указанной в свойстве ИнтерактивнаяОбработка.
//
Функция ИнтерактивнаяОбработкаПередНачаломРаботыСистемы(Параметры)
	
	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
	
	Если Параметры.ИнтерактивнаяОбработка = Неопределено Тогда
		Если Параметры.Отказ Тогда
			ВыполнитьОбработкуОповещения(Параметры.ОбработкаЗавершения);
			Возврат Истина;
		КонецЕсли;
		Возврат Ложь;
	КонецЕсли;
	
	ОбновитьПараметрыРаботыКлиента(Параметры);
	
	Если НЕ Параметры.НепрерывноеВыполнение Тогда
		ИнтерактивнаяОбработка = Параметры.ИнтерактивнаяОбработка;
		Параметры.ИнтерактивнаяОбработка = Неопределено;
		УстановитьПоследнююПроцедуру(Параметры,,, ИнтерактивнаяОбработка);
		ВыполнитьОбработкуОповещения(ИнтерактивнаяОбработка, Параметры);
		
	Иначе
		// Требуется подготовка к выполнению интерактивной обработки, затребованной
		// в процессе выполнения обработчика ПередНачаломРаботыСистемы, которая
		// предполагает скрытие рабочего стола и обновление интерфейса перед
		// продолжением при первом вызове процедуры ПриНачалеРаботыСистемы.
		ПараметрыПриЗапускеПрограммы.Вставить("ПараметрыОбработки", Параметры);
		СкрытьРабочийСтолПриНачалеРаботыСистемы();
		ПараметрыПриЗапускеПрограммы.Вставить("ПропуститьОчисткуСкрытияРабочегоСтола");
		
		Если Параметры.ОповещениеЗавершения = Неопределено Тогда
			// Вызов процедуры ПередНачаломРаботыСистемы выполнен платформой,
			// как обработчика события, до открытия главного окна 1С:Предприятия 8.
			Если Не ОтключенаЛогикаНачалаРаботыСистемы() Тогда
				УстановитьПараметрыФункциональныхОпцийИнтерфейсаПриЗапуске();
			КонецЕсли;
		Иначе
			// Вызов процедуры ПередНачаломРаботыСистемы выполнен программно, как вход в область данных,
			// поэтому продолжение после обновления интерфейса возможно только через обработчик ожидания.
			ПодключитьОбработчикОжидания("ОбработчикОжиданияПриНачалеРаботыСистемы", 0.1, Истина);
		КонецЕсли;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Процедура УстановитьПоследнююПроцедуру(Параметры, ИмяМодуля = "", ИмяПроцедуры = "", ОписаниеОповещения = Неопределено)
	
	ОписаниеПроцедуры = Новый Структура("Модуль, Имя");
	
	Если ОписаниеОповещения = Неопределено Тогда
		ОписаниеПроцедуры.Модуль = ИмяМодуля;
		ОписаниеПроцедуры.Имя = ИмяПроцедуры;
	Иначе
		ОписаниеПроцедуры.Модуль = ОписаниеОповещения.Модуль;
		ОписаниеПроцедуры.Имя = ОписаниеОповещения.ИмяПроцедуры;
	КонецЕсли;
	
	Параметры.ВызванныеПроцедуры.Вставить(0, ОписаниеПроцедуры);
	
КонецПроцедуры

// Для процедуры ДействияПриНачалеРаботыСистемы.
Функция ВызванныеПроцедурыПередНачаломРаботыСистемы() Экспорт
	
	Свойства = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
	Если Свойства = Неопределено
	 Или Не Свойства.Свойство("ПараметрыОбработкиПередНачаломРаботыСистемы") Тогда
		Возврат "";
	КонецЕсли;
	Параметры = Свойства.ПараметрыОбработкиПередНачаломРаботыСистемы;
	ИменаКлиентскихМодулей = Неопределено;
	
	Строки = Новый Массив;
	Для Каждого ОписаниеПроцедуры Из Параметры.ВызванныеПроцедуры Цикл
		Если ТипЗнч(ОписаниеПроцедуры.Модуль) = Тип("ОбщийМодуль") Тогда
			Если ИменаКлиентскихМодулей = Неопределено Тогда
				ИменаКлиентскихМодулей = СтандартныеПодсистемыВызовСервера.ИменаКлиентскихМодулей();
			КонецЕсли;
			Для Каждого ИмяКлиентскогоМодуля Из ИменаКлиентскихМодулей Цикл
				Попытка
					ТекущийМодуль = ОбщегоНазначенияКлиент.ОбщийМодуль(ИмяКлиентскогоМодуля);
				Исключение
					ТекущийМодуль = Неопределено;
				КонецПопытки;
				Если ТекущийМодуль = ОписаниеПроцедуры.Модуль Тогда
					ИмяМодуля = ИмяКлиентскогоМодуля;
					Прервать;
				КонецЕсли;
			КонецЦикла;
		ИначеЕсли ТипЗнч(ОписаниеПроцедуры.Модуль) = Тип("ФормаКлиентскогоПриложения") Тогда
			ИмяМодуля = ОписаниеПроцедуры.Модуль.ИмяФормы;
		Иначе
			ИмяМодуля = Строка(ОписаниеПроцедуры.Модуль);
		КонецЕсли;
		Строки.Добавить("- " + Строка(ИмяМодуля) + "." + ОписаниеПроцедуры.Имя);
	КонецЦикла;
	
	Возврат СтрСоединить(Строки, Символы.ПС);
	
КонецФункции

// Проверяет результат интерактивной обработки, если Отказ, тогда вызывает обработку завершения.
//
// Параметры:
//   Параметры - см. ОбщегоНазначенияКлиентПереопределяемый.ПриНачалеРаботыСистемы.Параметры.
//
// Возвращаемое значение:
//   Булево - Истина, если можно продолжить выполнения, и соответственно, не выполнялся
//            обработчик оповещения, указанный в свойствах ОбработкаЗавершения.
//
Функция ПродолжитьДействияПриНачалеРаботыСистемы(Параметры)
	
	Если Параметры.Отказ Тогда
		ВыполнитьОбработкуОповещения(Параметры.ОбработкаЗавершения);
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

// Обрабатывает ошибку, найденную при вызове обработчика события ПриНачалеРаботыСистемы.
//
// Параметры:
//   Параметры          - см. ОбщегоНазначенияКлиентПереопределяемый.ПриНачалеРаботыСистемы.Параметры.
//   ИнформацияОбОшибке - ИнформацияОбОшибке - информация об ошибке.
//   ПрекратитьРаботу   - Булево - если указано Истина, то при ошибке запуска не будет возможности продолжить работу.
//
Процедура ОбработатьОшибкуПриНачалеРаботыСистемы(Параметры, ИнформацияОбОшибке, ПрекратитьРаботу = Ложь)
	
	ОбработатьОшибкуПриЗапускеИлиЗавершении(Параметры, ИнформацияОбОшибке, "Запуск", ПрекратитьРаботу);
	
КонецПроцедуры

// Проверяет результат обработчика события ПриНачалеРаботыСистемы и выполняет обработчик оповещения.
//
// Параметры:
//   Параметры - см. ОбщегоНазначенияКлиентПереопределяемый.ПриНачалеРаботыСистемы.Параметры.
//
// Возвращаемое значение:
//   Булево - Истина, если был выполнен обработчик оповещения, указанный в
//            свойствах ОбработкаЗавершения или ИнтерактивнаяОбработка.
//
Функция ИнтерактивнаяОбработкаПриНачалеРаботыСистемы(Параметры)
	
	Если Параметры.ИнтерактивнаяОбработка = Неопределено Тогда
		Если Параметры.Отказ Тогда
			ВыполнитьОбработкуОповещения(Параметры.ОбработкаЗавершения);
			Возврат Истина;
		КонецЕсли;
		Возврат Ложь;
	КонецЕсли;
	
	ИнтерактивнаяОбработка = Параметры.ИнтерактивнаяОбработка;
	
	Параметры.НепрерывноеВыполнение = Ложь;
	Параметры.ИнтерактивнаяОбработка = Неопределено;
	
	ВыполнитьОбработкуОповещения(ИнтерактивнаяОбработка, Параметры);
	
	Возврат Истина;
	
КонецФункции

Функция ВыполняетсяИнтерактивнаяОбработкаПередНачаломРаботыСистемы()
	
	Если ПараметрыПриложения = Неопределено Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Возникла непредвиденная ситуация при запуске приложения.
			           |
			           |Техническая информация:
			           |Недопустимый вызов %1 при запуске приложения. Сначала должна быть завершена процедура %2.'"),
			"СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы",
			"СтандартныеПодсистемыКлиент.ПередНачаломРаботыСистемы");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;	

	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"]; // Структура
	Если Не ПараметрыПриЗапускеПрограммы.Свойство("ПараметрыОбработки") Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Параметры = ПараметрыПриЗапускеПрограммы.ПараметрыОбработки;
	УстановитьПоследнююПроцедуру(Параметры, "СтандартныеПодсистемыКлиент",
		"ВыполняетсяИнтерактивнаяОбработкаПередНачаломРаботыСистемы");
	Если Параметры.ИнтерактивнаяОбработка = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ПодключитьОбработчикОжидания("ОбработчикОжиданияНачатьИнтерактивнуюОбработкуПередНачаломРаботыСистемы", 0.1, Истина);
	Параметры.НепрерывноеВыполнение = Ложь;
	
	Возврат Истина;
	
КонецФункции

Процедура НачатьИнтерактивнуюОбработкуПередНачаломРаботыСистемы() Экспорт
	
	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"]; // Структура
	
	Параметры = ПараметрыПриЗапускеПрограммы.ПараметрыОбработки;
	ИнтерактивнаяОбработка = Параметры.ИнтерактивнаяОбработка;
	Параметры.ИнтерактивнаяОбработка = Неопределено;
	УстановитьПоследнююПроцедуру(Параметры,,, ИнтерактивнаяОбработка);
	
	ВыполнитьОбработкуОповещения(ИнтерактивнаяОбработка, Параметры);
	
	ПараметрыПриЗапускеПрограммы.Удалить("ПараметрыОбработки");
	
КонецПроцедуры

Функция ИнтерактивнаяОбработкаПередЗавершениемРаботыСистемы(Параметры)
	
	Если Параметры.ИнтерактивнаяОбработка = Неопределено Тогда
		Если Параметры.Отказ Тогда
			ВыполнитьОбработкуОповещения(Параметры.ОбработкаЗавершения);
			Возврат Истина;
		КонецЕсли;
		Возврат Ложь;
	КонецЕсли;
	
	Если Не Параметры.НепрерывноеВыполнение Тогда
		ИнтерактивнаяОбработка = Параметры.ИнтерактивнаяОбработка;
		Параметры.ИнтерактивнаяОбработка = Неопределено;
		ВыполнитьОбработкуОповещения(ИнтерактивнаяОбработка, Параметры);
		
	Иначе
		// Выполнен вызов из обработчика события ПередЗавершениемРаботыСистемы для подготовки
		// выполнения интерактивной обработки через обработчик ожидания.
		ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"].Вставить("ПараметрыОбработкиЗавершения", Параметры);
		Параметры.НепрерывноеВыполнение = Ложь;
		ПодключитьОбработчикОжидания(
			"ОбработчикОжиданияИнтерактивнаяОбработкаПередЗавершениемРаботыСистемы", 0.1, Истина);
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

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

// Продолжение процедуры ОткрытьФормуПредупрежденийПриЗавершенииРаботы.
Процедура ИнтерактивнаяОбработкаПредупрежденийПриЗавершенииРаботы(Параметры, ПараметрыОткрытияФормы) Экспорт
	
	ОткрытьФорму(
		ПараметрыОткрытияФормы.ИмяФормы,
		ПараметрыОткрытияФормы.ПараметрыФормы, , , , ,
		ПараметрыОткрытияФормы.ОбработкаОтвета,
		ПараметрыОткрытияФормы.РежимОткрытияОкна);
	
КонецПроцедуры

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

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

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

Процедура УстановитьПараметрыФункциональныхОпцийИнтерфейсаПриЗапуске()
	
	ПараметрыПриЗапускеПрограммы = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПриЗапускеПрограммы"];
	
	Если ТипЗнч(ПараметрыПриЗапускеПрограммы) <> Тип("Структура")
	 Или Не ПараметрыПриЗапускеПрограммы.Свойство("ОпцииИнтерфейса") Тогда
		// Обработка ошибки запуска.
		Возврат;
	КонецЕсли;
	
	Если ПараметрыПриЗапускеПрограммы.Свойство("ОпцииИнтерфейсаУстановлены") Тогда
		Возврат;
	КонецЕсли;
	
	ОпцииИнтерфейса = Новый Структура(ПараметрыПриЗапускеПрограммы.ОпцииИнтерфейса);
	
	// Установка параметров функциональных опций производится только тогда, когда они заданы.
	Если ОпцииИнтерфейса.Количество() > 0 Тогда
		УстановитьПараметрыФункциональныхОпцийИнтерфейса(ОпцииИнтерфейса);
	КонецЕсли;
	
	ПараметрыПриЗапускеПрограммы.Вставить("ОпцииИнтерфейсаУстановлены");
	
КонецПроцедуры

Функция ТребуетсяПоказРекомендацииПоОбъемуОперативнойПамяти()
	ПараметрыКлиента = ПараметрыРаботыКлиентаПриЗапуске();
	Возврат ПараметрыКлиента.ТребуетсяПоказРекомендацииПоОбъемуОперативнойПамяти;
КонецФункции

Процедура ОповеститьОНехваткеПамяти() Экспорт
	РекомендуемыйОбъем = ПараметрыРаботыКлиентаПриЗапуске().РекомендуемыйОбъемОперативнойПамяти;
	
	Заголовок = НСтр("ru = 'Скорость работы снижена'");
	Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Рекомендуется увеличить объем памяти до %1 Гб.'"), РекомендуемыйОбъем);
	
	ПоказатьОповещениеПользователя(Заголовок, 
		"e1cib/app/Обработка.РекомендацияПоПовышениюСкоростиРаботы",
		Текст, БиблиотекаКартинок.ДиалогВосклицание, СтатусОповещенияПользователя.Важное);
КонецПроцедуры

Процедура ОповещениеТекущегоПользователяОПредстоящемПерезапуске(СекундДоПерезапуска) Экспорт

	ВремяПерезапуска = СтандартныеПодсистемыВызовСервера.ВремяПерезапускаПриложенияДляПримененияИсправлений();
	ВремяПерезапуска = ?(ВремяПерезапуска <> Неопределено, Формат(ВремяПерезапуска,"ДФ=HH:mm"),
		Формат(ОбщегоНазначенияКлиент.ДатаСеанса() + СекундДоПерезапуска, "ДФ=HH:mm"));
	ТекстЗаголовка = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Перезапуск приложения в %1'"), ВремяПерезапуска);
	ТекстСообщения = НСтр("ru = 'Ранее был запланирован перезапуск приложения для применения исправлений. Нажмите здесь, чтобы отложить.'");
	ПоказатьОповещениеПользователя(
		ТекстЗаголовка,
		"e1cib/app/ОбщаяФорма.КонтрольДинамическогоОбновления",
		ТекстСообщения, БиблиотекаКартинок.ДиалогВосклицание,
		СтатусОповещенияПользователя.Важное,
		"ПерезапускПриложенияСегодня");

КонецПроцедуры
	
Процедура ПодключениеОбработчиковОжиданияПоказаОповещенийИПерезапуска(СекундДоПерезапуска) Экспорт
	ПодключитьОбработчикОжидания("ОповещениеОПредстоящемПерезапускеЗаПятьМинут", СекундДоПерезапуска - 300, Истина);
	ПодключитьОбработчикОжидания("ОповещениеОПредстоящемПерезапускеЗаТриМинуты", СекундДоПерезапуска - 180, Истина);
	ПодключитьОбработчикОжидания("ОповещениеОПредстоящемПерезапускеЗаМинуту", СекундДоПерезапуска - 60, Истина);
	ПодключитьОбработчикОжидания("ПерезапускПриложения", СекундДоПерезапуска, Истина);
КонецПроцедуры 

Процедура ОтключитьЗапланированныйПерезапуск() Экспорт
	ОтключитьОбработчикОжидания("ОповещениеОПредстоящемПерезапускеЗаПятьМинут");
	ОтключитьОбработчикОжидания("ОповещениеОПредстоящемПерезапускеЗаТриМинуты");
	ОтключитьОбработчикОжидания("ОповещениеОПредстоящемПерезапускеЗаМинуту");
	ОтключитьОбработчикОжидания("ПерезапускПриложения");
КонецПроцедуры

#КонецОбласти

#КонецОбласти