//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирКлиент Экспорт;

// Поместить строку соединения во временное хранилище
Функция ПоместитьСтрокуСоединенияВХранилищеЛкс(Адрес) Экспорт
	
	ПоместитьВоВременноеХранилище(СтрокаСоединенияИнформационнойБазы(), Адрес);
	
КонецФункции

// Получить строку соединения сервера
Функция СтрокаСоединенияСервераЛкс() Экспорт
	
	Если ирКэш.ЛиФайловаяБазаЛкс() Тогда
		Результат = СтрокаСоединенияИнформационнойБазы();
	Иначе
		Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
			Результат = СтрокаСоединенияИнформационнойБазы();
		Иначе
			// Антибаг https://partners.v8.1c.ru/forum/t/1361906/m/1361906
			//Если МонопольныйРежим() Тогда
			//	ВызватьИсключение "Невозможно определить строку соединения сервера в монопольном режиме";
			//КонецЕсли; 
			АдресХранилища = ПоместитьВоВременноеХранилище("");
			Параметры = Новый Массив();
			Параметры.Добавить(АдресХранилища);
			#Если Сервер И Не Сервер Тогда
				ПоместитьСтрокуСоединенияВХранилищеЛкс();
			#КонецЕсли
			ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирСервер.ПоместитьСтрокуСоединенияВХранилищеЛкс", Параметры,, "Получение строки соединения сервера (ИР)");
			Попытка
				ФоновоеЗадание.ОжидатьЗавершения(3);
			Исключение
				// http://www.hostedredmine.com/issues/851201
				ВызватьИсключение "Превышено время ожидания служебного фонового задания ИР. Отключите автоподключение фоновых заданий в отладчике и повторите попытку.";
			КонецПопытки; 
			Результат = ПолучитьИзВременногоХранилища(АдресХранилища);
		КонецЕсли; 
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

/////////////////////////////////////////////
// БСП. Отладка внешних обработок

Процедура ПриПодключенииВнешнейОбработки(Ссылка, СтандартнаяОбработка, Результат) Экспорт
	
	#Если Сервер И Не Сервер Тогда
	    Ссылка = Справочники.ДополнительныеОтчетыИОбработки.ПустаяСсылка(); //@skip-check unknown-method-property
	#КонецЕсли
	СтандартнаяОбработка = Истина;
	ОтладкаВключена = ХранилищеСистемныхНастроек.Загрузить("ирОтладкаВнешнихОбработок", "СозданиеВнешнихОбработокЧерезФайл");
	Если ОтладкаВключена = Истина Тогда
		ПутьКФайлу = ПолноеИмяФайлаВнешнейОбработкиВФайловомКэшеЛкс(Ссылка);
	Иначе
		Результат = "";
		Возврат;
	КонецЕсли;
	Если Ложь
		Или Ссылка = Вычислить("Справочники.ДополнительныеОтчетыИОбработки.ПустаяСсылка()") 
		Или ТипЗнч(Ссылка) <> Вычислить("Тип(""СправочникСсылка.ДополнительныеОтчетыИОбработки"")") 
	Тогда
		Результат = Неопределено;
		Возврат;
	КонецЕсли;
	Если Ложь
		Или Ссылка.Вид = Вычислить("Перечисления.ВидыДополнительныхОтчетовИОбработок.Отчет") 
		Или Ссылка.Вид = Вычислить("Перечисления.ВидыДополнительныхОтчетовИОбработок.ДополнительныйОтчет") 
	Тогда
		Менеджер = ВнешниеОтчеты;
	Иначе
		Менеджер = ВнешниеОбработки;
	КонецЕсли;
	ФайлВнешнейОбработки = Новый Файл(ПутьКФайлу);
	Если Не ФайлВнешнейОбработки.Существует() Тогда
		Ссылка.ХранилищеОбработки.Получить().Записать(ФайлВнешнейОбработки.ПолноеИмя);
	КонецЕсли; 
	ВнешнийОбъект = Менеджер.Создать(ПутьКФайлу, Ложь);
	ИмяОбработки = ВнешнийОбъект.Метаданные().Имя;
	Результат = ИмяОбработки;
	СтандартнаяОбработка = Ложь;
	Возврат;

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

Функция ПолноеИмяФайлаВнешнейОбработкиВФайловомКэшеЛкс(Ссылка, КаталогФайловогоКэша = "") Экспорт 
	
	#Если Сервер И Не Сервер Тогда
	    Ссылка = Справочники.ДополнительныеОтчетыИОбработки.ПустаяСсылка(); //@skip-check unknown-method-property
	#КонецЕсли
	Если Не ЗначениеЗаполнено(КаталогФайловогоКэша) Тогда
		Обработчик = НайтиПерехватВнешнихОбработокБСПЛкс();
		Если Обработчик = Неопределено Тогда
			ВызватьИсключение "Перехват внеших обработок не включен";
		КонецЕсли; 
		КаталогФайловогоКэша = Обработчик.КаталогФайловогоКэша;
	КонецЕсли; 
	ИмяФайла = Ссылка.ИмяФайла;
	Если Не ЗначениеЗаполнено(ИмяФайла) Тогда
		ИмяФайла = "" + Ссылка.УникальныйИдентификатор() + ".epf";
	КонецЕсли; 
	ПутьКФайлу = КаталогФайловогоКэша + "\" + ИмяФайла;
	Возврат ПутьКФайлу;

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

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

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

Функция ПолучитьОбработчикиПриПодключенииВнешнейОбработки()
	
	КонстантаПараметрыСлужебныхСобытий = Вычислить("Константы.ПараметрыСлужебныхСобытий");
	ИмяОбработчика = "СтандартныеПодсистемы.ДополнительныеОтчетыИОбработки\ПриПодключенииВнешнейОбработки";
	СтруктруаПараметрыСлужебныхСобытий = КонстантаПараметрыСлужебныхСобытий.Получить().Получить();
	ОбработчикиНаСервере = СтруктруаПараметрыСлужебныхСобытий.ОбработчикиСобытий.НаСервере;
	ОбработчикиСлужебныхСобытий = ОбработчикиНаСервере.ОбработчикиСлужебныхСобытий;
	Обработчики = ОбработчикиСлужебныхСобытий[ИмяОбработчика];
	Обработчики = Новый Массив(Обработчики);
	Возврат Обработчики;

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

Процедура УстановитьОбработчикиПриПодключенииВнешнейОбработки(Обработчики)
	
	ИмяОбработчика = "СтандартныеПодсистемы.ДополнительныеОтчетыИОбработки\ПриПодключенииВнешнейОбработки";
	КонстантаПараметрыСлужебныхСобытий = Вычислить("Константы.ПараметрыСлужебныхСобытий");
	СтруктураПараметрыСлужебныхСобытий = КонстантаПараметрыСлужебныхСобытий.Получить().Получить();
	ОбработчикиНаСервере = СтруктураПараметрыСлужебныхСобытий.ОбработчикиСобытий.НаСервере;
	ОбработчикиСлужебныхСобытий = Вычислить("Новый Соответствие(ОбработчикиНаСервере.ОбработчикиСлужебныхСобытий)");
	ОбработчикиСлужебныхСобытий[ИмяОбработчика] = Новый ФиксированныйМассив(Обработчики);
	ОбработчикиНаСервере.ОбработчикиСлужебныхСобытий = Новый ФиксированноеСоответствие(ОбработчикиСлужебныхСобытий);
	КонстантаПараметрыСлужебныхСобытий.Установить(Новый ХранилищеЗначения(СтруктураПараметрыСлужебныхСобытий));
	ОбновитьПовторноИспользуемыеЗначения();

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

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

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

/////////////////////////////////////////////
// Перенаправление

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

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

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

	Результат = ирОбщий.ИмяФайлаАктивнойНастройкиТехноЖурналаЛкс();
	Возврат Результат;

КонецФункции
                              
Функция ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала) Экспорт

	Результат = ирОбщий.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала);
	Возврат Результат;

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

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

Функция ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка = Неопределено) Экспорт
	
	Результат = ирОбщий.ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка);
	Возврат Результат;
	
КонецФункции

Функция НайтиИменаФайловЛкс(Путь, Маска = Неопределено, ИскатьВПодкаталогах = Истина) Экспорт
	
	Результат = ирОбщий.НайтиИменаФайловЛкс(Путь, Маска, ИскатьВПодкаталогах);
	Возврат Результат;
	
КонецФункции

Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт
	
	Результат = ирОбщий.ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги);
	Возврат Результат;

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

Функция ТекущаяДатаЛкс() Экспорт
	
	Результат = ТекущаяДата();
	Возврат Результат;
	
КонецФункции

Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения = Истина) Экспорт

	ирОбщий.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, , ВыводитьПредупрежденияИСообщения);

КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс()

Функция АдаптироватьРасширениеЛкс() Экспорт 

	Результат = ирОбщий.АдаптироватьРасширениеЛкс();
	Возврат Результат;
	
КонецФункции

Функция ВосстановитьЗначениеЛкс(Знач КлючНастроек) Экспорт 

	Возврат ирОбщий.ВосстановитьЗначениеЛкс(КлючНастроек);
	
КонецФункции

Функция СохранитьЗначениеЛкс(Знач КлючНастроек, Знач Значение) Экспорт 

	ирОбщий.СохранитьЗначениеЛкс(КлючНастроек, Значение);
	
КонецФункции

Функция УдалитьХранимуюНастройкуЛкс(Знач КлючНастроек) Экспорт 

	ирОбщий.УдалитьХранимуюНастройкуЛкс(КлючНастроек);
	
КонецФункции

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

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

Функция ВыполнитьЗапросЭтойСУБДЛкс(Знач ТекстЗапроса, Знач СмещениеГода, Знач ИспользованиеGWF) Экспорт 
	
	ирОбщий.ТребоватьРольИРЛкс();
	Результат = ирОбщий.ВыполнитьЗапросЭтойСУБДЛкс(ТекстЗапроса,,, СмещениеГода, ИспользованиеGWF, Ложь);
	Возврат Результат;

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

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

