Документы по партнеру и сделке / Модуль объекта

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

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

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

	ДеревоДокументов = Новый ДеревоЗначений;
	ДеревоДокументов.Колонки.Добавить("Документ");
	ДеревоДокументов.Колонки.Добавить("СтруктураДанных");
	ДеревоДокументов.Колонки.Добавить("ТабличнаяЧасть");
	ДеревоДокументов.Колонки.Добавить("ТекстУсловия");

	Для Каждого ЭлементСостава Из Метаданные.КритерииОтбора[ИмяКритерияОтбора].Состав Цикл

		СтруктураДанных = СтруктураДанных(ЭлементСостава.ПолноеИмя());

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

		КореньДокумента = ДеревоДокументов.Строки.Найти(СтруктураДанных.Метаданные, "Документ", Ложь);
		Если КореньДокумента = Неопределено Тогда

			КореньДокумента = ДеревоДокументов.Строки.Добавить();
			КореньДокумента.Документ = СтруктураДанных.Метаданные;

		КонецЕсли;

		СтрокаШапкаТЧ = КореньДокумента.Строки.Найти(СтруктураДанных.ИмяТаблЧасти, "ТабличнаяЧасть", Ложь);
		Если СтрокаШапкаТЧ = Неопределено Тогда

			СтрокаШапкаТЧ = КореньДокумента.Строки.Добавить();
			СтрокаШапкаТЧ.ТабличнаяЧасть = СтруктураДанных.ИмяТаблЧасти;

		КонецЕсли;

		СтрокаДанных = СтрокаШапкаТЧ.Строки.Добавить();
		СтрокаДанных.СтруктураДанных = СтруктураДанных;

	КонецЦикла;

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

	Для Каждого СтрокаКорня Из ДеревоДокументов.Строки Цикл

		ТекстУсловийПоДокументу = "";
		// Цикл по реквизитам и табличным частям одного документа
		Для Каждого СтрокаРеквизитТЧ Из СтрокаКорня.Строки Цикл

			ТекстУсловия = "";
			// Условие на поле в ТЧ.
			Если Не ПустаяСтрока(СтрокаРеквизитТЧ.ТабличнаяЧасть) Тогда

				ВремТекст = "";
				// Цикл по табличным частям
				Для Каждого СтрокаТЧ Из СтрокаРеквизитТЧ.Строки Цикл

					ВремТекст = ВремТекст + ?(ПустаяСтрока(ВремТекст),"", " ИЛИ ")
						+ СтрЗаменить(ШаблонУсловияДляТЧ, "%ПолеПараметрТЧ%", СтрокаТЧ.СтруктураДанных.ИмяРеквизита);

				КонецЦикла;

				ТекстУсловия = СтрЗаменить(ШаблонУсловияТЧ, "%ИмяТаблицыТЧ%", СтрокаКорня.Документ["Имя"] + "." + СтрокаРеквизитТЧ.ТабличнаяЧасть);
				ТекстУсловия = СтрЗаменить(ТекстУсловия, "%УсловиеНаСтрокиТЧ%", ВремТекст);

			Иначе // Условие по шапке

				// Цикл по реквизитам
				Для Каждого СтрокаТЧ Из СтрокаРеквизитТЧ.Строки Цикл

					ТекстУсловия = ТекстУсловия + ?(ПустаяСтрока(ТекстУсловия),"", " ИЛИ ")
						+ СтрЗаменить(ШаблонУсловияШапки, "%ПолеПараметрШапки%", СтрокаТЧ.СтруктураДанных.ИмяРеквизита);

				КонецЦикла;

			КонецЕсли;
			
			Если ТолькоАктуальные Тогда
				
				Если СтрокаКорня.Документ.Имя = "ЗаказКлиента" Тогда
					ВремТекстУсловия = СтрЗаменить(ШаблонУсловияТЧ, "%ИмяТаблицыТЧ%", "ЗаказКлиента.Товары");
					ВремТекстУсловия = СтрЗаменить(ВремТекстУсловия, "%УсловиеНаСтрокиТЧ%", ("НЕ ТаблицаСтрок.Отменено"));
					ТекстУсловия = ТекстУсловия + ?(ПустаяСтрока(ТекстУсловия),"", " И ") + ВремТекстУсловия;
				Иначе
					
					CRMЛокализация.ДополнитьУсловиеЗапросаПоАктуальностиДокумента(СтрокаКорня.Документ.Имя, ТекстУсловия);
					
				КонецЕсли;
			КонецЕсли;
			
			Если Не ПустаяСтрока(ТекстУсловия) Тогда
				
				ДобавитьТекстВСтроку(ТекстУсловийПоДокументу, ТекстУсловия, " ИЛИ ");
				
			КонецЕсли;
		КонецЦикла;

		Если Не ПустаяСтрока(ТекстУсловийПоДокументу) Тогда

			ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "&ИмяТаблицыШапки", "Документ." + СтрокаКорня.Документ.Имя);
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ТекстУсловия", ТекстУсловийПоДокументу);
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "%ПутьКТаблицеРеквизита%", "ТаблицаШапки");
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "%УсловиеНаСсылкуВТЧ%", " ТаблицаШапки.Ссылка");

			ДобавитьДополнительныеПоляШапки(ТекстЗапроса,СтрокаКорня.Документ, ДопПоляШапки);
			ДобавитьЗапросВТаблицу(ТаблицаЗапросов, СтрокаКорня.Документ, ТекстЗапроса);

			СтрокаКорня.ТекстУсловия = ТекстУсловийПоДокументу;

		КонецЕсли;
	КонецЦикла;

	// В запрос добавляются документы, которые в критерий не входят, но имеют ссылку
	// на документ, который входит в критерий по реквизиту шапки.

	ШаблонУсловияСтрокиТЧ = 
	"1 В
	|	(ВЫБРАТЬ
	|		1
	|	ИЗ
	|		Документ.%ИмяДокумента% КАК ТабличнаяЧасть%ИмяТабЧасти%
	|	ГДЕ
	|		ТабличнаяЧасть%ИмяТабЧасти%.Ссылка = ТаблицаШапки.Ссылка
	|		И (&ТекстУсловия)
	|)";
	МассивУсловий      = Новый Массив;
	СоответствиеПолей  = Новый Соответствие;

	Для Каждого Документ Из ДопДокументы Цикл
		Если Не ПравоДоступа("Чтение", Документ) Тогда
			Продолжить;
		КонецЕсли;

		МассивУсловий.Очистить();
		СоответствиеПолей.Очистить();

		Для Каждого Реквизит Из Документ.Реквизиты Цикл
			Для Каждого СтрокаДерева Из ДеревоДокументов.Строки Цикл

				// Проверка, что документ-основание содержит нужную ссылку только в шапке.
				Если Не РеквизитСодержитТип(Реквизит, "ДокументСсылка." + СтрокаДерева.Документ["Имя"])
				 Или Не РеквизитТолькоВШапке(СтрокаДерева) Тогда
					Продолжить;
				КонецЕсли;

				МассивСтруктур = СоответствиеПолей.Получить(Реквизит);
				Если МассивСтруктур = Неопределено Тогда

					МассивСтруктур = Новый Массив;
					СоответствиеПолей.Вставить(Реквизит, МассивСтруктур);

				КонецЕсли;

				МассивСтруктур.Добавить(Новый Структура("Документ, ТекстУсловия",
												СтрокаДерева.Документ,
												СтрокаДерева.ТекстУсловия));
			КонецЦикла;
		КонецЦикла;

		Для Каждого КлючИЗначение Из СоответствиеПолей Цикл
			Для Каждого ЭлементСтруктура Из КлючИЗначение.Значение Цикл

				Если РеквизитСоставной(КлючИЗначение.Ключ) Тогда
					ПутьКТаблицеРеквизита = "ВЫРАЗИТЬ(ТаблицаШапки." + КлючИЗначение.Ключ["Имя"] +" КАК Документ." + ЭлементСтруктура.Документ["Имя"] + ")";
				Иначе
					ПутьКТаблицеРеквизита = "ТаблицаШапки." + КлючИЗначение.Ключ.Имя;
				КонецЕсли;

				ВремТекст = ЭлементСтруктура.ТекстУсловия;
				ВремТекст = СтрЗаменить(ВремТекст, "%ПутьКТаблицеРеквизита%", ПутьКТаблицеРеквизита);
				ВремТекст = СтрЗаменить(ВремТекст, "%ПолеПараметр%", КлючИЗначение.Ключ.Имя);
				ВремТекст = СтрЗаменить(ВремТекст, "%УсловиеНаСсылкуВТЧ%", "ТаблицаШапки." + КлючИЗначение.Ключ.Имя);
				МассивУсловий.Добавить(ВремТекст);

			КонецЦикла;
		КонецЦикла;

		// По табличным частям
		Если УчитыватьТЧВДопДокументах Тогда
			Для Каждого ТабЧасть Из Документ.ТабличныеЧасти Цикл

				СоответствиеПолей.Очистить();
				Для Каждого Реквизит Из ТабЧасть.Реквизиты Цикл
					Для Каждого СтрокаДерева Из ДеревоДокументов.Строки Цикл

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

						МассивСтруктур = СоответствиеПолей.Получить(Реквизит);
						Если МассивСтруктур = Неопределено Тогда

							МассивСтруктур = Новый Массив;
							СоответствиеПолей.Вставить(Реквизит, МассивСтруктур);

						КонецЕсли;
						МассивСтруктур.Добавить(Новый Структура("Документ, ТекстУсловия",
														СтрокаДерева.Документ,
														СтрокаДерева.ТекстУсловия));
					КонецЦикла;
				КонецЦикла;

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

							Если РеквизитСоставной(КлючИЗначение.Ключ) Тогда
								ПутьКТаблице = "ВЫРАЗИТЬ(ТабличнаяЧасть%ИмяТабЧасти%." + КлючИЗначение.Ключ.Имя +" КАК Документ." + ТекСтруктура.Документ["Имя"] + ")";
							Иначе
								ПутьКТаблице = "ТабличнаяЧасть%ИмяТабЧасти%." + КлючИЗначение.Ключ.Имя;
							КонецЕсли;

							ТекстУсловия = СтрЗаменить(ТекСтруктура.ТекстУсловия, "%ПутьКТаблицеРеквизита%", ПутьКТаблице);
							ТекстУсловия = СтрЗаменить(ТекстУсловия, "%УсловиеНаСсылкуВТЧ%", "ТабличнаяЧасть%ИмяТабЧасти%." + КлючИЗначение.Ключ.Имя);
							ТекстУсловия = СтрЗаменить(ТекстУсловия, "%ИмяТабЧасти%",         ТабЧасть.Имя);

							ДобавитьТекстВСтроку(ВремТекст, ТекстУсловия, " ИЛИ ");

						КонецЦикла;
					КонецЦикла;

					ВремТекст = СтрЗаменить(ШаблонУсловияСтрокиТЧ, "&ТекстУсловия", ВремТекст);
					ВремТекст = СтрЗаменить(ВремТекст, "%ИмяДокумента%", Документ.Имя + "." + ТабЧасть.Имя);
					ВремТекст = СтрЗаменить(ВремТекст, "%ИмяТабЧасти%", ТабЧасть.Имя);

					МассивУсловий.Добавить(ВремТекст);

				КонецЕсли;
			КонецЦикла;
		КонецЕсли;

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

			ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "&ИмяТаблицыШапки",  "Документ." + Документ.Имя);
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ТекстУсловия", СтрокаИзМассиваСтрок(МассивУсловий, " ИЛИ "));

			ДобавитьДополнительныеПоляШапки(ТекстЗапроса, Документ, ДопПоляШапки);
			ДобавитьЗапросВТаблицу(ТаблицаЗапросов, Документ, ТекстЗапроса);

		КонецЕсли;

	КонецЦикла;

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

		ВремТекст= СтрЗаменить(ШаблонЗапроса, "&ИмяТаблицыШапки",  "Документ." + СтрокаТаб.ИмяДокумента);
		ДобавитьДополнительныеПоляШапки(ВремТекст, Метаданные.Документы[СтрокаТаб.ИмяДокумента], ДопПоляШапки);

		СтрокаТаб.ТекстЗапросаВыборка = ВремТекст;

	КонецЦикла;

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

