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

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

// Для вызова из обработчика ПриНачальномЗаполненииЭлементов.
// Заполняет колонки с именами ИмяРеквизита_<КодЯзыка> текстовыми значениями для указанных кодов языков.
//
// Параметры:
//  Элемент        - СтрокаТаблицыЗначений - заполняемая строка таблицы с колонками ИмяРеквизита_КодЯзыка.
//  ИмяРеквизита   - Строка - имя реквизита. Например, "Наименование"
//  ИсходнаяСтрока - Строка - строка в формате НСтр. Например, "ru = 'Сообщение на русском'; en = 'English message'".
//  КодыЯзыков     - Массив - коды языков, на которых нужно заполнить строки.
// 
// Пример:
//
//  МультиязычностьСервер.ЗаполнитьМультиязычныйРеквизит(Элемент, "Наименование", "ru = 'Сообщение на русском'; en =
//  'English message'", КодыЯзыков);	
//
Процедура ЗаполнитьМультиязычныйРеквизит(Элемент, ИмяРеквизита, ИсходнаяСтрока, КодыЯзыков = Неопределено) Экспорт
	
	Для каждого КодЯзыка Из КодыЯзыков Цикл
		
		ЗначениеПоКодуЯзыка = НСтр(ИсходнаяСтрока, КодЯзыка);
		ЗначениеДляЗаполнения = ?(ЗначениеЗаполнено(ЗначениеПоКодуЯзыка), ЗначениеПоКодуЯзыка, НСтр(ИсходнаяСтрока, ОбщегоНазначения.КодОсновногоЯзыка()));
		Элемент[ИмяЛокализуемогоРеквизита(ИмяРеквизита, КодЯзыка)] = ЗначениеДляЗаполнения;
		Если СтрСравнить(КодЯзыка, ОбщегоНазначения.КодОсновногоЯзыка()) = 0 Тогда
			Элемент[ИмяРеквизита] = ЗначениеДляЗаполнения;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

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

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

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

	ПроверкаСвойства = Новый Структура(ИмяОбъекта, Неопределено);
	ЗаполнитьЗначенияСвойств(ПроверкаСвойства, Форма, ИмяОбъекта);
	Если ПроверкаСвойства[ИмяОбъекта] <> Неопределено Тогда
		ПриЧтенииПредставленийНаСервере(Форма[ИмяОбъекта]);
	КонецЕсли;
	
КонецПроцедуры

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

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

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

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

// Вызывается из обработчика ОбработкаПолученияДанныхВыбора для формирования списка при вводе по строке,
// автоподборе текста и быстром выбора, а также при выполнении метода ПолучитьДанныеВыбора.
// Список содержит варианты на всех языках с учетом реквизитов определенных в свойстве ВводПоСтроке.
//
// Параметры:
//  ДанныеВыбора         - СписокЗначений - данные для выбора.
//  Параметры            - Структура - содержит параметры выбора.
//  СтандартнаяОбработка - Булево  - данный параметр передается признак выполнения стандартной (системной) обработки события.
//  ОбъектМетаданных     - ОбъектМетаданныхБизнесПроцесс
//                       - ОбъектМетаданныхДокумент
//                       - ОбъектМетаданныхЗадача
//                       - ОбъектМетаданныхПланВидовРасчета
//                       - ОбъектМетаданныхПланВидовХарактеристик
//                       - ОбъектМетаданныхПланОбмена
//                       - ОбъектМетаданныхПланСчетов
//                       - ОбъектМетаданныхСправочник
//                       - ОбъектМетаданныхТаблица - объект метаданных, для которого формируется список выбора.
//
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Знач Параметры, СтандартнаяОбработка, ОбъектМетаданных) Экспорт
	
	Если МультиязычностьПовтИсп.КонфигурацияИспользуетТолькоОдинЯзык(ОбъектМетаданных.ТабличныеЧасти.Найти("Представления") = Неопределено) Тогда
		Возврат;
	КонецЕсли;
	
	СтандартнаяОбработка = Ложь;
	
	ПоляВводаПоСтроке = ОбъектМетаданных.ВводПоСтроке;
	Поля              = Новый Массив;
	
	НаименованияЛокализуемыхРеквизитов = НаименованияЛокализуемыхРеквизитовОбъекта(ОбъектМетаданных);
	СведенияОбЯзыках = МультиязычностьПовтИсп.СведенияОбИспользуемыхЯзыках();
	Шаблон = "Таблица.%1%2 ПОДОБНО &СтрокаПоиска СПЕЦСИМВОЛ ""~""";

	Для каждого Поле Из ПоляВводаПоСтроке Цикл
		Поля.Добавить(СтрШаблон(Шаблон, Поле.Имя, ""));

		Если НаименованияЛокализуемыхРеквизитов.Получить(Поле.Имя) <> Неопределено Тогда
			
			Для Каждого ИспользуетсяДополнительныйЯзык Из СведенияОбЯзыках Цикл
				Если ИспользуетсяДополнительныйЯзык.Значение Тогда
					Поля.Добавить(СтрШаблон(Шаблон, Поле.Имя, ИспользуетсяДополнительныйЯзык.Ключ));
				КонецЕсли;
			КонецЦикла;
			
		КонецЕсли;
	КонецЦикла;
	
	ШаблонЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 20
	|	Таблица.Ссылка КАК Ссылка
	|ИЗ
	|	&ИмяОбъекта КАК Таблица
	|ГДЕ
	|	&УсловияОтбора";
	
	ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "&ИмяОбъекта", ОбъектМетаданных.ПолноеИмя());
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&УсловияОтбора", СтрСоединить(Поля, " ИЛИ "));
	
	Запрос = Новый Запрос(ТекстЗапроса);	
	Запрос.УстановитьПараметр("СтрокаПоиска", "%" + ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(Параметры.СтрокаПоиска) +"%");
	РезультатЗапроса = Запрос.Выполнить().Выбрать();
	
	ДанныеВыбора = Новый СписокЗначений;
	Пока РезультатЗапроса.Следующий() Цикл
		ДанныеВыбора.Добавить(РезультатЗапроса.Ссылка, РезультатЗапроса.Ссылка);
	КонецЦикла;
	
КонецПроцедуры

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

// Возвращает суффикс дополнительного языка для текущего языка интерфейса пользователя.
// 
// Возвращаемое значение:
//  Строка - суффикс языка, который добавляются к имени реквизита в котором хранится значение на указанном языке.
//           Например, суффикс "Язык1", для реквизита "НаименованиеЯзык1"
//
Функция СуффиксТекущегоЯзыка() Экспорт

	Возврат СуффиксЯзыка(ТекущийЯзык().КодЯзыка);

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

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

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

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

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