Функция ОбработатьПорциюСтрокТаблицыЛкс(Знач АдресТаблицыЗначений, Знач НачальныйНомерСтроки, Знач РазмерПорции, Знач МодальныйРежим = Ложь, Знач ПропускатьОшибки = Ложь, Знач ТекстАлгоритма,
	Знач ПараметраАлгоритмы = Неопределено) Экспорт 
	
	ирОбщий.ОбработатьПорциюСтрокТаблицыЛкс(АдресТаблицыЗначений, НачальныйНомерСтроки, РазмерПорции, МодальныйРежим, ПропускатьОшибки, ТекстАлгоритма, ПараметраАлгоритмы);

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

Функция НеблокирующиеМетаданныеБСПЛкс() Экспорт 
	
	Результат = ирОбщий.НеблокирующиеМетаданныеБСПЛкс();
	Возврат Результат;

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

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

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

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

Процедура УстановитьИспользованиеИсторииДанныхЛкс(Знач ИменаМД, Знач НовоеИспользование, Знач НовоеИспользованиеПолей) Экспорт 
	
	ирОбщий.УстановитьИспользованиеИсторииДанныхЛкс(ИменаМД, НовоеИспользование, НовоеИспользованиеПолей);
	
КонецПроцедуры

Функция ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки, П0 = null, П1 = null, П2 = null, П3 = null, П4 = null, П5 = null, П6 = null, П7 = null) Экспорт 
	Результат = ирОбщий.ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки,, П0, П1, П2, П3, П4, П5, П6, П7);
	Возврат Результат
КонецФункции

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

Функция СоединениеHTTPЛкс(СерверЗапроса, ПортВременный, ПользовательЗапроса, ПарольЗапроса, СобственныйПрокси, ТаймаутЗапроса, ИспользоватьЗащищенноеСоединение, АутентификацияОС,
	ПредставлениеСоединения, ТаблицаСобытий) Экспорт 
	
	ирОбщий.СоединениеHTTPЛкс(СерверЗапроса, ПортВременный, ПользовательЗапроса, ПарольЗапроса, СобственныйПрокси, ТаймаутЗапроса, ИспользоватьЗащищенноеСоединение, АутентификацияОС,
		ПредставлениеСоединения,, ТаблицаСобытий);
КонецФункции

////////

// Антибаг 8.3.22 https://www.hostedredmine.com/issues/948691
Процедура РазблокироватьАутентифкациюЛкс(Знач ИмяПользователя) Экспорт 
	
	БлокировкаАутентификацииМой = Вычислить("БлокировкаАутентификации");
	#Если Сервер И Не Сервер Тогда
		БлокировкаАутентификацииМой = БлокировкаАутентификации;
	#КонецЕсли
	БлокировкаПользователя = БлокировкаАутентификацииМой.ПолучитьБлокировки(Новый Структура("ИмяПользователя", ИмяПользователя));
	Если БлокировкаПользователя.Количество() > 0 Тогда
		БлокировкаПользователя = БлокировкаПользователя[0];
		БлокировкаПользователя.Разблокировать();
	КонецЕсли;

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

Процедура ПодключитьСистемнуюФормуЛкс(Знач ИмяВыбраннойФормы) Экспорт 
	
	ВнешниеОбработки.Подключить("v8res://mngbase/" + ИмяВыбраннойФормы + ".epf");

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

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

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

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

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

	ПереместитьФайл(ИмяИсточника, ИмяПриемника);

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

Функция ЛиФайлСуществуетЛкс(ПолноеИмяФайла, выхДатаИзменения = Неопределено) Экспорт 

	Файл1 = Новый Файл(ПолноеИмяФайла);
	ФайлНайден = Файл1.Существует();
	Если ФайлНайден Тогда
		выхДатаИзменения = Файл1.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
	КонецЕсли; 
	Возврат ФайлНайден;

КонецФункции // ЛиФайлСуществует()
 
// Выполняет текст алгоритма.
//
// Параметры:
//  ТекстДляВыполнения - Строка;
//  _АлгоритмОбъект - СправочникОбъект
//  *СтруктураПараметров - Структура, *Неопределено.
//
Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим  = Null,
	_П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт 
	
	Перем Результат;
	ирОбщий.ТребоватьРольИРЛкс();
	Если Истина
		И ирКэш.ЛиПортативныйРежимЛкс()
		И ирПортативный.ЛиСерверныйМодульДоступенЛкс(Ложь)
	Тогда
		ПараметрыКоманды = Новый Структура("_ТекстДляВыполнения, _АлгоритмОбъект, Результат", _ТекстДляВыполнения, _АлгоритмОбъект);
		#Если Сервер И Не Сервер Тогда
			Обработки.ирПортативныйСервер.Создать().ВыполнитьАлгоритм();
		#КонецЕсли
		ирПортативный.ВыполнитьСерверныйМетодЛкс("ВыполнитьАлгоритм", ПараметрыКоманды);
		Результат = ПараметрыКоманды.Результат;
	Иначе
		Результат = ирОбщий.ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект, _Режим, _П0, _П1, _П2, _П3, _П4, _П5, _П6, _П7, _П8, _П9);
	КонецЕсли;
	Результат = Неопределено; // Защита от возвращения на клиент мутабельного значения в консоли кода http://www.hostedredmine.com/issues/871627
	Возврат Результат;
	
КонецФункции

Процедура ВыполнитьАлгоритмБезРезультата(_ТекстДляВыполнения) Экспорт 
	
	ирОбщий.ТребоватьРольИРЛкс();
	Выполнить(_ТекстДляВыполнения);
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

Процедура УстановитьНовыйКодXMLЛкс(ОбъектXML, ПрефиксКода, ТипОбъекта) Экспорт 
	
	Объект = Новый (ТипОбъекта);
	Объект.ЗагрузитьСнимок(ОбъектXML);
	Объект.УстановитьНовыйКод(ПрефиксКода);
	ОбъектXML = Объект.Снимок();
	
КонецПроцедуры

Процедура УстановитьНовыйНомерXMLЛкс(ОбъектXML, ПрефиксНомера, ТипОбъекта) Экспорт 
	
	Объект = Новый (ТипОбъекта);
	Объект.ЗагрузитьСнимок(ОбъектXML);
	Объект.УстановитьНовыйНомер(ПрефиксНомера);
	ОбъектXML = Объект.Снимок();
	
КонецПроцедуры

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

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

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

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

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

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

Функция ПолучитьИспользованиеСобытияЖурналаРегистрацииКакСтруктуру(ИмяСобытия) Экспорт
	
	Результат = Новый Структура("Использование, ОписаниеИспользования");
	ИспользованиеСобытия = ПолучитьИспользованиеСобытияЖурналаРегистрации(ИмяСобытия);
	Если ИспользованиеСобытия = Неопределено И ирКэш.ЛиПортативныйРежимЛкс() Тогда
		// http://devtool1c.ucoz.ru/forum/2-941-1
		ВызватьИсключение "Функция недоступна в портативном варианте на платформе 8.2 из-за ошибки платформы";
	КонецЕсли; 
	Результат.Использование = ИспользованиеСобытия.Использование;
	Если ТипЗнч(ИспользованиеСобытия.ОписаниеИспользования) = Тип("Массив") И ИспользованиеСобытия.ОписаниеИспользования.Количество() > 0  Тогда
		ОписаниеИспользования = Новый Массив();
		Если ТипЗнч(ИспользованиеСобытия.ОписаниеИспользования[0]) = Тип("ОписаниеИспользованияСобытияДоступЖурналаРегистрации") Тогда
			СтрокаКлючей = "Объект, ПоляРегистрации, ПоляДоступа";
		ИначеЕсли ТипЗнч(ИспользованиеСобытия.ОписаниеИспользования[0]) = Тип("ОписаниеИспользованияСобытияОтказВДоступеЖурналаРегистрации") Тогда
			СтрокаКлючей = "Объект, ПоляРегистрации";
		Иначе
			//ВызватьИсключение "Неизвестный тип " + ТипЗнч(ИспользованиеСобытия.ОписаниеИспользования[0]);
		КонецЕсли;
		Для Каждого ЭлементОписания Из ИспользованиеСобытия.ОписаниеИспользования Цикл
			ЭлементМассива = Новый Структура(СтрокаКлючей);		
			ЗаполнитьЗначенияСвойств(ЭлементМассива, ЭлементОписания); 
			ОписаниеИспользования.Добавить(ЭлементМассива);
		КонецЦикла;
		Результат.ОписаниеИспользования = ОписаниеИспользования;
	Иначе
		Результат.ОписаниеИспользования = Неопределено;
	КонецЕсли;
	Возврат Результат;
	
КонецФункции

Процедура УстановитьИспользованиеСобытияЖурналаРегистрацииПоСтруктуре(ИмяСобытия, пИспользованиеСобытия) Экспорт
	
	ИспользованиеСобытия = Новый ИспользованиеСобытияЖурналаРегистрации;
	ИспользованиеСобытия.Использование = пИспользованиеСобытия.Использование;
	пОписаниеИспользования = Неопределено;
	пИспользованиеСобытия.Свойство("ОписаниеИспользования", пОписаниеИспользования);
	Если Истина
		 И ТипЗнч(пОписаниеИспользования) = Тип("Массив") 
		 И пОписаниеИспользования.Количество() > 0
		 И (Ложь
		 	Или ИмяСобытия = "_$Access$_.Access"
			Или ИмяСобытия = "_$Access$_.AccessDenied")
	Тогда
		ТипОписанияСтрокой = ?(ИмяСобытия = "_$Access$_.Access", "ОписаниеИспользованияСобытияДоступЖурналаРегистрации","ОписаниеИспользованияСобытияОтказВДоступеЖурналаРегистрации");
		ОписаниеИспользования = Новый Массив();
		Для Каждого пЭлементОписания Из пОписаниеИспользования Цикл
			ЭлементОписания = Новый(ТипОписанияСтрокой);
			ЗаполнитьЗначенияСвойств(ЭлементОписания, пЭлементОписания); 
			ОписаниеИспользования.Добавить(ЭлементОписания);
		КонецЦикла;
		ИспользованиеСобытия.ОписаниеИспользования = ОписаниеИспользования;
	КонецЕсли; 
	УстановитьИспользованиеСобытияЖурналаРегистрации(ИмяСобытия, ИспользованиеСобытия)
	
КонецПроцедуры

