[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ПроверитьВложеннуюТранзакциюПриВыполненииОтложенногоОбработчика`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

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

[Assistant]
Процедура ПроверитьВложеннуюТранзакциюПриВыполненииОтложенногоОбработчика(КонтекстОбработчика, Результат)

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

		Пока ТранзакцияАктивна() Цикл
			ОтменитьТранзакцию(); // АПК:325 Отмена незакрытых транзакций.
		КонецЦикла;
	КонецПопытки;

КонецПроцедуры

Процедура ПроверитьВложеннуюТранзакцию(ТранзакцияАктивнаНаНачалоВыполнения, НазваниеОбработчика)

	ИмяСобытия = СобытиеЖурналаРегистрации() + "." + НСтр("ru = 'Выполнение обработчиков'", ОбщегоНазначения.КодОсновногоЯзыка());
	Если ТранзакцияАктивнаНаНачалоВыполнения Тогда

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

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

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

			ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
			ВызватьИсключение(Комментарий);
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

Процедура ПроверитьСвойстваОбработчиков(ИтерацияОбновления)

	Для каждого Обработчик Из ИтерацияОбновления.Обработчики Цикл
		ОписаниеОшибки = "";

		// Обратная совместимость
		Если Обработчик.РежимВыполнения = "Исключительный" Тогда
			Обработчик.РежимВыполнения = "Монопольно";
		КонецЕсли;

		Если ПустаяСтрока(Обработчик.Версия) Тогда

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

		ИначеЕсли Обработчик.Версия <> "*"
			И Не СтрНачинаетсяС(Обработчик.Версия, "ОтладкаОбработчика") Тогда

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

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

			Если НЕ ЗначениеЗаполнено(ОписаниеОшибки)
			   И Обработчик.ВыполнятьВГруппеОбязательных <> Истина
			   И Обработчик.Приоритет <> 0 Тогда

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

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

		Если НЕ ЗначениеЗаполнено(ОписаниеОшибки)
		   И Обработчик.Опциональный = Истина
		   И Обработчик.НачальноеЗаполнение = Истина Тогда

			ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'У обработчика неправильно заполнено свойство %1 или
			               |свойство %2.'"),
				"Опциональный", "НачальноеЗаполнение");
		КонецЕсли;

		Если Не ЗначениеЗаполнено(ОписаниеОшибки) Тогда
			Продолжить;
		КонецЕсли;

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

		ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			ЗаголовокОшибки + Символы.ПС
			+ НСтр("ru = '(%1).'") + Символы.ПС
			+ Символы.ПС
			+ ОписаниеОшибки,
			Обработчик.Процедура);

		ЗаписатьОшибку(ОписаниеОшибки);
		ВызватьИсключение ОписаниеОшибки;

	КонецЦикла;

КонецПроцедуры


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `СообщенияСкриптов`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция СообщенияСкриптов()
Сообщения = Новый Соответствие;

	// Сообщения в макетах МакетФайлаОбновленияКонфигурации, НеинтерактивноеОбновлениеКонфигурации, ЗаставкаОбновленияКонфигурации
	Сообщения["[СообщениеНачалоЗапуска]"] = НСтр("ru = 'Запускается: {0}; параметры: {1}; окно: {2}; ожидание: {3}'");
	Сообщения["[СообщениеДеталиИсключения]"] = НСтр("ru = 'Исключение при запуске приложения: {0}, {1}'");
	Сообщения["[СообщениеРезультатЗапуска]"] = НСтр("ru = 'Код возврата: {0}'");
	Сообщения["[СообщениеПутьКФайлуСкрипта]"] = НСтр("ru = 'Файл скрипта: {0}'");
	Сообщения["[СообщениеСчетчикФайловОбновления]"] = НСтр("ru = 'Количество файлов обновления: {0}'");
	Сообщения["[СообщениеВосстановлениеБазы]"] = НСтр("ru = 'Восстановление ИБ из временного архива'");
	Сообщения["[СообщениеНачалоСеансаСоединенияСБазой]"] = НСтр("ru = 'Начат сеанс внешнего соединения с ИБ'");
	Сообщения["[СообщениеУдалениеЗадачиПланировщика]"] = НСтр("ru = 'Удаление задачи планировщика задач: {0}'");
	Сообщения["[СообщениеОтказУдаленияЗадачиПланировщика]"] = НСтр("ru = 'Задача из планировщика задач не была удалена по причине: {0}'");
	Сообщения["[СообщениеОтказСоединенияСБазой]"] = НСтр("ru = 'Исключение при создании COM-соединения: {0}, {1}'");
	Сообщения["[СообщениеВызовЗавершитьОбновление]"] = "ОбновлениеКонфигурации.ЗавершитьОбновление" + "({0}, {1}, {2})";
	Сообщения["[СообщениеОтказПриВызовеЗавершитьОбновление]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}'"), "ОбновлениеКонфигурации.ЗавершитьОбновление");
	Сообщения["[СообщениеРезультатОбновленияБазы]"] = НСтр("ru = 'Обновление информационной базы завершилось успешно'");
	Сообщения["[СообщениеОтказОбновленияБазы]"] = НСтр("ru = 'Непредвиденная ситуация при обновлении информационной базы'");
	Сообщения["[СообщениеПараметрыБазы]"] = НСтр("ru = 'Параметры информационной базы: {0}.'");
	Сообщения["[СообщениеОтказЛогирования]"] = НСтр("ru = 'Исключение при записи журнала: {0}, {1}'");
	Сообщения["[СообщениеОбновлениеЛогирование1С]"] = НСтр("ru = 'Протокол обновления сохранен в журнал регистрации.'");
	Сообщения["[СообщениеКопированиеБазы]"] = НСтр("ru = '\r\n\Выполняется копирование из:\r\n\{0}\r\n\в:\r\n\{1}'");
	Сообщения["[СообщениеФайлБазыНеСуществует]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Файл базы данных %1 не существует по пути: {0}'"), "1Cv8.1CD");
	Сообщения["[СообщениеКаталогРезервнойКопииБазыНеСуществует]"] = НСтр("ru = 'Папки для сохранения резервной копии не существует: {0}'");
	Сообщения["[СообщениеПараметрыФайлаРезервнойКопии]"] = НСтр("ru = '\r\n\Файл резервной копии уже существует: {0}\r\n\Создан: {1}\r\n\Последнее обращение: {2}\r\n\Последнее изменение: {3}\r\n\Размер: {4}\r\n\Тип: {5}\r\n\Атрибуты:\r\n\{6}'");
	Сообщения["[СообщениеДискНеСуществует]"] = НСтр("ru = '\r\n\Диск не найден по пути {0}\r\n\Исключение: {1}, {2}'");
	Сообщения["[СообщениеДискНедоступен]"] = НСтр("ru = 'Диск не доступен по пути {0}'");
	Сообщения["[СообщениеДисковогоПространстваДостаточно]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Доступно на диске {0}: {1} Mb\r\n\Размер файла %1: {2} Mb\r\n\Тип диска: {3}'"), "1Cv8.1CD");
	Сообщения["[СообщениеДисковогоПространстваНедостаточно]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = '\r\n\Недостаточно свободного места для создания резервной копии.\r\n\Освободите место или укажите папку на другом диске.\r\n\Требуется: {0} Mb\r\n\Доступно на диске {1}: {2} Mb\r\n\Размер файла %1: {3} Mb\r\n\Тип диска: {4}'"), "1Cv8.1CD");
	Сообщения["[СообщениеРезультатСозданияРезервнойКопииБазы]"] = НСтр("ru = 'Резервная копия базы создана'");
	Сообщения["[СообщениеОтказСозданияРезервнойКопииБазыПодробно]"] = НСтр("ru = 'Исключение при создании резервной копии базы: {0}, {1}'");
	Сообщения["[СообщениеРезультатВосстановленияБазы]"] = НСтр("ru = 'База данных восстановлена из резервной копии'");
	Сообщения["[СообщениеОтказВосстановленияБазыПодробно]"] = НСтр("ru = 'Исключение при восстановлении базы из резервной копии: {0}, {1}.'");
	Сообщения["[СообщениеВызовРазрешитьРаботуПользователей]"] = "СоединенияИБ.РазрешитьРаботуПользователей";
	Сообщения["[СообщениеОтказВызоваРазрешитьРаботуПользователей]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}'"), "СоединенияИБ.РазрешитьРаботуПользователей");
	Сообщения["[СообщениеОтказОбновленияИсправлений]"] = НСтр("ru = 'Не удалось обновить исправления конфигурации. Подробности см. в предыдущей записи.'");
	Сообщения["[СообщениеОтказВызоваОбновитьИсправленияИзСкрипта]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}'"), "ОбновлениеКонфигурацииВызовСервера.ОбновитьИсправленияИзСкрипта");
	Сообщения["[СообщениеВызовВыполнитьОбновлениеИнформационнойБазы]"] = "ОбновлениеИнформационнойБазыВызовСервера.ВыполнитьОбновлениеИнформационнойБазы" + "({0})";
	Сообщения["[СообщениеОтказВызоваВыполнитьОбновлениеИнформационнойБазы]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}.'"), "ОбновлениеИнформационнойБазыВызовСервера.ВыполнитьОбновлениеИнформационнойБазы");
	Сообщения["[СообщениеОтказОбновленияБазыОбщее]"] = НСтр("ru = 'Не удалось обновить информационную базу по причине:'");
	Сообщения["[СообщениеБлокировкаБазы]"] = НСтр("ru = 'в связи с необходимостью обновления конфигурации'");
	Сообщения["[СообщениеОтказЗавершенияРаботыПользователей]"] = НСтр("ru = 'Попытка завершения работы пользователей завершилась безуспешно: отменена блокировка ИБ.'");
	Сообщения["[СообщениеОтменаБлокировкиРаботыПользователей]"] = НСтр("ru = 'Исключение при завершении работы пользователей: {0}, {1}'");
	Сообщения["[СообщениеКонецСеансаСоединенияСБазой]"] = НСтр("ru = 'Завершен сеанс внешнего соединения с ИБ'");
	Сообщения["[СообщениеБлокировкаРаботыПользователейЛогирование]"] = НСтр("ru = 'Установка блокировки сеансов в связи с необходимостью обновления конфигурации'");
	Сообщения["[СообщениеБлокировкаРаботыПользователей]"] = НСтр("ru = 'в связи с необходимостью обновления конфигурации'");
	Сообщения["[СообщениеСчетчикСеансовБазы]"] = НСтр("ru = 'Количество сеансов информационной базы: {0}'");
	Сообщения["[СообщениеРезультатБлокировкиСеансов]"] = НСтр("ru = 'Блокировка начала сеансов установлена: {0}'");
    // TODO: допиши оставшуюся часть

[Assistant]
Функция СообщенияСкриптов()

	Сообщения = Новый Соответствие;

	// Сообщения в макетах МакетФайлаОбновленияКонфигурации, НеинтерактивноеОбновлениеКонфигурации, ЗаставкаОбновленияКонфигурации
	Сообщения["[СообщениеНачалоЗапуска]"] = НСтр("ru = 'Запускается: {0}; параметры: {1}; окно: {2}; ожидание: {3}'");
	Сообщения["[СообщениеДеталиИсключения]"] = НСтр("ru = 'Исключение при запуске приложения: {0}, {1}'");
	Сообщения["[СообщениеРезультатЗапуска]"] = НСтр("ru = 'Код возврата: {0}'");
	Сообщения["[СообщениеПутьКФайлуСкрипта]"] = НСтр("ru = 'Файл скрипта: {0}'");
	Сообщения["[СообщениеСчетчикФайловОбновления]"] = НСтр("ru = 'Количество файлов обновления: {0}'");
	Сообщения["[СообщениеВосстановлениеБазы]"] = НСтр("ru = 'Восстановление ИБ из временного архива'");
	Сообщения["[СообщениеНачалоСеансаСоединенияСБазой]"] = НСтр("ru = 'Начат сеанс внешнего соединения с ИБ'");
	Сообщения["[СообщениеУдалениеЗадачиПланировщика]"] = НСтр("ru = 'Удаление задачи планировщика задач: {0}'");
	Сообщения["[СообщениеОтказУдаленияЗадачиПланировщика]"] = НСтр("ru = 'Задача из планировщика задач не была удалена по причине: {0}'");
	Сообщения["[СообщениеОтказСоединенияСБазой]"] = НСтр("ru = 'Исключение при создании COM-соединения: {0}, {1}'");
	Сообщения["[СообщениеВызовЗавершитьОбновление]"] = "ОбновлениеКонфигурации.ЗавершитьОбновление" + "({0}, {1}, {2})";
	Сообщения["[СообщениеОтказПриВызовеЗавершитьОбновление]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}'"), "ОбновлениеКонфигурации.ЗавершитьОбновление");
	Сообщения["[СообщениеРезультатОбновленияБазы]"] = НСтр("ru = 'Обновление информационной базы завершилось успешно'");
	Сообщения["[СообщениеОтказОбновленияБазы]"] = НСтр("ru = 'Непредвиденная ситуация при обновлении информационной базы'");
	Сообщения["[СообщениеПараметрыБазы]"] = НСтр("ru = 'Параметры информационной базы: {0}.'");
	Сообщения["[СообщениеОтказЛогирования]"] = НСтр("ru = 'Исключение при записи журнала: {0}, {1}'");
	Сообщения["[СообщениеОбновлениеЛогирование1С]"] = НСтр("ru = 'Протокол обновления сохранен в журнал регистрации.'");
	Сообщения["[СообщениеКопированиеБазы]"] = НСтр("ru = '\r\n\Выполняется копирование из:\r\n\{0}\r\n\в:\r\n\{1}'");
	Сообщения["[СообщениеФайлБазыНеСуществует]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Файл базы данных %1 не существует по пути: {0}'"), "1Cv8.1CD");
	Сообщения["[СообщениеКаталогРезервнойКопииБазыНеСуществует]"] = НСтр("ru = 'Папки для сохранения резервной копии не существует: {0}'");
	Сообщения["[СообщениеПараметрыФайлаРезервнойКопии]"] = НСтр("ru = '\r\n\Файл резервной копии уже существует: {0}\r\n\Создан: {1}\r\n\Последнее обращение: {2}\r\n\Последнее изменение: {3}\r\n\Размер: {4}\r\n\Тип: {5}\r\n\Атрибуты:\r\n\{6}'");
	Сообщения["[СообщениеДискНеСуществует]"] = НСтр("ru = '\r\n\Диск не найден по пути {0}\r\n\Исключение: {1}, {2}'");
	Сообщения["[СообщениеДискНедоступен]"] = НСтр("ru = 'Диск не доступен по пути {0}'");
	Сообщения["[СообщениеДисковогоПространстваДостаточно]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Доступно на диске {0}: {1} Mb\r\n\Размер файла %1: {2} Mb\r\n\Тип диска: {3}'"), "1Cv8.1CD");
	Сообщения["[СообщениеДисковогоПространстваНедостаточно]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = '\r\n\Недостаточно свободного места для создания резервной копии.\r\n\Освободите место или укажите папку на другом диске.\r\n\Требуется: {0} Mb\r\n\Доступно на диске {1}: {2} Mb\r\n\Размер файла %1: {3} Mb\r\n\Тип диска: {4}'"), "1Cv8.1CD");
	Сообщения["[СообщениеРезультатСозданияРезервнойКопииБазы]"] = НСтр("ru = 'Резервная копия базы создана'");
	Сообщения["[СообщениеОтказСозданияРезервнойКопииБазыПодробно]"] = НСтр("ru = 'Исключение при создании резервной копии базы: {0}, {1}'");
	Сообщения["[СообщениеРезультатВосстановленияБазы]"] = НСтр("ru = 'База данных восстановлена из резервной копии'");
	Сообщения["[СообщениеОтказВосстановленияБазыПодробно]"] = НСтр("ru = 'Исключение при восстановлении базы из резервной копии: {0}, {1}.'");
	Сообщения["[СообщениеВызовРазрешитьРаботуПользователей]"] = "СоединенияИБ.РазрешитьРаботуПользователей";
	Сообщения["[СообщениеОтказВызоваРазрешитьРаботуПользователей]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}'"), "СоединенияИБ.РазрешитьРаботуПользователей");
	Сообщения["[СообщениеОтказОбновленияИсправлений]"] = НСтр("ru = 'Не удалось обновить исправления конфигурации. Подробности см. в предыдущей записи.'");
	Сообщения["[СообщениеОтказВызоваОбновитьИсправленияИзСкрипта]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}'"), "ОбновлениеКонфигурацииВызовСервера.ОбновитьИсправленияИзСкрипта");
	Сообщения["[СообщениеВызовВыполнитьОбновлениеИнформационнойБазы]"] = "ОбновлениеИнформационнойБазыВызовСервера.ВыполнитьОбновлениеИнформационнойБазы" + "({0})";
	Сообщения["[СообщениеОтказВызоваВыполнитьОбновлениеИнформационнойБазы]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}.'"), "ОбновлениеИнформационнойБазыВызовСервера.ВыполнитьОбновлениеИнформационнойБазы");
	Сообщения["[СообщениеОтказОбновленияБазыОбщее]"] = НСтр("ru = 'Не удалось обновить информационную базу по причине:'");
	Сообщения["[СообщениеБлокировкаБазы]"] = НСтр("ru = 'в связи с необходимостью обновления конфигурации'");
	Сообщения["[СообщениеОтказЗавершенияРаботыПользователей]"] = НСтр("ru = 'Попытка завершения работы пользователей завершилась безуспешно: отменена блокировка ИБ.'");
	Сообщения["[СообщениеОтменаБлокировкиРаботыПользователей]"] = НСтр("ru = 'Исключение при завершении работы пользователей: {0}, {1}'");
	Сообщения["[СообщениеКонецСеансаСоединенияСБазой]"] = НСтр("ru = 'Завершен сеанс внешнего соединения с ИБ'");
	Сообщения["[СообщениеБлокировкаРаботыПользователейЛогирование]"] = НСтр("ru = 'Установка блокировки сеансов в связи с необходимостью обновления конфигурации'");
	Сообщения["[СообщениеБлокировкаРаботыПользователей]"] = НСтр("ru = 'в связи с необходимостью обновления конфигурации'");
	Сообщения["[СообщениеСчетчикСеансовБазы]"] = НСтр("ru = 'Количество сеансов информационной базы: {0}'");
	Сообщения["[СообщениеРезультатБлокировкиСеансов]"] = НСтр("ru = 'Блокировка начала сеансов установлена: {0}'");
	Сообщения["[СообщениеСчетчикЗависшихСеансовБазы]"] = НСтр("ru = 'Количество зависших сеансов информационной базы: {0}, попытка № {1}'");
	Сообщения["[СообщениеВызовВыполнитьОтложенноеОбновлениеСейчас]"] = "ОбновлениеИнформационнойБазыСлужебный.ВыполнитьОтложенноеОбновлениеСейчас" + "()";
	Сообщения["[СообщениеОтказВызоваВыполнитьОтложенноеОбновлениеСейчас]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}.'"), "ОбновлениеИнформационнойБазыСлужебный.ВыполнитьОтложенноеОбновлениеСейчас");
	Сообщения["[СообщениеОтказВызоваУдалитьИсправленияИзСкрипта]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Исключение при вызове %1: {0}, {1}.'"), "ОбновлениеКонфигурацииВызовСервера.УдалитьИсправленияИзСкрипта");
	Сообщения["[СообщениеОтказУдаленияИсправлений]"] = НСтр("ru = 'Не удалось удалить исправления конфигурации. Подробности см. в предыдущей записи.'");
	Сообщения["[СообщениеПараметрыCOMСоединителя]"] = НСтр("ru = 'Используется COM-соединение: {0}'");
	Сообщения["[СообщениеОтказОбновленияБазыИзФайла]"] = НСтр("ru = 'Не удалось обновить по файлу, возможно конфигурация не находится на поддержке, попытка загрузки конфигурации.'");
	Сообщения["[СообщениеЗаставкиОшибкаШага]"] = НСтр("ru = 'Завершение с ошибкой. Код ошибки: {0}. Подробности см. в предыдущей записи.'");
	Сообщения["[СообщениеИнициализация]"] = НСтр("ru = 'Инициализация'");
	Сообщения["[СообщениеЗавершениеРаботыПользователей]"] = НСтр("ru = 'Завершение работы пользователей'");
	Сообщения["[СообщениеСозданиеРезервнойКопииБазы]"] = НСтр("ru = 'Создание резервной копии информационной базы'");
	Сообщения["[СообщениеВыполнениеОтложенныхОбработчиковОбновления]"] = НСтр("ru = 'Выполнение отложенных обработчиков обновления'");
	Сообщения["[СообщениеОбновлениеКонфигурации]"] = НСтр("ru = 'Обновление конфигурации информационной базы'");
	Сообщения["[СообщениеЗагрузкаРасширений]"] = НСтр("ru = 'Обновление расширений информационной базы'");
	Сообщения["[СообщениеЗагрузкаФайлаОбновлений]"] = НСтр("ru = 'Загрузка файла обновления в основную базу ({0}/{1})'");
	Сообщения["[СообщениеПараметрыОбновленияКонфигурации]"] = НСтр("ru = 'Обновление конфигурации информационной базы ({0}/{1})'");
	Сообщения["[СообщениеВыполнениеОбработчиковОбновления]"] = НСтр("ru = 'Выполнение обработчиков обновления ({0}/{1})'");
	Сообщения["[СообщениеРазрешениеПодключений]"] = НСтр("ru = 'Разрешение подключений новых соединений'");
	Сообщения["[СообщениеЗавершениеОбновления]"] = НСтр("ru = 'Завершение'");

	// Сообщения в макете СкриптУдаленияПатчей
	Сообщения["[СообщениеОтказИнициализации]"] = НСтр("ru = 'Переменные не инициализированы'");
	Сообщения["[СообщениеСозданиеОбъектаCOMСоединителя]"] = НСтр("ru = 'Создание объекта COM-соединителя...'");
	Сообщения["[СообщениеОтказСозданияОбъектаCOMСоединителя]"] = НСтр("ru = 'Не удалось создать объект COM-соединителя:'");
	Сообщения["[СообщениеУстановкаСоединенияСБазой]"] = НСтр("ru = 'Установка соединения с'");
	Сообщения["[СообщениеОтказСоединенияСБазойОбщее]"] = НСтр("ru = 'Не удалось установить соединение с'");
	Сообщения["[СообщениеОсновноеСобытие]"] = НСтр("ru = 'Удаление исправлений (патчей)'");
	Сообщения["[СообщениеВызовУдалитьИсправленияИзСкрипта]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Вызов %1...'"), "ОбновлениеКонфигурацииВызовСервера.УдалитьИсправленияИзСкрипта");
	Сообщения["[СообщениеВызовОбновитьИсправленияИзСкрипта]"] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Вызов %1...'"), "ОбновлениеКонфигурацииВызовСервера.ОбновитьИсправленияИзСкрипта");
	Сообщения["[СообщениеОшибка]"] = НСтр("ru = ': Ошибка в конфигурации:'") + Символы.НПП;
	Сообщения["[СообщениеВажность]"] = НСтр("ru = 'Обязательная'");

	Возврат Сообщения;

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

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


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `ПолучитьПараметрыАутентификацииАдминистратораОбновления`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция ПолучитьПараметрыАутентификацииАдминистратораОбновления(ПараметрыАдминистрирования)
Результат = Новый Структура("СтрокаПодключения, СтрокаСоединенияИнформационнойБазы");

	ПортКластера = ПараметрыАдминистрирования.ПортКластера;
	ТекущиеСоединения = СоединенияИБВызовСервера.ИнформацияОСоединениях(Истина,
		ПараметрыПриложения["СтандартныеПодсистемы.СообщенияДляЖурналаРегистрации"], ПортКластера);

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

[Assistant]
Функция ПолучитьПараметрыАутентификацииАдминистратораОбновления(ПараметрыАдминистрирования)

	Результат = Новый Структура("СтрокаПодключения, СтрокаСоединенияИнформационнойБазы");

	ПортКластера = ПараметрыАдминистрирования.ПортКластера;
	ТекущиеСоединения = СоединенияИБВызовСервера.ИнформацияОСоединениях(Истина,
		ПараметрыПриложения["СтандартныеПодсистемы.СообщенияДляЖурналаРегистрации"], ПортКластера);

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

		ТекстОшибки = ТекстОшибки + Символы.ПС + Символы.ПС + ПостФикс;
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки, Символы.ПС, ПутьКБазе);

		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	Результат.СтрокаСоединенияИнформационнойБазы = ТекущиеСоединения.СтрокаСоединенияИнформационнойБазы;
	Результат.СтрокаПодключения = "Usr=""{0}"";Pwd=""{1}""";

	Возврат Результат;

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

Функция ИмяЗадачиScheduleService(Знач КодЗадачи)

	Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Обновление конфигурации (%1)'"), Формат(КодЗадачи, "ЧГ=0"));

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

Функция СтрокаUnicode(Строка)

	Результат = "";

	Для НомерСимвола = 1 По СтрДлина(Строка) Цикл

		Символ = Формат(КодСимвола(Сред(Строка, НомерСимвола, 1)), "ЧГ=0");
		Символ = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(Символ, 4);
		Результат = Результат + Символ;

	КонецЦикла;

	Возврат Результат;

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

// Возвращает имя события для записи журнала регистрации.

Функция СобытиеЖурналаРегистрации() Экспорт
	Возврат НСтр("ru = 'Обновление конфигурации'", ОбщегоНазначенияКлиент.КодОсновногоЯзыка());
КонецФункции

// Проверяет наличие обновления конфигурации при запуске программы.
//

Процедура ПроверитьОбновлениеКонфигурации()

	Если Не ОбщегоНазначенияКлиент.ЭтоWindowsКлиент() Тогда
		Возврат;
	КонецЕсли;

#Если Не ВебКлиент И Не МобильныйКлиент Тогда
	Если ОбщегоНазначенияКлиент.РазделениеВключено()
	 Или Не ОбщегоНазначенияКлиент.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;

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

	НастройкиОбновления = ПараметрыРаботыКлиента.НастройкиОбновления;
	НаличиеОбновления = НастройкиОбновления.ПроверитьПрошлыеОбновленияБазы;

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

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

#КонецЕсли

КонецПроцедуры

Функция ПоддерживаетсяПланировщикЗаданий()

	// Планировщик заданий поддерживается начиная с версии 6.0 - Windows Vista.

	СистемнаяИнформация = Новый СистемнаяИнформация();

	ПозицияТочки = СтрНайти(СистемнаяИнформация.ВерсияОС, ".");
	Если ПозицияТочки < 2 Тогда
		Возврат Ложь;
	КонецЕсли;

	НомерВерсии = Сред(СистемнаяИнформация.ВерсияОС, ПозицияТочки - 2, 2);

	ОписаниеТипаЧисло = Новый ОписаниеТипов("Число");
	ВерсияВышеVista = ОписаниеТипаЧисло.ПривестиЗначение(НомерВерсии) >= 6;

	Возврат ВерсияВышеVista;

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

Процедура ЗаписатьСобытияВЖурналРегистрации() Экспорт

	СобытияДляЖурналаРегистрации = ПараметрыПриложения["СтандартныеПодсистемы.СообщенияДляЖурналаРегистрации"];

	Если ТипЗнч(СобытияДляЖурналаРегистрации) <> Тип("СписокЗначений") Тогда
		Возврат;
	КонецЕсли;

	Если СобытияДляЖурналаРегистрации.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	ЖурналРегистрацииВызовСервера.ЗаписатьСобытияВЖурналРегистрации(СобытияДляЖурналаРегистрации);

КонецПроцедуры

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

Процедура ПрочитатьДанныеВЖурналРегистрации(РезультатОбновления, КаталогСкрипта)

	РезультатОбновления = Неопределено;
	ПриОбновленииПроизошлаОшибка = Ложь;

	МассивФайлов = НайтиФайлы(КаталогСкрипта, "log*.txt");

	Если МассивФайлов.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	ФайлЖурнала = МассивФайлов[0];

	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.Прочитать(ФайлЖурнала.ПолноеИмя);

	Для НомерСтроки = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл

		ТекущаяСтрока = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки);
		Если ПустаяСтрока(ТекущаяСтрока) Тогда
			Продолжить;
		КонецЕсли;

		ПредставлениеУровня = "Информация";
		Если Сред(ТекущаяСтрока, 3, 1) = "." И Сред(ТекущаяСтрока, 6, 1) = "." Тогда // Строка с датой
			МассивСтроки = СтрРазделить(ТекущаяСтрока, " ", Ложь);
			МассивДаты = СтрРазделить(МассивСтроки[0], ".");
			МассивВремени = СтрРазделить(МассивСтроки[1], ":");
			ДатаСобытия = Дата(МассивДаты[2], МассивДаты[1], МассивДаты[0], МассивВремени[0], МассивВремени[1], МассивВремени[2]);
			Если МассивСтроки[2] = "{ERR}" Тогда
				ПредставлениеУровня = "Ошибка";
				ПриОбновленииПроизошлаОшибка = Истина;
			КонецЕсли;

			Комментарий = СокрЛП(Сред(ТекущаяСтрока, СтрНайти(ТекущаяСтрока, "}") + 2));
			Если СтрНачинаетсяС(Комментарий, "ОбновлениеВыполненоУспешно")
				Или Комментарий = "Обновление выполнено" Тогда // АПК:1297 не локализуется (фрагмент журнала), для совместимости
				РезультатОбновления = Истина;
				Продолжить;
			ИначеЕсли СтрНачинаетсяС(Комментарий, "ОбновлениеНеВыполнено")
				Или Комментарий = "Обновление не выполнено" Тогда // АПК:1297 не локализуется (фрагмент журнала), для совместимости
				РезультатОбновления = Ложь;
				Продолжить;
			КонецЕсли;

			Для НомерСледСтроки = НомерСтроки + 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
				ТекущаяСтрока = ТекстовыйДокумент.ПолучитьСтроку(НомерСледСтроки);
				Если Сред(ТекущаяСтрока, 3, 1) = "." И Сред(ТекущаяСтрока, 6, 1) = "." Тогда
					// Следующая строка - строка нового события.
					НомерСтроки = НомерСледСтроки - 1;
					Прервать;
				КонецЕсли;

				Комментарий = Комментарий + Символы.ПС + ТекущаяСтрока;
			КонецЦикла;

			ЖурналРегистрацииКлиент.ДобавитьСообщениеДляЖурналаРегистрации(СобытиеЖурналаРегистрации(),
				ПредставлениеУровня, Комментарий, ДатаСобытия);

		КонецЕсли;

	КонецЦикла;

	// Если обновление выполнялось с версии БСП ниже 2.3.1.6, то записей лога
	// - "Обновление выполнено"
	// - "Обновление не выполнено"
	// может не быть, потому будем опираться на то - происходили ли ошибки в ходе обновления.
	Если РезультатОбновления = Неопределено Тогда
		РезультатОбновления = Не ПриОбновленииПроизошлаОшибка;
	КонецЕсли;

	ЗаписатьСобытияВЖурналРегистрации();

КонецПроцедуры

Функция КодировкаФайловПрограммыОбновления()

	// wscript.exe может работать только с файлами в кодировке UTF-16 LE.
	Возврат КодировкаТекста.UTF16;

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


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `СтруктураПоМенеджеруЗаписи`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция СтруктураПоМенеджеруЗаписи(МенеджерЗаписи, МетаданныеРегистра)
Экспорт

	ЗаписьКакСтруктура = Новый Структура;

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

[Assistant]
Функция СтруктураПоМенеджеруЗаписи(МенеджерЗаписи, МетаданныеРегистра) Экспорт

	ЗаписьКакСтруктура = Новый Структура;

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

	Возврат ЗаписьКакСтруктура;

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

// Создает массив и копирует в него значения, содержащиеся в колонке объекта, для
// которого доступен обход посредством оператора Для каждого … Из.
//
// Параметры:
//  КоллекцияСтрок           - ТаблицаЗначений
//                           - ДеревоЗначений
//                           - СписокЗначений
//                           - ТабличнаяЧасть
//                           - Соответствие
//                           - Структура - коллекция, колонку которой нужно выгрузить в массив.
//                                         А так же другие объекты, для которых доступен обход
//                                         посредством оператора Для каждого … Из … Цикл.
//  ИмяКолонки               - Строка - имя поля коллекции, значения которого нужно выгрузить.
//  ТолькоУникальныеЗначения - Булево - если Истина, то в массив будут включены
//                                      только различающиеся значения.
//
// Возвращаемое значение:
//  Массив - значения колонки.
//

Функция ВыгрузитьКолонку(КоллекцияСтрок, ИмяКолонки, ТолькоУникальныеЗначения = Ложь) Экспорт

	МассивЗначений = Новый Массив;

	УникальныеЗначения = Новый Соответствие;

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

	Возврат МассивЗначений;

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

// Преобразует текст указанного формата XML в таблицу значений,
// при этом колонки таблицы формируются на основе описания в XML.
//
// Схема XML:
// <?xml version="1.0" encoding="utf-8"?>
//  <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
//   <xs:element name="Items">
//    <xs:complexType>
//     <xs:sequence>
//      <xs:element maxOccurs="unbounded" name="Item">
//       <xs:complexType>
//        <xs:attribute name="Code" type="xs:integer" use="required" />
//        <xs:attribute name="Name" type="xs:string" use="required" />
//        <xs:attribute name="Socr" type="xs:string" use="required" />
//        <xs:attribute name="Index" type="xs:string" use="required" />
//       </xs:complexType>
//      </xs:element>
//     </xs:sequence>
//    <xs:attribute name="Description" type="xs:string" use="required" />
//    <xs:attribute name="Columns" type="xs:string" use="required" />
//   </xs:complexType>
//  </xs:element>
// </xs:schema>
//
// Параметры:
//  XML - Строка
//      - ЧтениеXML - текст в формате XML или ЧтениеXML.
//
// Возвращаемое значение:
//  Структура:
//   * ИмяТаблицы - Строка          - имя таблицы.
//   * Данные     - ТаблицаЗначений - преобразованная из XML таблица.
//
// Пример:
//   КлассификаторТаблица = ОбщегоНазначения.ПрочитатьXMLВТаблицу(
//     Обработки.ЗагрузкаКурсовВалют.ПолучитьМакет("ОбщероссийскийКлассификаторВалют").ПолучитьТекст()).Данные;
//

Функция ПрочитатьXMLВТаблицу(Знач XML) Экспорт

	Если ТипЗнч(XML) <> Тип("ЧтениеXML") Тогда
		Чтение = Новый ЧтениеXML;
		Чтение.УстановитьСтроку(XML);
	Иначе
		Чтение = XML;
	КонецЕсли;

	// Прочитаем первый узел и проверим его.
	Если Не Чтение.Прочитать() Тогда
		ВызватьИсключение НСтр("ru = 'Пустой XML'");
	ИначеЕсли Чтение.Имя <> "Items" Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка в структуре XML'");
	КонецЕсли;

	// Получим описание таблицы и создадим ее.
	ИмяТаблицы = Чтение.ПолучитьАтрибут("Description");
	ИменаКолонок = СтрЗаменить(Чтение.ПолучитьАтрибут("Columns"), ",", Символы.ПС);
	Колонок = СтрЧислоСтрок(ИменаКолонок);

	ТаблицаЗначений = Новый ТаблицаЗначений;
	Для Сч = 1 По Колонок Цикл
		ТаблицаЗначений.Колонки.Добавить(СтрПолучитьСтроку(ИменаКолонок, Сч), Новый ОписаниеТипов("Строка"));
	КонецЦикла;

	// Заполним значения в таблице.
	Пока Чтение.Прочитать() Цикл

		Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента И Чтение.Имя = "Items" Тогда
			Прервать;
		ИначеЕсли Чтение.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
			Продолжить;
		ИначеЕсли Чтение.Имя <> "Item" Тогда
			ВызватьИсключение НСтр("ru = 'Ошибка в структуре XML'");
		КонецЕсли;

		новСтр = ТаблицаЗначений.Добавить();
		Для Сч = 1 По Колонок Цикл
			ИмяКолонки = СтрПолучитьСтроку(ИменаКолонок, Сч);
			новСтр[Сч-1] = Чтение.ПолучитьАтрибут(ИмяКолонки);
		КонецЦикла;

	КонецЦикла;

	// Заполним результат
	Результат = Новый Структура;
	Результат.Вставить("ИмяТаблицы", ИмяТаблицы);
	Результат.Вставить("Данные", ТаблицаЗначений);

	Возврат Результат;

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

// Сравнивает две коллекции строк (ТаблицаЗначений, ДеревоЗначений и т.д.),
// для которых доступен обход посредством оператора Для каждого … Из … Цикл.
// Сравниваемые коллекции должны отвечать следующим требованиям:
//  - доступен обход посредством оператора Для каждого … Из … Цикл,
//  - наличие в обеих коллекциях всех колонок, перечисленных в параметре ИменаКолонок
//  (если ИменаКолонок не заполнен - все колонки первой коллекции должны существовать во второй коллекции).
//  Также позволяет сравнивать массивы.
//
// Параметры:
//  КоллекцияСтрок1 - ТаблицаЗначений
//                  - ДеревоЗначений
//                  - СписокЗначений
//                  - ТабличнаяЧасть
//                  - Соответствие
//                  - Массив
//                  - ФиксированныйМассив
//                  - Структура - коллекция, отвечающая вышеописанным требованиям. А также другие
//                     объекты, для которых доступен обход посредством оператора Для каждого … Из … Цикл.
//  КоллекцияСтрок2 - ТаблицаЗначений
//                  - ДеревоЗначений
//                  - СписокЗначений
//                  - ТабличнаяЧасть
//                  - Соответствие
//                  - Массив
//                  - ФиксированныйМассив
//                  - Структура - коллекция, отвечающая вышеописанным требованиям. А также другие
//                     объекты, для которых доступен обход посредством оператора Для каждого … Из … Цикл.
//  ИменаКолонок - Строка - имена колонок через запятую, по которым производится сравнение.
//                          Не обязательно для коллекций, состав колонок которых можно определить автоматически:
//                          ТаблицаЗначений, СписокЗначений, Соответствие, Структура.
//                          Если не указан, то сравнение производится по колонкам первой коллекции.
//                          Для коллекций других типов является обязательным.
//  ИсключаяКолонки - Строка - имена колонок, которые игнорируются при сравнении.
//  УчитыватьПоследовательностьСтрок - Булево - если Истина, то коллекции признаются
//                      идентичными, только если одинаковые строки размещены в коллекциях на одинаковых местах.
//
// Возвращаемое значение:
//  Булево - Истина, если идентичны.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `СообщитьПользователю`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю,
		Знач КлючДанных = Неопределено,
		Знач Поле = "",
		Знач ПутьКДанным = "",
		Отказ = Ложь)
Экспорт

	Сообщение = Новый СообщениеПользователю;
	Сообщение.Текст = ТекстСообщенияПользователю;
	Сообщение.Поле = Поле;

	ЭтоОбъект = Ложь;

#Если НЕ ТонкийКлиент И НЕ ВебКлиент И НЕ МобильныйКлиент Тогда
	Если КлючДанных <> Неопределено
	   И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
		ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
		ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, "Object.") > 0;
	КонецЕсли;
#КонецЕсли

	Если ЭтоОбъект Тогда
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура СообщитьПользователю(
		Знач ТекстСообщенияПользователю,
		Знач КлючДанных = Неопределено,
		Знач Поле = "",
		Знач ПутьКДанным = "",
		Отказ = Ложь) Экспорт

	Сообщение = Новый СообщениеПользователю;
	Сообщение.Текст = ТекстСообщенияПользователю;
	Сообщение.Поле = Поле;

	ЭтоОбъект = Ложь;

#Если НЕ ТонкийКлиент И НЕ ВебКлиент И НЕ МобильныйКлиент Тогда
	Если КлючДанных <> Неопределено
	   И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
		ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
		ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, "Object.") > 0;
	КонецЕсли;
#КонецЕсли

	Если ЭтоОбъект Тогда
		Сообщение.УстановитьДанные(КлючДанных);
	Иначе
		Сообщение.КлючДанных = КлючДанных;
	КонецЕсли;

	Если НЕ ПустаяСтрока(ПутьКДанным) Тогда
		Сообщение.ПутьКДанным = ПутьКДанным;
	КонецЕсли;

	Сообщение.Сообщить();

	Отказ = Истина;

КонецПроцедуры

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

Функция СкопироватьРекурсивно(Источник) Экспорт

	Перем Приемник;

	ТипИсточника = ТипЗнч(Источник);

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
	Если ТипИсточника = Тип("ТаблицаЗначений") Тогда
		Возврат Источник.Скопировать();
	КонецЕсли;
#КонецЕсли
	Если ТипИсточника = Тип("Структура") Тогда
		Приемник = СкопироватьСтруктуру(Источник);
	ИначеЕсли ТипИсточника = Тип("Соответствие") Тогда
		Приемник = СкопироватьСоответствие(Источник);
	ИначеЕсли ТипИсточника = Тип("Массив") Тогда
		Приемник = СкопироватьМассив(Источник);
	ИначеЕсли ТипИсточника = Тип("СписокЗначений") Тогда
		Приемник = СкопироватьСписокЗначений(Источник);
	Иначе
		Приемник = Источник;
	КонецЕсли;

	Возврат Приемник;

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

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

Функция СкопироватьСтруктуру(СтруктураИсточник) Экспорт

	СтруктураРезультат = Новый Структура;

	Для Каждого КлючИЗначение Из СтруктураИсточник Цикл
		СтруктураРезультат.Вставить(КлючИЗначение.Ключ, СкопироватьРекурсивно(КлючИЗначение.Значение));
	КонецЦикла;

	Возврат СтруктураРезультат;

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

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

Функция СкопироватьСоответствие(СоответствиеИсточник) Экспорт

	СоответствиеРезультат = Новый Соответствие;

	Для Каждого КлючИЗначение Из СоответствиеИсточник Цикл
		СоответствиеРезультат.Вставить(КлючИЗначение.Ключ, СкопироватьРекурсивно(КлючИЗначение.Значение));
	КонецЦикла;

	Возврат СоответствиеРезультат;

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

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

Функция СкопироватьМассив(МассивИсточник) Экспорт

	МассивРезультат = Новый Массив;

	Для Каждого Элемент Из МассивИсточник Цикл
		МассивРезультат.Добавить(СкопироватьРекурсивно(Элемент));
	КонецЦикла;

	Возврат МассивРезультат;

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

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

Функция СкопироватьСписокЗначений(СписокИсточник) Экспорт

	СписокРезультат = Новый СписокЗначений;

	Для Каждого ЭлементСписка Из СписокИсточник Цикл
		СписокРезультат.Добавить(
			СкопироватьРекурсивно(ЭлементСписка.Значение),
			ЭлементСписка.Представление,
			ЭлементСписка.Пометка,
			ЭлементСписка.Картинка);
	КонецЦикла;

	Возврат СписокРезультат;

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

// Устарела. Следует использовать ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу
// Заполняет коллекцию-приемник значениями из коллекции-источник.
// В качестве коллекций источника и приемника могут выступать типы:
// ТаблицаЗначений; ДеревоЗначений; СписокЗначений и пр.
//
// Параметры:
//  КоллекцияИсточник - см. ДополнитьТаблицу.ТаблицаИсточник
//  КоллекцияПриемник - см. ДополнитьТаблицу.ТаблицаПриемник
//


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Функция ИмяФункции(НомераПолучателей, Текст, ИмяОтправителя, Логин, Пароль) Экспорт

	Результат = Новый Структура("ОтправленныеСообщения,ОписаниеОшибки", Новый Массив, "");

	// Подготовка строки получателей.
	СтрокаПолучателей = МассивПолучателейСтрокой(НомераПолучателей);

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

	// Подготовка параметров запроса.
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("login", Логин);
	ПараметрыЗапроса.Вставить("psw", Пароль);

	ПараметрыЗапроса.Вставить("mes", Текст);
	ПараметрыЗапроса.Вставить("phones", СтрокаПолучателей);
	ПараметрыЗапроса.Вставить("sender", ИмяОтправителя);
	ПараметрыЗапроса.Вставить("fmt", 3); // Ответ в формате JSON.
	ПараметрыЗапроса.Вставить("op", 1); // Выводить информацию по каждому номеру отдельно.
	ПараметрыЗапроса.Вставить("charset", "utf-8");

	// отправка запроса
	ТекстОтвета = ВыполнитьЗапрос("send.php", ПараметрыЗапроса); // АПК:1425 Не является именем временного исполняемого файла.
	Если Не ЗначениеЗаполнено(ТекстОтвета) Тогда
		Результат.ОписаниеОшибки = Результат.ОписаниеОшибки + НСтр("ru = 'Соединение не установлено'");
		Возврат Результат;
	КонецЕсли;

	ОтветСервера = ОбщегоНазначения.JSONВЗначение(ТекстОтвета, , Ложь);

	Если ОтветСервера.Свойство("error") Тогда
		Результат.ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(
			"ru = 'Не удалось отправить SMS:
			|%1 (код ошибки: %2)'"), ОписаниеОшибкиОтправки(ОтветСервера["error_code"]), ОтветСервера["error_code"]);

		ЗаписьЖурналаРегистрации(НСтр("ru = 'Отправка SMS'", ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка, , , Результат.ОписаниеОшибки);
	Иначе
		ИдентификаторСообщения = ОтветСервера["id"];
		Для Каждого СведенияОбОтправке Из ОтветСервера["phones"] Цикл
			НомерПолучателя = ФорматироватьНомер(СведенияОбОтправке["phone"]);
			Если СведенияОбОтправке.Свойство("status") И ЗначениеЗаполнено(СведенияОбОтправке["status"]) Тогда
				Продолжить;
			КонецЕсли;
			ОтправленноеСообщение = Новый Структура("НомерПолучателя,ИдентификаторСообщения", НомерПолучателя,
				"" + НомерПолучателя + "/" + Формат(ИдентификаторСообщения, "ЧГ=0"));
			Результат.ОтправленныеСообщения.Добавить(ОтправленноеСообщение);
		КонецЦикла;
	КонецЕсли;

	Возврат Результат;

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

// Возвращает текстовое представление статуса доставки сообщения.
//
// Параметры:
//  ИдентификаторСообщения - Строка - идентификатор, присвоенный sms при отправке.
//  НастройкиОтправкиSMS   - см. ОтправкаSMS.НастройкиОтправкиSMS.
//
// Возвращаемое значение:
//   см. ОтправкаSMS.СтатусДоставки.
//

Функция СтатусДоставки(ИдентификаторСообщения, НастройкиОтправкиSMS) Экспорт
	Логин = НастройкиОтправкиSMS.Логин;
	Пароль = НастройкиОтправкиSMS.Пароль;

	ЧастиИдентификатора = СтрРазделить(ИдентификаторСообщения, "/", Истина);

	// Подготовка параметров запроса.
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("login", Логин);
	ПараметрыЗапроса.Вставить("psw", Пароль);
	ПараметрыЗапроса.Вставить("phone", ЧастиИдентификатора[0]);
	ПараметрыЗапроса.Вставить("id", Число(ЧастиИдентификатора[1]));
	ПараметрыЗапроса.Вставить("fmt", 3);

	// отправка запроса
	ТекстОтвета = ВыполнитьЗапрос("status.php", ПараметрыЗапроса); // АПК:1425 Не является именем временного исполняемого файла.
	Если Не ЗначениеЗаполнено(ТекстОтвета) Тогда
		Возврат "Ошибка";
	КонецЕсли;

	ОтветСервера = ОбщегоНазначения.JSONВЗначение(ТекстОтвета, , Ложь);

	Если ОтветСервера.Свойство("error") Тогда
		ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(
			"ru = 'Не удалось получить статус доставки SMS (id: ""%3""):
			|%1 (код ошибки: %2)'"), ОписаниеОшибкиПолученияСтатуса(ОтветСервера["error_code"]), ОтветСервера["error_code"], ИдентификаторСообщения);
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Отправка SMS'", ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки);
		Возврат "Ошибка";
	КонецЕсли;

	Возврат СтатусДоставкиSMS(ОтветСервера["status"]);

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

Функция СтатусДоставкиSMS(КодСостояния)
	СоответствиеСтатусов = Новый Соответствие;
	СоответствиеСтатусов.Вставить(-3, "НеОтправлялось");
	СоответствиеСтатусов.Вставить(-1, "Отправляется");
	СоответствиеСтатусов.Вставить(0, "Отправлено");
	СоответствиеСтатусов.Вставить(1, "Доставлено");
	СоответствиеСтатусов.Вставить(3, "НеДоставлено");
	СоответствиеСтатусов.Вставить(20, "НеДоставлено");
	СоответствиеСтатусов.Вставить(22, "НеОтправлено");
	СоответствиеСтатусов.Вставить(23, "НеОтправлено");
	СоответствиеСтатусов.Вставить(24, "НеОтправлено");
	СоответствиеСтатусов.Вставить(25, "НеОтправлено");

	Результат = СоответствиеСтатусов[КодСостояния];
	Возврат ?(Результат = Неопределено, "Ошибка", Результат);
КонецФункции

Функция ОписаниеОшибкиОтправки(КодОшибки)
	ОписанияОшибок = Новый Соответствие;
	ОписанияОшибок.Вставить(1, НСтр("ru = 'Ошибка в параметрах.'"));
	ОписанияОшибок.Вставить(2, НСтр("ru = 'Неверный логин или пароль.'"));
	ОписанияОшибок.Вставить(3, НСтр("ru = 'Недостаточно средств на счете.'"));
	ОписанияОшибок.Вставить(4, НСтр("ru = 'IP-адрес временно заблокирован из-за частых ошибок в запросах. Подробнее см. http://smsc.ru/faq/99'"));
	ОписанияОшибок.Вставить(5, НСтр("ru = 'Неверный формат даты.'"));
	ОписанияОшибок.Вставить(6, НСтр("ru = 'Сообщение запрещено (по тексту или по имени отправителя).'"));
	ОписанияОшибок.Вставить(7, НСтр("ru = 'Неверный формат номера телефона.'"));
	ОписанияОшибок.Вставить(8, НСтр("ru = 'Сообщение на указанный номер не может быть доставлено.'"));
	ОписанияОшибок.Вставить(9, НСтр("ru = 'Отправка более одного одинакового запроса на передачу SMS-сообщения в течение минуты.'"));

	ТекстСообщения = ОписанияОшибок[КодОшибки];
	Если ТекстСообщения = Неопределено Тогда
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Сообщение не отправлено (код ошибки: %1).'"), КодОшибки);
	КонецЕсли;
	Возврат ТекстСообщения;
КонецФункции

Функция ОписаниеОшибкиПолученияСтатуса(КодОшибки)
	ОписанияОшибок = Новый Соответствие;
	ОписанияОшибок.Вставить(1, НСтр("ru = 'Ошибка в параметрах.'"));
	ОписанияОшибок.Вставить(2, НСтр("ru = 'Неверный логин или пароль.'"));
	ОписанияОшибок.Вставить(5, НСтр("ru = 'Ошибка удаления сообщения.'"));
	ОписанияОшибок.Вставить(4, НСтр("ru = 'IP-адрес временно заблокирован из-за частых ошибок в запросах. Подробнее см. http://smsc.ru/faq/99'"));
	ОписанияОшибок.Вставить(9, НСтр("ru = 'Отправка более пяти запросов на получения статуса одного и того же сообщения в течение минуты.'"));

	ТекстСообщения = ОписанияОшибок[КодОшибки];
	Если ТекстСообщения = Неопределено Тогда
		ТекстСообщения = НСтр("ru = 'Отказ выполнения операции'");
	КонецЕсли;
	Возврат ТекстСообщения;
КонецФункции

[Assistant] Функция ОтправитьSMS(НомераПолучателей, Текст, ИмяОтправителя, Логин, Пароль)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Функция ИмяФункции(ИмяМетода, ПараметрыЗапроса)

	HTTPЗапрос = ОтправкаSMS.ПодготовитьHTTPЗапрос("/sys/" + ИмяМетода, ПараметрыЗапроса);
	HTTPОтвет = Неопределено;

	Попытка
		Соединение = Новый HTTPСоединение("smsc.ru", , , , ПолучениеФайловИзИнтернета.ПолучитьПрокси("https"),
			60, ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение());
		HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
	Исключение
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Отправка SMS'", ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка, , , ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		Возврат Неопределено;
	КонецПопытки;

	Если HTTPОтвет.КодСостояния <> 200 Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Запрос ""%1"" не выполнен. Код состояния: %2.'"), ИмяМетода, HTTPОтвет.КодСостояния) + Символы.ПС
			+ HTTPОтвет.ПолучитьТелоКакСтроку();
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Отправка SMS'", ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
		Возврат Неопределено;
	КонецЕсли;

	Если HTTPОтвет <> Неопределено Тогда
		Возврат HTTPОтвет.ПолучитьТелоКакСтроку();
	КонецЕсли;

	Возврат Неопределено;

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

Функция МассивПолучателейСтрокой(Массив)
	Получатели = Новый Массив;
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Получатели, Массив, Истина);

	Результат = "";
	Для Каждого Получатель Из Получатели Цикл
		Номер = ФорматироватьНомер(Получатель);
		Если НЕ ПустаяСтрока(Номер) Тогда
			Если Не ПустаяСтрока(Результат) Тогда
				Результат = Результат + ",";
			КонецЕсли;
			Результат = Результат + Номер;
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;
КонецФункции

Функция ФорматироватьНомер(Номер)
	Результат = "";
	ДопустимыеСимволы = "+1234567890";
	Для Позиция = 1 По СтрДлина(Номер) Цикл
		Символ = Сред(Номер,Позиция,1);
		Если СтрНайти(ДопустимыеСимволы, Символ) > 0 Тогда
			Результат = Результат + Символ;
		КонецЕсли;
	КонецЦикла;

	Если СтрДлина(Результат) > 10 Тогда
		ПервыйСимвол = Лев(Результат, 1);
		Если ПервыйСимвол = "8" Тогда
			Результат = "+7" + Сред(Результат, 2);
		ИначеЕсли ПервыйСимвол <> "+" Тогда
			Результат = "+" + Результат;
		КонецЕсли;
	КонецЕсли;

	Возврат Результат;
КонецФункции

// Возвращает список разрешений для отправки SMS с использованием всех доступных провайдеров.
//
// Возвращаемое значение:
//  Массив
//

Функция Разрешения() Экспорт

	Протокол = "HTTPS";
	Адрес = "smsc.ru";
	Порт = Неопределено;
	Описание = НСтр("ru = 'Отправка SMS через ""SMS-ЦЕНТР"".'");

	МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме");

	Разрешения = Новый Массив;
	Разрешения.Добавить(
		МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеИнтернетРесурса(Протокол, Адрес, Порт, Описание));

	Возврат Разрешения;
КонецФункции

Процедура ПриОпределенииНастроек(Настройки) Экспорт

	Настройки.АдресОписанияУслугиВИнтернете = "https://smsc.ru";

КонецПроцедуры

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

[Assistant] Функция ВыполнитьЗапрос(ИмяМетода, ПараметрыЗапроса)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

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

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

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

	ПодключенныеОбъекты(Источник, ПодключенныеОбъекты, НастройкиПрограммногоИнтерфейса);

	Возврат Источник;
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Шаблоны.

// Шаблон сведений об объектах метаданных - источников команд.
//
// Возвращаемое значение:
//   см. ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту.Источники.
//

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

// Шаблон сведений об отчетах и обработках, подключенных к источникам команд.
//
// Возвращаемое значение:
//   ТаблицаЗначений - вспомогательные параметры:
//       * ПолноеИмя  - Строка           - полное имя объекта. Например: "Документ.ИмяДокумента".
//       * Менеджер   - Произвольный     - модуль менеджера объекта.
//       * Размещение - Массив           - список объектов, к которым подключен отчет или обработка.
//       * ТипСсылкиДанных - Тип
//                         - ОписаниеТипов - тип объектов, к которым подключен отчет или обработка..
//

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

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

	Таблица.Индексы.Добавить("ПолноеИмя");

	Возврат Таблица;
КонецФункции

// Шаблон сведений об отчетах и обработках, подключенных к источникам команд.
//
// Возвращаемое значение:
//   ТаблицаЗначений - описание параметра Настройки процедуры ПриОпределенииНастроек объектов,
//       включенных в состав подсистемы ПодключаемыеОтчетыИОбработки:
//       * Ключ             - Строка        - имя настройки.
//       * ОписаниеТипов    - ОписаниеТипов - тип настройки.
//       * ВидыПодключаемыхОбъектов - Строка - вид объекта метаданных в верхнем регистре.
//                                            Например: "ОТЧЕТ" или "ОБРАБОТКА".
//

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

	Настройка = Таблица.Добавить();
	Настройка.Ключ          = "Размещение";
	Настройка.ОписаниеТипов = Новый ОписаниеТипов("Массив");
	Настройка.ВидыПодключаемыхОбъектов = "Отчет, Обработка";

	ЗаполнениеОбъектов.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);
	СозданиеНаОсновании.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);
	ИнтеграцияПодсистемБСП.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);
	ПодключаемыеКомандыПереопределяемый.ПриОпределенииСоставаНастроекПодключаемыхОбъектов(Таблица);

	Возврат Таблица;
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Обработчики событий подсистем конфигурации.

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.

Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	Обработчик = Обработчики.Добавить();
	Обработчик.ВыполнятьВГруппеОбязательных = Ложь;
	Обработчик.ОбщиеДанные                  = Истина;
	Обработчик.УправлениеОбработчиками      = Ложь;
	Обработчик.РежимВыполнения              = "Оперативно";
	Обработчик.Версия    = "*";
	Обработчик.Процедура = "ПодключаемыеКоманды.ОперативноеОбновлениеОбщихДанныхКонфигурации";
	Обработчик.Приоритет = 90;
КонецПроцедуры

// Обработчик обновления кэшей, связанных с расширениями.

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

////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы.

Функция ОперативноеОбновлениеОбщихДанныхКонфигурации() Экспорт
	Возврат ОперативноеОбновлениеОбщихДанных(Тип("СправочникСсылка.ИдентификаторыОбъектовМетаданных"));
КонецФункции

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

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

////////////////////////////////////////////////////////////////////////////////
// Кэш формы ПриСозданииНаСервере.

// Кэш формы, в которой будут выводиться подключаемые команды.

[Assistant] Функция ЗарегистрироватьИсточник(ОбъектМетаданных, Источники, ПодключенныеОбъекты, НастройкиПрограммногоИнтерфейса)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Функция ИмяФункции(ИмяФормы, ИсточникиЧерезЗапятую, ЭтоФормаОбъекта) Экспорт
	Команды = ТаблицаКоманд();
	Источники = ДеревоИсточниковКоманд();
	НастройкиПрограммногоИнтерфейса = НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов();
	ПодключенныеОбъекты = ТаблицаПодключаемыхОбъектов(НастройкиПрограммногоИнтерфейса);

	КэшФормы = Новый Структура;
	КэшФормы.Вставить("Команды", Команды);
	КэшФормы.Вставить("ЕстьУсловияВидимости", Ложь);
	КэшФормы.Вставить("ФункциональныеОпции", Новый Структура);

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

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

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

	Контекст = Новый Структура;
	Контекст.Вставить("ВидВРег", ВидВРег);
	Контекст.Вставить("ИмяФормы", ИмяФормы);
	Контекст.Вставить("МетаданныеФормы", МетаданныеФормы);
	Контекст.Вставить("ТипыИсточников", ТипыИсточников);
	Контекст.Вставить("ЭтоФормаОбъекта", ЭтоФормаОбъекта);
	Контекст.Вставить("ФункциональныеОпции", КэшФормы.ФункциональныеОпции);

	КэшФормы.Вставить("ВводНаОснованииЧерезПодключаемыеКоманды", СозданиеНаОсновании.ОбъектыПодключеныКПодсистеме(ТипыИсточников));
	Если КэшФормы.ВводНаОснованииЧерезПодключаемыеКоманды Тогда
		СозданиеНаОсновании.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);
	КонецЕсли;

	ЗаполнениеОбъектов.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);
	ИнтеграцияПодсистемБСП.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);
	ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту(Контекст, Источники, ПодключенныеОбъекты, Команды);

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

		// Фильтр по назначению.
		Если Команда.Назначение = "ДляСписка" И Контекст.ЭтоФормаОбъекта Или Команда.Назначение = "ДляОбъекта" И Не Контекст.ЭтоФормаОбъекта Тогда
			Команды.Удалить(Команда);
			Продолжить;
		КонецЕсли;

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

		Если ПустаяСтрока(Команда.Идентификатор) Тогда
			Команда.Идентификатор = "Авто_" + ОбщегоНазначения.КонтрольнаяСуммаСтрокой(Команда.Менеджер + "/" + Команда.ИмяФормы + "/" + Команда.Обработчик);
		КонецЕсли;
	КонецЦикла;

	Возврат КэшФормы;
КонецФункции

Процедура ПроверитьИмяВидаКоманд(ИмяВида) Экспорт

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

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Вывод.

// Размещает подключенные команды в форме.
//
// Параметры:
//   Форма - ФормаКлиентскогоПриложения - форма, в которой необходимо разместить команды.
//   Команды - см. ТаблицаКоманд
//   ПараметрыРазмещения - см. ПараметрыРазмещения
//

[Assistant] Функция КэшФормы(ИмяФормы, ИсточникиЧерезЗапятую, ЭтоФормаОбъекта)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Функция ИмяФункции(Отбор)
	Результат = Новый Структура;
	Результат.Вставить("ЕстьИзменения", Ложь);

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

	ПодключенныеОбъекты = Новый Соответствие;
	НастройкиПрограммногоИнтерфейса = НастройкиПрограммногоИнтерфейсаПодключаемыхОбъектов();

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

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

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

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

	Результат.Вставить("ПодключенныеОбъекты", ПодключенныеОбъекты);
	Возврат Результат;
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Вызовы из модулей ВызовСервера.

// Возвращает описание команды по имени элемента формы.
//
// Параметры:
//  ИмяКомандыВФорме Имя команды в форме
//  АдресНастроек Адрес настроек
//
// Возвращаемое значение:
//  ФиксированнаяСтруктура:
//   * Вид - Строка
//   * Идентификатор - Строка
//   * Представление - Строка
//   * Подменю - Строка
//   * Важность - Строка
//   * Порядок - Число
//   * Картинка - Картинка
//   * СочетаниеКлавиш - СочетаниеКлавиш
//   * ОтображениеКнопки - Неопределено
//   * ТолькоВоВсехДействиях - Булево
//   * ЗначениеПометки - Строка
//   * ТипПараметра - ОписаниеТипов
//   * ВидимостьВФормах - Строка
//   * Назначение - Строка
//   * ФункциональныеОпции - Строка
//   * УсловияВидимости - Массив
//   * ИзменяетВыбранныеОбъекты - Булево
//   * МножественныйВыбор - Булево, Неопределено
//   * РежимЗаписи - Строка
//   * ТребуетсяРаботаСФайлами - Булево
//   * Менеджер - Строка
//   * Обработчик - Строка
//   * ДополнительныеПараметры - Структура
//   * ИмяФормы - Строка
//   * ПараметрыФормы - Структура, Неопределено
//   * ИмяПараметраФормы - Строка
//   * ПорядокВажности - Число
//   * ИмяВФорме - Строка
//   * ЕстьУсловияВидимости - Булево
//   * КлючПараметровРазмещения - Строка
//

Функция ОписаниеКоманды(ИмяКомандыВФорме, АдресНастроек) Экспорт
	Команды = ПолучитьИзВременногоХранилища(АдресНастроек);
	Команда = Команды.Найти(ИмяКомандыВФорме, "ИмяВФорме");
	Если Команда = Неопределено Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Сведения о команде ""%1"" не существуют.'"),
			ИмяКомандыВФорме);
	КонецЕсли;
	ОписаниеКоманды = ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(Команда);

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

	Возврат Новый ФиксированнаяСтруктура(ОписаниеКоманды);
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Работа с объектами метаданных.

// Возвращает вид объекта во множественном числе.

[Assistant] Функция ОперативноеОбновлениеОбщихДанных(Отбор)


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `ОписаниеНовойКонтактнойИнформации`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция ОписаниеНовойКонтактнойИнформации(Знач ТипКонтактнойИнформации)
Экспорт

	Если ТипЗнч(ТипКонтактнойИнформации) <> Тип("ПеречислениеСсылка.ТипыКонтактнойИнформации") Тогда
		ТипКонтактнойИнформации = "";
	КонецЕсли;

	Результат = УправлениеКонтактнойИнформациейКлиентСервер.ОписаниеНовойКонтактнойИнформации(ТипКонтактнойИнформации);

	Если ТипКонтактнойИнформации = ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.Адрес") Тогда

		Результат.Вставить("id",               "");
		Результат.Вставить("areaCode",         "");
		Результат.Вставить("areaId",           "");
		Результат.Вставить("areaValue",        "");
		Результат.Вставить("district",         "");
		Результат.Вставить("districtType",     "");
		Результат.Вставить("districtId",       "");
		Результат.Вставить("munDistrict",      "");
		Результат.Вставить("munDistrictType",  "");
		Результат.Вставить("munDistrictId",    "");
		Результат.Вставить("cityId",           "");
		Результат.Вставить("settlement",       "");
		Результат.Вставить("settlementType",   "");
		Результат.Вставить("settlementId",     "");
		Результат.Вставить("cityDistrict",     "");
		Результат.Вставить("cityDistrictType", "");
		Результат.Вставить("cityDistrictId",   "");
		Результат.Вставить("territory",        "");
		Результат.Вставить("territoryType",    "");
		Результат.Вставить("territoryId",      "");
		Результат.Вставить("locality",         "");
		Результат.Вставить("localityType",     "");
		Результат.Вставить("localityId",       "");
    // TODO: допиши оставшуюся часть

[Assistant]
Функция ОписаниеНовойКонтактнойИнформации(Знач ТипКонтактнойИнформации) Экспорт

	Если ТипЗнч(ТипКонтактнойИнформации) <> Тип("ПеречислениеСсылка.ТипыКонтактнойИнформации") Тогда
		ТипКонтактнойИнформации = "";
	КонецЕсли;

	Результат = УправлениеКонтактнойИнформациейКлиентСервер.ОписаниеНовойКонтактнойИнформации(ТипКонтактнойИнформации);

	Если ТипКонтактнойИнформации = ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.Адрес") Тогда

		Результат.Вставить("id",               "");
		Результат.Вставить("areaCode",         "");
		Результат.Вставить("areaId",           "");
		Результат.Вставить("areaValue",        "");
		Результат.Вставить("district",         "");
		Результат.Вставить("districtType",     "");
		Результат.Вставить("districtId",       "");
		Результат.Вставить("munDistrict",      "");
		Результат.Вставить("munDistrictType",  "");
		Результат.Вставить("munDistrictId",    "");
		Результат.Вставить("cityId",           "");
		Результат.Вставить("settlement",       "");
		Результат.Вставить("settlementType",   "");
		Результат.Вставить("settlementId",     "");
		Результат.Вставить("cityDistrict",     "");
		Результат.Вставить("cityDistrictType", "");
		Результат.Вставить("cityDistrictId",   "");
		Результат.Вставить("territory",        "");
		Результат.Вставить("territoryType",    "");
		Результат.Вставить("territoryId",      "");
		Результат.Вставить("locality",         "");
		Результат.Вставить("localityType",     "");
		Результат.Вставить("localityId",       "");
		Результат.Вставить("streetId",         "");
		Результат.Вставить("houseType",        "");
		Результат.Вставить("houseNumber",      "");
		Результат.Вставить("houseId",          "");
		Результат.Вставить("buildings",        Новый Массив);
		Результат.Вставить("apartments",       Новый Массив);
		Результат.Вставить("codeKLADR",        "");
		Результат.Вставить("oktmo",            "");
		Результат.Вставить("oktmoBudget",      "");
		Результат.Вставить("okato",            "");
		Результат.Вставить("asInDocument",     "");
		Результат.Вставить("ifnsFLCode",       "");
		Результат.Вставить("ifnsULCode",       "");
		Результат.Вставить("ifnsFLAreaCode",   "");
		Результат.Вставить("ifnsULAreaCode",   "");
		Результат.Вставить("stead",            "");
		Результат.Вставить("steadId",          "");
		Результат.Вставить("admLevels",        Новый Массив);
		Результат.Вставить("munLevels",        Новый Массив);

	КонецЕсли;

	Возврат Результат;

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

Функция СопоставлениеНаименованиеУровнюАдреса(ИмяУровня) Экспорт

	Уровни = Новый Соответствие;

	Уровни.Вставить("AREA",        1);
	Уровни.Вставить("DISTRICT",    2);
	Уровни.Вставить("MUNDISTRICT", 3);
	Уровни.Вставить("SETTLEMENT",  4);
	Уровни.Вставить("CITY",        5);
	Уровни.Вставить("LOCALITY",    6);
	Уровни.Вставить("TERRITORY",   7);
	Уровни.Вставить("STREET",      8);

	Возврат Уровни[ВРег(ИмяУровня)];

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

Функция ИменаУровнейАдреса(ТипАдреса, ВключатьУровеньУлицы, ВключатьУровеньДома = Ложь) Экспорт

	Уровни = Новый Массив;

	Если ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес() Тогда

		Уровни.Добавить("area");

	Иначе

		Уровни.Добавить("area");
		Если ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС() Тогда

			Уровни.Добавить("district");
			Уровни.Добавить("city");
			Уровни.Добавить("locality");

		Иначе

			Если ТипАдреса = "Все" Тогда
				Уровни.Добавить("district");
				Уровни.Добавить("munDistrict");
				Уровни.Добавить("settlement");
			Иначе
				Если ЭтоМуниципальныйАдрес(ТипАдреса) Тогда
					Уровни.Добавить("munDistrict");
					Уровни.Добавить("settlement");
				Иначе
					Уровни.Добавить("district");
				КонецЕсли;
			КонецЕсли;

			Уровни.Добавить("city");
			Уровни.Добавить("locality");
			Уровни.Добавить("territory");

		КонецЕсли;

	КонецЕсли;

	Если ВключатьУровеньУлицы Тогда
		Уровни.Добавить("street");
	КонецЕсли;

	Если ВключатьУровеньДома Тогда
		Уровни.Добавить("house");
	КонецЕсли;

	Возврат Уровни;

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

Функция ИменаУровнейАдресаПоАдресу(Адрес, ВключатьУровеньУлицы, ВключатьУровеньДома = Ложь, ТипАдреса = Неопределено) Экспорт

	Если ТипАдреса = Неопределено Тогда
		ТипАдреса = Адрес.AddressType;
	КонецЕсли;

	Если ЭтоМуниципальныйАдрес(ТипАдреса) Тогда
		Уровни = Адрес.munLevels;
	ИначеЕсли ЭтоАдминистративноТерриториальныйАдрес(ТипАдреса) Тогда
		 Уровни = Адрес.admLevels;
	Иначе
		Уровни = Новый Массив;
	КонецЕсли;

	Уровни = ?(ТипЗнч(Уровни) = Тип("Массив"), Новый Массив(Новый ФиксированныйМассив(Уровни)), Новый Массив);

	Если Уровни.Количество() > 0 Тогда

		Если Не ВключатьУровеньУлицы Тогда
			Позиция = Уровни.Найти("street");
			Если Позиция <> Неопределено Тогда
				Уровни.Удалить(Позиция);
			КонецЕсли;
		КонецЕсли;

		Позиция = Уровни.Найти("house");
		Если ВключатьУровеньДома Тогда
			Если Позиция = Неопределено Тогда
				Уровни.Добавить("house");
			КонецЕсли;
		Иначе
			Если Позиция <> Неопределено Тогда
				Уровни.Удалить(Позиция);
			КонецЕсли;
		КонецЕсли;

		Позиция = Уровни.Найти("stead");
		Если ВключатьУровеньДома Тогда
			Если Позиция = Неопределено Тогда
				Уровни.Добавить("stead");
			КонецЕсли;
		Иначе
			Если Позиция <> Неопределено Тогда
				Уровни.Удалить(Позиция);
			КонецЕсли;
		КонецЕсли;

		Для Позиция = -Уровни.ВГраница() По 0 Цикл
			Если ТипЗнч(Уровни[-Позиция]) <> Тип("Строка")
				 Или СопоставлениеНаименованиеУровнюАдреса(ВРег(Строка(Уровни[-Позиция]))) = Неопределено Тогда
					Уровни.Удалить(-Позиция);
			КонецЕсли;
		КонецЦикла;

		Возврат Уровни;

	КонецЕсли;

	Если ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес() Тогда

		Уровни.Добавить("area");

	Иначе

		Уровни.Добавить("area");
		Если ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС() Тогда

			Уровни.Добавить("district");
			Уровни.Добавить("city");
			Уровни.Добавить("locality");

		Иначе

			Если ТипАдреса = "Все" Тогда
				Уровни.Добавить("district");
				Уровни.Добавить("munDistrict");
				Уровни.Добавить("settlement");

			Иначе
				Если ЭтоМуниципальныйАдрес(ТипАдреса) Тогда
					Уровни.Добавить("munDistrict");
					Уровни.Добавить("settlement");
				Иначе
					Уровни.Добавить("district");
				КонецЕсли;
			КонецЕсли;
			Уровни.Добавить("city");
			Уровни.Добавить("locality");
			Уровни.Добавить("territory");

		КонецЕсли;

	КонецЕсли;

	Если ВключатьУровеньУлицы Тогда
		Уровни.Добавить("street");
	КонецЕсли;

	Если ВключатьУровеньДома Тогда
		Уровни.Добавить("house");
	КонецЕсли;

	Возврат Уровни;

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

Процедура ОбновитьПредставлениеАдреса(Адрес, ВключатьСтрануВПредставление) Экспорт

	Представление = ПредставлениеАдреса(Адрес, ВключатьСтрануВПредставление);
	Адрес.Value = Представление;

КонецПроцедуры

Функция ПредставлениеУровняАдреса(Адрес, ИмяУровня) Экспорт

	Если (ЭтоМуниципальныйАдрес(Адрес.addressType)
		Или ЭтоАдминистративноТерриториальныйАдрес(Адрес.addressType))
		И ЭтоИмяУровняРегиона(ИмяУровня)
		И ЗначениеЗаполнено(Адрес["areaValue"]) Тогда
			Возврат Адрес["areaValue"];
	КонецЕсли;

	Возврат УправлениеКонтактнойИнформациейКлиентСервер.СоединитьНаименованиеИТипАдресногоОбъекта(
			Адрес[ИмяУровня], Адрес[ИмяУровня + "Type"], СтрСравнить(ИмяУровня, "area") = 0);

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

Функция ЭтоИмяУровняРегиона(ИмяУровня)
	Возврат СтрСравнить(ИмяУровня, "area") = 0;
КонецФункции

Функция НаименованиеЗемельногоУчастка() Экспорт
	Возврат "Зем. участок";
КонецФункции

Функция СоединитьНомерИТипЗдания(Знач Номер, Знач ТипЗданияИлиПомещения)

	Если ПустаяСтрока(ТипЗданияИлиПомещения) Тогда
		Возврат Номер;
	КонецЕсли;

	СокращенияЗданийИПомещений = СокращенияЗданийИПомещений();

	Если СокращенияЗданийИПомещений[ВРег(ТипЗданияИлиПомещения)] = Неопределено Тогда
		Возврат НРег(ТипЗданияИлиПомещения) + " "+ Номер;
	КонецЕсли;

	Возврат СокращенияЗданийИПомещений[ВРег(ТипЗданияИлиПомещения)] + " " + Номер;

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


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Процедура ИмяФункции(Знач Дескриптор, Знач ПутьКФайлу)

	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.ПоставляемыеДанные") Тогда
		Возврат;
	КонецЕсли;

	МодульПоставляемыеДанные = ОбщегоНазначения.ОбщийМодуль("ПоставляемыеДанные");

	ТаблицаКурсов = ПрочитатьТаблицуКурсов(ПутьКФайлу);

	ДатаКурсов = "";
	Для каждого Характеристика Из Дескриптор.Properties.Property Цикл
		Если Характеристика.Code = "Дата" Тогда
			ДатаКурсов = Дата(Характеристика.Value);
		КонецЕсли;
	КонецЦикла;

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

	ОбластиДляОбновления = МодульПоставляемыеДанные.ОбластиТребующиеОбработки(Дескриптор.FileGUID, "КурсыВалютЗаДень", Истина);

	ИндексОбщихКурсов = ОбластиДляОбновления.Найти(-1);
	Если ИндексОбщихКурсов <> Неопределено Тогда

		КэшКурсов = МодульПоставляемыеДанные.ДескрипторыПоставляемыхДанныхИзКэша("КурсыОднойВалюты", , Ложь);
		Если КэшКурсов.Количество() > 0 Тогда
			Для каждого СтрокаКурсов Из ТаблицаКурсов Цикл

				КэшТекущей = Неопределено;
				Для	каждого ДескрипторКэша Из КэшКурсов Цикл
					Если ДескрипторКэша.Характеристики.Количество() > 0
						И ДескрипторКэша.Характеристики[0].Код = "Валюта"
						И ДескрипторКэша.Характеристики[0].Значение = СтрокаКурсов.Код Тогда
						КэшТекущей = ДескрипторКэша;
						Прервать;
					КонецЕсли;
				КонецЦикла;

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

					КэшТекущей.Характеристики.Добавить(Новый Структура("Код, Значение, Ключевая", "Валюта", СтрокаКурсов.Код, Истина));
				КонецЕсли;

				ЗаписьТекста = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.UTF8,
				Символы.ПС, Истина);

				ТаблицаДляЗаписи = Новый Массив;
				ТаблицаДляЗаписи.Добавить(СтрокаКурсов);
				ЗаписатьТаблицуКурсов(ТаблицаДляЗаписи, ЗаписьТекста);
				ЗаписьТекста.Закрыть();

				МодульПоставляемыеДанные.СохранитьПоставляемыеДанныеВКэш(КэшТекущей, ИмяВременногоФайла);
				УдалитьФайлы(ИмяВременногоФайла);
			КонецЦикла;

		КонецЕсли;

		ОбластиДляОбновления.Удалить(ИндексОбщихКурсов);
	КонецЕсли;

	РаспространитьКурсыПоОД(ДатаКурсов, ТаблицаКурсов, ОбластиДляОбновления,
		Дескриптор.FileGUID, "КурсыВалютЗаДень");

КонецПроцедуры

// Копирует курсы во все ОД
//
// Параметры:
//  ДатаКурсов - Дата, Неопределено - курсы добавляются за указанную дату либо за все время.
//  ТаблицаКурсов - ТаблицаЗначений с курсами.
//  ОбластиДляОбновления - массив со списком кодов областей.
//  ИдентификаторФайла - УникальныйИдентификатор файла обрабатываемых курсов.
//  КодОбработчика - Строка - код обработчика.
//

Процедура РаспространитьКурсыПоОД(Знач ДатаКурсов, Знач ТаблицаКурсов, Знач ОбластиДляОбновления, Знач ИдентификаторФайла, Знач КодОбработчика)

	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		Возврат;
	КонецЕсли;

	МодульПоставляемыеДанные = ОбщегоНазначения.ОбщийМодуль("ПоставляемыеДанные");
	МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");

	ВалютыОбластей = Новый Соответствие();

	ЗапросОбщий = Новый Запрос();
	ЗапросОбщий.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
	ЗапросОбщий.УстановитьПараметр("ПоставляемыеКурсы", ТаблицаКурсов);
	ЗапросОбщий.УстановитьПараметр("ТолькоЗаОдинДень", ДатаКурсов <> Неопределено);
	ЗапросОбщий.УстановитьПараметр("ДатаКурсов", ДатаКурсов);
	ЗапросОбщий.УстановитьПараметр("НачалоПоставкиКурсов", Дата("19800101"));

	Для каждого ОбластьДанных Из ОбластиДляОбновления Цикл

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

			ЗаписьЖурналаРегистрации(НСтр("ru = 'Поставляемые данные.Распространение курсов валют по областям данных'", ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Ошибка,,,
				ТекстОшибки);

			ЗапланироватьОбновлениеКурсовВалют(ОбластьДанных);
			Продолжить;

		КонецПопытки;

		ВалютыОбластейСтрокой = ОбщегоНазначения.ЗначениеВСтрокуXML(ВалютыОбластей);

		НачатьТранзакцию();
		Попытка
			// @skip-check query-in-loop - обработка областей данных.
			ОбработатьКурсыОбластиВТранзакции(ЗапросОбщий, ВалютыОбластей, ТаблицаКурсов);
			МодульРаботаВМоделиСервиса.ВыйтиИзОбластиДанных();
			МодульПоставляемыеДанные.ОбластьОбработана(ИдентификаторФайла, КодОбработчика, ОбластьДанных);

			ЗафиксироватьТранзакцию();

		Исключение

			ОтменитьТранзакцию();

			ВалютыОбластей = ОбщегоНазначения.ЗначениеИзСтрокиXML(ВалютыОбластейСтрокой);
			МодульРаботаВМоделиСервиса.ВыйтиИзОбластиДанных();

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

		КонецПопытки;

	КонецЦикла;

КонецПроцедуры

Процедура ЗапланироватьОбновлениеКурсовВалют(ОбластьДанных)

	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.ОчередьЗаданий") Тогда
		Возврат;
	КонецЕсли;

	ПараметрыЗадания = Новый Структура;
	ПараметрыЗадания.Вставить("ИмяМетода", "РаботаСКурсамиВалютСлужебный.ОбновитьКурсыВалют");
	ПараметрыЗадания.Вставить("ОбластьДанных", ОбластьДанных);

	МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");

	УстановитьПривилегированныйРежим(Истина);
	МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);

КонецПроцедуры

[Assistant] Процедура ОбработатьПоставляемыеКурсыЗаДень(Знач Дескриптор, Знач ПутьКФайлу)