// Возвращает количество дополнительных языков.
// 
// Возвращаемое значение:
//  Число - количество дополнительных языков в конфигурации
// 
Функция КоличествоДополнительныхЯзыков() Экспорт
	Возврат МультиязычностьПовтИсп.КоличествоДополнительныхЯзыков();
КонецФункции

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

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

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

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

Функция КодОсновногоЯзыка() Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	Возврат ПараметрыСеанса.ОсновнойЯзык;
	
КонецФункции

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


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

Функция ИмяРеквизитаБезСуффиксаЯзык(Знач ИмяРеквизита) Экспорт
	
	Шаблон = МультиязычностьКлиентСервер.СуффиксЯзыка() + "\d+";
	
	РезультатВыражения = СтрНайтиПоРегулярномуВыражению(ИмяРеквизита, Шаблон, НаправлениеПоиска.СКонца,, Истина);
	Если РезультатВыражения.НачальнаяПозиция > 0 Тогда
		Возврат Лев(ИмяРеквизита, РезультатВыражения.НачальнаяПозиция - 1);
	КонецЕсли;
	
	Возврат ИмяРеквизита;
	
КонецФункции

Функция СведенияОРеквизите(Знач ИмяРеквизита) Экспорт
	
	Результат = Новый Структура;
	Результат.Вставить("Мультиязычный", Ложь);
	Результат.Вставить("ИмяРеквизитаБезСуффиксаЯзык", ИмяРеквизита);
	Результат.Вставить("Удаленный", СтрНачинаетсяС(ИмяРеквизита, "Удалить"));
	
	Шаблон = МультиязычностьКлиентСервер.СуффиксЯзыка() + "\d+";
	РезультатВыражения = СтрНайтиПоРегулярномуВыражению(ИмяРеквизита, Шаблон, НаправлениеПоиска.СКонца,, Истина);
	Если РезультатВыражения.НачальнаяПозиция > 0 Тогда
		Результат.Мультиязычный = Истина;
		Результат.ИмяРеквизитаБезСуффиксаЯзык = Лев(ИмяРеквизита, РезультатВыражения.НачальнаяПозиция - 1);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ПризнакЛокализуемогоРеквизита() Экспорт
	Возврат "Локализуемый";
КонецФункции

Функция МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Экспорт
	
	Возврат МультиязычностьПовтИсп.ЕстьМультиязычныеРеквизитыВШапкеОбъекта(ОбъектМетаданных.ПолноеИмя());
	
КонецФункции

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

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

Процедура ОпределитьИзмененныеМультиязычныеЭлементы(НовоеЗначение, СтрокаТаблицы, ИмяЛокализуемогоРеквизита, ОтредактированныеРеквизиты, НаборДанныхДляЗаполнения) Экспорт

	ЛокализуемыеРеквизитыОбъекта = НаборДанныхДляЗаполнения.ЛокализуемыеРеквизитыОбъекта;

	Если ЛокализуемыеРеквизитыОбъекта.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	Языки                  = СтандартныеПодсистемыСервер.ЯзыкиКонфигурации();
	СведенияОбЯзыках       = СведенияОЯзыках();
	ПоддерживаетсяИерархия = НаборДанныхДляЗаполнения.ПоддерживаетсяИерархия;

	Если НаборДанныхДляЗаполнения.МультиязычныеСтрокиВРеквизитах Тогда
		
		Для НомерЯзыка = 0 По СведенияОбЯзыках.КоличествоДополнительныхЯзыков Цикл

			КодЯзыка = СведенияОбЯзыках["Язык" + Строка(НомерЯзыка)];

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

	КонецЕсли;

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

Процедура УдалитьМультиязычныеРеквизиты(ОтредактированныеРеквизиты) Экспорт
	
	СведенияОбЯзыках = СведенияОЯзыках();
	
	Позиция = ОтредактированныеРеквизиты.Количество() - 1;
	
	Пока Позиция >= 0 Цикл
	
		Для НомерЯзыка = 1 По СведенияОбЯзыках.КоличествоДополнительныхЯзыков Цикл
			Если СтрЗаканчиваетсяНа(ОтредактированныеРеквизиты[Позиция], "Язык" + НомерЯзыка) Тогда
				ОтредактированныеРеквизиты.Удалить(Позиция);
				Прервать;
			КонецЕсли;
		КонецЦикла;
		
		Позиция = Позиция - 1;
	
	КонецЦикла;
	
КонецПроцедуры

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

// Обновление данных

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

// Регистрирует объекты к обработке в обработчике обновления
//
Процедура ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию(Параметры) Экспорт
	
	Если Метаданные.Языки.Количество() = 1 Тогда
		Возврат;
	КонецЕсли;
	
	ОбъектыКОбработке = СписокОбъектовКОбработкеДляПереходаНаНовуюВерсию(ВариантДанныхДляОбработкиСУчетомРазделения());

	Если ОбъектыКОбработке.Количество() > 0 Тогда
		ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры, ОбъектыКОбработке);
	КонецЕсли;
	
КонецПроцедуры

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

		Если ОбрабатываемыеОбъекты.Найти(ОбъектСПредопределеннымиЭлементами.Значение) = Неопределено Тогда
			ОбрабатываемыеОбъекты.Добавить(ОбъектСПредопределеннымиЭлементами.Значение);
		КонецЕсли;
		
	КонецЦикла;
	
	Для каждого ОбъектСПредопределеннымиЭлементами Из ОбъектыСПредопределеннымиЭлементами Цикл
		
		Если ИтогоОбработано >= Порция Тогда
			Прервать;
		КонецЕсли;
		
		Выборка = ОбновлениеИнформационнойБазы.ВыбратьСсылкиДляОбработки(Параметры.Очередь,
			ОбъектСПредопределеннымиЭлементами.Значение);
		Если Выборка.Количество() > 0 Тогда
		
			// @skip-check query-in-loop - Порционная обработка данных в обработчике обновления
			ЗаполнитьПустыеМультиязычныеРеквизитыЗначениемОсновногоЯзыка(Выборка, ОбъектСПредопределеннымиЭлементами.Ключ,
				ИтогоОбработано);
			
		КонецЕсли;
	КонецЦикла;

	Параметры.ОбработкаЗавершена = ОбновлениеИнформационнойБазы.ОбработкаДанныхЗавершена(Параметры.Очередь, ОбрабатываемыеОбъекты);
	
КонецПроцедуры