Функция ПолучитьПараметрыПроцессаАгентаСервера(выхИдентификаторПроцесса = Неопределено, выхКомманднаяСтрока = Неопределено, выхИмяСлужбы = Неопределено) Экспорт 
	
	выхИмяСлужбы = Неопределено;
	РабочийПроцесс = ирОбщий.ПолучитьПроцессОСЛкс("текущий",,, Ложь);
	Если ТипЗнч(РабочийПроцесс) = Тип("Строка") Тогда
		ирОбщий.СообщитьЛкс("Ошибка обращения к процессу ОС рабочего процесса: " + РабочийПроцесс);
		Возврат Неопределено;
	КонецЕсли; 
	КомпьютерКластера = ирОбщий.ИмяКомпьютераКластераЛкс();
	Если Не ЗначениеЗаполнено(КомпьютерКластера) Тогда
		Возврат Неопределено;
	КонецЕсли; 
	Попытка
		WMIЛокатор = ирКэш.ПолучитьCOMОбъектWMIЛкс(КомпьютерКластера);
	Исключение
		ирОбщий.СообщитьЛкс("У пользователя рабочего процесса нет прав на подключение к WMI кластера: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
		Возврат Неопределено;
	КонецПопытки; 
	выхИдентификаторПроцесса = РабочийПроцесс.ParentProcessId;
	ПроцессАгента = ирОбщий.ПолучитьПроцессОСЛкс(выхИдентификаторПроцесса,, КомпьютерКластера);
	Если ТипЗнч(ПроцессАгента) = Тип("COMОбъект") Тогда
		выхКомманднаяСтрока = ПроцессАгента.CommandLine;
		ТекстЗапросаWQL = "Select * from Win32_Service Where ProcessId = " + XMLСтрока(выхИдентификаторПроцесса);
		ВыборкаСистемныхСлужб = WMIЛокатор.ExecQuery(ТекстЗапросаWQL);
		Для Каждого лСистемнаяСлужба Из ВыборкаСистемныхСлужб Цикл
			СистемнаяСлужба = лСистемнаяСлужба;
			Прервать;
		КонецЦикла;
	КонецЕсли; 
	Если СистемнаяСлужба = Неопределено Тогда
		//ирОбщий.СообщитьЛкс("Не удалось определить имя системной службы агента сервера приложений", СтатусСообщения.Внимание);
		Возврат Неопределено;
	КонецЕсли;
	выхИмяСлужбы = СистемнаяСлужба.Name;
	Возврат выхИдентификаторПроцесса;
	
КонецФункции

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

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

Функция ИнфоСервераПриложений() Экспорт
	Если ирКэш.ЛиПортативныйРежимЛкс() Тогда 
		Если ирПортативный.ЛиСерверныйМодульДоступенЛкс(Ложь) Тогда
			ПараметрыМетода = Новый Структура("Результат");
			#Если Сервер И Не Сервер Тогда
				Обработки.ирПортативныйСервер.Создать().ИнфоСервераПриложений();
			#КонецЕсли
			ирПортативный.ВыполнитьСерверныйМетодЛкс("ИнфоСервераПриложений", ПараметрыМетода);
			ИнфоСервера = ПараметрыМетода.Результат;
		Иначе
			ИнфоСервера = "";
		КонецЕсли; 
	Иначе
		ИнфоСервера = 
		"Сервер. ОС: " + ирОбщий.ОписаниеОСЛкс() + "
		|Сервер. Процесс: " + ?(ирКэш.Это64битныйПроцессЛкс(), "64", "32") + "б";
		Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
			ИнфоСервера = ИнфоСервера + Символы.ПС + "Сервер. Отладка: " + ирОбщий.РежимОтладкиСервераИзКоманднойСтрокиЛкс();
		КонецЕсли; 
	КонецЕсли; 
	Возврат ИнфоСервера;
КонецФункции 

Функция РежимОтладкиСервераИзКоманднойСтрокиЛкс() Экспорт
	Возврат ирОбщий.РежимОтладкиСервераИзКоманднойСтрокиЛкс();
КонецФункции

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

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

Функция СписокДопСвойствОбъектаБСПЛкс(СсылкаОбъекта) Экспорт 
	
	СписокСвойств = Новый Массив;
	МодульУправлениеСвойствами = Вычислить("УправлениеСвойствами");
	#Если Сервер И Не Сервер Тогда
		МодульУправлениеСвойствами = УправлениеСвойствами;
	#КонецЕсли
	Если ирОбщий.МетодРеализованЛкс(МодульУправлениеСвойствами, "СвойстваОбъекта") Тогда
		// БСП 2.4+
		СписокСвойств = МодульУправлениеСвойствами.СвойстваОбъекта(СсылкаОбъекта);
	//ИначеЕсли ирОбщий.МетодРеализованЛкс(МодульУправлениеСвойствами, "ПолучитьСписокСвойств") Тогда
	//	// БСП 2.3-
	//	// https://www.hostedredmine.com/issues/917471
	//	СписокСвойств = МодульУправлениеСвойствами.ПолучитьСписокСвойств(СсылкаОбъекта);
	//  Здесь полностью другие свойства свойств https://www.hostedredmine.com/issues/921992
	КонецЕсли; 
	Возврат СписокСвойств;

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

Функция СоздатьКаталогТрассыПоПользователюЛкс() Экспорт 
	
	Каталог = КаталогТрассыПоПользователюЛкс();
	СоздатьКаталог(Каталог);
	Возврат Каталог;
	
КонецФункции

Функция КаталогТрассыПоПользователюЛкс() Экспорт 
	
	СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
	Каталог = КаталогВременныхФайлов() + ирОбщий.ИдентификаторИзПредставленияЛкс(СтрокаСоединения) + "\" + ИмяПользователя();
	Возврат Каталог;

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

Функция ТаблицаВсехТаблицБДЛкс() Экспорт 
	Возврат ирКэш.ТаблицаВсехТаблицБДЛкс();
КонецФункции

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

// В управляемом приложении нельзя возвращать РезультатЗапроса https://www.hostedredmine.com/issues/971440
Процедура ВыполнитьЗапросЛкс(ТекстЗапроса, Параметры = Неопределено, АдресРезультата = "", МоментНачала = Неопределено, выхТекущаяДата = Неопределено) Экспорт 
	ирОбщий.ТребоватьРольИРЛкс();
	Результат = ирОбщий.ВыполнитьЗапросЛкс(ТекстЗапроса, Параметры, МоментНачала);
	Если ЗначениеЗаполнено(АдресРезультата) Тогда
		ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
	КонецЕсли; 
	выхТекущаяДата = ТекущаяДата();
КонецПроцедуры

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

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

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

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

Процедура ДобавитьТекущемуПользователюБСПРолиИРЛкс() Экспорт 
	УстановитьПривилегированныйРежим(Истина); 
	УИД = Новый УникальныйИдентификатор("e1c1e21c-7913-11ed-8618-001a7dda7114");
	ПрофилиГруппДоступаМенеджер = Справочники.ПрофилиГруппДоступа; //@skip-check unknown-method-property
	СсылкаПрофиль = ПрофилиГруппДоступаМенеджер.ПолучитьСсылку(УИД); 
	ОбъектПрофиль = СсылкаПрофиль.ПолучитьОбъект();
	Если ОбъектПрофиль = Неопределено Тогда
		ОбъектПрофиль = ПрофилиГруппДоступаМенеджер.СоздатьЭлемент();
		ОбъектПрофиль.УстановитьСсылкуНового(СсылкаПрофиль);
		ОбъектПрофиль.Наименование = ирОбщий.ИмяПродуктаЛкс() + " (системная, не изменять)";
	КонецЕсли;
	ОбщегоНазначенияМой = Вычислить("ОбщегоНазначения");
	#Если Сервер И Не Сервер Тогда
		ОбщегоНазначенияМой = ОбщегоНазначения; //@skip-check unknown-method-property
	#КонецЕсли
	СсылкаРоль = ОбщегоНазначенияМой.ИдентификаторОбъектаМетаданных(Метаданные.Роли.ирРазработчик);
	Если ОбъектПрофиль.Роли.Найти(СсылкаРоль) = Неопределено Тогда
		ОбъектПрофиль.Роли.Добавить().Роль = СсылкаРоль;
	КонецЕсли;
	Если ОбъектПрофиль.Модифицированность() Тогда
		ОбъектПрофиль.Записать();
	КонецЕсли;               
	ГруппыДоступаМенеджер = Справочники.ГруппыДоступа; //@skip-check unknown-method-property
	СсылкаГруппа = ГруппыДоступаМенеджер.ПолучитьСсылку(УИД); 
	ОбъектГруппа = СсылкаГруппа.ПолучитьОбъект();
	Если ОбъектГруппа = Неопределено Тогда
		ОбъектГруппа = ГруппыДоступаМенеджер.СоздатьЭлемент();
		ОбъектГруппа.УстановитьСсылкуНового(СсылкаГруппа);
		ОбъектГруппа.Наименование = ирОбщий.ИмяПродуктаЛкс() + "(профиль не изменять)";
	КонецЕсли;
	ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ОбъектГруппа.Профиль, СсылкаПрофиль);
	Если ОбъектГруппа.Пользователи.Найти(ПараметрыСеанса.ТекущийПользователь) = Неопределено Тогда
		ОбъектГруппа.Пользователи.Добавить().Пользователь = ПараметрыСеанса.ТекущийПользователь;
	КонецЕсли;
	Если ОбъектГруппа.Модифицированность() Тогда
		ОбъектГруппа.Записать();
	КонецЕсли;

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

Функция КомандыБСППоИмениТаблицыЛкс(Знач ИмяОсновнойТаблицы) Экспорт 
	
	ПодключаемыеКомандыМой = Вычислить("ПодключаемыеКомандыПовтИсп");
	#Если Сервер И Не Сервер Тогда
		ПодключаемыеКомандыМой = ПодключаемыеКоманды;
	#КонецЕсли
	КомандыБСП = ПодключаемыеКомандыМой.КэшФормы(".", ИмяОсновнойТаблицы, Ложь).Команды.Скопировать();
	КомандыБСП.Сортировать("Представление"); 
	Для Каждого КомандаБСП Из КомандыБСП Цикл
		КомандаБСП.ИмяВФорме = ирОбщий.ИдентификаторИзПредставленияЛкс(КомандаБСП.Представление + "_" + Новый УникальныйИдентификатор);
	КонецЦикла;
	Результат = ирОбщий.ОбъектВСтрокуXMLЛкс(КомандыБСП); // Защита от попытка передачи мутабельного значения результата в обычном приложении https://www.hostedredmine.com/issues/959970
	Возврат Результат;

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