Процедура ДобавитьТекстВСтроку(Строка, Текст, Разделитель = " Или ")

	Строка = Строка + ?(ПустаяСтрока(Строка), "", Разделитель) + Текст;

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

Функция СтрокаИзМассиваСтрок(МассивСтрок, Разделитель = " Или ")

	Результат = "";
	Для Каждого Элемент Из МассивСтрок Цикл

		ДобавитьТекстВСтроку(Результат, Элемент, Разделитель);

	КонецЦикла;

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

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

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

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

	СтрокаТаб = ТаблицаЗапросов.Добавить();
	СтрокаТаб.ИмяДокумента     = МетаданныеДокумента.Имя;
	СтрокаТаб.СинонимДокумента = МетаданныеДокумента.Синоним;
	СтрокаТаб.Использовать     = Истина;
	СтрокаТаб.ТекстЗапроса     = ТекстЗапроса;

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

Процедура ДобавитьДополнительныеПоляШапки(ТекстЗапроса, МетаданныеДокумента, ДопПоляШапки)

	ШаблонПоля  = "%ИмяПоля% КАК %ПсевдонимПоля%,";
	СтрокаПолей = "";

	Для Каждого ИмяПоля Из ДопПоляШапки Цикл
	
		Если МетаданныеДокумента.Реквизиты.Найти(ИмяПоля) <> Неопределено Тогда
	
			Текст = СтрЗаменить(ШаблонПоля, "%ИмяПоля%", "ПРЕДСТАВЛЕНИЕССЫЛКИ(ТаблицаШапки." + ИмяПоля +" ) "); // @query-part-2
	
		Иначе
	
			Текст = СтрЗаменить(ШаблонПоля, "%ИмяПоля%", " NULL ");
	
		КонецЕсли;
	
		СтрокаПолей = СтрокаПолей + ?(ПустаяСтрока(СтрокаПолей), "", Символы.ПС)
		              + СтрЗаменить(Текст, "%ПсевдонимПоля%", ИмяПоля);
	
	КонецЦикла;
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&СтрокаДопПолей,", СтрокаПолей);
	
КонецПроцедуры

Функция РеквизитСоставной(МетаданныеРеквизита)

	Возврат МетаданныеРеквизита.Тип.Типы().Количество() > 1;

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

Функция РеквизитСодержитТип(МетаданныеРеквизита, ИмяТипа)

	Возврат МетаданныеРеквизита.Тип.СодержитТип(Тип(ИмяТипа));

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

Функция РеквизитТолькоВШапке(СтрокаДерева)

	Возврат СтрокаДерева.Строки.НайтиСтроки(Новый Структура("ТабличнаяЧасть", ""), Ложь).Количество()>0;

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

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

#КонецЕсли

Связанные материалы