#Область НачальноеЗаполнениеЭлементовДанными

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

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

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

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

// Параметры:
//  ИменаРеквизитовОбъекта - Массив из Строка
//  ЛокализуемыеРеквизитыОбъекта - Соответствие из КлючИЗначение:
//   * Ключ - Строка
//   * Значение - Булево
//
Процедура СформироватьИменаМультиязычныхРеквизитов(Знач ИменаРеквизитовОбъекта, Знач ЛокализуемыеРеквизитыОбъекта) Экспорт
	
	СведенияОбЯзыках = МультиязычностьПовтИсп.СведенияОЯзыках();
	
	Для каждого РеквизитОбъекта Из ЛокализуемыеРеквизитыОбъекта Цикл
		
		ИменаРеквизитовОбъекта.Добавить(РеквизитОбъекта.Ключ);
		
		Для Каждого ЯзыкИспользуется Из СведенияОбЯзыках.Используется Цикл
			Если ЯзыкИспользуется.Значение Тогда
				ИменаРеквизитовОбъекта.Добавить(РеквизитОбъекта.Ключ + ЯзыкИспользуется.Ключ);
			КонецЕсли;
		КонецЦикла;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПриПолученииПараметровЗаполненияПредопределенныхДанных(ПараметрыЗаполнения) Экспорт
	
	ПараметрыЗаполнения.Вставить("Языки", СтандартныеПодсистемыСервер.ЯзыкиКонфигурации());
	ПараметрыЗаполнения.Вставить("СведенияОбЯзыках", СведенияОЯзыках());
	
КонецПроцедуры

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


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

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

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	
	Если Метаданные.Языки.Количество() > 1 Тогда
	
		Обработчик = Обработчики.Добавить();
		Обработчик.Версия = "3.1.6.16";
		Обработчик.Комментарий = НСтр("ru = 'Заполнение значений мультиязычных реквизитов значением основного языка.'");
	
		Если ОбщегоНазначения.РазделениеВключено() 
			 И Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
			
			Обработчик.РежимВыполнения = "Оперативно";
			Обработчик.ОбщиеДанные     = Истина;
			Обработчик.Процедура       = "МультиязычностьСервер.ОбработатьОбщиеДанныеДляПереходаНаНовуюВерсию";
		
		Иначе
		
			Обработчик.РежимВыполнения = "Отложенно";
			Обработчик.Процедура = "МультиязычностьСервер.ОбработатьДанныеДляПереходаНаНовуюВерсию";
			
			Обработчик.Идентификатор = Новый УникальныйИдентификатор("68d400bb-e5bb-49da-a567-ebf7458b29f8");
			Обработчик.ПроцедураЗаполненияДанныхОбновления = "МультиязычностьСервер.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
			Обработчик.ПроцедураПроверки = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
			
			ОбъектыСТЧПредставления = ОбъектыСТЧПредставления(ВариантДанныхДляОбработкиСУчетомРазделения());
			
			ОбъектыДляОбработки = ОбъектыСНачальнымЗаполнениемСтрокой(ОбъектыСТЧПредставления);
			
			Обработчик.ЧитаемыеОбъекты    = ОбъектыДляОбработки;
			Обработчик.ИзменяемыеОбъекты  = ОбъектыДляОбработки;
			Обработчик.БлокируемыеОбъекты = ОбъектыДляОбработки;
			
		КонецЕсли;

	КонецЕсли;

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

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

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

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

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

Функция ИмяКонстантыЯзыка(ПорядковыйНомерЯзыка) Экспорт
	Возврат "ДополнительныйЯзык" + Формат(ПорядковыйНомерЯзыка,"ЧГ=0");
КонецФункции

Функция ИмяФункциональнойОпции(ПорядковыйНомерЯзыка) Экспорт
	Возврат "ИспользоватьДополнительныйЯзык" + Формат(ПорядковыйНомерЯзыка,"ЧГ=0");
КонецФункции

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

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

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

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

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

Функция ИмяЛокализуемогоРеквизита(ИмяРеквизита, КодЯзыка)
	
	Возврат ИмяРеквизита + "_" + КодЯзыка;
	
КонецФункции

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


// Возвращаемое значение:
//  Структура:
//   * ОсновнойЯзыкСтароеЗначение - Строка
//   * ДополнительныйЯзык1СтароеЗначение - Строка
//   * ДополнительныйЯзык2СтароеЗначение - Строка
//   * ОсновнойЯзыкНовоеЗначение - Строка
//   * ДополнительныйЯзык1НовоеЗначение - Строка
//   * ДополнительныйЯзык2НовоеЗначение - Строка
//
Функция ОписаниеСтарыхИНовыхНастроекЯзыков(КоличествоДополнительныхЯзыков) Экспорт
	
	ОписаниеКонстант = Новый Структура;

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

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

Функция ЛокализуемыеРеквизитыОбъектаДляТекущегоЯзыка(ОбъектМетаданных, Язык = Неопределено)
	
	СписокРеквизитов = Новый Соответствие;
	
	Если ЗначениеЗаполнено(Язык) Тогда
		ПрефиксЯзыка = Язык;
	Иначе
		ПрефиксЯзыка = СуффиксТекущегоЯзыка();
	КонецЕсли;
	
	СписокРеквизитовОбъекта = Новый Соответствие;
	ОбъектМетаданныхРеквизиты = ОбъектМетаданных.Реквизиты; //  КоллекцияОбъектовМетаданных из ОбъектМетаданныхРеквизит -
	Для Каждого Реквизит Из ОбъектМетаданныхРеквизиты Цикл
		СписокРеквизитовОбъекта.Вставить(Реквизит.Имя, Реквизит);
	КонецЦикла;
	
	ОбъектМетаданныхСтандартныеРеквизиты = ОбъектМетаданных.СтандартныеРеквизиты; // КоллекцияОбъектовМетаданных из ОписаниеСтандартногоРеквизита -
	Для Каждого Реквизит Из ОбъектМетаданныхСтандартныеРеквизиты Цикл
		СписокРеквизитовОбъекта.Вставить(Реквизит.Имя, Реквизит);
	КонецЦикла;
	
	ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ 0
		|	*
		|ИЗ
		|	&ОбъектМетаданныхПолноеИмя КАК ДанныеИсточника";
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ОбъектМетаданныхПолноеИмя", ОбъектМетаданных.ПолноеИмя());
	Запрос = Новый Запрос(ТекстЗапроса);
	
	РезультатЗапроса = Запрос.Выполнить();
	
	СписокРеквизитов = Новый Соответствие;
	Для каждого Колонка Из РезультатЗапроса.Колонки Цикл
		Если СтрЗаканчиваетсяНа(Колонка.Имя, ПрефиксЯзыка) Тогда
			Реквизит = СписокРеквизитовОбъекта.Получить(Колонка.Имя);
			Если Реквизит = Неопределено Тогда
				Реквизит = Метаданные.ОбщиеРеквизиты.Найти(Колонка.Имя);
			КонецЕсли;
			СписокРеквизитов.Вставить(Колонка.Имя, Реквизит);
			
		КонецЕсли;
	КонецЦикла;
	
	Возврат СписокРеквизитов;
	