Функция ВернутьПараметрЛкс(Знач Параметр) Экспорт 
	Возврат Параметр;
КонецФункции

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

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

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

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

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

Функция ПодключитьВнешнююОбработкуБСП(Ссылка) Экспорт 
	Возврат Вычислить("ДополнительныеОтчетыИОбработки").ПодключитьВнешнююОбработку(Ссылка);
КонецФункции

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

Функция ЛиРаботаСВнешнимиРесурсамиЗаблокированаБСП() Экспорт
	Результат = Вычислить("БлокировкаРаботыСВнешнимиРесурсами").РаботаСВнешнимиРесурсамиЗаблокирована();
	Возврат Результат;
КонецФункции

///////////////////////////////////////////////////
// Управляемые формы

// 
// Параметры:
//  ЭтаФорма			 - УправляемаяФорма - 
//  ОсновнойЭУ			 - РасширениеТаблицыФормыДляДинамическогоСписка - 
//  ПолноеИмяТаблицыБД	 - 	 - 
//  РежимИмяСиноним		 - Булево - 
//  СоединенныеРегистры	 - см. Обработка.ирДинамическийСписок.Форма.ФормаУпр.СоединяемыеРегистры.Выгрузить() - 
//  выхСхемаПодвала		 - 	 - 
// 
// Возвращаемое значение:
//   - 
//
Функция НастроитьАвтоТаблицуФормыДинамическогоСпискаЛкс(Знач ЭтаФорма, Знач ОсновнойЭУ, Знач ПолноеИмяТаблицыБД, Знач РежимИмяСиноним = Ложь, Знач СоединенныеРегистры, выхСхемаПодвала = Неопределено) Экспорт
	
	ПредельноеЧислоВидимыхКолонок = ирОбщий.ПредельноеЧислоВидимыхКолонокДинамСпискаЛкс();
	ОбъектМД = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, Истина);
	Если ОбъектМД = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли; 
	#Если Сервер И Не Сервер Тогда
		ЭтаФорма = ОткрытьФорму();
		ОбъектМД = Метаданные.Справочники.ирАлгоритмы;
	#КонецЕсли
	ИменаВажныхКолонок = Новый Массив;
	//ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Ссылка") + СуффиксПоляТипаЗначенияЛкс());
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Ссылка"));
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Дата"));
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Номер"));
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Период"));
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Код"));
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Наименование"));
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("НомерСтроки"));
	//ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Регистратор") + СуффиксПоляТипаЗначенияЛкс());
	ИменаВажныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Регистратор"));
	ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ОсновнойЭУ); // ДинамическийСписок
	КолонкиТП = ОсновнойЭУ.ПодчиненныеЭлементы;
	выхСхемаПодвала = Новый Структура;
	ПутьКДаннымСписка = ОсновнойЭУ.ПутьКДанным;
	ДинамическийСписок.ПроизвольныйЗапрос = Истина;
	ДинамическийСписок.ДинамическоеСчитываниеДанных = Истина; 
	СкрытыеПоля = Неопределено;   
	ТекстЗапроса = ТекстЗапросаДинамическогоСпискаЛкс(ОбъектМД, ПолноеИмяТаблицыБД, СоединенныеРегистры, ДинамическийСписок, СкрытыеПоля);
	// Так на втором исключении безсловно завершается программа
	//ДинамическийСписок.ТекстЗапроса = "ВЫБРАТЬ 0";
	//Запрос = Новый Запрос;  
	//Запрос.Текст = ТекстЗапроса;
	//Запрос.НайтиПараметры(); // Для ранней диагностики неудобных имен полей http://devtool1c.ucoz.ru/forum/2-2245-1
	ДинамическийСписок.ТекстЗапроса = ТекстЗапроса; 
	ДинамическийСписок.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("ИмяТаблицы", ПолноеИмяТаблицыБД); // Вызывает неявное обновление списка
	СуффиксПоляТипаЗначения = СуффиксПоляТипаЗначенияЛкс();
	ПоляСписка = ЭтаФорма.ПолучитьРеквизиты(ПутьКДаннымСписка);
	Пока ОсновнойЭУ.ПодчиненныеЭлементы.Количество() > 0 Цикл
		Попытка
			ЭтаФорма.Элементы.Удалить(ОсновнойЭУ.ПодчиненныеЭлементы[0]);
		Исключение
			Пустышка = 0; // Для отладки
		КонецПопытки;
	КонецЦикла;
	СкрытьПредопределенные = Истина
		И ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД))
		И ирКэш.НомерВерсииПлатформыЛкс() >= 803005
		И ОбъектМД.ПолучитьИменаПредопределенных().Количество() = 0;
	ИмяПоляЧислоСтрок = ирОбщий.ИмяПоляЧислоСтрокЛкс();
	СловоСсылка = ирОбщий.ПеревестиСтроку("Ссылка");
	ЧислоВидимыхКолонок = 0; 
	ЗаголовокГруппыЧислоСтрок = "Число строк";
	Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803019 Тогда
		ПоляСхемы = ДинамическийСписок.Поля;
		ПоляСхемы.Очистить();
	КонецЕсли;
	Для Каждого ПолеСписка Из ПоляСписка Цикл
		#Если Сервер И Не Сервер Тогда
		    ПолеСписка = Новый РеквизитФормы;
		#КонецЕсли
		Если Ложь
			Или ПолеСписка.ТипЗначения.СодержитТип(Тип("Картинка"))
			Или ПолеСписка.ТипЗначения.СодержитТип(Тип("КомпоновщикНастроекКомпоновкиДанных"))
			Или ПолеСписка.ТипЗначения.СодержитТип(Тип("ПорядокКомпоновкиДанных"))
			Или ПолеСписка.ТипЗначения.СодержитТип(Тип("ОтборКомпоновкиДанных"))
			Или ПолеСписка.ТипЗначения.СодержитТип(Тип("ПоляГруппировкиКомпоновкиДанных"))
			Или ПолеСписка.ТипЗначения.СодержитТип(Тип("ЗначенияПараметровДанныхКомпоновкиДанных"))
			Или ПолеСписка.ТипЗначения.СодержитТип(Тип("УсловноеОформлениеКомпоновкиДанных"))
			Или СкрытыеПоля.Найти(ПолеСписка.Имя) <> Неопределено // Так ячейка данных не будет попадать в коллекцию строки
		Тогда
			Если Истина
				И ПолеСписка.ТипЗначения.СодержитТип(Тип("Картинка"))
				И Не ЗначениеЗаполнено(ОсновнойЭУ.ПутьКДаннымКартинкиСтроки) 
			Тогда
				// Антибаг платформы 8.3.20 Почему то свойство не заполнялось
				ОсновнойЭУ.ПутьКДаннымКартинкиСтроки = ПолеСписка.Путь + "." + ПолеСписка.Имя;
			КонецЕсли;
			Продолжить;
		КонецЕсли; 
		ИмяКолонки = ПолеСписка.Имя;
		Если ПоляСхемы <> Неопределено Тогда
			ПолеСхемы = ПоляСхемы.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
			ПолеСхемы.Поле = ИмяКолонки;
			ПолеСхемы.ПутьКДанным = ИмяКолонки;
		КонецЕсли;
		РастягиватьПоГоризонтали = Ложь;
		ШиринаКолонки = ирОбщий.ШиринаОписанияТиповЛкс(ПолеСписка.ТипЗначения, Ложь, РастягиватьПоГоризонтали);
		РодительПоляФормы = ОсновнойЭУ;
		ЗаголовокПоля = ""; // Для основных полей заполняется в отдельном методе
		Подсказка = ""; // Для основных полей заполняется в отдельном методе
		ЭтоПолезноеПоле = Истина;
		Для Каждого ОписаниеСоединения Из СоединенныеРегистры Цикл
			СоединенныйРегистр = ОписаниеСоединения.ПолноеИмя;
			ПсевдонимРегистра = ПсевдонимРегистраЛкс(СоединенныйРегистр);
			Если ИмяКолонки = ИмяПоляЧислоСтрок + "_" + ПсевдонимРегистра Тогда
				Если РежимИмяСиноним Тогда
					ЗаголовокПоля = ОписаниеСоединения.Имя;
				Иначе
					ЗаголовокПоля = ОписаниеСоединения.Представление;
				КонецЕсли;
				Если ПоляСхемы <> Неопределено Тогда
					ПолеСхемы.Заголовок = ЗаголовокПоля;
				КонецЕсли;
				Подсказка = ЗаголовокПоля;
				ЗаголовокПоля = РазбитьЗаголовокПоляТаблицыФормыЛкс(ЗаголовокПоля, ОсновнойЭУ, ШиринаКолонки);
				РодительПоляФормы = ДобавитьГруппуКолонокБД(ЗаголовокГруппыЧислоСтрок, ОсновнойЭУ, ИмяПоляЧислоСтрок, ЭтаФорма);
				Прервать;
			КонецЕсли;
			ПрефиксИмениПолей = ПсевдонимРегистра + "_"; 
			Если ирОбщий.СтрНачинаетсяСЛкс(ИмяКолонки, ПрефиксИмениПолей) Тогда
				ИмяПоляЗапросаБезТаблицы = Сред(ИмяКолонки, СтрДлина(ПрефиксИмениПолей) + 1);
				ИмяПоляТаблицы = ИмяПоляЗапросаБезТаблицы;
				МодификаторПоля = Неопределено;
				Если ирОбщий.СтрКончаетсяНаЛкс(ИмяПоляТаблицы, СуффиксПоляТипаЗначения) Тогда
					ИмяПоляТаблицы = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ИмяПоляТаблицы, СуффиксПоляТипаЗначения);
					МодификаторПоля = "тип"; 
				КонецЕсли;
				ПодчиненныйМД = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(СоединенныйРегистр);
				#Если Сервер И Не Сервер Тогда
					ПодчиненныйМД = Метаданные.РегистрыСведений.КурсыВалют;
				#КонецЕсли
				Если ПодчиненныйМД.Измерения.Найти(ИмяПоляТаблицы) <> Неопределено Тогда
					ЭтоПолезноеПоле = Ложь;
					Прервать;
				КонецЕсли;
				Если РежимИмяСиноним Тогда
					ЗаголовокРегистра = ПодчиненныйМД.Имя;
				Иначе
					ЗаголовокРегистра = ПодчиненныйМД.Представление();
				КонецЕсли;
				РодительПоляФормы = ДобавитьГруппуКолонокБД(ЗаголовокРегистра, ОсновнойЭУ, ПсевдонимРегистра, ЭтаФорма, СоединенныйРегистр);
				ПолеТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(СоединенныйРегистр).Найти(ИмяПоляТаблицы);
				Если ПолеТаблицыБД <> Неопределено Тогда
					ЗаголовокПоля = ЗаголовокПоляТаблицыБДДляФормыЛкс(ОсновнойЭУ, ПолеТаблицыБД, РежимИмяСиноним, Подсказка,, МодификаторПоля, ШиринаКолонки);
				Иначе
					ЗаголовокПоля = ИмяПоляЗапросаБезТаблицы;
				КонецЕсли;
				Прервать;
			КонецЕсли;
		КонецЦикла; 
		Если Не ЭтоПолезноеПоле Тогда
			Продолжить;
		КонецЕсли;
		ИмяПоля = ОсновнойЭУ.Имя + ИмяКолонки;
		КолонкаТП = КолонкиТП.Найти(ИмяПоля);
		Если КолонкаТП = Неопределено Тогда 
			Если Истина
				И Не ЗначениеЗаполнено(ЗаголовокПоля)
				И ирОбщий.СтрКончаетсяНаЛкс(ПолеСписка.Имя, СуффиксПоляТипаЗначения) 
			Тогда 
				ЗаголовокПоля = ЗаголовокПоляТаблицыБДДляФормыЛкс(ОсновнойЭУ, ПолеСписка, РежимИмяСиноним, Подсказка,,, ШиринаКолонки);
			КонецЕсли;
			СуществующийЭлемент = ЭтаФорма.Элементы.Найти(ИмяПоля);
			Если СуществующийЭлемент <> Неопределено Тогда
				// https://www.hostedredmine.com/issues/917823
				// Удалить или переименовать его нельзя
				ИмяПоля = "_" + ИмяПоля;
			КонецЕсли; 
			КолонкаТП = ЭтаФорма.Элементы.Добавить(ИмяПоля, Тип("ПолеФормы"), РодительПоляФормы);
			Если ирОбщий.ЛиОписаниеТиповБулевоЛкс(ПолеСписка.ТипЗначения) Тогда
				КолонкаТП.Вид = ВидПоляФормы.ПолеКартинки;
				КолонкаТП.КартинкаЗначений = ирКэш.КартинкаПоИмениЛкс("ирСостоянияФлажка");
			Иначе
				КолонкаТП.Вид = ВидПоляФормы.ПолеНадписи;
			КонецЕсли;
			КолонкаТП.Ширина = ШиринаКолонки;  
			КолонкаТП.РастягиватьПоГоризонтали = РастягиватьПоГоризонтали;
			//КолонкаТП.АвтоМаксимальнаяШирина = КолонкаТП.Ширина = 2;
			КолонкаТП.Заголовок = ЗаголовокПоля; 
			Если ЗначениеЗаполнено(Подсказка) Тогда
				КолонкаТП.Подсказка = Подсказка;
				ирОбщий.ДобавитьОписаниеТиповВПодсказкуШапкиКолонкиЛкс(КолонкаТП, ПолеСписка.ТипЗначения,,, ИмяКолонки);
			КонецЕсли;
			ПутьКДаннымПоля = ПутьКДаннымСписка + "." + ИмяКолонки;
			Попытка
				КолонкаТП.ПутьКДанным = ПутьКДаннымПоля;
			Исключение
				// Например при ИмяКолонки = "ВерсияДанных"
			КонецПопытки;  
			Если Ложь
				Или ПолеСписка.ТипЗначения.СодержитТип(Тип("Число")) 
				Или ПолеСписка.ТипЗначения.СодержитТип(Тип("Булево"))
			Тогда
				КолонкаТП.ГоризонтальноеПоложениеВПодвале = ГоризонтальноеПоложениеЭлемента.Право;
				Попытка
					КолонкаТП.ПутьКДаннымПодвала = "Итог" + выхСхемаПодвала.Количество();
					выхСхемаПодвала.Вставить(ИмяКолонки, КолонкаТП.ПутьКДаннымПодвала);
				Исключение
					Пустышка = 0; // Для отладки. Не хватило статических реквизитов "Итог<Индекс>"
				КонецПопытки; 
			КонецЕсли;
			Если ИмяКолонки = СловоСсылка Тогда
				КолонкаТП.Ширина = 2;
				ДинамическийСписок.УстановитьОбязательноеИспользование(СловоСсылка, Истина);
			КонецЕсли; 
		КонецЕсли;
		Если Ложь
			Или СкрытьПредопределенные И ИмяКолонки = "Предопределенный"
			Или СкрытьПредопределенные И ИмяКолонки = "ИмяПредопределенныхДанных"
			Или (Истина
				И ИменаВажныхКолонок.Найти(ИмяКолонки) = Неопределено
				И ЧислоВидимыхКолонок > ПредельноеЧислоВидимыхКолонок 
				И РодительПоляФормы.ПодчиненныеЭлементы.Количество() > 1 
				И РодительПоляФормы.Заголовок <> ЗаголовокГруппыЧислоСтрок)
		Тогда
			КолонкаТП.Видимость = Ложь; // Не нашел способа скрыть колонку, чтобы пользователь через "Изменить форму" смог ее включить
		КонецЕсли; 
		Если КолонкаТП.Видимость Тогда
			ЧислоВидимыхКолонок = ЧислоВидимыхКолонок + 1;
		КонецЕсли;
	КонецЦикла;
	//НовыйПорядок = ирОбщий.ВыражениеПорядкаКомпоновкиНаЯзыкеЗапросовЛкс(ДинамическийСписок.КомпоновщикНастроек.ПользовательскиеНастройки.Порядок);
	//Если Не ЗначениеЗаполнено(НовыйПорядок) Тогда
	//	// Обязательную установку делаем, чтобы в шапках появились индикаторы сортировки и чтобы он стал виден другим механизмам
	//	ирОбщий.СкопироватьПорядокЛюбойЛкс(ДинамическийСписок.КомпоновщикНастроек.ПользовательскиеНастройки.Порядок, ДинамическийСписок.Порядок);
	//КонецЕсли; 
	// Порядок по возрастанию важности
	Для Каждого ИмяВажнойКолонки Из ИменаВажныхКолонок Цикл
		ПолеФормы = ОсновнойЭУ.ПодчиненныеЭлементы.Найти(ОсновнойЭУ.Имя + ИмяВажнойКолонки);
		Если ПолеФормы <> Неопределено Тогда
			ЭтаФорма.Элементы.Переместить(ПолеФормы, ОсновнойЭУ, ОсновнойЭУ.ПодчиненныеЭлементы[0]);
		КонецЕсли; 
	КонецЦикла;
	// Порядок по убыванию важности
	ИменаНеважныхКолонок = Новый Массив;
	ИменаНеважныхКолонок.Добавить("ИдентификаторСсылкиЛкс");
	ИменаНеважныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("ВерсияДанных"));
	Если ирКэш.НомерВерсииПлатформыЛкс() > 803010 Тогда
		// Антибаг платформы. Для старых режимов совместимости, чтобы при быстром поиске на эти поля не накладывался отбор https://www.hostedredmine.com/issues/981422
		ДинамическийСписок.УстановитьОграниченияИспользованияВОтборе(ИменаНеважныхКолонок); 
	КонецЕсли;
	Если СкрытьПредопределенные Тогда
		ИменаНеважныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("Предопределенный"));
		ИменаНеважныхКолонок.Добавить(ирОбщий.ПеревестиСтроку("ИмяПредопределенныхДанных"));
	КонецЕсли;
	Для Каждого ИмяНеважнойКолонки Из ИменаНеважныхКолонок Цикл
		ПолеФормы = ОсновнойЭУ.ПодчиненныеЭлементы.Найти(ОсновнойЭУ.Имя + ИмяНеважнойКолонки);
		Если ПолеФормы <> Неопределено Тогда
			ЭтаФорма.Элементы.Переместить(ПолеФормы, ОсновнойЭУ);
		КонецЕсли; 
	КонецЦикла; 
	ПоляБезОбрезкиЗаголовков = Новый Массив;
	НастроитьСистемноеПолеФормыТипаБулевоЛкс(ОсновнойЭУ, ирОбщий.ПеревестиСтроку("Предопределенный"), ПоляБезОбрезкиЗаголовков);
	НастроитьСистемноеПолеФормыТипаБулевоЛкс(ОсновнойЭУ, ирОбщий.ПеревестиСтроку("ПометкаУдаления"), ПоляБезОбрезкиЗаголовков);
	НастроитьСистемноеПолеФормыТипаБулевоЛкс(ОсновнойЭУ, ирОбщий.ПеревестиСтроку("Проведен"), ПоляБезОбрезкиЗаголовков);
	НастроитьСистемноеПолеФормыТипаБулевоЛкс(ОсновнойЭУ, ирОбщий.ПеревестиСтроку("ЭтоГруппа"), ПоляБезОбрезкиЗаголовков);
	ОбновитьЗаголовкиАвтоТаблицыФормыДинамическогоСпискаЛкс(ОсновнойЭУ, ПолноеИмяТаблицыБД, РежимИмяСиноним, ПоляБезОбрезкиЗаголовков, ДинамическийСписок);
	ПостроительПорядка = ирОбщий.ОсновнойПорядокТаблицыБДЛкс(ПолноеИмяТаблицыБД, ирОбщий.ВыражениеПорядкаКомпоновкиНаЯзыкеЗапросовЛкс(ДинамическийСписок.Порядок));
	Если ЗначениеЗаполнено(ПостроительПорядка.Порядок) Тогда
		ирОбщий.СкопироватьПорядокЛюбойЛкс(ДинамическийСписок.Порядок, ПостроительПорядка.Порядок);
	КонецЕсли;
	Возврат Истина;
	
