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