КонецФункции

// Возвращаемое значение:
//  Соответствие из КлючИЗначение:
//   * Ключ - Строка
//   * Значение - Булево
//
Функция НаименованияЛокализуемыхРеквизитовОбъекта(ОбъектМетаданных, Префикс = "") Экспорт
	
	СписокРеквизитовОбъекта = Новый Соответствие;
	Если МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Тогда
		
		Запрос = Новый Запрос;
		Запрос.Текст = 
			"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 0
			|	*
			|ИЗ
			|	&ИмяТаблицы КАК ДанныеИсточника";
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицы", ОбъектМетаданных.ПолноеИмя());
		
		РезультатЗапроса = Запрос.Выполнить();
		
		Для каждого Колонка Из РезультатЗапроса.Колонки Цикл
			СведенияОРеквизите = СведенияОРеквизите(Колонка.Имя);
			Если СведенияОРеквизите.Мультиязычный И Не СведенияОРеквизите.Удаленный Тогда
				СписокРеквизитовОбъекта.Вставить(Префикс + СведенияОРеквизите.ИмяРеквизитаБезСуффиксаЯзык, Ложь);
			КонецЕсли;
		КонецЦикла;
		
	КонецЕсли;
	
	ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
	
	Если ОбъектСодержитТЧПредставления(ПолноеИмя) Тогда
		
		РеквизитыТабличнойЧастиПредставления = МультиязычностьПовтИсп.МультиязычныеРеквизитыТабличнойЧасти(ПолноеИмя);
		Для каждого ИмяРеквизита Из РеквизитыТабличнойЧастиПредставления Цикл
			СписокРеквизитовОбъекта.Вставить(Префикс + ИмяРеквизита, Истина);
		КонецЦикла;
		
	КонецЕсли;
	
	Возврат СписокРеквизитовОбъекта;
	
КонецФункции

Функция НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданных, Префикс = "") Экспорт
	
	СписокРеквизитовОбъекта = Новый Соответствие;
	Если МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Тогда
	
		Запрос = Новый Запрос;
		Запрос.Текст = 
			"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 0
			|	*
			|ИЗ
			|	&ИмяТаблицы КАК ДанныеИсточника";
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицы", ОбъектМетаданных.ПолноеИмя());
		
		РезультатЗапроса = Запрос.Выполнить();
		
		Для каждого Колонка Из РезультатЗапроса.Колонки Цикл
			СведенияОРеквизите = СведенияОРеквизите(Колонка.Имя);
			Если СведенияОРеквизите.Мультиязычный И Не СведенияОРеквизите.Удаленный Тогда
				СписокРеквизитовОбъекта.Вставить(Префикс + СведенияОРеквизите.ИмяРеквизитаБезСуффиксаЯзык, Ложь);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Возврат СписокРеквизитовОбъекта;
	
КонецФункции

Функция МассивВСоответствие(Массив)
	Соответствие = Новый Соответствие();
	Для Каждого Элемент Из Массив Цикл
		Соответствие.Вставить(Элемент, Истина);
	КонецЦикла; 
	Возврат Соответствие;
КонецФункции

Функция ОсновнаяФормаСписка(ЧастиИмениФормы)
	
	Если ЧастиИмениФормы[0]= "СПРАВОЧНИК"
		Или ЧастиИмениФормы[0] = "ДОКУМЕНТ"
		Или ЧастиИмениФормы[0] = "ПЕРЕЧИСЛЕНИЕ"
		Или ЧастиИмениФормы[0] = "ПЛАНВИДОВХАРАКТЕРИСТИК"
		Или ЧастиИмениФормы[0] = "ПЛАНСЧЕТОВ"
		Или ЧастиИмениФормы[0] = "ПЛАНВИДОВРАСЧЕТА"
		Или ЧастиИмениФормы[0] = "БИЗНЕСПРОЦЕСС"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "РЕГИСТРБУХГАЛТЕРИИ"
		Или ЧастиИмениФормы[0] = "РЕГИСТРНАКОПЛЕНИЯ"
		Или ЧастиИмениФормы[0] = "РЕГИСТРРАСЧЕТА"
		Или ЧастиИмениФормы[0] = "РЕГИСТРСВЕДЕНИЙ"
		Или ЧастиИмениФормы[0] = "ПЛАНОБМЕНА" Тогда
			Возврат ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ЧастиИмениФормы[0] + "." + ЧастиИмениФормы[1]).ОсновнаяФормаСписка;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Функция ОсновнаяФормаДляВыбора(ЧастиИмениФормы)
	
	Если ЧастиИмениФормы[0]= "СПРАВОЧНИК"
		Или ЧастиИмениФормы[0] = "ДОКУМЕНТ"
		Или ЧастиИмениФормы[0] = "ПЕРЕЧИСЛЕНИЕ"
		Или ЧастиИмениФормы[0] = "ПЛАНВИДОВХАРАКТЕРИСТИК"
		Или ЧастиИмениФормы[0] = "ПЛАНСЧЕТОВ"
		Или ЧастиИмениФормы[0] = "БИЗНЕСПРОЦЕСС"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "ПЛАНОБМЕНА" Тогда
			Возврат ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ЧастиИмениФормы[0] + "." + ЧастиИмениФормы[1]).ОсновнаяФормаДляВыбора;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

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

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

Функция ЭтоОсновнойЯзык() Экспорт
	
	Возврат СтрСравнить(ОбщегоНазначения.КодОсновногоЯзыка(), ТекущийЯзык().КодЯзыка) = 0;
	
КонецФункции

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

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

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

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

// Параметры:
//  ВариантДанных - Строка - Варианты: Общие, Разделенные, Все 
// 
// Возвращаемое значение:
//  Массив - объекты СТЧПредставления
//
Функция ОбъектыСТЧПредставления(ВариантДанных)
	
	ОбъектыСТЧПредставления = Новый Массив;

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