КонецФункции

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

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

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

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

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

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

Функция СуффиксПоляТипаЗначенияЛкс() Экспорт 
	
	Возврат "_ТипЗначения_";

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

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

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

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

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

Функция ТекстЗапросаДинамическогоСпискаЛкс(Знач ОбъектМД, Знач ПолноеИмяТаблицыБД, Знач СоединенныеРегистры, Знач ДинамическийСписок, СкрытыеПоля = Неопределено, ПсевдонимыТаблиц = Неопределено) Экспорт 
	
	Если СкрытыеПоля = Неопределено Тогда
		СкрытыеПоля = Новый Массив; 
	КонецЕсли;
	ОсновнойПсевдоним = "_Т";
	ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
	Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда
		ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД));
	КонецЕсли;
	ИсточникиДанных = Новый Соответствие;
	СуффиксПоляТипаЗначения = СуффиксПоляТипаЗначенияЛкс();
	ТекстИсточников = " ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ОсновнойПсевдоним;
	ИсточникиДанных.Вставить(ОсновнойПсевдоним, ПолноеИмяТаблицыБД);
	ИмяПоляЧислоСтрок = ирОбщий.ИмяПоляЧислоСтрокЛкс();
	ВыбранныеПоля = Новый Массив;
	Отборы = Новый Массив;
	Для Каждого ОписаниеСоединения Из СоединенныеРегистры Цикл
		СоединенныйРегистр = ОписаниеСоединения.ПолноеИмя;
		ПсевдонимРегистра = ПсевдонимРегистраЛкс(СоединенныйРегистр);
		ПодчиненныйМД = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(СоединенныйРегистр);
		//ПодчиненныйМД = Метаданные.НайтиПоПолномуИмени(ирОбщий.СтрСоединитьЛкс(ФрагментыИмени, "."));
		#Если Сервер И Не Сервер Тогда
			ПодчиненныйМД = Метаданные.РегистрыСведений.ABCКлассификацияПокупателей;
		#КонецЕсли
		ПодчиненныйИсточникДанных = СоединенныйРегистр;
		СоединяемыеПоля = Новый Массив;
		Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда
			Если ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ирОбщий.ТипТаблицыБДЛкс(СоединенныйРегистр)) Тогда 
				ИмяПоляРегистра = "Ссылка";
			Иначе
				ИмяПоляРегистра = "Регистратор";
			КонецЕсли;
			Если Истина
				И ИмяПоляРегистра = "Регистратор"
				И ПодчиненныйМД.Измерения.Количество() = 1
				И ПодчиненныйМД.Измерения[0].Тип.СодержитТип(ТипСсылки) 
			Тогда
				МетаИзмерение = ПодчиненныйМД.Измерения[0];
				ИмяПоляРегистра = МетаИзмерение.Имя;
				ПараметрыТаблицы = "";
				Если СтрЧислоВхождений(СоединенныйРегистр, ".") > 1 Тогда
					ПараметрыТаблицы = "(, {ВЫРАЗИТЬ(" + МетаИзмерение.Имя + " КАК " + ПолноеИмяТаблицыБД + ").* КАК Ссылка" + "})";
				КонецЕсли;
				ПодчиненныйИсточникДанных = СоединенныйРегистр + ПараметрыТаблицы;
			Иначе
				// Квалификаторы тут не установятся даже через ВЫРАЗИТЬ() https://www.hostedredmine.com/issues/931800
				ВыбранныеПоля.Добавить("ВЫРАЗИТЬ(ЕСТЬNULL(" + ПсевдонимРегистра + "._" + ИмяПоляЧислоСтрок + ", 0) КАК ЧИСЛО(10, 0)) КАК " + ИмяПоляЧислоСтрок + "_" + ПсевдонимРегистра);
				ПодчиненныйИсточникДанных = "(ВЫБРАТЬ _Регистр_." + ИмяПоляРегистра + ", КОЛИЧЕСТВО(*) КАК _" + ИмяПоляЧислоСтрок + "
				|	ИЗ " + СоединенныйРегистр + " КАК _Регистр_ СГРУППИРОВАТЬ ПО _Регистр_." + ИмяПоляРегистра + ")";
				СоединенныйРегистр = Неопределено;
			КонецЕсли;
			СоединяемыеПоля.Добавить(Символы.ПС + "И _Т.Ссылка = " + ПсевдонимРегистра + "." + ИмяПоляРегистра);
		Иначе
			Для Каждого МетаИзмерение Из ПодчиненныйМД.Измерения Цикл
				#Если Сервер И Не Сервер Тогда
					МетаИзмерение = ПодчиненныйМД.Измерения.Контрагент;
				#КонецЕсли
				СоединяемыеПоля.Добавить(Символы.ПС + "И _Т." + МетаИзмерение.Имя + " = " + ПсевдонимРегистра + "." + МетаИзмерение.Имя);
			КонецЦикла;
		КонецЕсли;
		ТекстИсточников = ТекстИсточников + "
		|{ЛЕВОЕ СОЕДИНЕНИЕ " + ПодчиненныйИсточникДанных + " КАК " + ПсевдонимРегистра + "
		|ПО ИСТИНА" + ирОбщий.СтрСоединитьЛкс(СоединяемыеПоля, "") + "}";
		Если СоединенныйРегистр <> Неопределено Тогда
			ИсточникиДанных.Вставить(ПсевдонимРегистра, СоединенныйРегистр);
		КонецЕсли;
	КонецЦикла;
	ИмяЛюбойКонстанты = "";
	ИмяСтроковойКонстанты = "";
	Если ТипТаблицы <> "Внешняя" Тогда
		Для Каждого МетаКонстанта Из Метаданные.Константы Цикл
			#Если Сервер И Не Сервер Тогда
				МетаКонстанта = Метаданные.Константы.АлгоритмПодписи;
			#КонецЕсли
			ОпцииВключены = Ложь;
			ирОбщий.ФункциональныеОпцииОбъектаМДЛкс(МетаКонстанта,,, ОпцииВключены);
			Если ОпцииВключены Тогда 
				Если Не ирОбщий.ЛиОписаниеТиповНеограниченнойДлиныЛкс(МетаКонстанта.Тип) Тогда
					ИмяЛюбойКонстанты = МетаКонстанта.Имя;
				КонецЕсли;
				Если МетаКонстанта.Тип.СодержитТип(Тип("Строка")) Тогда
					ИмяСтроковойКонстанты = МетаКонстанта.Имя;
				КонецЕсли;
				Если ЗначениеЗаполнено(ИмяЛюбойКонстанты) И ЗначениеЗаполнено(ИмяСтроковойКонстанты) Тогда
					Прервать;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
		Если ЗначениеЗаполнено(ИмяЛюбойКонстанты) Или ЗначениеЗаполнено(ИмяСтроковойКонстанты) Тогда
			ТекстИсточников = ТекстИсточников + "
			|{ЛЕВОЕ СОЕДИНЕНИЕ Константы КАК Константы ПО ЛОЖЬ}";
		КонецЕсли;
	КонецЕсли;
	ЗначениеНедоступногоПоля = ЗначениеНедоступногоПоляЛкс();
	ИмяПоляСсылка = "";
	ИмяПоляВерсияДанных = "";
	ИмяПоляИмяПредопределенныхДанных = ""; 
	ИмяПоляПометкаУдаления = ""; 
	ИмяПоляВладелец = "";
	Если ирОбщий.ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД) Тогда
		ВыбранныеПоля.Добавить("0 КАК ИдентификаторСсылкиЛкс"); // ИдентификаторСсылкиЛкс сделан числом, чтобы на него не накладывался отбор поиска
		ИмяПоляСсылка = ирОбщий.ПеревестиСтроку("Ссылка");
		ИмяПоляВерсияДанных = ирОбщий.ПеревестиСтроку("ВерсияДанных");
		ИмяПоляИмяПредопределенныхДанных = ирОбщий.ПеревестиСтроку("ИмяПредопределенныхДанных");
		ИмяПоляПометкаУдаления = ирОбщий.ПеревестиСтроку("ПометкаУдаления");
		ИмяПоляВладелец = ирОбщий.ПеревестиСтроку("Владелец");
	КонецЕсли;
	Для Каждого КлючИЗначение Из ИсточникиДанных Цикл
		ЭтоОсновнаяТаблицаБД = КлючИЗначение.Ключ = ОсновнойПсевдоним;
		ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(КлючИЗначение.Значение);
		ОбъектМДСоединяемый = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(КлючИЗначение.Значение);
		ЛиМетаданныеВнешнегоИсточника = ирОбщий.ЛиМетаданныеВнешнегоИсточникаДанныхЛкс(ОбъектМДСоединяемый);
		КомпоновщикТаблицы = ирОбщий.КомпоновщикТаблицыМетаданныхЛкс(КлючИЗначение.Значение);
		#Если Сервер И Не Сервер Тогда
			ОбъектМДСоединяемый = Метаданные.Справочники.Валюты;
			КомпоновщикТаблицы = Новый КомпоновщикНастроекКомпоновкиДанных;
		#КонецЕсли
		ДоступныеПоляКомпоновки = КомпоновщикТаблицы.Настройки.ДоступныеПоляВыбора;
		ПутьКПолю = КлючИЗначение.Ключ + ".";
		#Если Сервер И Не Сервер Тогда
			ОбъектМДСоединяемый = Метаданные.РегистрыСведений.КурсыВалют;
		#КонецЕсли
		Для Каждого ПолеТаблицы Из ПоляТаблицыБД Цикл
			Если Истина
				И Не ЭтоОсновнаяТаблицаБД
				И ОбъектМДСоединяемый.Измерения.Найти(ПолеТаблицы.Имя) <> Неопределено
			Тогда
				Продолжить;
			КонецЕсли; 
			Если Ложь
				Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) 
				//Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) 
			Тогда 
				Продолжить;
			КонецЕсли;
			ПсевдонимПоля = ПолеТаблицы.Имя; 
			Если Не ЭтоОсновнаяТаблицаБД Тогда
				ПсевдонимПоля = КлючИЗначение.Ключ + "_" + ПсевдонимПоля;
			КонецЕсли;
			ТипЗначенияБезNull = Новый ОписаниеТипов(ПолеТаблицы.ТипЗначения,, "Null");
			ВыражениеПоля = ПутьКПолю + ПолеТаблицы.Имя;
			Если ирОбщий.ЛиОписаниеТиповНеограниченнойСтрокиЛкс(ТипЗначенияБезNull) Тогда
				Отборы.Добавить(ВыражениеПоля + " КАК " + ПсевдонимПоля);
				ВыражениеПоля = "ПОДСТРОКА(" + ВыражениеПоля + ирОбщий.ОкончаниеВыраженияПодстрокиДинСпискаЛкс();
			КонецЕсли;
			ЛиПолеВидимоПользователю = ДоступныеПоляКомпоновки.НайтиПоле(Новый ПолеКомпоновкиДанных(ПолеТаблицы.Имя)) <> Неопределено;
			Если ТипТаблицы = "ДвиженияССубконто" Тогда
				// Чтобы тип NULL был виден
				ВыражениеПоля = "ВЫБОР КОГДА ЛОЖЬ ТОГДА """" // Обходим недоступность типа Null в компоновке
				|	ИНАЧЕ " + ВыражениеПоля + " КОНЕЦ";  
			КонецЕсли;
			ОбъектМДТипа = Метаданные.НайтиПоТипу(ТипЗначенияБезNull.Типы()[0]);
			Если Истина
				И Не ЛиПолеВидимоПользователю 
				// Для этих полей недоступно приведение типа
				И ПолеТаблицы.Имя <> ИмяПоляВерсияДанных
				И ПолеТаблицы.Имя <> ИмяПоляИмяПредопределенныхДанных
				// На эти поля не действуют функциональные опции. Поэтому даже если они в доступных полях отсутствуют, реквизит формы будет создан
				И ПолеТаблицы.Имя <> ИмяПоляСсылка
				И ПолеТаблицы.Имя <> ИмяПоляПометкаУдаления
				И ПолеТаблицы.Имя <> ИмяПоляВладелец
				И Не ирОбщий.ЛиМетаданныеВнешнегоИсточникаДанныхЛкс(ОбъектМДТипа) // Иначе будет ошибка "Несовместимые типы" https://www.hostedredmine.com/issues/1004460
			Тогда 
				ИмяКонстантыПодмены = "";
				Если ирОбщий.ЛиОписаниеТиповНеограниченнойСтрокиЛкс(ТипЗначенияБезNull) Тогда
					Если ЗначениеЗаполнено(ИмяСтроковойКонстанты) Тогда
						ИмяКонстантыПодмены = ИмяСтроковойКонстанты;
					КонецЕсли;
				Иначе
					Если ЗначениеЗаполнено(ИмяЛюбойКонстанты) Тогда
						ИмяКонстантыПодмены = ИмяЛюбойКонстанты;
					КонецЕсли;
				КонецЕсли;
				Если ЗначениеЗаполнено(ИмяКонстантыПодмены) Тогда
					ВыражениеОбъединения = "ВЫБОР КОГДА ЛОЖЬ ТОГДА Константы." + ИмяКонстантыПодмены + " ИНАЧЕ " + ВыражениеПоля + " КОНЕЦ";
					ВыражениеСТипом = ирОбщий.ВыражениеПриведенияТипаНаЯзыкеЗапросовЛкс(ТипЗначенияБезNull.Типы()[0], ТипЗначенияБезNull, ВыражениеОбъединения);
					ВыражениеПоля = "ВЫБОР КОГДА ЛОЖЬ ТОГДА " + ВыражениеСТипом + " // Обходим недоступность поля в компоновке, сохраняя тип
					|	ИНАЧЕ " + ВыражениеПоля + " КОНЕЦ";  
				Иначе
					ВыражениеПоля = """" + ЗначениеНедоступногоПоля + """";
				КонецЕсли;
			КонецЕсли;
			Если ЛиМетаданныеВнешнегоИсточника И ПолеТаблицы.Метаданные <> Неопределено Тогда
				МетаданныеПоля = ПолеТаблицы.Метаданные;
				// Антибаг платформы 8.3.18 теряются значения NULL https://www.hostedredmine.com/issues/925439
				#Если Сервер И Не Сервер Тогда
					МетаданныеПоля = Метаданные.ВнешниеИсточникиДанных.Tropic.Таблицы.dbo_Dorem.Поля.Posted;
				#КонецЕсли
				Если МетаданныеПоля.РазрешитьNULL Тогда
					ИмяСкрытогоПоля = ПолеТаблицы.Имя + "_ЭтоNULL_";
					СкрытыеПоля.Добавить(ИмяСкрытогоПоля);
					ВыбранныеПоля.Добавить(ВыражениеПоля + " ЕСТЬ NULL КАК " + ИмяСкрытогоПоля);
					Если ДинамическийСписок <> Неопределено Тогда
						ДинамическийСписок.УстановитьОбязательноеИспользование(ИмяСкрытогоПоля, Истина);
					КонецЕсли;
				КонецЕсли;
			КонецЕсли; 
			Если Истина
				И ТипЗначенияБезNull.Типы().Количество() > 1 
				И НЕ (Истина
					// Антибаг платформы http://www.hostedredmine.com/issues/882688, http://www.hostedredmine.com/issues/882690
					И ПолеТаблицы.Имя = "ВедущаяЗадача"
					И ирОбщий.ЛиКорневойТипБизнесПроцессаЛкс(ТипТаблицы)
					И Метаданные.Задачи.Количество() > 1)
			Тогда
				ВыбранныеПоля.Добавить("ТИПЗНАЧЕНИЯ(" + ВыражениеПоля + ") КАК " + ПсевдонимПоля + СуффиксПоляТипаЗначения);
			КонецЕсли;
			Если Истина
				И ЭтоОсновнаяТаблицаБД
				И ПолеТаблицы.РежимПароля 
				И ТипЗначенияБезNull.СодержитТип(Тип("Строка"))
				И ТипЗначенияБезNull.КвалификаторыСтроки.Длина > 0
				И ирКэш.НомерВерсииПлатформыЛкс() >= 803010 // Иначе мы не сможем маскировать текст при выводе
			Тогда
				ВыражениеПоля = """""+" + ВыражениеПоля; // Запароленные поля по умолчанию игнорируются
			КонецЕсли; 
			ВыбранныеПоля.Добавить(ВыражениеПоля + " КАК " + ПсевдонимПоля);
		КонецЦикла;
	КонецЦикла;
	Разделитель = ", " + Символы.ПС;
	ВыбранныеПоля = ирОбщий.СтрСоединитьЛкс(ВыбранныеПоля, Разделитель);
	ТекстЗапроса = "ВЫБРАТЬ
	|	" + ВыбранныеПоля + "
	|" + ТекстИсточников;
	Если Отборы.Количество() > 0 Тогда
		ТекстЗапроса = ТекстЗапроса + "
		|{ГДЕ 
		|	" + ирОбщий.СтрСоединитьЛкс(Отборы, Символы.ПС + Символы.Таб + ",") + "
		|}";
	КонецЕсли;
	Возврат ТекстЗапроса;

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

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

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

