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

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

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

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

// СтандартныеПодсистемы.ВариантыОтчетов

// Параметры:
//   Настройки - см. ВариантыОтчетовПереопределяемый.НастроитьВариантыОтчетов.Настройки.
//   НастройкиОтчета - см. ВариантыОтчетов.ОписаниеОтчета.
//
Процедура НастроитьВариантыОтчета(Настройки, НастройкиОтчета) Экспорт
	
	НастройкиОтчета.ОпределитьНастройкиФормы = Истина;

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

// Конец СтандартныеПодсистемы.ВариантыОтчетов

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ДобавитьИтогиКоличестваПодчиненныхЗаписей(СхемаКомпоновкиДанных)
	
	ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить();
	ВычисляемоеПоле.ПутьКДанным = "КоличествоПодчиненныхЗаписей";
	ВычисляемоеПоле.Заголовок = НСтр("ru = 'Количество записей'");
	ВычисляемоеПоле.Выражение = "1";
	ВычисляемоеПоле.ТипЗначения = Новый ОписаниеТипов("Число");
	
	ОформлениеПоля = ВычисляемоеПоле.Оформление.Элементы;
	ИдентификаторыПараметров = СтрРазделить("МинимальнаяШирина, МаксимальнаяШирина", ", ", Ложь);
	
	Для Каждого Идентификатор Из ИдентификаторыПараметров Цикл 
		Параметр = ОформлениеПоля.Найти(Идентификатор);
		Параметр.Значение = 12;
		Параметр.Использование = Истина;
	КонецЦикла;
	
	ДобавитьПолеИтога(СхемаКомпоновкиДанных, "КоличествоПодчиненныхЗаписей");
	
КонецПроцедуры

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

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

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

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

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

#Область РаботаСТиповойСхемойНастраиваемойВПользовательскихНастройках

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

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

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

#Область РаботаСПроизвольнойСхемойИзФайла

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

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

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

#Область РаботаСИсточникомДанныхВариантаОтчета

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

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

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

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

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

#Область СтандартныйЗаголовок

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

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

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

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

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

#Область КоличествоПодчиненныхЗаписейВГруппировках

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

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

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

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

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

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

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

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

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

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

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

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

Функция ПредставлениеИмениТаблицыОсновныеДанные()
	
	Возврат НСтр("ru = 'Основные данные'");
	
КонецФункции

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

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

#КонецЕсли