Функция ВариантДанныхДляОбработкиСУчетомРазделения()
	Возврат ?(ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных(), "Разделенные", "Все");
КонецФункции

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

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

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

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

Функция ИспользуетсяПервыйДополнительныйЯзык()
	
	Возврат ИспользуетсяДополнительныйЯзык(1);
	
КонецФункции

Функция ИспользуетсяВторойДополнительныйЯзык()
	
	Возврат ИспользуетсяДополнительныйЯзык(2);
	
КонецФункции

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

	Для ПорядковыйНомерЯзыка =1 По КоличествоДополнительныхЯзыков() Цикл
		
		Если ЗначениеЗаполнено(КодДополнительногоЯзыкаИнформационнойБазы(ПорядковыйНомерЯзыка)) Тогда
			ДополнительныеЯзыкиИспользуются = Истина;
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если ДополнительныеЯзыкиИспользуются Тогда
	
		ОбъектыСПредопределеннымиЭлементами = ОбъектыСНачальнымЗаполнением(ВариантДанных);
		
		ШаблонЗапроса = "ВЫБРАТЬ
			|	ДанныеОбъекта.Ссылка
			|ИЗ
			|	&Таблица КАК ДанныеОбъекта
			|ГДЕ
			|	&УсловиеОтбора";
		
		НаборЗапросов = Новый Массив;
		
		Для Каждого ОбъектСПредопределеннымиЭлементами Из ОбъектыСПредопределеннымиЭлементами Цикл
			
			ОбъектМетаданныхСЭлементами = ОбъектСПредопределеннымиЭлементами.Ключ;
			ПолноеИмяОбъектаМетаданных  = ОбъектСПредопределеннымиЭлементами.Значение;
			
			// @skip-check query-in-loop - Порционная обработка больших объемов данных.
			ЛокализуемыеРеквизитыОбъекта = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданныхСЭлементами);
			Отборы = Новый Массив;
			
			Для каждого РеквизитОбъекта Из ЛокализуемыеРеквизитыОбъекта Цикл
				
				Если Не РеквизитОбъекта.Значение Тогда
					Продолжить;
				КонецЕсли;
				
				Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык1) И ЗначениеЗаполнено(СведенияОбЯзыках.Язык2) Тогда
					ШаблонОтбора = "ВЫРАЗИТЬ(&Реквизит КАК СТРОКА(1)) <> """"
					| И (ВЫРАЗИТЬ(&Язык1 КАК СТРОКА(1)) = """" ИЛИ ВЫРАЗИТЬ(&Язык2 КАК СТРОКА(1)) = """")";
					
					ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык1", РеквизитОбъекта.Ключ + "Язык1");
					ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык2", РеквизитОбъекта.Ключ + "Язык2");
					
				Иначе
					ШаблонОтбора = "ВЫРАЗИТЬ(&Реквизит КАК СТРОКА(1)) <> """"
					| И ВЫРАЗИТЬ(&Язык1Или2 КАК СТРОКА(1)) = """"";
					
					Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык2) Тогда
						ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык1Или2", РеквизитОбъекта.Ключ + "Язык2");
					Иначе
						ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык1Или2", РеквизитОбъекта.Ключ + "Язык1");
					КонецЕсли;
					
				КонецЕсли;
				
				ТекстОтбора = СтрЗаменить(ШаблонОтбора, "&Реквизит", РеквизитОбъекта.Ключ);
				Отборы.Добавить(ТекстОтбора);
				
			КонецЦикла;
			
			Если Отборы.Количество() = 0 Тогда
				Продолжить;
			КонецЕсли;
				
			ТекстЗапросаПредварительный = СтрЗаменить(ШаблонЗапроса, "&Таблица", ПолноеИмяОбъектаМетаданных);
			ТекстЗапросаПредварительный = СтрЗаменить(ТекстЗапросаПредварительный, "&УсловиеОтбора", СтрСоединить(
				Отборы, " ИЛИ "));
			НаборЗапросов.Добавить(ТекстЗапросаПредварительный);
			
		КонецЦикла;
		
		Если НаборЗапросов.Количество() > 0 Тогда
			
			Запрос = Новый Запрос;
			Запрос.Текст = СтрСоединить(НаборЗапросов, РазделительЗапросов);
			РезультатыЗапроса = Запрос.Выполнить().Выгрузить();
			ОбъектыКОбработке = РезультатыЗапроса.ВыгрузитьКолонку("Ссылка");
			
		КонецЕсли;
		
	КонецЕсли;
	
	// Отдельная порция объектов для регистрации с табличной частью Представления
	ОбъектыСТЧПредставления = ОбъектыСТЧПредставления(ВариантДанных);
	
	Если ОбъектыСТЧПредставления.Количество() > 0 Тогда
		
		ШаблонЗапроса = "ВЫБРАТЬ
		|СправочникСТЧПредставления.Ссылка
		|ИЗ
		|	#ТаблицаПредставления КАК СправочникСТЧПредставления
		|	ЛЕВОЕ СОЕДИНЕНИЕ #Таблица КАК СправочникСТЧ
		|		ПО СправочникСТЧПредставления.Ссылка = СправочникСТЧ.Ссылка
		|ГДЕ СправочникСТЧПредставления.КодЯзыка = ""&КодЯзыка"" И &Условие";
		
		ШаблонГде = "(ВЫРАЗИТЬ(СправочникСТЧПредставления.%1 КАК СТРОКА(10)) <> """" 
		|И ВЫРАЗИТЬ(СправочникСТЧ.%1#СуффиксЯзыка КАК СТРОКА(10)) = """")";
		
		НаборЗапросов = Новый Массив;
		
		Для Каждого ИмяОбъектаМетаданных Из ОбъектыСТЧПредставления Цикл
			
			ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ИмяОбъектаМетаданных);
			ТабличнаяЧастьОбъекта = ОбъектМетаданных.ТабличныеЧасти.Найти("Представления"); // ОбъектМетаданныхТабличнаяЧасть
			
			МультиязычныеРеквизиты = МультиязычностьПовтИсп.МультиязычныеРеквизитыТабличнойЧасти(ИмяОбъектаМетаданных);
			УсловияОтбора = Новый Массив;
			
			Для Каждого МультиязычныйРеквизит Из МультиязычныеРеквизиты Цикл
				
				УсловияОтбора.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					ШаблонГде, МультиязычныйРеквизит));
			КонецЦикла;
			
			ТекстЗапросаГде = "(" + СтрСоединить(УсловияОтбора, " ИЛИ ") + ")";
			
			Если ОбъектМетаданных.Иерархический 
				И ОбъектМетаданных.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
				
				Если ТабличнаяЧастьОбъекта.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента Тогда
					ТекстЗапросаГде = ТекстЗапросаГде + "
					|И СправочникСТЧ.ЭтоГруппа <> ИСТИНА";
				ИначеЕсли ТабличнаяЧастьОбъекта.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы Тогда
					ТекстЗапросаГде = ТекстЗапросаГде + "
					|И СправочникСТЧ.ЭтоГруппа = ИСТИНА";
				КонецЕсли;
			КонецЕсли;
			
			ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "#ТаблицаПредставления", 
				ОбъектМетаданных.ПолноеИмя() + "." + "Представления");
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#Таблица", ОбъектМетаданных.ПолноеИмя());
			
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Условие", ТекстЗапросаГде);
			НаборЗапросов.Добавить(ТекстЗапроса);
			
		КонецЦикла;
		
		ТекстЗапроса = СтрСоединить(НаборЗапросов, РазделительЗапросов);
		Запрос = Новый Запрос;
		
		
		НаборЗапросов = Новый Массив;
		Для Каждого ЯзыкИспользуется Из СведенияОбЯзыках.Используется Цикл
			Если ЯзыкИспользуется.Значение Тогда
				ТекстЗапроса2 = СтрЗаменить(ТекстЗапроса, "#СуффиксЯзыка", ЯзыкИспользуется.Ключ);
				ТекстЗапроса2 = СтрЗаменить(ТекстЗапроса2, "&КодЯзыка", СведенияОбЯзыках[ЯзыкИспользуется.Ключ]);
				НаборЗапросов.Добавить(ТекстЗапроса2);
			КонецЕсли;
		КонецЦикла;
		
		Запрос.Текст = СтрСоединить(НаборЗапросов, ОбщегоНазначения.РазделительПакетаЗапросов());
		
		Если ЗначениеЗаполнено(Запрос.Текст) Тогда
			РезультатыЗапроса = Запрос.ВыполнитьПакет();
			Для Каждого РезультатЗапроса Из РезультатыЗапроса Цикл
				
				ОбъектыСТабличнойЧастьюПредставлениеКОбработке = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка");
				ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ОбъектыКОбработке, 
					ОбъектыСТабличнойЧастьюПредставлениеКОбработке, Истина);
			КонецЦикла;
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат ОбъектыКОбработке;
	