Функция ЗначениеНедоступногоПоляЛкс() Экспорт 
	
	Возврат "<Недоступно из-за отсутствия константы типа Строка(1+)>";

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

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

// Процедура - Управляемая форма обновить служебные данные лкс
//
// Параметры:
//  ЭтаФорма				 - УправляемаяФорма - 
//  ПоляДляЗапоминанияТипов	 - Массив из ПолеФормы - 
//  ПоляСИсториейВыбора		 - Массив из РасширениеПоляФормыДляПоляВвода - 
//  ДинамическиеСписки		 - Структура - для ускорения; ключ - имя таблицы формы, значение - исполняемые настройки
//
Процедура УправляемаяФорма_ОбновитьСлужебныеДанныеЛкс(Знач ЭтаФорма, Знач ПоляДляЗапоминанияТипов = Неопределено, Знач ПоляСИсториейВыбора = Неопределено, Знач ДинамическиеСписки = Неопределено) Экспорт 
	
	СтруктураПутиКДанным = Новый Структура();
	ЗаполнитьСоответствиеПутиКДаннымПодчиненныхЭлементовФормыЛкс(ЭтаФорма, СтруктураПутиКДанным,, ДинамическиеСписки);
	ФиксированнаяСтруктураПутиКДанным = Новый ФиксированнаяСтруктура(СтруктураПутиКДанным);
	
	СтруктураТипыЗначений = Новый Структура;
	МассивПолей = Новый Массив();
	Если ПоляДляЗапоминанияТипов <> Неопределено Тогда
		Если ТипЗнч(ПоляДляЗапоминанияТипов) = Тип("Массив") Тогда
			ирОбщий.СкопироватьКоллекциюЛкс(ПоляДляЗапоминанияТипов, МассивПолей);
		Иначе
			МассивПолей.Добавить(ПоляДляЗапоминанияТипов);
		КонецЕсли;
	КонецЕсли; 
	Если ПоляСИсториейВыбора <> Неопределено Тогда
		Если ТипЗнч(ПоляСИсториейВыбора) = Тип("Массив") Тогда
			ирОбщий.СкопироватьКоллекциюЛкс(ПоляСИсториейВыбора, МассивПолей);
		Иначе
			МассивПолей.Добавить(ПоляСИсториейВыбора);
		КонецЕсли;
	КонецЕсли;
	ПоляДляЗапоминанияТипов = МассивПолей;
	Для Каждого Поле Из ПоляДляЗапоминанияТипов Цикл
		СтруктураТипыЗначений.Вставить(Поле.Имя, ПолучитьТипЗначенияПоляФормыЛкс(Поле, ЭтаФорма));
	КонецЦикла;
	
	КорневыеРеквизиты = ЭтаФорма.ПолучитьРеквизиты();
	СтруктураСохраняемыеДанные = Новый Структура();
	ДинамическиеСписки = Новый Структура();
	Для Каждого КорневойРеквизит Из КорневыеРеквизиты Цикл
		Если КорневойРеквизит.СохраняемыеДанные Тогда
			СтруктураСохраняемыеДанные.Вставить(КорневойРеквизит.Имя);
		КонецЕсли; 
		Если КорневойРеквизит.ТипЗначения.СодержитТип(Тип("ДинамическийСписок")) Тогда
			Если ирОбщий.ЭтоУпрДинамическийСписокИРЛкс(ЭтаФорма) Тогда
				ОсновнаяТаблица = ЭтаФорма.фОбъект.ПолноеИмяТаблицы; // Имя таблицы ТЧ не может помещаться в свойство дин. списка
			Иначе
				ОсновнаяТаблица = ЭтаФорма[КорневойРеквизит.Имя].ОсновнаяТаблица;
			КонецЕсли;
			ОписаниеСписка = Новый Структура;
			ОписаниеСписка.Вставить("ОсновнаяТаблица", ОсновнаяТаблица);
			ОписаниеСписка.Вставить("ТекстЗапроса", ЭтаФорма[КорневойРеквизит.Имя].ТекстЗапроса);
			ДинамическиеСписки.Вставить(КорневойРеквизит.Имя, ОписаниеСписка);
		КонецЕсли; 
	КонецЦикла; 
	СтруктураСохраняемыеДанные = Новый ФиксированнаяСтруктура(СтруктураСохраняемыеДанные);
	ДинамическиеСписки = Новый ФиксированнаяСтруктура(ДинамическиеСписки);
	Попытка
		НеготовыеСтраницы = ЭтаФорма.мСлужебныеДанные.НеготовыеСтраницы;
	Исключение
		НеготовыеСтраницы = Новый СписокЗначений;
	КонецПопытки;
	Попытка
		ДатаОткрытия = ЭтаФорма.мСлужебныеДанные.ДатаОткрытия;
	Исключение
		ДатаОткрытия = Неопределено;
	КонецПопытки;
	Попытка
		Задания = ЭтаФорма.мСлужебныеДанные.Задания;
	Исключение
		Задания = Новый Массив;
	КонецПопытки;
	Попытка
		ОригинальныйЗаголовок = ЭтаФорма.мСлужебныеДанные.ОригинальныйЗаголовок;
	Исключение
		ОригинальныйЗаголовок = ЭтаФорма.Заголовок;
	КонецПопытки;
	Для Каждого Элемент Из ЭтаФорма.Элементы Цикл
		//Если Истина
		//	И ТипЗнч(Элемент) = Тип("ГруппаФормы") 
		//	И Элемент.Вид = ВидГруппыФормы.Страница
		//	И Найти(Элемент.Имя, "Страница") = 1
		//Тогда
		//	НеготовыеСтраницы.Добавить(Элемент.Имя);
		//КонецЕсли; 
		Если Истина
			И ТипЗнч(Элемент) = Тип("ПолеФормы")
			И Не Элемент.ТолькоПросмотр
			И Элемент.Доступность
		Тогда
			ТипЗначения = ПолучитьТипЗначенияПоляФормыЛкс(Элемент, ЭтаФорма);
			#Если Сервер И Не Сервер Тогда
			    ТипЗначения = Новый ОписаниеТипов;
			#КонецЕсли
			Если ТипЗначения <> Неопределено Тогда
				Типы = ТипЗначения.Типы();
				Если Ложь
					Или Типы.Количество() > 1
					Или Типы.Количество() = 0
				Тогда
					СтруктураТипыЗначений.Вставить(Элемент.Имя, ТипЗначения);
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли;  
		Если Истина
			И ТипЗнч(Элемент) = Тип("ТаблицаФормы")
		Тогда
			ТипЗначения = ПолучитьТипЗначенияПоляФормыЛкс(Элемент, ЭтаФорма);
			#Если Сервер И Не Сервер Тогда
				ТипЗначения = Новый ОписаниеТипов;
			#КонецЕсли
			СтруктураТипыЗначений.Вставить(Элемент.Имя, ТипЗначения);
		КонецЕсли;  
	КонецЦикла;
	ФиксированнаяСтруктураТипыЗначений = Новый ФиксированнаяСтруктура(СтруктураТипыЗначений);
	
	СлужебныеДанные = Новый Структура();
	СлужебныеДанные.Вставить("Тип", ТипЗнч(ЭтаФорма));
	СлужебныеДанные.Вставить("ПутиКДанным", ФиксированнаяСтруктураПутиКДанным);
	СлужебныеДанные.Вставить("СохраняемыеДанные", СтруктураСохраняемыеДанные);
	СлужебныеДанные.Вставить("ТипыЗначений", ФиксированнаяСтруктураТипыЗначений);
	СлужебныеДанные.Вставить("ДинамическиеСписки", ДинамическиеСписки);
	// Мультиметка55835453
	СлужебныеДанные.Вставить("НеготовыеСтраницы", НеготовыеСтраницы);
	СлужебныеДанные.Вставить("Задания", Задания);
	СлужебныеДанные.Вставить("ОригинальныйЗаголовок", ОригинальныйЗаголовок);
	СлужебныеДанные.Вставить("ДатаОткрытия", ДатаОткрытия);
	ЭтаФорма.мСлужебныеДанные = СлужебныеДанные;
	Возврат;
	
	// Очень долго на формах с больших количеством реквизитов
	// Преобразуем автозаголовки в статические заголовки для возможности поиска https://partners.v8.1c.ru/forum/topic/1074579
	СоответствиеРеквизитов = СоответствиеРеквизитовФормы(ЭтаФорма);
	Для Каждого ЭлементФормы Из ЭтаФорма.Элементы Цикл
		СтруктураСвойств = Новый Структура("ПутьКДанным, Заголовок");
		ЗаполнитьЗначенияСвойств(СтруктураСвойств, ЭлементФормы); 
		Если Истина
			И ЗначениеЗаполнено(СтруктураСвойств.ПутьКДанным) 
			И Не ЗначениеЗаполнено(СтруктураСвойств.Заголовок) 
		Тогда
			ЭлементФормы.Заголовок = СоответствиеРеквизитов[ЭлементФормы.ПутьКДанным].Заголовок;
		КонецЕсли; 
		Если Истина
			И Типзнч(ЭлементФормы) = Тип("КнопкаФормы")
			И ЗначениеЗаполнено(ЭлементФормы.ИмяКоманды) 
			И Не ЗначениеЗаполнено(ЭлементФормы.Заголовок) 
		Тогда
			КомандаФормы = ЭтаФорма.Команды.Найти(ЭлементФормы.Имя);
			Если КомандаФормы <> Неопределено Тогда
				ЭлементФормы.Заголовок = КомандаФормы.Заголовок;
			КонецЕсли; 
		КонецЕсли; 
	КонецЦикла;
	