КонецФункции

#Область ИзменениеЯзыка

// Данные для изменения мультиязычных реквизитов.
// 
// Возвращаемое значение:
//  Структура:
//   * НастройкиИзмененияЯзыков - см. МультиязычностьСервер.ОписаниеСтарыхИНовыхНастроекЯзыков
//   * ОсновнойЯзыкИзменен - Булево
//   * Объекты - Соответствие из КлючИЗначение:
//     ** Ключ - Строка
//     ** Значение - Структура:
//       *** СсылкаНаПоследнийОбработанныйОбъекты - Произвольный
//       *** ЯзыковыеПоля - Массив
//   * Изменения - Структура:
//      ** ДополнительныйЯзык1 - Булево
//      ** ДополнительныйЯзык2 - Булево
//	
Функция ДанныеДляИзмененияМультиязычныхРеквизитов() Экспорт

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

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

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

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

		Если ОбъектыСНачальнымЗаполнением.Получить(МетаданныеОбъекта) <> Неопределено Тогда

			Контекст = ОбновлениеИнформационнойБазыСлужебный.НаборПараметровДляЗаполненияОбъекта(
				МетаданныеОбъекта);
			
		КонецЕсли;
		
		Процент = Окр(ОбработаноОбъектов * 100 / ОбъектыСНачальнымЗаполнением.Количество()) + 1;
		ДлительныеОперации.СообщитьПрогресс(?(Процент > 99, 98, Процент), МетаданныеОбъекта.Представление());
		
		Если СтрНачинаетсяС(ПолноеИмя, "Справочник")
		 Или СтрНачинаетсяС(ПолноеИмя, "ПланВидовХарактеристик")
		 Или СтрНачинаетсяС(ПолноеИмя, "ПланСчетов")
		 Или СтрНачинаетсяС(ПолноеИмя, "ПланВидовРасчета") Тогда
			
			// @skip-check query-in-loop - Порционная обработка больших объемов данных.
			ОбработатьСсылочныеОбъекты(ПолноеИмя, ДанныеОбъекта.Значение, ДанныеДляИзмененияМультиязычныхРеквизитов,
				Контекст);
				
		ИначеЕсли СтрНачинаетсяС(ПолноеИмя, "РегистрСведений") Тогда
			ОбъектМетаданных = ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ПолноеИмя);
			
			Если ОбъектМетаданных.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
				// @skip-check query-in-loop - Порционная обработка больших объемов данных.
				ИзменитьЯзыкВПодчиненныхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта.Значение,
					ДанныеДляИзмененияМультиязычныхРеквизитов, Контекст);
			Иначе
				Периодический = ОбъектМетаданных.ПериодичностьРегистраСведений
					<> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический;
				// @skip-check query-in-loop - Порционная обработка больших объемов данных.
				ИзменитьЯзыкВНезависимыхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта.Значение,
					ДанныеДляИзмененияМультиязычныхРеквизитов, Контекст, Периодический);
			КонецЕсли;
		Иначе
			ОбъектыДляУдаления.Добавить(ПолноеИмя);
		КонецЕсли;
		
		ОбработаноОбъектов = ОбработаноОбъектов + 1;
	КонецЦикла;
	
	Если ОбъектыДляУдаления.Количество() > 0 Тогда
		Для Каждого ПолноеИмяОбъектаДляУдаления Из ОбъектыДляУдаления Цикл
			ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты.Удалить(ПолноеИмяОбъектаДляУдаления);
		КонецЦикла;
		ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
	КонецЕсли;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
		
		ДлительныеОперации.СообщитьПрогресс(99 , НСтр("ru = 'Варианты отчетов'"));
		
		МодульВариантыОтчетов = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетов");
		Настройки = МодульВариантыОтчетов.ПараметрыОбновленияНастроек();
		Настройки.Отложенное = Истина;
		МодульВариантыОтчетов.Обновить(Настройки);
		МодульВариантыОтчетов.СброситьЗаполнениеПредставлений("ОбщиеДанныеКонфигурации");
	КонецЕсли;
	
	ДлительныеОперации.СообщитьПрогресс(100, "");
	
КонецПроцедуры

Процедура ОбработатьСсылочныеОбъекты(ПолноеИмя, ДанныеОбъекта, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения)
	
	ПоследняяСсылка = ?(ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты <> Неопределено,
	ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты,
	ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя).ПустаяСсылка());
	
	ШаблонПолейЗапроса = "ДанныеОбъекта.%1%2 КАК %1%2";
	
	ЗначенияЯзыковыхКонстант = ДанныеДляИзмененияМультиязычныхРеквизитов.НастройкиИзмененияЯзыков;
	МультиязычныеРеквизиты = ДанныеОбъекта.ЯзыковыеПоля;
	
	ЕстьПорцияДанных = Истина;
	КоличествоДополнительныхЯзыков = КоличествоДополнительныхЯзыков();
	
	ОбъектСодержитТЧПредставления = Ложь;
	Если ПараметрыЗаполнения.Количество() > 0 Тогда
		ОбъектСодержитТЧПредставления =  ПараметрыЗаполнения.ОбъектСодержитТЧПредставления;
	КонецЕсли;
	
	Пока ЕстьПорцияДанных Цикл

		ПоляЗапроса = Новый Массив;

		Для Каждого МультиязычныйРеквизит Из МультиязычныеРеквизиты Цикл
			
			ПоляЗапроса.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				ШаблонПолейЗапроса, МультиязычныйРеквизит, ""));
			
			Для ПорядковыйНомерЯзыка = 1 По КоличествоДополнительныхЯзыков Цикл
				СуффиксЯзыка = МультиязычностьКлиентСервер.СуффиксЯзыка(ПорядковыйНомерЯзыка);
				ПоляЗапроса.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					ШаблонПолейЗапроса, МультиязычныйРеквизит, СуффиксЯзыка));
			КонецЦикла;
			
		КонецЦикла;
		
		Запрос = Новый Запрос;
		ТекстЗапроса =
		"ВЫБРАТЬ ПЕРВЫЕ 1000
		|	ДанныеОбъекта.Ссылка КАК Ссылка,
		|	&ПолеОбъекта
		|ИЗ
		|	#ДанныеОбъекта КАК ДанныеОбъекта
		|ГДЕ
		|	ДанныеОбъекта.Ссылка > &Ссылка
		|
		|УПОРЯДОЧИТЬ ПО
		|	Ссылка";

		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолеОбъекта", СтрСоединить(ПоляЗапроса, "," + Символы.ПС));
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ДанныеОбъекта", ПолноеИмя);

		Запрос.Текст = ТекстЗапроса;
		Запрос.УстановитьПараметр("Ссылка", ПоследняяСсылка);
		
		// @skip-check query-in-loop - Порционная обработка данных
		РезультатЗапроса = Запрос.Выполнить();
		
		Если Не РезультатЗапроса.Пустой() Тогда

			ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

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

					Блокировка = Новый БлокировкаДанных;
					ЭлементБлокировки = Блокировка.Добавить(ПолноеИмя);
					ЭлементБлокировки.УстановитьЗначение("Ссылка", ВыборкаДетальныеЗаписи.Ссылка);
					Блокировка.Заблокировать();

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

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

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

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

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

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

Процедура ИзменитьЯзыкВПодчиненныхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения, Периодический = Ложь)
	
	ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); 
	МенеджерРегистра = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя);
	СведенияОЯзыках = СведенияОЯзыках();
	
	МультиязычныеРеквизиты = ДанныеОбъекта.ЯзыковыеПоля;
	ЗначенияЯзыковыхКонстант = ДанныеДляИзмененияМультиязычныхРеквизитов.НастройкиИзмененияЯзыков;
	
	ИмяТаблицы = СтрЗаменить(ПолноеИмя, ".", "");
	
	ТекстЗапроса = "ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 1000
	|	ИмяТаблицы.Регистратор КАК РегистраторРеквизитСсылка
	|ИЗ
	|	&ОбъектМетаданных КАК ИмяТаблицы
	|ГДЕ
	|	ИмяТаблицы.Регистратор > &Регистратор
	|УПОРЯДОЧИТЬ ПО
	|	ИмяТаблицы.Регистратор";

	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ОбъектМетаданных", ПолноеИмя);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ИмяТаблицы", ИмяТаблицы);
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Если ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Неопределено Тогда
		Запрос.УстановитьПараметр("Регистратор", Неопределено);
	Иначе
		Отбор = ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты;
		Запрос.УстановитьПараметр("Регистратор", Отбор["Регистратор"]);
	КонецЕсли;
	
	Результат = Запрос.Выполнить().Выгрузить();
	
	Пока Результат.Количество() > 0 Цикл
		
		Для Каждого СтрокаРезультата Из Результат Цикл
			
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить(ПолноеИмя + "." + "НаборЗаписей");
			
			ТекущийНаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();
			ТекущийНаборЗаписей.Отбор.Регистратор.Установить(СтрокаРезультата.РегистраторРеквизитСсылка);
			
			ЭлементБлокировки.УстановитьЗначение("Регистратор", СтрокаРезультата.РегистраторРеквизитСсылка);
			
			НачатьТранзакцию();
				Попытка
					
					Блокировка.Заблокировать();
					ТекущийНаборЗаписей.Прочитать();
					
					Если ТекущийНаборЗаписей.Количество() = 0 Тогда
						ОтменитьТранзакцию();
						Продолжить;
					КонецЕсли;
					
					Для Каждого ИзменяемаяЗапись Из ТекущийНаборЗаписей Цикл
						
						Для Каждого МультиязычныйРеквизит Из МультиязычныеРеквизиты Цикл
							
							// Сохраняем старые значения
							ЗначенияРеквизита = Новый Соответствие;
							ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзык.СтароеЗначение] =  ИзменяемаяЗапись[МультиязычныйРеквизит]; 
							Для ПорядковыйНомерЯзыка = 1 По КоличествоДополнительныхЯзыков() Цикл
								ИмяКонстантыЯзыка = ИмяКонстантыЯзыка(ПорядковыйНомерЯзыка);
								ИмяСуффиксаЯзыка   = МультиязычностьКлиентСервер.СуффиксЯзыка(ПорядковыйНомерЯзыка);
								ЗначенияРеквизита[ЗначенияЯзыковыхКонстант[ИмяКонстантыЯзыка].СтароеЗначение] = ИзменяемаяЗапись[МультиязычныйРеквизит + ИмяСуффиксаЯзыка];
							КонецЦикла;
							
							ЗначениеПоУмолчанию = Строка(ИзменяемаяЗапись[МультиязычныйРеквизит]);
							Если ДанныеДляИзмененияМультиязычныхРеквизитов.ОсновнойЯзыкИзменен Тогда
								НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение];
								ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
									ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение);
							КонецЕсли;
							
							Для Каждого ДополнительныйЯзыкИзменен Из ДанныеДляИзмененияМультиязычныхРеквизитов.Изменения Цикл
								Если ДополнительныйЯзыкИзменен.Значение Тогда
									
									НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант[ДополнительныйЯзыкИзменен.Ключ].НовоеЗначение];
									ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
										ЗначенияЯзыковыхКонстант[ДополнительныйЯзыкИзменен.Ключ].НовоеЗначение);
								КонецЕсли;
							КонецЦикла;
							
						КонецЦикла;
						
					КонецЦикла;
					
					ОбновлениеИнформационнойБазы.ЗаписатьДанные(ТекущийНаборЗаписей);
					
					Отбор = Новый Структура();
					Отбор.Вставить("Регистратор", СтрокаРезультата.РегистраторРеквизитСсылка);
					
					ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Отбор;
					
					ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
					
					ЗафиксироватьТранзакцию();
					
				Исключение
					ОтменитьТранзакцию();
					
					Отбор = Новый Структура();
					Отбор.Вставить("Регистратор", СтрокаРезультата.РегистраторРеквизитСсылка);
					
					ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Отбор;
					
					ОписаниеОшибки     = ИнформацияОбОшибке();
					МетаданныеОбъекта = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
					ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Ошибка,
						МетаданныеОбъекта,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ОписаниеОшибки));
					
				КонецПопытки;
			
		КонецЦикла;
		
		Запрос.УстановитьПараметр("Регистратор", СтрокаРезультата.РегистраторРеквизитСсылка);
		
		// @skip-check query-in-loop - Порционная обработка данных
		Результат = Запрос.Выполнить().Выгрузить();
		
	КонецЦикла;
	
	ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты.Удалить(ПолноеИмя);
	ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
	