КонецПроцедуры

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

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

//  Заполнить соответствие пути к данным подчиненных элементов формы
//
// Параметры:
//	НачальныйЭлемент - <тип> - 
//	СтруктураПутиКДанным - <тип> - 
//
Процедура ЗаполнитьСоответствиеПутиКДаннымПодчиненныхЭлементовФормыЛкс(НачальныйЭлемент, СтруктураПутиКДанным, Знач ЭтаФорма = Неопределено, Знач ДинамическиеСписки = Неопределено) Экспорт

	Если ТипЗнч(НачальныйЭлемент) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
		ЭтаФорма = НачальныйЭлемент;
	КонецЕсли; 
	Для Каждого Поле Из НачальныйЭлемент.ПодчиненныеЭлементы Цикл
		Если ТипЗнч(Поле) = Тип("ПолеФормы") Тогда 
			Если Поле.ПутьКДанным <> "" Тогда
				ТаблицаФормы = ирОбщий.РодительЭлементаУправляемойФормыЛкс(Поле, Тип("ТаблицаФормы"));
				Если ТаблицаФормы <> Неопределено Тогда
					СтруктураПутиКДанным.Вставить(Поле.Имя, "Элементы." + ТаблицаФормы.Имя + ".ТекущиеДанные." + ирОбщий.ПоследнийФрагментЛкс(Поле.ПутьКДанным));
				Иначе
					СтруктураПутиКДанным.Вставить(Поле.Имя, Поле.ПутьКДанным);
				КонецЕсли; 
			КонецЕсли; 
		ИначеЕсли ТипЗнч(Поле) = Тип("ТаблицаФормы") Тогда
			ТаблицаФормы = Поле;
			Если ТаблицаФормы.ПутьКДанным <> "" Тогда
				СтруктураПутиКДанным.Вставить(ТаблицаФормы.Имя, ТаблицаФормы.ПутьКДанным);
				ТипЗначения = ПолучитьТипЗначенияПоляФормыЛкс(ТаблицаФормы, ЭтаФорма);
				// Антибаг платформы http://www.hostedredmine.com/issues/850204
				Если Истина
					И ТипЗначения <> Неопределено
					И ТипЗначения.СодержитТип(Тип("ДинамическийСписок")) 
				Тогда
					//! ТаблицаФормы=0; // РасширениеТаблицыФормыДляДинамическогоСписка
					НастройкаКомпоновки = Неопределено;
					Если ДинамическиеСписки <> Неопределено Тогда 
						ДинамическиеСписки.Свойство(ТаблицаФормы.Имя, НастройкаКомпоновки);
					КонецЕсли;
					Если НастройкаКомпоновки = Неопределено Тогда
						НастройкаКомпоновки = ТаблицаФормы.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
					КонецЕсли;
					#Если Сервер И Не Сервер Тогда
						НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
					#КонецЕсли
					Для Каждого ВыбранноеПоле Из НастройкаКомпоновки.Структура[0].Выбор.Элементы Цикл
						ИмяПоляКомпоновки = "" + ВыбранноеПоле.Поле;
						ИмяПоля = ТаблицаФормы.Имя + СтрЗаменить(ИмяПоляКомпоновки, ".", "_");
						Если ТаблицаФормы.ПодчиненныеЭлементы.Найти(ИмяПоля) = Неопределено Тогда
							ИмяПоля = ирОбщий.АвтоУникальноеИмяВКоллекцииЛкс(СтруктураПутиКДанным, ИмяПоля,,,, 0);
							СтруктураПутиКДанным.Вставить(ИмяПоля, "Элементы." + ТаблицаФормы.Имя + ".ТекущиеДанные." + ИмяПоляКомпоновки);
						КонецЕсли; 
					КонецЦикла;
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
		Если Ложь
			Или ТипЗнч(Поле) = Тип("ГруппаФормы") 
			Или ТипЗнч(Поле) = Тип("ТаблицаФормы")
		Тогда
			ЗаполнитьСоответствиеПутиКДаннымПодчиненныхЭлементовФормыЛкс(Поле, СтруктураПутиКДанным, ЭтаФорма, ДинамическиеСписки);
		КонецЕсли; 
	КонецЦикла;

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

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

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

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

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

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

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

#Если Сервер И Не Сервер Тогда
	ирПортативный = Обработки.ирПортативный.Создать();
#КонецЕсли