КонецПроцедуры

Процедура ИзменитьЯзыкВНезависимыхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения, Периодический = Ложь)
	
	ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); 
	МенеджерРегистра = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя);
	
	МультиязычныеРеквизиты = ДанныеОбъекта.ЯзыковыеПоля;
	ЗначенияЯзыковыхКонстант = ДанныеДляИзмененияМультиязычныхРеквизитов.НастройкиИзмененияЯзыков;
	
	ИмяТаблицы = СтрЗаменить(ПолноеИмя, ".", "");
	ШаблонПолейВыборки = "ИмяТаблицы.[ИмяПоля] КАК [ИмяПоля]ИзмерениеСсылка";
	
	Измерения          = ОбъектМетаданных.Измерения;// Массив из ОбъектМетаданныхИзмерение
	
	НаборПолейВыборки        = Новый Массив;
	НаборУсловий             = Новый Массив;
	НаборПолейУпорядочивания = Новый Массив;
	
	Если Периодический Тогда
		НаборПолейУпорядочивания.Добавить(ИмяТаблицы + "." + "Период");
		НаборУсловий.Добавить("ИмяТаблицы.Период > &Период");
		НаборПолейВыборки.Добавить("ИмяТаблицы.Период КАК Период");
	КонецЕсли;
	
	Для Каждого Измерение Из Измерения Цикл
		НаборДополнительныхУсловий = Новый Массив;
		
		Если НаборУсловий.Количество() > 0 Тогда
			НаборДополнительныхУсловий.Добавить(СтрЗаменить(НаборУсловий.Получить(НаборУсловий.ВГраница()), ">", "="));
		КонецЕсли;
		НаборДополнительныхУсловий.Добавить(ИмяТаблицы + "." + Измерение.Имя + " > &" + Измерение.Имя);
		
		НаборУсловий.Добавить(СтрСоединить(НаборДополнительныхУсловий, " И "));
		
		НаборПолейУпорядочивания.Добавить(ИмяТаблицы + "." + Измерение.Имя);
		НаборПолейВыборки.Добавить(СтрЗаменить(ШаблонПолейВыборки, "[ИмяПоля]", Измерение.Имя));
		
	КонецЦикла;
	
	УсловиеПоИзмерениям = СтрСоединить(НаборУсловий, " ИЛИ ");
	ПоляУпорядочивания  = СтрСоединить(НаборПолейУпорядочивания, ", " + Символы.ПС);
	ПоляВыборки         = СтрСоединить(НаборПолейВыборки, ", " + Символы.ПС);
	
	ТекстЗапроса =
	"ВЫБРАТЬ ПЕРВЫЕ 1000
	|	&ПоляВыборки КАК ПоляВыборки
	|ИЗ
	|	&ОбъектМетаданных КАК ИмяТаблицы
	|ГДЕ
	|	&Условие
	|
	|УПОРЯДОЧИТЬ ПО
	|	&ПоляУпорядочивания";
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Условие", УсловиеПоИзмерениям);

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

					ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
					
					ЗафиксироватьТранзакцию();
					
				Исключение
					ОтменитьТранзакцию();
					
					Отбор = Новый Структура();
					Для Каждого Измерение Из Измерения Цикл
						Отбор.Вставить(Измерение.Имя, СтрокаРезультата[Измерение.Имя + "ИзмерениеСсылка"]);
					КонецЦикла;
					
					Если Периодический Тогда
						Отбор.Вставить("Период", СтрокаРезультата["Период"]);
					КонецЕсли;
					
					ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Отбор;
					
					ОписаниеОшибки     = ИнформацияОбОшибке();
					МетаданныеОбъекта = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
					ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Ошибка, 
						МетаданныеОбъекта,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ОписаниеОшибки));
					
				КонецПопытки;
			
		КонецЦикла;
		
		Если Периодический Тогда
			Запрос.УстановитьПараметр("Период", СтрокаРезультата["Период"]);
		КонецЕсли;
		
		Для Каждого Измерение Из Измерения Цикл
			Запрос.УстановитьПараметр(Измерение.Имя, СтрокаРезультата[Измерение.Имя + "ИзмерениеСсылка"]);
		КонецЦикла;
		
		// @skip-check query-in-loop - Порционная обработка данных
		Результат = Запрос.Выполнить().Выгрузить();
		
	КонецЦикла;
	
	ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты.Удалить(ПолноеИмя);
	ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
	
КонецПроцедуры

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

// Имя событие для записи в журнал регистрации.
// 
// Возвращаемое значение:
//  Строка - событие журнала регистрации
//
Функция СобытиеЖурналаРегистрации()

	Возврат НСтр("ru = 'Мультиязычность'", ОбщегоНазначения.КодОсновногоЯзыка());

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

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

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