2334 lines
146 KiB
Plaintext
2334 lines
146 KiB
Plaintext
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
|
||
|
||
#Область СлужебныеПроцедурыИФункции
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
// ФУНКЦИИ РАБОТЫ С ВРЕМЕННЫМ ХРАНИЛИЩЕМ
|
||
|
||
// Помещает во внутреннее хранилище Запросы, Параметры, Имя файла.
|
||
//
|
||
// Параметры:
|
||
// Объект - передаваемый объект обработки.
|
||
// ИдентификаторТекущегоЗапроса - GUID текущего запроса.
|
||
// ИдентификаторТекущегоПараметра - GUID текущего параметра.
|
||
//
|
||
Функция ПоместитьЗапросыВоВременноеХранилище(Объект, ИдентификаторТекущегоЗапроса, ИдентификаторТекущегоПараметра) Экспорт
|
||
ПараметрыПередачи = Новый Структура;
|
||
ПараметрыПередачи.Вставить("Запросы", Объект.Запросы.Выгрузить());
|
||
ПараметрыПередачи.Вставить("Параметры", Объект.Параметры.Выгрузить());
|
||
ПараметрыПередачи.Вставить("ИмяФайла", Объект.ИмяФайла);
|
||
ПараметрыПередачи.Вставить("ИдентификаторТекущегоЗапроса", ИдентификаторТекущегоЗапроса);
|
||
ПараметрыПередачи.Вставить("ИдентификаторТекущегоПараметра", ИдентификаторТекущегоПараметра);
|
||
|
||
АдресХранилища = ПоместитьВоВременноеХранилище(ПараметрыПередачи);
|
||
Возврат АдресХранилища;
|
||
КонецФункции
|
||
|
||
// Помещает во внутренне хранилище настройки обработки.
|
||
//
|
||
// Параметры:
|
||
// Объект - передаваемый Объект обработки.
|
||
//
|
||
Функция ПоместитьНастройкиВоВременноеХранилище(Объект) Экспорт
|
||
ПараметрыПередачи = Новый Структура;
|
||
ПараметрыПередачи.Вставить("ИспользоватьАвтосохранение", Объект.ИспользоватьАвтосохранение);
|
||
ПараметрыПередачи.Вставить("ПериодАвтосохранения", Объект.ПериодАвтосохранения);
|
||
ПараметрыПередачи.Вставить("ВыводитьВРезультатахЗапросаЗначенияСсылок", Объект.ВыводитьВРезультатахЗапросаЗначенияСсылок);
|
||
ПараметрыПередачи.Вставить("ЧередованиеЦветовВРезультатеЗапроса", Объект.ЧередованиеЦветовВРезультатеЗапроса);
|
||
ПараметрыПередачи.Вставить("ТипОбхода", Объект.ТипОбхода);
|
||
|
||
АдресХранилища = ПоместитьВоВременноеХранилище(ПараметрыПередачи);
|
||
Возврат АдресХранилища;
|
||
КонецФункции
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
// ФУНКЦИИ РАБОТЫ С XML-ФАЙЛАМИ
|
||
|
||
// Записывает Запросы(текст и параметры запроса) в файл XML.
|
||
//
|
||
// Параметры:
|
||
// ИмяФайла - имя файла XML.
|
||
// Объект - передаваемый объект обработки.
|
||
//
|
||
Функция ЗаписатьЗапросыВФайлXML(знач Объект) Экспорт
|
||
|
||
ФайлXML = Новый ЗаписьXML;
|
||
ИмяФайла = ПолучитьИмяВременногоФайла("q1c");
|
||
ФайлXML.ОткрытьФайл(ИмяФайла);
|
||
ФайлXML.ЗаписатьОбъявлениеXML();
|
||
ФайлXML.ЗаписатьНачалоЭлемента("querylist");
|
||
// Цикл запросов.
|
||
Для каждого ТекЗапрос Из Объект.Запросы Цикл
|
||
ФайлXML.ЗаписатьНачалоЭлемента("query");
|
||
ФайлXML.ЗаписатьАтрибут("name", ТекЗапрос.Имя);
|
||
ФайлXML.ЗаписатьНачалоЭлемента("text");
|
||
ТекстЗапроса = ТекЗапрос.Текст;
|
||
Для Счетчик = 1 По СтрЧислоСтрок(ТекстЗапроса) Цикл
|
||
ПереносСтр = Символы.ВК + Символы.ПС;
|
||
ТекСтрока = СтрПолучитьСтроку(ТекстЗапроса, Счетчик);
|
||
ФайлXML.ЗаписатьТекст(ТекСтрока);
|
||
ФайлXML.ЗаписатьБезОбработки(ПереносСтр);
|
||
КонецЦикла;
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
ИдентификаторЗапроса = ТекЗапрос.Идентификатор;
|
||
// Запись параметров в XML-файл.
|
||
Если Объект.Параметры.Количество() > 0 Тогда
|
||
ФайлXML.ЗаписатьНачалоЭлемента("parameters");
|
||
Для каждого ТекПараметр Из Объект.Параметры Цикл
|
||
Если ТекПараметр.ИдентификаторЗапроса = ИдентификаторЗапроса Тогда
|
||
ИмяПараметра = ТекПараметр.Имя;
|
||
ТипПараметра = ТекПараметр.Тип;
|
||
Значение = ТекПараметр.Значение;
|
||
Если ПустаяСтрока(Значение) Тогда
|
||
ЗначениеПараметра = "";
|
||
Иначе
|
||
ЗначениеПараметра = ЗначениеИзСтрокиВнутр(ТекПараметр.Значение);
|
||
КонецЕсли;
|
||
|
||
ФайлXML.ЗаписатьНачалоЭлемента("parameter");
|
||
ФайлXML.ЗаписатьАтрибут("name", ИмяПараметра);
|
||
Если ТипПараметра = "СписокЗначений" Тогда
|
||
ФайлXML.ЗаписатьАтрибут("type", ТипПараметра);
|
||
ЗаписатьСписокЗначенийВXML(ФайлXML, ЗначениеПараметра);
|
||
ИначеЕсли ТипПараметра = "ТаблицаЗначений" Тогда
|
||
ФайлXML.ЗаписатьАтрибут("type", ТипПараметра);
|
||
|
||
Колонки = ЗначениеПараметра.Колонки.Количество();
|
||
Строки = ЗначениеПараметра.Количество();
|
||
|
||
ФайлXML.ЗаписатьАтрибут("colcount", XMLСтрока(Колонки));
|
||
ФайлXML.ЗаписатьАтрибут("rowcount", XMLСтрока(Строки));
|
||
|
||
ЗаписатьТаблицуЗначенийВXML(ФайлXML, ЗначениеПараметра);
|
||
ИначеЕсли ТипПараметра = "МоментВремени" Тогда
|
||
ФайлXML.ЗаписатьАтрибут("type", ТипПараметра);
|
||
ЗаписатьМоментВремениВXML(ФайлXML, ЗначениеПараметра);
|
||
ИначеЕсли ТипПараметра = "Граница" Тогда
|
||
ФайлXML.ЗаписатьАтрибут("type", ТипПараметра);
|
||
ЗаписатьГраницуВXML(ФайлXML, ЗначениеПараметра);
|
||
Иначе
|
||
ИмяТипа = ИмяТипаИзЗначения(ЗначениеПараметра);
|
||
ФайлXML.ЗаписатьАтрибут("type", ИмяТипа);
|
||
ФайлXML.ЗаписатьАтрибут("value", XMLСтрока(ЗначениеПараметра));
|
||
КонецЕсли;
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
КонецЕсли;
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
КонецЦикла;
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
ФайлXML.Закрыть();
|
||
|
||
ВозвращаемоеЗначение = Новый ДвоичныеДанные(ИмяФайла);
|
||
|
||
УдалитьФайлы(ИмяФайла);
|
||
|
||
Возврат ВозвращаемоеЗначение;
|
||
|
||
КонецФункции
|
||
|
||
// Записывает строки списка значений в Файл XML.
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - записьXML.
|
||
// Значение - список значений.
|
||
//
|
||
Процедура ЗаписатьСписокЗначенийВXML(ФайлXML, Значение)
|
||
Если ТипЗнч(Значение) <> Тип("СписокЗначений") Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Для каждого СтрСписка Из Значение Цикл
|
||
ЗначениеЭлементаСписка = СтрСписка.Значение;
|
||
// Определение имени типа.
|
||
ИмяТипа = ИмяТипаИзЗначения(ЗначениеЭлементаСписка);
|
||
|
||
ФайлXML.ЗаписатьНачалоЭлемента("item");
|
||
ФайлXML.ЗаписатьАтрибут("type", ИмяТипа);
|
||
ФайлXML.ЗаписатьАтрибут("value", XMLСтрока(ЗначениеЭлементаСписка));
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
// Записывает ячейки таблицы значений в Файл XML.
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - записьXML.
|
||
// Значение - таблица значений.
|
||
//
|
||
Процедура ЗаписатьТаблицуЗначенийВXML(ФайлXML, Значение)
|
||
Если ТипЗнч(Значение) <> Тип("ТаблицаЗначений") Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
КолКолонок = Значение.Колонки.Количество();
|
||
КолСтрок = Значение.Количество();
|
||
|
||
Для СтрокаИндекс = 0 По КолСтрок - 1 Цикл
|
||
Для КолонкаИндекс = 0 По КолКолонок - 1 Цикл
|
||
ЗначениеЭлементаСписка = Значение.Получить(СтрокаИндекс).Получить(КолонкаИндекс);
|
||
ИмяКолонки = Значение.Колонки.Получить(КолонкаИндекс).Имя;
|
||
// Определение имени типа.
|
||
ИмяТипа = ИмяТипаИзЗначения(ЗначениеЭлементаСписка);
|
||
Если ИмяТипа = "Строка" Тогда
|
||
Длина = Значение.Колонки.Получить(КолонкаИндекс).ТипЗначения.КвалификаторыСтроки.Длина;
|
||
Иначе
|
||
Длина = 0;
|
||
КонецЕсли;
|
||
|
||
ФайлXML.ЗаписатьНачалоЭлемента("item");
|
||
ФайлXML.ЗаписатьАтрибут("nameCol", ИмяКолонки);
|
||
ФайлXML.ЗаписатьАтрибут("row", XMLСтрока(СтрокаИндекс));
|
||
ФайлXML.ЗаписатьАтрибут("col", XMLСтрока(КолонкаИндекс));
|
||
ФайлXML.ЗаписатьАтрибут("type", ИмяТипа);
|
||
ФайлXML.ЗаписатьАтрибут("length", XMLСтрока(Длина));
|
||
ФайлXML.ЗаписатьАтрибут("value", XMLСтрока(ЗначениеЭлементаСписка));
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
// Записывает момент времени в Файл XML.
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - записьXML.
|
||
// Значение - момент времени.
|
||
//
|
||
Процедура ЗаписатьМоментВремениВXML(ФайлXML, Значение)
|
||
Если ТипЗнч(Значение) <> Тип("МоментВремени") Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
// Определение имени типа.
|
||
ИмяТипа = ИмяТипаИзЗначения(Значение.Ссылка);
|
||
|
||
ФайлXML.ЗаписатьНачалоЭлемента("item");
|
||
Если Значение.Ссылка <> Неопределено Тогда
|
||
ФайлXML.ЗаписатьАтрибут("type", ИмяТипа);
|
||
ФайлXML.ЗаписатьАтрибут("valueRef", XMLСтрока(Значение.Ссылка));
|
||
КонецЕсли;
|
||
ФайлXML.ЗаписатьАтрибут("valueDate", XMLСтрока(Значение.Дата));
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
КонецПроцедуры
|
||
|
||
// Записывает границу.
|
||
//
|
||
Процедура ЗаписатьГраницуВXML(ФайлXML, Граница)
|
||
Если ТипЗнч(Граница) <> Тип("Граница") Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
ФайлXML.ЗаписатьНачалоЭлемента("divide");
|
||
// Определение имени типа.
|
||
ИмяТипа = ИмяТипаИзЗначения(Граница.Значение);
|
||
ТипЗначенияГраницы = ТипЗнч(Граница.Значение);
|
||
|
||
// Запись в строку вида границы.
|
||
ИмяВидаГраницы = Строка(Граница.ВидГраницы);
|
||
|
||
ФайлXML.ЗаписатьАтрибут("type", ИмяТипа);
|
||
ФайлXML.ЗаписатьАтрибут("valueDiv", ИмяВидаГраницы);
|
||
|
||
Если ТипЗначенияГраницы <> Тип("МоментВремени") Тогда
|
||
ФайлXML.ЗаписатьАтрибут("value", XMLСтрока(Граница.Значение));
|
||
Иначе
|
||
ЗаписатьМоментВремениВXML(ФайлXML, Граница.Значение);
|
||
КонецЕсли;
|
||
ФайлXML.ЗаписатьКонецЭлемента();
|
||
КонецПроцедуры
|
||
|
||
// Читает Запросы(текст и параметры) из XML-файла.
|
||
//
|
||
Функция ПрочитатьЗапросыИзФайлаXML(ДвоичныеДанные) Экспорт
|
||
Объект = ЭтотОбъект;
|
||
ИмяФайла = ПолучитьИмяВременногоФайла("q1c");
|
||
ДвоичныеДанные.Записать(ИмяФайла);
|
||
ФайлXML = Новый ЧтениеXML;
|
||
ФайлXML.ОткрытьФайл(ИмяФайла);
|
||
ФайлXML.Прочитать();
|
||
// Чтение всех запросов.
|
||
Если ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ФайлXML.Имя = "querylist" Тогда
|
||
Пока ФайлXML.Прочитать() Цикл
|
||
// Чтение запроса.
|
||
Если ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ФайлXML.Имя = "query" Тогда
|
||
Пока ФайлXML.ПрочитатьАтрибут() Цикл
|
||
Если ФайлXML.Имя = "name" Тогда
|
||
// Добавление запроса в таблицу.
|
||
текЭлементЗапроса = Запросы.Добавить();
|
||
текЭлементЗапроса.Идентификатор = Новый УникальныйИдентификатор;
|
||
текЭлементЗапроса.Имя = ФайлXML.Значение;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Пока ФайлXML.Прочитать() Цикл
|
||
Если ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ФайлXML.Имя = "text" Тогда
|
||
ФайлXML.Прочитать();
|
||
текЭлементЗапроса.Текст = ФайлXML.Значение;
|
||
// Чтение параметров.
|
||
КонецЕсли;
|
||
Если ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ФайлXML.Имя = "parameters" Тогда
|
||
Пока ФайлXML.Прочитать() Цикл
|
||
// Чтение отдельного параметра.
|
||
Если ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ФайлXML.Имя = "parameter" Тогда
|
||
Пока ФайлXML.ПрочитатьАтрибут() Цикл
|
||
// Чтение имени атрибута.
|
||
Если ФайлXML.Имя = "name" Тогда
|
||
текПараметрЗапроса = Параметры.Добавить();
|
||
текПараметрЗапроса.Идентификатор = Новый УникальныйИдентификатор;
|
||
текПараметрЗапроса.Имя = ФайлXML.Значение;
|
||
текПараметрЗапроса.ИдентификаторЗапроса = текЭлементЗапроса.Идентификатор;
|
||
КонецЕсли;
|
||
|
||
// Чтение типа параметра.
|
||
Если ФайлXML.Имя = "type" Тогда
|
||
ТипЭлемента = Тип(ФайлXML.Значение);
|
||
текПараметрЗапроса.Тип = Строка(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
|
||
// Чтение значения параметра.
|
||
Если ФайлXML.Имя = "value" Тогда
|
||
Значение = XMLЗначение(ТипЭлемента, ФайлXML.Значение);
|
||
текПараметрЗапроса.Значение = ЗначениеВСтрокуВнутр(Значение);
|
||
КонецЕсли;
|
||
|
||
// Чтение количества колонок Таблицы Значений.
|
||
Если ФайлXML.Имя = "colcount" Тогда
|
||
КоличествоКолонок = Число(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
|
||
// Чтение количества строк Таблицы Значений.
|
||
Если ФайлXML.Имя = "rowcount" Тогда
|
||
КоличествоСтрок = Число(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Чтение отдельных типов.
|
||
// Для отдельных типов предусмотрено индивидуальное чтение параметров.
|
||
// Под отдельными типами понимаются: Список значений, Таблица значений,
|
||
// Момент Времени, Граница.
|
||
//
|
||
// Список отдельных типов может увеличиваться.
|
||
Если текПараметрЗапроса.Тип = "СписокЗначений" Тогда
|
||
ПрочитатьСписокЗначенийИзXML(ФайлXML, текПараметрЗапроса);
|
||
КонецЕсли;
|
||
Если текПараметрЗапроса.Тип = "ТаблицаЗначений" Тогда
|
||
Если КоличествоКолонок > 0 Тогда
|
||
ПрочитатьТаблицуЗначенийИзXML(ФайлXML, текПараметрЗапроса, КоличествоСтрок, КоличествоКолонок);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если текПараметрЗапроса.Тип = "МоментВремени" Тогда
|
||
ПрочитатьМоментВремениИзXML(ФайлXML, текПараметрЗапроса);
|
||
КонецЕсли;
|
||
Если текПараметрЗапроса.Тип = "Граница" Тогда
|
||
ПрочитатьГраницуИзXML(ФайлXML, текПараметрЗапроса);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если ПроверкаКонцаТэгов(ФайлXML) Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Если ПроверкаКонцаТэгов(ФайлXML) Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла; // Обход по тэгам "query".
|
||
КонецЕсли; // Если "query".
|
||
КонецЦикла; // Обход по запросам.
|
||
КонецЕсли; // Если "querylist".
|
||
ФайлXML.Закрыть();
|
||
Возврат ЭтотОбъект;
|
||
КонецФункции
|
||
|
||
// Читает Список значений.
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - Чтение XML.
|
||
// ПараметрЗапроса - текущий параметр.
|
||
//
|
||
Процедура ПрочитатьСписокЗначенийИзXML(ФайлXML, ПараметрЗапроса)
|
||
СписокЗН = Новый СписокЗначений;
|
||
Пока ФайлXML.Прочитать() Цикл
|
||
Если ФайлXML.Имя = "item" И ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
|
||
Пока ФайлXML.ПрочитатьАтрибут() Цикл
|
||
Если ФайлXML.Имя = "type" Тогда
|
||
ТипЭлемента = Тип(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "value" Тогда
|
||
// Чтение значения.
|
||
Значение = XMLЗначение(ТипЭлемента, ФайлXML.Значение);
|
||
ЗначениеЭлементаСписка = Значение;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
СписокЗН.Добавить(ЗначениеЭлементаСписка);
|
||
ИначеЕсли ФайлXML.Имя <> "item" Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ПараметрЗапроса.Значение = ЗначениеВСтрокуВнутр(СписокЗН);
|
||
КонецПроцедуры
|
||
|
||
// Читает Таблицу значений.
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - Чтение XML.
|
||
// ПараметрЗапроса - текущий параметр.
|
||
// КоличествоСтрок - количество строк.
|
||
// КоличествоКолонок - количество колонок.
|
||
//
|
||
Процедура ПрочитатьТаблицуЗначенийИзXML(ФайлXML, ПараметрЗапроса, КоличествоСтрок, КоличествоКолонок)
|
||
ТаблицаЗначений = Новый ТаблицаЗначений;
|
||
МассивКолонок = Новый Массив;
|
||
|
||
Пока ФайлXML.Прочитать() Цикл
|
||
Если ФайлXML.Имя = "item" И ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
|
||
Пока ФайлXML.ПрочитатьАтрибут() Цикл
|
||
Если ФайлXML.Имя = "col" Тогда
|
||
ИндексКолонки = Число(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "row" Тогда
|
||
ИндексСтроки = Число(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "type" Тогда
|
||
ТипЭлемента = Тип(ФайлXML.Значение);
|
||
МассивТипов = Новый Массив;
|
||
МассивТипов.Добавить(ТипЭлемента);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "nameCol" Тогда
|
||
ИмяКолонки = ФайлXML.Значение;
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "length" Тогда
|
||
Длина = ФайлXML.Значение;
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "value" Тогда
|
||
Значение = XMLЗначение(ТипЭлемента, ФайлXML.Значение);
|
||
ЗначениеЯчейки = Значение;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
ПараметрыСтроки = Новый КвалификаторыСтроки(Длина);
|
||
//ag(
|
||
Если ИндексСтроки = неопределено Тогда
|
||
//добавим пустую ТЗ
|
||
ОписаниеТипов = Новый ОписаниеТипов();
|
||
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, МассивТипов);
|
||
|
||
|
||
СтруктураКолонки = Новый Структура;
|
||
СтруктураКолонки.Вставить("Имя", ИмяКолонки);
|
||
СтруктураКолонки.Вставить("ОписаниеТипов", ОписаниеТипов);
|
||
СтруктураКолонки.Вставить("СписокЗначенийЯчеекКолонки", Новый СписокЗначений);
|
||
|
||
МассивКолонок.Вставить(ИндексКолонки,СтруктураКолонки);
|
||
Иначе
|
||
//ag)
|
||
|
||
Если МассивКолонок.Количество() - 1 < ИндексКолонки Тогда
|
||
ОписаниеТипов = Новый ОписаниеТипов();
|
||
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, МассивТипов,,, ПараметрыСтроки);
|
||
|
||
СписокЗначенийЯчеекКолонки = Новый СписокЗначений;
|
||
СписокЗначенийЯчеекКолонки.Вставить(ИндексСтроки,ЗначениеЯчейки);
|
||
|
||
СтруктураКолонки = Новый Структура;
|
||
СтруктураКолонки.Вставить("Имя", ИмяКолонки);
|
||
СтруктураКолонки.Вставить("ОписаниеТипов", ОписаниеТипов);
|
||
СтруктураКолонки.Вставить("СписокЗначенийЯчеекКолонки", СписокЗначенийЯчеекКолонки);
|
||
|
||
МассивКолонок.Вставить(ИндексКолонки, СтруктураКолонки);
|
||
Иначе
|
||
Имя = МассивКолонок.Получить(ИндексКолонки).Имя;
|
||
ОписаниеТипов = МассивКолонок.Получить(ИндексКолонки).ОписаниеТипов;
|
||
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, МассивТипов,,, ПараметрыСтроки);
|
||
СписокЗначенийЯчеекКолонки = МассивКолонок.Получить(ИндексКолонки).СписокЗначенийЯчеекКолонки;
|
||
СписокЗначенийЯчеекКолонки.Вставить(ИндексСтроки,ЗначениеЯчейки);
|
||
|
||
МассивКолонок.Удалить(ИндексКолонки);
|
||
СтруктураКолонки = Новый Структура;
|
||
СтруктураКолонки.Вставить("Имя", ИмяКолонки);
|
||
СтруктураКолонки.Вставить("ОписаниеТипов", ОписаниеТипов);
|
||
СтруктураКолонки.Вставить("СписокЗначенийЯчеекКолонки", СписокЗначенийЯчеекКолонки);
|
||
МассивКолонок.Вставить(ИндексКолонки, СтруктураКолонки);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ИначеЕсли ФайлXML.Имя <> "item" Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КолКолонок = МассивКолонок.Количество();
|
||
Для ИндексКолонок = 0 По КолКолонок - 1 Цикл
|
||
ИмяКолонки = МассивКолонок.Получить(ИндексКолонок).Имя;
|
||
ТипКолонки = МассивКолонок.Получить(ИндексКолонок).ОписаниеТипов;
|
||
ТаблицаЗначений.Колонки.Вставить(ИндексКолонок, ИмяКолонки, ТипКолонки, ИмяКолонки);
|
||
|
||
СписокЗначений = МассивКолонок.Получить(ИндексКолонок).СписокЗначенийЯчеекКолонки;
|
||
КолСтрок = СписокЗначений.Количество();
|
||
Для ИндексСтрок = 0 По КолСтрок - 1 Цикл
|
||
ЗначениеЯчейки = СписокЗначений.Получить(ИндексСтрок).Значение;
|
||
Если ИндексСтрок <= ТаблицаЗначений.Количество() - 1 Тогда
|
||
ТаблицаЗначений.Получить(ИндексСтрок).Установить(ИндексКолонок, ЗначениеЯчейки);
|
||
Иначе
|
||
ТаблицаЗначений.Вставить(ИндексСтрок).Установить(ИндексКолонок, ЗначениеЯчейки);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
|
||
ПараметрЗапроса.Значение = ЗначениеВСтрокуВнутр(ТаблицаЗначений);
|
||
КонецПроцедуры
|
||
|
||
// Читает Момент времени.
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - Чтение XML.
|
||
// ПараметрЗапроса - текущий параметр.
|
||
//
|
||
Процедура ПрочитатьМоментВремениИзXML(ФайлXML, ПараметрЗапроса)
|
||
Пока ФайлXML.Прочитать() Цикл
|
||
Если ФайлXML.Имя = "item" И ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
|
||
Пока ФайлXML.ПрочитатьАтрибут() Цикл
|
||
Если ФайлXML.Имя = "type" Тогда
|
||
ТипЭлемента = Тип(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "valueRef" Тогда
|
||
ЗначениеСсылки = XMLЗначение(ТипЭлемента, ФайлXML.Значение);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "valueDate" Тогда
|
||
ЗначениеДаты = XMLЗначение(Тип("Дата"), ФайлXML.Значение);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
МВ = Новый МоментВремени(ЗначениеДаты, ЗначениеСсылки);
|
||
ИначеЕсли ФайлXML.Имя <> "item" Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ПараметрЗапроса.Значение = ЗначениеВСтрокуВнутр(МВ);
|
||
КонецПроцедуры
|
||
|
||
// Читает Границу.
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - Чтение XML.
|
||
// ПараметрЗапроса - текущий параметр.
|
||
//
|
||
Процедура ПрочитатьГраницуИзXML(ФайлXML, ПараметрЗапроса)
|
||
Пока ФайлXML.Прочитать() Цикл
|
||
Если ФайлXML.Имя = "divide" И ФайлXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
|
||
Пока ФайлXML.ПрочитатьАтрибут() Цикл
|
||
Если ФайлXML.Имя = "type" Тогда
|
||
ТипЭлемента = Тип(ФайлXML.Значение);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "value" Тогда
|
||
Значение = XMLЗначение(ТипЭлемента, ФайлXML.Значение);
|
||
КонецЕсли;
|
||
Если ФайлXML.Имя = "valueDiv" Тогда
|
||
Вид = XMLЗначение(Тип("Строка"), ФайлXML.Значение);
|
||
Вид = ОпределениеВидаГраницы(Вид);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ТипЭлемента = Тип("МоментВремени") Тогда
|
||
ПрочитатьМоментВремениИзXML(ФайлXML, ПараметрЗапроса);
|
||
Значение = ЗначениеИзСтрокиВнутр(ПараметрЗапроса.Значение);
|
||
КонецЕсли;
|
||
|
||
Граница = Новый Граница(Значение, Вид);
|
||
ИначеЕсли ФайлXML.Имя <> "divide" Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ПараметрЗапроса.Значение = ЗначениеВСтрокуВнутр(Граница);
|
||
КонецПроцедуры
|
||
|
||
// Определяет условие конца тэга "query" или "parameters".
|
||
//
|
||
// Параметры:
|
||
// ФайлXML - чтениеXML.
|
||
//
|
||
Функция ПроверкаКонцаТэгов(ФайлXML)
|
||
Если (ФайлXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ФайлXML.Имя = "query")
|
||
Или (ФайлXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ФайлXML.Имя = "parameters") Тогда
|
||
Возврат Истина;
|
||
Иначе
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецФункции
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
// ФУНКЦИИ РАБОТЫ С ЗАПРОСОМ
|
||
|
||
// Считывает параметры из текста запроса.
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - текст запроса.
|
||
// ИдентификаторЗапроса - уникальный идентификатор запроса.
|
||
//
|
||
Функция СчитатьПараметрыЗапроса(ТекстЗапроса, ИдентификаторЗапроса) Экспорт
|
||
МассивСтруктуры = Новый Массив;
|
||
|
||
Запрос = Новый Запрос;
|
||
Запрос.Текст = ТекстЗапроса;
|
||
|
||
SPS_ЗаполнениеОбщихНаборовДанных(Запрос, Истина, ИдентификаторЗапроса);
|
||
|
||
// Заполняем параметрами таблицу параметров.
|
||
ПарЗап = Запрос.НайтиПараметры();
|
||
Для каждого СтрПараметры Из ПарЗап Цикл
|
||
РезультатСтруктура = ДобавлениеНовогоПараметра(СтрПараметры, ИдентификаторЗапроса);
|
||
|
||
SPS_ЗаполнитьЗначениеПараметра_ИзЗапроса(Запрос, РезультатСтруктура);
|
||
|
||
МассивСтруктуры.Добавить(РезультатСтруктура);
|
||
КонецЦикла;
|
||
|
||
Возврат МассивСтруктуры;
|
||
КонецФункции
|
||
|
||
// Добавляет новый параметр в структуру параметров.
|
||
//
|
||
// Параметры:
|
||
// ТекущийПрочитанныйПараметр - текущий параметр, прочитанный из текста запроса.
|
||
// ИдентификаторЗапроса - GUID запроса.
|
||
//
|
||
// Возвращает: структуру параметров.
|
||
//
|
||
Функция ДобавлениеНовогоПараметра(ТекущийПрочитанныйПараметр, ИдентификаторЗапроса)
|
||
|
||
ЭлементПараметр = Новый Структура("ИдентификаторЗапроса, Имя, Тип, Значение",
|
||
ИдентификаторЗапроса, ТекущийПрочитанныйПараметр.Имя
|
||
);
|
||
|
||
// Смотрим на первый тип из списка, если есть.
|
||
ДоступныеТипы = ТекущийПрочитанныйПараметр.ТипЗначения.Типы();
|
||
|
||
|
||
Если ДоступныеТипы.Количество()=0 Тогда
|
||
// Считаем строкой
|
||
ЭлементПараметр.Тип = "Строка";
|
||
ЭлементПараметр.Значение = ЗначениеВСтрокуВнутр("");
|
||
Возврат ЭлементПараметр;
|
||
КонецЕсли;
|
||
|
||
// Формируем описание типа из первого доступного типа.
|
||
Массив = Новый Массив;
|
||
Массив.Добавить( ДоступныеТипы.Получить(0) );
|
||
НовоеОписаниеТипов = Новый ОписаниеТипов(Массив);
|
||
|
||
Значение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
|
||
|
||
СписокДобавленныхТипов = Новый СписокЗначений;
|
||
СформироватьСписокТипов(СписокДобавленныхТипов);
|
||
|
||
Флаг = Ложь;
|
||
СтроковоеПредставлениеТипа = Строка(ТипЗнч(Значение));
|
||
Для каждого ЭлементСписка Из СписокДобавленныхТипов Цикл
|
||
Если ЭлементСписка.Представление = СтроковоеПредставлениеТипа Тогда
|
||
Флаг = Истина;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
ЭлементПараметр.Тип = ?(Флаг, СтроковоеПредставлениеТипа, XMLТип(ТипЗнч(Значение)).ИмяТипа);
|
||
ЭлементПараметр.Значение = ЗначениеВСтрокуВнутр(Значение);
|
||
|
||
Возврат ЭлементПараметр;
|
||
КонецФункции
|
||
|
||
// Загружает параметры в запрос.
|
||
// Если строковое представление значения - пустая строка, тогда значение параметра является Неопределено.
|
||
//
|
||
// Параметры:
|
||
// Запрос - передаваемый запрос.
|
||
// ПараметрыЗапроса - передаваемые параметры для запроса.
|
||
//
|
||
Процедура ЗагрузкаПараметровВЗапрос(Запрос, ПараметрыЗапроса)
|
||
Для каждого ЭлементПараметр Из ПараметрыЗапроса Цикл
|
||
СтрокаЗначение = ЭлементПараметр.Значение;
|
||
Если ПустаяСтрока(СтрокаЗначение) Тогда
|
||
Значение = Неопределено;
|
||
Иначе
|
||
Значение = ЗначениеИзСтрокиВнутр(СтрокаЗначение);
|
||
КонецЕсли;
|
||
Запрос.УстановитьПараметр(ЭлементПараметр.Имя, Значение);
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
// Выполняется запрос
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - текст запроса.
|
||
// ПараметрыЗапроса - массив параметров запроса.
|
||
// ТДРезультатаЗапроса - табличный документ результата запроса.
|
||
// ПараметрыВыводаЗапроса - Структура - Параметры вывода запроса.
|
||
// * ВыводитьВременныеТаблицы - выводить временные таблицы или нет.
|
||
// * ВыводитьИдентификатор - выводить GUID для ссылок или нет.
|
||
// * ПорядокОбхода - порядок обхода результата запроса.
|
||
// * ИспользованиеЧередования - использовать чередование или нет в результирующем табличном документе.
|
||
// ОтчетПоВыполнениюЗапроса - Структура - Статистика о выполнение запроса.
|
||
// * ВремяВыполнения - время выполнения запроса.
|
||
// * КоличествоСтрок - Количество строк в результате запроса.
|
||
// * ТекстСообщения - текст сообщения об ошибке.
|
||
// Метка запроса - Строка - Метка запроса для поиска его в технологическом журнале.
|
||
//
|
||
Функция ВыполнитьЗапрос(ТекстЗапроса, ПараметрыЗапроса, ТДРезультатаЗапроса, ПараметрыВыводаЗапроса, ОтчетПоВыполнениюЗапроса, МеткаЗапроса) Экспорт
|
||
|
||
Если ЗначениеЗаполнено(МеткаЗапроса) Тогда
|
||
ЗаписатьМеткуЗапроса(ТекстЗапроса, МеткаЗапроса, "begin");
|
||
КонецЕсли;
|
||
|
||
Если ЗначениеЗаполнено(МеткаЗапроса) Тогда
|
||
ЗаписатьМеткуЗапроса(ТекстЗапроса, МеткаЗапроса, "end");
|
||
КонецЕсли;
|
||
|
||
// Массив текстов запросов.
|
||
МассивТекстов = ПостроитьМассивТекстовЗапросов(ТекстЗапроса);
|
||
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса ,"\;", ";"); // Экранирование точки с запятой.
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
|
||
|
||
// Загрузка параметров.
|
||
ЗагрузкаПараметровВЗапрос(Запрос, ПараметрыЗапроса);
|
||
|
||
///SPS
|
||
SPS_ЗаполнениеОбщихНаборовДанных(Запрос);
|
||
МассивТекстов = ПостроитьМассивТекстовЗапросов(Запрос.Текст);
|
||
SPS_ЗаполнитьЗначенияПараметровИзЗапроса(Запрос, ПараметрыЗапроса);
|
||
///SPS||
|
||
|
||
// Проверка на правильность запросов.
|
||
Попытка
|
||
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
||
МассивЗапросов = Запрос.ВыполнитьПакет();
|
||
Конец = ТекущаяУниверсальнаяДатаВМиллисекундах() ;
|
||
ОтчетПоВыполнениюЗапроса.ВремяВыполнения = (Конец - Начало) / 1000;
|
||
Исключение
|
||
ТекстСообщения = ОписаниеОшибки();
|
||
Возврат Неопределено;
|
||
КонецПопытки;
|
||
|
||
МассивДанныхПоЗапросу = Новый Структура;
|
||
МассивДанныхПоЗапросу.Вставить("Запрос", Запрос);
|
||
МассивДанныхПоЗапросу.Вставить("МассивТекстов", МассивТекстов);
|
||
МассивДанныхПоЗапросу.Вставить("МассивЗапросов", МассивЗапросов);
|
||
МассивДанныхПоЗапросу.Вставить("МеткаЗапроса", МеткаЗапроса);
|
||
|
||
Успешно = ВывестиРезультатЗапросов(ТДРезультатаЗапроса, МассивДанныхПоЗапросу, ПараметрыЗапроса, ПараметрыВыводаЗапроса, ОтчетПоВыполнениюЗапроса);
|
||
Если Не Успешно Тогда
|
||
Если ВозможноОшибкаИзЗаТочкиСЗапятой(ТекстЗапроса) Тогда
|
||
ОтчетПоВыполнениюЗапроса.ТекстСообщения = НСтр("ru = 'Результат запроса не был выведен. Возможно не экранирована точка с запятой. Для экранирования точки с запятой используется обратный слеш -""\;""(см. справку)'");
|
||
Иначе
|
||
ОтчетПоВыполнениюЗапроса.ТекстСообщения = НСтр("ru = 'Запрос не был выполнен, т.к. текст запроса некорректный'");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Возврат МассивЗапросов;
|
||
КонецФункции
|
||
|
||
Процедура ЗаписатьМеткуЗапроса(ТекстЗапроса, Метка, Статус)
|
||
Если Статус = "begin" Тогда
|
||
ТекстЗапроса = "ВЫБРАТЬ ""Marker_" + Метка+ "_"+ Статус + """ КАК МЕТКА ПОМЕСТИТЬ Marker_begin " + Символы.ПС + ";" + Символы.ПС + ТекстЗапроса + Символы.ПС + ";" + Символы.ПС;
|
||
Иначе
|
||
ТекстЗапроса = Символы.ПС + ТекстЗапроса + "ВЫБРАТЬ ""Marker_" + Метка+ "_"+ Статус + """ Как МЕТКА ПОМЕСТИТЬ Marker_end " + Символы.ПС + ";" + Символы.ПС;
|
||
КонецЕсли;
|
||
КонецПроцедуры
|
||
|
||
// Возвращает массив текстов запросов.
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - Текст передаваемого запроса.
|
||
//
|
||
Функция ПостроитьМассивТекстовЗапросов(знач ТекстЗапроса)
|
||
|
||
МассивТекстов = Новый Массив;
|
||
Пока Не ПустаяСтрока(ТекстЗапроса) Цикл
|
||
ТочкаСЗапятой = ";";
|
||
ПозицияТочкиСЗапятой = Найти(ТекстЗапроса, ТочкаСЗапятой);
|
||
Если Сред(ТекстЗапроса, ПозицияТочкиСЗапятой - 1, 1) = "\" Тогда
|
||
ПозицияТочкиСЗапятой = 0;
|
||
КонецЕсли;
|
||
Если ПозицияТочкиСЗапятой = 0 Тогда
|
||
ТекстОчередногоЗапроса = ТекстЗапроса;
|
||
ПозицияТочкиСЗапятой = СтрДлина(ТекстЗапроса);
|
||
Иначе
|
||
ТекстОчередногоЗапроса = Лев(ТекстЗапроса, ПозицияТочкиСЗапятой - 1);
|
||
КонецЕсли;
|
||
Если Не ПустаяСтрока(ТекстОчередногоЗапроса) Тогда
|
||
МассивТекстов.Добавить(СокрЛП(ТекстОчередногоЗапроса));
|
||
КонецЕсли;
|
||
ТекстЗапроса = Сред(ТекстЗапроса, ПозицияТочкиСЗапятой + 1);
|
||
КонецЦикла;
|
||
|
||
Возврат МассивТекстов;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает есть ли в запросе иерархия.
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - текст запроса.
|
||
//
|
||
Функция НаличиеИерархииВЗапросе(ТекстЗапроса)
|
||
Итоги = "ИТОГИ";
|
||
Позиция = Найти(ВРег(ТекстЗапроса), Итоги);
|
||
|
||
Возврат ?(Позиция = 0, Ложь, Истина);
|
||
КонецФункции
|
||
|
||
// Возвращает имя временной таблицы.
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - текст запроса.
|
||
// Буфер - переменная хранения строки вида 'ПОМЕСТИТЬ %ИмяВременнойТаблицы%'.
|
||
// Позиция - позиция после слова 'ПОМЕСТИТЬ' в тексте запроса.
|
||
//
|
||
Функция ПолучитьИмяВременнойТаблицы(ТекстЗапроса, Буфер, Позиция)
|
||
ИмяТаблицы = "";
|
||
ДлиннаТекста = СтрДлина(ТекстЗапроса);
|
||
|
||
// Добавление пустых символов к буферу.
|
||
Для Индекс = Позиция По ДлиннаТекста Цикл
|
||
Символ = Сред(ТекстЗапроса, Индекс, 1);
|
||
Если ПустаяСтрока(Символ) Тогда
|
||
Буфер = Буфер + Символ;
|
||
Иначе
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Добавление имени временной таблицы.
|
||
Для ИндексВременнойТаблицы = Индекс По ДлиннаТекста Цикл
|
||
Символ = Сред(ТекстЗапроса, ИндексВременнойТаблицы, 1);
|
||
Если Не ПустаяСтрока(Символ) Тогда
|
||
Буфер = Буфер + Символ;
|
||
ИмяТаблицы = ИмяТаблицы + Символ;
|
||
Иначе
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат ИмяТаблицы;
|
||
КонецФункции
|
||
|
||
// Возвращает имя запроса из текста запроса.
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - текст запроса.
|
||
//
|
||
Функция ПолучитьИмяЗапроса(знач ТекстЗапроса)
|
||
РезультатЗначение = НСтр("ru = 'Запрос:'") + " ";
|
||
ДлинаТекста = СтрДлина(ТекстЗапроса);
|
||
ФлагПредлогаИЗ = Истина;
|
||
|
||
|
||
Пока ФлагПредлогаИЗ Цикл
|
||
СловоИЗ = "ИЗ";
|
||
ДлинаИЗ = СтрДлина(СловоИЗ);
|
||
ПозицияИЗ = Найти(ВРег(ТекстЗапроса), СловоИЗ);
|
||
Если ПозицияИЗ = 0 Тогда
|
||
Возврат РезультатЗначение;
|
||
КонецЕсли;
|
||
|
||
СимволДоИЗ = Сред(ТекстЗапроса, ПозицияИЗ - 1, 1);
|
||
СимволПослеИЗ = Сред(ТекстЗапроса, ПозицияИЗ + ДлинаИЗ, 1);
|
||
Если ПустаяСтрока(СимволДоИЗ) И ПустаяСтрока(СимволПослеИЗ) Тогда
|
||
ФлагПредлогаИЗ = Ложь;
|
||
Иначе
|
||
ТекстЗапроса = Сред(ТекстЗапроса, ПозицияИЗ + ДлинаИЗ);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
НачальнаяПозиция = ПозицияИЗ + ДлинаИЗ;
|
||
|
||
Для Индекс = НачальнаяПозиция По ДлинаТекста Цикл
|
||
Символ = Сред(ТекстЗапроса, Индекс, 1);
|
||
Если Не ПустаяСтрока(Символ) Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Формирование имени таблицы.
|
||
Для ИндексЗапроса = Индекс По ДлинаТекста Цикл
|
||
Символ = Сред(ТекстЗапроса, ИндексЗапроса, 1);
|
||
Если Не ПустаяСтрока(Символ) Тогда
|
||
РезультатЗначение = РезультатЗначение + Символ;
|
||
Иначе
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат РезультатЗначение;
|
||
КонецФункции
|
||
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
// ФУНКЦИИ РАБОТЫ С РЕЗУЛЬТАТОМ ЗАПРОСА
|
||
|
||
Функция ВозможноОшибкаИзЗаТочкиСЗапятой(ТекстЗапроса)
|
||
Позиция = 1;
|
||
Пока Позиция >0 Цикл
|
||
Позиция = Найти(ТекстЗапроса, ";");
|
||
Если Позиция > 0 Тогда
|
||
ТекстДляПоиска = Лев(ТекстЗапроса, Позиция);
|
||
Если Найти(ТекстДляПоиска, """") >0 Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ТекстЗапроса = Сред(ТекстЗапроса, Позиция + 1);
|
||
КонецЦикла;
|
||
|
||
Возврат Ложь;
|
||
КонецФункции
|
||
|
||
// Вывод результата всех запросов с временными таблицами.
|
||
//
|
||
// Если временная таблица, то выполняется запрос из массива текстов и формируется результат.
|
||
// Если не временная таблица, то результат берется из МассиваРезультатов.
|
||
//
|
||
// Параметры:
|
||
// ТДРезультатаЗапроса - табличный документ результата запроса.
|
||
// МассивДанныхПоЗапросу - Структура - Содержит данные по запроса.
|
||
// * Запрос - Запрос - передаваемый запрос.
|
||
// * МассивТекстов - Массив - массив текстов запросов.
|
||
// * МассивЗапросов - Массив - массив результатов запросов.
|
||
// ПараметрыЗапроса - массив параметров запросов.
|
||
// ПараметрыВыводаЗапроса - Структура - Параметры вывода запроса.
|
||
// * ВыводитьВременныеТаблицы - выводить временные таблицы или нет.
|
||
// * ВыводитьИдентификатор - выводить GUID для ссылок или нет.
|
||
// * ПорядокОбхода - порядок обхода результата запроса.
|
||
// * ИспользованиеЧередования - использовать чередование или нет в результирующем табличном документе.
|
||
// ОтчетПоВыполнениюЗапроса - Структура - Статистика о выполнение запроса.
|
||
// * ВремяВыполнения - время выполнения запроса.
|
||
// * КоличествоСтрок - Количество строк в результате запроса.
|
||
// * ТекстСообщения - текст сообщения об ошибке.
|
||
//
|
||
Функция ВывестиРезультатЗапросов(ТДРезультатаЗапроса, МассивДанныхПоЗапросу, ПараметрыЗапроса, ПараметрыВыводаЗапроса, ОтчетПоВыполнениюЗапроса)
|
||
|
||
МассивТекстов = МассивДанныхПоЗапросу.МассивТекстов;
|
||
МассивЗапросов = МассивДанныхПоЗапросу.МассивЗапросов;
|
||
МеткаЗапроса = МассивДанныхПоЗапросу.МеткаЗапроса;
|
||
|
||
КоличествоТекстовЗапросов = МассивТекстов.Количество();
|
||
КоличествоРезультатовЗапросов = МассивЗапросов.Количество();
|
||
|
||
Если КоличествоРезультатовЗапросов <> КоличествоТекстовЗапросов Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
// Накапливаемый запрос необходим для вывода временных таблиц, в том числе и удаляемых.
|
||
НакапливаемыйЗапрос = Новый Запрос;
|
||
ЗагрузкаПараметровВЗапрос(НакапливаемыйЗапрос, ПараметрыЗапроса);
|
||
|
||
Для Индекс = 0 По КоличествоТекстовЗапросов - 1 Цикл
|
||
ТекстЗапросаМассива = МассивТекстов.Получить(Индекс);
|
||
|
||
Если ЗначениеЗаполнено(МеткаЗапроса) И Найти(ТекстЗапросаМассива, МеткаЗапроса) > 0 Тогда
|
||
КоличествоРезультатовЗапросов = КоличествоРезультатовЗапросов - 1;
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
КоличествоСтрокОдногоЗапроса = 0;
|
||
МассивШириныКолонок = Новый Массив;
|
||
Свертка = ОпределитьСвертку(Индекс, КоличествоРезультатовЗапросов);
|
||
|
||
Поместить = "ПОМЕСТИТЬ";
|
||
ДлинаПоместить = СтрДлина(Поместить);
|
||
ПозицияПоместить = Найти(ВРег(ТекстЗапросаМассива), Поместить);
|
||
|
||
Если Индекс = 0 Тогда
|
||
СимволРазделенияЗапросов = "";
|
||
Иначе
|
||
СимволРазделенияЗапросов = ";";
|
||
КонецЕсли;
|
||
НакапливаемыйЗапрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
|
||
НакопленныйТекст = НакапливаемыйЗапрос.Текст + СимволРазделенияЗапросов + МассивТекстов.Получить(Индекс);
|
||
НакапливаемыйЗапрос.Текст = НакопленныйТекст;
|
||
|
||
// Если временная таблица и выводить временные таблицы.
|
||
Если ПозицияПоместить <> 0 И ПараметрыВыводаЗапроса.ВыводитьВременныеТаблицы Тогда
|
||
БуферПоместить = Сред(ТекстЗапросаМассива, ПозицияПоместить, ДлинаПоместить);
|
||
ПозицияПослеПоместить = ПозицияПоместить + ДлинаПоместить;
|
||
ИмяТаблицы = ПолучитьИмяВременнойТаблицы(ТекстЗапросаМассива, БуферПоместить, ПозицияПослеПоместить);
|
||
|
||
// Выполнение запроса.
|
||
ИмяЗапроса = "";
|
||
Результат = ВыполнитьЗапросСВременнойТаблицей(НакапливаемыйЗапрос, ИмяТаблицы, ИмяЗапроса);
|
||
|
||
Если Результат <> Неопределено Тогда
|
||
ТД = ВывестиРезультатОдногоЗапроса(ИмяЗапроса, Результат, Свертка, ПараметрыВыводаЗапроса, Ложь, КоличествоСтрокОдногоЗапроса, МассивШириныКолонок);
|
||
ТДРезультатаЗапроса.Вывести(ТД);
|
||
КонецЕсли;
|
||
ИначеЕсли ПозицияПоместить = 0 Тогда // Если таблица не временная, то используется готовый результат.
|
||
Результат = МассивЗапросов.Получить(Индекс);
|
||
ИмяЗапроса = ПолучитьИмяЗапроса(ТекстЗапросаМассива);
|
||
Иерархия = НаличиеИерархииВЗапросе(ТекстЗапросаМассива);
|
||
|
||
ТД = ВывестиРезультатОдногоЗапроса(ИмяЗапроса, Результат, Свертка, ПараметрыВыводаЗапроса, Иерархия, КоличествоСтрокОдногоЗапроса, МассивШириныКолонок);
|
||
ТДРезультатаЗапроса.Вывести(ТД);
|
||
КонецЕсли;
|
||
ОтчетПоВыполнениюЗапроса.КоличествоСтрок = ОтчетПоВыполнениюЗапроса.КоличествоСтрок + КоличествоСтрокОдногоЗапроса;
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
КонецФункции
|
||
|
||
// Вывод результат запроса в табличный документ.
|
||
//
|
||
// Параметры:
|
||
// ИмяЗапроса - Строка - имя запроса.
|
||
// РезультатЗапроса - результат запроса.
|
||
// Открыта - свернуть результат одного запроса в выводимом табличном документе.
|
||
// ПараметрыВыводаЗапроса - Структура - Параметры вывода запроса.
|
||
// * ВыводитьВременныеТаблицы - выводить временные таблицы или нет.
|
||
// * ВыводитьИдентификатор - выводить GUID для ссылок или нет.
|
||
// * ПорядокОбхода - порядок обхода результата запроса.
|
||
// * ИспользованиеЧередования - использовать чередование или нет в результирующем табличном документе.
|
||
// Иерархия - наличие итогов в запросе.
|
||
// КоличествоСтрок - Число - Количество строк в результате данного запроса.
|
||
// МассивШириныКолонок - массив максимальной ширины каждой колонки.
|
||
//
|
||
Функция ВывестиРезультатОдногоЗапроса(ИмяЗапроса, РезультатЗапроса, Открыта, ПараметрыВыводаЗапроса, Иерархия, КоличествоСтрок, МассивШириныКолонок)
|
||
|
||
РезультатЗапроса = ВыгрузкаРезультата(РезультатЗапроса, ПараметрыВыводаЗапроса.ПорядокОбхода, Иерархия);
|
||
|
||
ВыходнойМакет = Новый ТабличныйДокумент;
|
||
МакетОдногоЗапроса = Новый ТабличныйДокумент;
|
||
|
||
Если РезультатЗапроса = Неопределено Тогда
|
||
Возврат ВыходнойМакет;
|
||
КонецЕсли;
|
||
|
||
МакетОдногоЗапроса.Очистить();
|
||
ВыходнойМакет.Очистить();
|
||
|
||
УровеньВерхний = 1;
|
||
УровеньЗаголовкаИДеталей = 2;
|
||
|
||
// Вывод в табличный документ.
|
||
ЗаголовкиКолонок = ВывестиЗаголовкиКолонок(РезультатЗапроса, МассивШириныКолонок);
|
||
ПараметрыВыводаЗапроса.Вставить("МассивШириныКолонок", МассивШириныКолонок);
|
||
ПараметрыВыводаЗапроса.Вставить("КоличествоСтрок", КоличествоСтрок);
|
||
Детали = ВывестиДетали(РезультатЗапроса, ПараметрыВыводаЗапроса);
|
||
КоличествоСтрок = ПараметрыВыводаЗапроса.КоличествоСтрок;
|
||
Заголовок = ВывестиЗаголовокЗапроса(ИмяЗапроса, КоличествоСтрок);
|
||
|
||
МакетОдногоЗапроса.НачатьАвтогруппировкуСтрок();
|
||
|
||
МакетОдногоЗапроса.Вывести(Заголовок, УровеньВерхний);
|
||
МакетОдногоЗапроса.Вывести(ЗаголовкиКолонок, УровеньЗаголовкаИДеталей,, Открыта);
|
||
МакетОдногоЗапроса.Вывести(Детали, УровеньЗаголовкаИДеталей,, Открыта);
|
||
|
||
МакетОдногоЗапроса.ЗакончитьАвтогруппировкуСтрок();
|
||
|
||
УстановкаАвтоШирины(ВыходнойМакет, МассивШириныКолонок);
|
||
ВыходнойМакет.Вывести(МакетОдногоЗапроса).СоздатьФорматСтрок();
|
||
|
||
Возврат ВыходнойМакет;
|
||
КонецФункции
|
||
|
||
// Возвращает ТаблицуЗначений или ДеревоЗначений результата.
|
||
//
|
||
// Параметры:
|
||
// РезультатЗапроса - результат запроса.
|
||
// Иерархия - есть ли иерархия в запросе.
|
||
//
|
||
Функция ВыгрузкаРезультата(РезультатЗапроса, ПорядокОбхода, Иерархия)
|
||
|
||
Если РезультатЗапроса = Неопределено Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
|
||
Если ВРег(ПорядокОбхода) = "АВТО" Тогда
|
||
Если Иерархия Тогда
|
||
ВыгруженноеЗначение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
|
||
Иначе
|
||
ВыгруженноеЗначение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
|
||
КонецЕсли;
|
||
Иначе
|
||
ВыгруженноеЗначение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
|
||
КонецЕсли;
|
||
|
||
Возврат ВыгруженноеЗначение;
|
||
|
||
КонецФункции
|
||
|
||
Функция ВывестиЗаголовокЗапроса(ИмяЗапроса,КоличествоСтрок)
|
||
Заголовок = Новый ТабличныйДокумент;
|
||
|
||
МакетВывода = ПолучитьМакет("РезультатВыполненияЗапроса");
|
||
|
||
ОбластьЗаголовок = МакетВывода.ПолучитьОбласть("ЗапросИмя");
|
||
ОбластьЗаголовок.Параметры.ИмяЗапроса = ИмяЗапроса;
|
||
ОбластьЗаголовок.Параметры.КоличествоСтрок = КоличествоСтрок;
|
||
Заголовок.Вывести(ОбластьЗаголовок);
|
||
|
||
Возврат Заголовок;
|
||
КонецФункции
|
||
|
||
Функция ВывестиЗаголовкиКолонок(Результат, МассивШириныКолонок)
|
||
МакетВывода = ПолучитьМакет("РезультатВыполненияЗапроса");
|
||
|
||
ВерхнийЗаголовокКолонок = Новый ТабличныйДокумент;
|
||
|
||
ЗаголовокКолонок = Новый ТабличныйДокумент;
|
||
ОбластьЗаголовкиКолонок = МакетВывода.ПолучитьОбласть("ОбластьЯчейки");
|
||
|
||
Область = ОбластьЗаголовкиКолонок.Область();
|
||
Область.Шрифт = Новый Шрифт(,, Ложь);
|
||
Область.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
|
||
Область.ЦветФона = Новый Цвет(204, 192, 133);
|
||
|
||
Индекс = 0;
|
||
// Вывод заголовка таблицы.
|
||
Для каждого Стр Из Результат.Колонки Цикл
|
||
УстановкаМаксимальнойШириныВМассив(Индекс, Стр.Имя, МассивШириныКолонок);
|
||
ОбластьЗаголовкиКолонок.Параметры.Значение = Стр.Имя;
|
||
Об = ЗаголовокКолонок.Присоединить(ОбластьЗаголовкиКолонок);
|
||
Об.ШиринаКолонки = МассивШириныКолонок.Получить(Индекс);
|
||
Индекс = Индекс + 1;
|
||
КонецЦикла;
|
||
ВерхнийЗаголовокКолонок.Вывести(ЗаголовокКолонок);
|
||
|
||
Возврат ВерхнийЗаголовокКолонок;
|
||
КонецФункции
|
||
|
||
Функция ВывестиДетали(Результат, ПараметрыВыводаЗапроса)
|
||
Детали = Новый ТабличныйДокумент;
|
||
Уровень = 1;
|
||
Детали.НачатьАвтогруппировкуСтрок();
|
||
|
||
Если ТипЗнч(Результат) = Тип("ДеревоЗначений") Тогда
|
||
ИндексСтроки = 1;
|
||
КоличествоКолонок = Результат.Колонки.Количество();
|
||
ВывестиДеталиСИерархией(Детали, Результат, ПараметрыВыводаЗапроса, Уровень, КоличествоКолонок, ИндексСтроки);
|
||
КонецЕсли;
|
||
Если ТипЗнч(Результат) = Тип("ТаблицаЗначений") Тогда
|
||
КоличествоКолонок = Результат.Колонки.Количество();
|
||
ВывестиДеталиБезИерархии(Детали, Результат, ПараметрыВыводаЗапроса, Уровень, КоличествоКолонок);
|
||
КонецЕсли;
|
||
|
||
Детали.ЗакончитьАвтогруппировкуСтрок();
|
||
Возврат Детали;
|
||
КонецФункции
|
||
|
||
Функция ВывестиДеталиБезИерархии(ОбщиеДетали, Результат, ПараметрыВыводаЗапроса, Уровень, КоличествоКолонок)
|
||
МакетВывода = ПолучитьМакет("РезультатВыполненияЗапроса");
|
||
ПараметрыВыводаЗапроса.КоличествоСтрок = Результат.Количество();
|
||
ИндексСтроки = 1;
|
||
Для каждого Строка Из Результат Цикл
|
||
Детали = Новый ТабличныйДокумент;
|
||
ОбластьДетали = МакетВывода.ПолучитьОбласть("ОбластьЯчейки");
|
||
|
||
Область = ОбластьДетали.ТекущаяОбласть;
|
||
Область.Шрифт = Новый Шрифт(,, Ложь);
|
||
Область.ЦветФона = ОпределитьЦветФонаПоИндексу(ИндексСтроки, ПараметрыВыводаЗапроса.ИспользованиеЧередования);
|
||
|
||
Для Индекс = 0 По КоличествоКолонок - 1 Цикл
|
||
Значение = Строка.Получить(Индекс);
|
||
|
||
Если ТипЗнч(Значение) = Тип("ТаблицаЗначений") Тогда
|
||
Значение = ПреобразоватьТаблицуЗначенийВСтроке(Значение);
|
||
КонецЕсли;
|
||
|
||
ЗначениеДляПараметра = Значение;
|
||
Если ЭтоСсылка(ТипЗнч(Значение)) И ПараметрыВыводаЗапроса.ВыводитьИдентификатор Тогда
|
||
Попытка
|
||
ЗначениеДляПараметра = Значение.УникальныйИдентификатор();
|
||
Исключение
|
||
ЗначениеДляПараметра = Значение;
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
ОбластьДетали.Параметры.Значение = ЗначениеДляПараметра;
|
||
ОбластьДетали.Параметры.Расшифровка = Значение;
|
||
УстановкаМаксимальнойШириныВМассив(Индекс, ЗначениеДляПараметра, ПараметрыВыводаЗапроса.МассивШириныКолонок);
|
||
Детали.Присоединить(ОбластьДетали);
|
||
КонецЦикла;
|
||
ИндексСтроки = ИндексСтроки + 1;
|
||
ОбщиеДетали.Вывести(Детали, Уровень);
|
||
КонецЦикла;
|
||
КонецФункции
|
||
|
||
Функция ВывестиДеталиСИерархией(ОбщиеДетали, Результат, ПараметрыВыводаЗапроса , Уровень, КоличествоКолонок, ИндексСтроки)
|
||
МакетВывода = ПолучитьМакет("РезультатВыполненияЗапроса");
|
||
Открыта = Истина;
|
||
Подчиненные = Результат.Строки;
|
||
ПараметрыВыводаЗапроса.КоличествоСтрок = ПараметрыВыводаЗапроса.КоличествоСтрок + Подчиненные.Количество();
|
||
Для Каждого Подчиненный Из Подчиненные Цикл
|
||
Детали = Новый ТабличныйДокумент;
|
||
ОбластьДетали = МакетВывода.ПолучитьОбласть("ОбластьЯчейки");
|
||
|
||
Область = ОбластьДетали.ТекущаяОбласть;
|
||
Область.Шрифт = Новый Шрифт(,, Ложь);
|
||
Область.ЦветФона = ОпределитьЦветФонаПоИндексу(ИндексСтроки, ПараметрыВыводаЗапроса.ИспользованиеЧередования);
|
||
|
||
Для Индекс = 0 По КоличествоКолонок - 1 Цикл
|
||
Значение = Подчиненный.Получить(Индекс);
|
||
|
||
Если ТипЗнч(Значение) = Тип("ТаблицаЗначений") Тогда
|
||
Значение = ПреобразоватьТаблицуЗначенийВСтроке(Значение);
|
||
КонецЕсли;
|
||
|
||
ЗначениеДляПараметра = Значение;
|
||
// Определение количество отступа по уровню.
|
||
Пробел = ОпределениеОтступаПоУровню(Уровень, Индекс, Открыта);
|
||
|
||
Если ЭтоСсылка(ТипЗнч(Значение)) И ПараметрыВыводаЗапроса.ВыводитьИдентификатор Тогда
|
||
Попытка
|
||
ЗначениеДляПараметра = Значение.УникальныйИдентификатор();
|
||
Исключение
|
||
ЗначениеДляПараметра = Значение;
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
ЗначениеДляПараметра = "" + Пробел + ЗначениеДляПараметра;
|
||
ОбластьДетали.Параметры.Значение = ЗначениеДляПараметра;
|
||
ОбластьДетали.Параметры.Расшифровка = Значение;
|
||
|
||
УстановкаМаксимальнойШириныВМассив(Индекс, ЗначениеДляПараметра, ПараметрыВыводаЗапроса.МассивШириныКолонок);
|
||
|
||
Детали.Присоединить(ОбластьДетали);
|
||
КонецЦикла;
|
||
|
||
ОбщиеДетали.Вывести(Детали, Уровень,, Открыта);
|
||
ИндексСтроки = ИндексСтроки + 1;
|
||
ВывестиДеталиСИерархией(ОбщиеДетали, Подчиненный, ПараметрыВыводаЗапроса, Уровень + 1, КоличествоКолонок, ИндексСтроки);
|
||
КонецЦикла;
|
||
КонецФункции
|
||
|
||
// Определяет сворачивать или нет результат одного запроса.
|
||
//
|
||
// Параметры:
|
||
// ПозицияТекущегоЗапроса - порядок запроса в пакете.
|
||
// КоличествоВсехЗапросов - количество всех запросов в пакете.
|
||
//
|
||
Функция ОпределитьСвертку(знач ПозицияТекущегоЗапроса, КоличествоВсехЗапросов)
|
||
ПозицияТекущегоЗапроса = ПозицияТекущегоЗапроса + 1;
|
||
|
||
Если КоличествоВсехЗапросов = 1 Тогда
|
||
РезультатЗначение = Истина;
|
||
Иначе
|
||
Если ПозицияТекущегоЗапроса = КоличествоВсехЗапросов Тогда
|
||
РезультатЗначение = Истина;
|
||
Иначе
|
||
РезультатЗначение = Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Возврат РезультатЗначение;
|
||
КонецФункции
|
||
|
||
// Выводит строку с автошириной колонок.
|
||
//
|
||
// Параметры:
|
||
// РезультатЗапроса - табличный документ с результатом запроса.
|
||
// МассивМаксШирины - массив ширины колонок для отдельного запроса.
|
||
//
|
||
Процедура УстановкаАвтоШирины(РезультатЗапроса, МассивМаксШирины)
|
||
ВерхняяГраница = МассивМаксШирины.ВГраница();
|
||
Если ВерхняяГраница = -1 Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Для Индекс = 0 По ВерхняяГраница Цикл
|
||
ВременныйТабличныйДокумент = Новый ТабличныйДокумент;
|
||
Стр = ВременныйТабличныйДокумент.ПолучитьОбласть(1, Индекс + 1, 1, Индекс + 1);
|
||
РезультатЗапроса.Присоединить(Стр).ШиринаКолонки = МассивМаксШирины.Получить(Индекс);
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
// ПРОЧИЕ ПРОЦЕДУРЫ И ФУНКЦИИ
|
||
|
||
// Формирует список возможных типов конфигурации.
|
||
//
|
||
// Параметры:
|
||
// СписокДобавленныхТипов - список типов, добавленных "вручную".
|
||
//
|
||
Функция СформироватьСписокТипов(СписокДобавленныхТипов = Неопределено) Экспорт
|
||
МассивТипов = ДоступныеТипыДанных.Типы();
|
||
|
||
НеПримитивныеТипы = Новый СписокЗначений;
|
||
НеПримитивныеТипы.ЗагрузитьЗначения(МассивТипов);
|
||
НеПримитивныеТипы.СортироватьПоЗначению(НаправлениеСортировки.Возр);
|
||
|
||
СписокТипов = Новый СписокЗначений;
|
||
СписокТипов.Добавить("Строка", НСтр("ru = 'Строка'"));
|
||
СписокТипов.Добавить("Число", НСтр("ru = 'Число'"));
|
||
СписокТипов.Добавить("Дата", НСтр("ru = 'Дата'"));
|
||
СписокТипов.Добавить("Булево", НСтр("ru = 'Булево'"));
|
||
СписокТипов.Добавить("Граница", НСтр("ru = 'Граница'"));
|
||
СписокТипов.Добавить("МоментВремени", НСтр("ru = 'Момент времени'"));
|
||
СписокТипов.Добавить("СписокЗначений", НСтр("ru = 'Список значений'"));
|
||
СписокТипов.Добавить("ТаблицаЗначений", НСтр("ru = 'Таблица значений'"));
|
||
|
||
СписокДобавленныхТипов = Новый СписокЗначений;
|
||
СписокДобавленныхТипов = СписокТипов.Скопировать();
|
||
|
||
Для каждого Стр Из НеПримитивныеТипы Цикл
|
||
ЗначениеТипа = XMLТип(Стр.Значение).ИмяТипа;
|
||
ПредставлениеТипа = Строка(Стр.Значение);
|
||
СписокТипов.Добавить(ЗначениеТипа, ПредставлениеТипа);
|
||
КонецЦикла;
|
||
|
||
Возврат СписокТипов;
|
||
КонецФункции
|
||
|
||
// Определяет отступ по уровню.
|
||
//
|
||
// Параметры:
|
||
// Уровень - переданный уровень в дереве.
|
||
// НомерКолонки - номер колонки, отступ устанавливается только для первой колонки.
|
||
// Открыта - открыта группа или нет.
|
||
//
|
||
Функция ОпределениеОтступаПоУровню(Уровень, НомерКолонки, Открыта)
|
||
Пробел = "";
|
||
Если НомерКолонки = 0 Тогда
|
||
Если Уровень > 1 Тогда
|
||
Для Индекс = 1 По Уровень Цикл
|
||
Пробел = Пробел + Символы.Таб;
|
||
КонецЦикла;
|
||
Открыта = Ложь;
|
||
Иначе
|
||
Открыта = Истина;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Возврат Пробел;
|
||
КонецФункции
|
||
|
||
// Возвращает строковое представление типа по значению.
|
||
//
|
||
// Параметры:
|
||
// Значение - передаваемое значение.
|
||
//
|
||
Функция ИмяТипаИзЗначения(Значение) Экспорт
|
||
Возврат SPS_ИмяТипаИзЗначения(Значение);
|
||
|
||
Если ТипЗнч(Значение) = Тип("Строка") Тогда
|
||
ИмяТипа = "Строка";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда
|
||
ИмяТипа = "Число";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Булево") Тогда
|
||
ИмяТипа = "Булево";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Дата") Тогда
|
||
ИмяТипа = "Дата";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("МоментВремени") Тогда
|
||
ИмяТипа = "МоментВремени";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Неопределено") Тогда
|
||
ИмяТипа = "Строка";
|
||
Иначе
|
||
ИмяТипа = xmlТип(ТипЗнч(Значение)).ИмяТипа;
|
||
КонецЕсли;
|
||
|
||
Возврат ИмяТипа;
|
||
КонецФункции
|
||
|
||
// Возвращает вид границы из ее строкового представления.
|
||
//
|
||
// Параметры:
|
||
// Вид - строковое представление вида границы.
|
||
//
|
||
Функция ОпределениеВидаГраницы(Вид) Экспорт
|
||
Если ВРег(Вид) = "ИСКЛЮЧАЯ" Тогда
|
||
Результат = ВидГраницы.Исключая;
|
||
Иначе
|
||
Результат = ВидГраницы.Включая;
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Возвращает представление значения.
|
||
//
|
||
// Параметры:
|
||
// Значение - передаваемое значение.
|
||
//
|
||
Функция ФормированиеПредставленияЗначения(Значение) Экспорт
|
||
Результат = "";
|
||
|
||
Если ТипЗнч(Значение) = Тип("ТаблицаЗначений") Тогда
|
||
ИтоговаяСтрока = "Таблица: строк = %КоличествоСтрок%, колонок = %КоличествоКолонок%";
|
||
ИтоговаяСтрока = СтрЗаменить(ИтоговаяСтрока, "%КоличествоСтрок%", Строка(Значение.Количество()));
|
||
ИтоговаяСтрока = СтрЗаменить(ИтоговаяСтрока, "%КоличествоКолонок%", Строка(Значение.Колонки.Количество()));
|
||
Результат = ИтоговаяСтрока;
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("МоментВремени") Тогда
|
||
Результат = Строка(Значение.Дата) + "; " + Строка(Значение.Ссылка);
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Граница") Тогда
|
||
Результат = Строка(Значение.Значение) + "; " + Строка(Значение.ВидГраницы);
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Фильтрует список типов для данного контекста.
|
||
//
|
||
// Параметры:
|
||
// СписокТипов - список значений передаваемых типов.
|
||
// Контекст - передаваемый контекст в виде строки.
|
||
//
|
||
Процедура ФильтрацияСпискаТипов(СписокТипов, Контекст) Экспорт
|
||
Если нРег(Контекст) = "граница" Тогда
|
||
Элемент = СписокТипов.НайтиПоЗначению("СписокЗначений");
|
||
СписокТипов.Удалить(Элемент);
|
||
Элемент = СписокТипов.НайтиПоЗначению("ТаблицаЗначений");
|
||
СписокТипов.Удалить(Элемент);
|
||
Элемент = СписокТипов.НайтиПоЗначению("Граница");
|
||
СписокТипов.Удалить(Элемент);
|
||
КонецЕсли;
|
||
|
||
Элемент = СписокТипов.НайтиПоЗначению("TypeDescription"); // Тип "Описание типов" удаляется всегда.
|
||
СписокТипов.Удалить(Элемент);
|
||
КонецПроцедуры
|
||
|
||
// Устанавливает максимальную ширину ячейки для каждой колонки.
|
||
//
|
||
Процедура УстановкаМаксимальнойШириныВМассив(Индекс, знач Элем, МассивШириныКолонок)
|
||
МаксимальнаяШиринаЯчейки = 100;
|
||
|
||
Элем = СокрП(Элем);
|
||
Элем = СтрДлина(Элем);
|
||
Если Индекс > МассивШириныКолонок.ВГраница() Тогда
|
||
Если Элем < МаксимальнаяШиринаЯчейки Тогда
|
||
МассивШириныКолонок.Вставить(Индекс, Элем + 1);
|
||
Иначе
|
||
МассивШириныКолонок.Вставить(Индекс, МаксимальнаяШиринаЯчейки);
|
||
КонецЕсли;
|
||
Иначе
|
||
Макс = МассивШириныКолонок.Получить(Индекс);
|
||
Если Элем > Макс Тогда
|
||
Если Элем < МаксимальнаяШиринаЯчейки Тогда
|
||
МассивШириныКолонок.Установить(Индекс, Элем + 1);
|
||
Иначе
|
||
МассивШириныКолонок.Установить(Индекс, МаксимальнаяШиринаЯчейки);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецПроцедуры
|
||
|
||
// Проверяет является ли тип ссылкой.
|
||
//
|
||
// Параметры:
|
||
// Тип - передаваемый тип.
|
||
//
|
||
Функция ЭтоСсылка(Тип) Экспорт
|
||
|
||
Возврат Справочники.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ Документы.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ Перечисления.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ ПланыСчетов.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ БизнесПроцессы.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ БизнесПроцессы.ТипВсеСсылкиТочекМаршрутаБизнесПроцессов().СодержитТип(Тип)
|
||
ИЛИ Задачи.ТипВсеСсылки().СодержитТип(Тип)
|
||
ИЛИ ПланыОбмена.ТипВсеСсылки().СодержитТип(Тип);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает результат выполнения временной таблицы по имени.
|
||
//
|
||
// Параметры:
|
||
// Запрос - передаваемый запрос.
|
||
// ИмяВременнойТаблицы - имя временной таблицы.
|
||
// ИмяЗапроса - имя запроса, изменяемое в теле процедуры.
|
||
//
|
||
Функция ВыполнитьЗапросСВременнойТаблицей(знач ЗапросДляВыполнения, ИмяВременнойТаблицы, ИмяЗапроса)
|
||
ЗапросДляВыполнения.Текст = ЗапросДляВыполнения.Текст + " ; " + "ВЫБРАТЬ * ИЗ " + ИмяВременнойТаблицы;
|
||
|
||
Попытка
|
||
Результат = ЗапросДляВыполнения.Выполнить();
|
||
ИмяЗапроса = НСтр("ru = 'Временная таблица:'") + " " + ИмяВременнойТаблицы;
|
||
Исключение
|
||
Результат = Неопределено;
|
||
КонецПопытки;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Возвращает цвет фона табличного документа по индексу строки и по использованию.
|
||
//
|
||
// Параметры:
|
||
// Индекс - передаваемый индекс строки.
|
||
// Использование - использовать или нет чередование.
|
||
//
|
||
Функция ОпределитьЦветФонаПоИндексу(Индекс, Использование)
|
||
ЦветЧередования = Новый Цвет(245, 242, 221);
|
||
|
||
Если Не Использование Тогда
|
||
Возврат WebЦвета.Белый;
|
||
КонецЕсли;
|
||
|
||
Остаток = Индекс % 2;
|
||
Если Остаток = 0 Тогда
|
||
Цвет = ЦветЧередования;
|
||
Иначе
|
||
Цвет = WebЦвета.Белый;
|
||
КонецЕсли;
|
||
|
||
Возврат Цвет;
|
||
КонецФункции
|
||
|
||
Функция ПреобразоватьТаблицуЗначенийВСтроке(ТаблицаЗначений)
|
||
|
||
ПредставлениеТаблицыЗначений = "";
|
||
Для каждого СтрокаТаблицыЗначений Из ТаблицаЗначений Цикл
|
||
Разделитель = "";
|
||
Для каждого ЯчейкаТаблицыЗначений Из СтрокаТаблицыЗначений Цикл
|
||
ПредставлениеТаблицыЗначений = ПредставлениеТаблицыЗначений + Разделитель + Строка(ЯчейкаТаблицыЗначений);
|
||
Разделитель = ";";
|
||
КонецЦикла;
|
||
ПредставлениеТаблицыЗначений = ПредставлениеТаблицыЗначений + Символы.ПС;
|
||
КонецЦикла;
|
||
Значение = ПредставлениеТаблицыЗначений;
|
||
|
||
Возврат ПредставлениеТаблицыЗначений
|
||
КонецФункции
|
||
|
||
|
||
#КонецОбласти
|
||
|
||
#Область РаботаСТехнологическимЖурналом
|
||
|
||
Функция ФайлКонфигурацииСуществует(ПутьКФайлуКонфигурации)
|
||
ФайлКонфигурации = Новый Файл(ПутьКФайлуКонфигурации + ПолучитьРазделительПути() + "logcfg.xml");
|
||
Если ФайлКонфигурации.Существует() Тогда
|
||
ФайлТекстаКонфигурации = Новый ЧтениеТекста(ФайлКонфигурации.ПолноеИмя);
|
||
СтрокаТекстКонфигурации = ФайлТекстаКонфигурации.ПрочитатьСтроку();
|
||
Пока СтрокаТекстКонфигурации <> Неопределено Цикл
|
||
Если Найти(СтрокаТекстКонфигурации, "ConsoleQueries") > 0 Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
СтрокаТекстКонфигурации = ФайлТекстаКонфигурации.ПрочитатьСтроку();
|
||
КонецЦикла;
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
Возврат Ложь;
|
||
|
||
КонецФункции
|
||
|
||
// Включает технологический журнал.
|
||
//
|
||
Процедура ВключениеТехнологическогоЖурнала(ПараметрыТехнологическогоЖурнала, РезультатВключения) Экспорт
|
||
|
||
КаталогКонфигурацииПриложения = ПутьККонфигурационномуФайлу();
|
||
|
||
Если КаталогКонфигурацииПриложения <> Неопределено Тогда
|
||
Если ФайлКонфигурацииСуществует(КаталогКонфигурацииПриложения) Тогда
|
||
ПереместитьФайл(КаталогКонфигурацииПриложения + ПолучитьРазделительПути() + "logcfg.xml", КаталогКонфигурацииПриложения + ПолучитьРазделительПути() + "logcfg.off");
|
||
КонецЕсли;
|
||
|
||
КаталогВременныхФайлов = КаталогВременныхФайлов();
|
||
СоздатьКаталог(КаталогВременныхФайлов + "1c_logs");
|
||
КаталогСЛогФайлами = КаталогВременныхФайлов + "1c_logs";
|
||
|
||
ЛогФайлыДляУдаления = НайтиФайлы(КаталогСЛогФайлами, "*.log", Истина);
|
||
Для каждого Файл Из ЛогФайлыДляУдаления Цикл
|
||
Попытка
|
||
УдалитьФайлы(Файл.ПолноеИмя);
|
||
Исключение
|
||
// Удаление файла log вызвало ошибку (нет прав, файл уже не существует).
|
||
КонецПопытки;
|
||
КонецЦикла;
|
||
|
||
ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь.Наименование;
|
||
МассивСобытие = Новый Массив;
|
||
МассивСобытие.Добавить("db2");
|
||
МассивСобытие.Добавить("dbmssql");
|
||
МассивСобытие.Добавить("dbpostgrs");
|
||
МассивСобытие.Добавить("dboracle");
|
||
МассивСобытие.Добавить("SDBL");
|
||
МассивСобытие.Добавить("DBV8DBEng");
|
||
МассивСобытие.Добавить("QERR");
|
||
МассивСобытие.Добавить("EXCP");
|
||
МассивСобытие.Добавить("EXCPCNTX");
|
||
|
||
Текст = "<?xml version=""1.0"" encoding=""UTF-8""?>" + Символы.ПС+ "<!-- ConsoleQueries -->" + Символы.ПС+ "<config xmlns=""http://v8.1c.ru/v8/tech-log"">" +
|
||
Символы.ПС + "<dump create=""false"" type=""0"" prntscrn=""false""/>" + Символы.ПС + "<log history=""1"" location=""" + КаталогСЛогФайлами + """>" + Символы.ПС;
|
||
|
||
Для каждого событие Из МассивСобытие Цикл
|
||
Текст = Текст + "<event>" + Символы.ПС+ " <eq property=""name"" value=""" + событие + """/>" + Символы.ПС + "</event>" + Символы.ПС;
|
||
КонецЦикла;
|
||
|
||
Текст = Текст + "<property name=""all""/>" + Символы.ПС+ " <property name=""sql""/>" + Символы.ПС + " <property name=""plansqltext""/>" + Символы.ПС+ "</log>" + Символы.ПС+ "<plansql/>" + Символы.ПС + "</config>";
|
||
|
||
ПолныйПутьКонфигурационногоФайла = КаталогКонфигурацииПриложения + ПолучитьРазделительПути() + "logcfg.xml";
|
||
Попытка
|
||
Файл = Новый ЗаписьТекста(ПолныйПутьКонфигурационногоФайла);
|
||
Файл.ЗаписатьСтроку(Текст);
|
||
Файл.Закрыть();
|
||
Исключение
|
||
РезультатВключения.Результат = Ложь;
|
||
РезультатВключения.Причина = НСтр("ru = 'Ошибка создания конфигурационного файла в каталоге'") + " " + КаталогКонфигурацииПриложения + Символы.ПС + НСтр("ru = 'Проверьте права доступа.'");
|
||
КонецПопытки;
|
||
|
||
ИдентификаторПроцессаОС = ИдентификаторПроцессаОС();
|
||
ПараметрыТехнологическогоЖурнала.КаталогСЛогФайлами = КаталогСЛогФайлами;
|
||
ПараметрыТехнологическогоЖурнала.ИдентификаторПроцессаОС = Формат(ИдентификаторПроцессаОС, "ЧРД=; ЧРГ=; ЧГ=0");
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ПутьККонфигурационномуФайлу()
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация();
|
||
Если НЕ ((СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86) Или (СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64)) Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
|
||
КаталогаОбщихКонфигурационныхФайлов = КаталогПрограммы() + "conf";
|
||
ФайлУказатель = Новый Файл(КаталогаОбщихКонфигурационныхФайлов + ПолучитьРазделительПутиСервера() + "conf.cfg");
|
||
Если ФайлУказатель.Существует() Тогда
|
||
ФайлКонфигурации = Новый ЧтениеТекста(ФайлУказатель.ПолноеИмя);
|
||
Строка = ФайлКонфигурации.ПрочитатьСтроку();
|
||
Пока Строка <> Неопределено Цикл
|
||
Позиция = Найти(Строка, "ConfLocation=");
|
||
Если Позиция > 0 Тогда
|
||
КаталогКонфигурацииПриложения = СокрЛП(Сред(Строка, Позиция + 13));
|
||
Прервать;
|
||
КонецЕсли;
|
||
Строка = ФайлКонфигурации.ПрочитатьСтроку();
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
|
||
Возврат КаталогКонфигурацииПриложения;
|
||
КонецФункции
|
||
|
||
// Выключает технологический журнал.
|
||
//
|
||
Процедура ВыключениеТехнологическогоЖурнала() Экспорт
|
||
КаталогКонфигурацииПриложения = ПутьККонфигурационномуФайлу();
|
||
Если КаталогКонфигурацииПриложения <> Неопределено Тогда
|
||
УдалитьФайлы(КаталогКонфигурацииПриложения + ПолучитьРазделительПути() + "logcfg.xml");
|
||
КонецЕсли;
|
||
|
||
СтарыйФайлКонфигурации = Новый Файл(КаталогКонфигурацииПриложения + ПолучитьРазделительПути() + "logcfg.off");
|
||
Если СтарыйФайлКонфигурации.Существует() Тогда
|
||
ПереместитьФайл(КаталогКонфигурацииПриложения + ПолучитьРазделительПути() + "logcfg.off", КаталогКонфигурацииПриложения + ПолучитьРазделительПути() + "logcfg.xml");
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Находит в файле технологического журнала запрос и план выполнения запроса.
|
||
//
|
||
Процедура ПрочитатьТехнологическийЖурнал(ПутьКФайлу, ИДМетки, ПрочитанныеДанные) Экспорт
|
||
|
||
МассивСтрок = Новый Массив;
|
||
ДобавлятьВМассив = Ложь;
|
||
|
||
ВременныйФайл = ПолучитьИмяВременногоФайла(".log");
|
||
КопироватьФайл(ПутьКФайлу, ВременныйФайл);
|
||
|
||
Файл = Новый ЧтениеТекста();
|
||
Файл.Открыть(ВременныйФайл);
|
||
Строка = Файл.ПрочитатьСтроку();
|
||
ВременнаяСтрока = "";
|
||
Пока Строка <> Неопределено Цикл
|
||
Если ДобавлятьВМассив Тогда
|
||
Если ДобавлятьВМассив И Найти(Строка, ИДМетки + "_end") = 0 Тогда
|
||
Если Сред(Строка, 3, 1) = ":" И Сред(Строка, 6, 1) = "." Тогда
|
||
Если ЗначениеЗаполнено(ВременнаяСтрока)
|
||
И Найти(ВременнаяСтрока, "Sql=") > 0
|
||
И Найти(ВременнаяСтрока, "planSQLText=") > 0
|
||
И Найти(ВременнаяСтрока, "Marker_" + ИДМетки) = 0 Тогда
|
||
МассивСтрок.Добавить(ВременнаяСтрока);
|
||
КонецЕсли;
|
||
ВременнаяСтрока = Строка;
|
||
Иначе
|
||
ВременнаяСтрока = ВременнаяСтрока + Символы.ПС + Строка;
|
||
КонецЕсли;
|
||
Иначе
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Если Найти(Строка, ИДМетки + "_begin") > 0 Тогда
|
||
ДобавлятьВМассив = Истина;
|
||
КонецЕсли;
|
||
Строка = Файл.ПрочитатьСтроку();
|
||
КонецЦикла;
|
||
|
||
СКЛТекстИзТехЖурнала = "";
|
||
ПланВыполненияЗапроса = "";
|
||
|
||
Если МассивСтрок.Количество() > 1 Тогда
|
||
Разделитель = Символы.ПС + Символы.ПС;
|
||
Иначе
|
||
Разделитель = "";
|
||
КонецЕсли;
|
||
|
||
Для каждого Строка Из МассивСтрок Цикл
|
||
ПозицияНачало = Найти(Строка, ",");
|
||
СтрокаСдвиг = Сред(Строка, ПозицияНачало + 1);
|
||
ПозицияКонец = Найти(СтрокаСдвиг, ",");
|
||
ТипСУБД = ВРег(Лев(СтрокаСдвиг, ПозицияКонец -1));
|
||
Позиция = Найти(СтрокаСдвиг, "Sql=");
|
||
Если Сред(СтрокаСдвиг, Позиция + 4, 1) = """" ИЛИ Сред(СтрокаСдвиг, Позиция + 4, 1) = "'" Тогда
|
||
СтрокаСдвиг = Сред(СтрокаСдвиг, Позиция + 5);
|
||
Иначе
|
||
СтрокаСдвиг = Сред(СтрокаСдвиг, Позиция + 4);
|
||
КонецЕсли;
|
||
|
||
Если ТипСУБД = "DBMSSQL" Тогда
|
||
Позиция = Найти(СтрокаСдвиг, ",Rows");
|
||
СКЛТекстТекущийЗапрос = Лев(СтрокаСдвиг, Позиция-2);
|
||
Позиция = Найти(СтрокаСдвиг, "planSQLText=");
|
||
СтрокаСдвиг = Сред(СтрокаСдвиг, Позиция + 13);
|
||
Позиция = Найти(СтрокаСдвиг, "'");
|
||
ПланВыполненияЗапросаТекущийЗапрос = Лев(СтрокаСдвиг, Позиция-1);
|
||
ИначеЕсли ТипСУБД = "DBPOSTGRS" Тогда
|
||
Позиция = Найти(СтрокаСдвиг, ",planSQLText=");
|
||
СКЛТекстТекущийЗапрос = Лев(СтрокаСдвиг, Позиция-1);
|
||
СтрокаСдвиг = Сред(СтрокаСдвиг, Позиция + 13);
|
||
Позиция = Найти(СтрокаСдвиг, ",Result");
|
||
ПланВыполненияЗапросаТекущийЗапрос = Лев(СтрокаСдвиг, Позиция-1);
|
||
Иначе
|
||
Позиция = Найти(СтрокаСдвиг, "',");
|
||
СКЛТекстТекущийЗапрос = Лев(СтрокаСдвиг, Позиция-2);
|
||
Позиция = Найти(СтрокаСдвиг, "planSQLText=");
|
||
СтрокаСдвиг = Сред(СтрокаСдвиг, Позиция + 13);
|
||
Позиция = Найти(СтрокаСдвиг, "'");
|
||
ПланВыполненияЗапросаТекущийЗапрос = Лев(СтрокаСдвиг, Позиция-1);
|
||
КонецЕсли;
|
||
|
||
ПланВыполненияЗапроса = ПланВыполненияЗапроса + ПланВыполненияЗапросаТекущийЗапрос + Разделитель;
|
||
СКЛТекстИзТехЖурнала = СКЛТекстИзТехЖурнала + СКЛТекстТекущийЗапрос +Разделитель;
|
||
КонецЦикла;
|
||
|
||
ПрочитанныеДанные.ТипСУБД = ТипСУБД;
|
||
ПрочитанныеДанные.СКЛЗапрос = СокрЛП(СКЛТекстИзТехЖурнала);
|
||
ПрочитанныеДанные.ПланВыполненияЗапроса = СокрЛП(ПланВыполненияЗапроса);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает идентификатор процесса ОС.
|
||
//
|
||
Функция ИдентификаторПроцессаОС() Экспорт
|
||
|
||
ИДТекущегоПроцесса = Неопределено;
|
||
ОбъектСистемы = Новый COMОбъект("WScript.Shell");
|
||
Если ИДТекущегоПроцесса = Неопределено Тогда
|
||
Процесс = ОбъектСистемы.Exec("rundll32.exe kernel32,Sleep");
|
||
ИДТекущегоПроцесса = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + Формат(Процесс.ProcessID,"ЧГ=0") + "'").ParentProcessID;
|
||
Процесс.Terminate();
|
||
КонецЕсли;
|
||
|
||
Возврат ИДТекущегоПроцесса;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ОбработкаЗапросаИПланаВыполненияЗапроса
|
||
|
||
Функция ИмяСУБД()
|
||
СтрокаПодключения = СтрокаСоединенияИнформационнойБазы();
|
||
Позиция = Найти(СтрокаПодключения, "Ref=""");
|
||
Если Позиция > 0 Тогда
|
||
СтрокаПодключения = Сред(СтрокаПодключения, Позиция + 5);
|
||
Позиция = Найти(СтрокаПодключения, """");
|
||
Если Позиция > 0 Тогда
|
||
Возврат Лев(СтрокаПодключения, Позиция - 1);
|
||
Иначе
|
||
Возврат СтрокаПодключения;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Возврат Неопределено;
|
||
КонецФункции
|
||
|
||
// Преобразовывает объекты запроса к объектам в виде метаданных ИБ.
|
||
//
|
||
Функция ПреобразоватьВМетаданные(ТекстЗапроса, ПланВыполненияЗапроса, ТипСУБД) Экспорт
|
||
|
||
ТекстЗапросаВМетаданных = ТекстЗапроса;
|
||
ПланЗапросаВМетаданных = ПланВыполненияЗапроса;
|
||
|
||
ТипСтрока = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150));
|
||
ТипСтрокаЗначение = Новый ОписаниеТипов("Строка", , );
|
||
ТипЧисло = Новый ОписаниеТипов("Число");
|
||
|
||
СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных(, Истина);
|
||
СтруктураБД.Сортировать("ИмяТаблицыХранения УБЫВ");
|
||
|
||
СоответствиеБДИндекс = Новый ТаблицаЗначений;
|
||
СоответствиеБДИндекс.Колонки.Добавить("Ключ", ТипСтрока);
|
||
СоответствиеБДИндекс.Колонки.Добавить("Значение", ТипСтрокаЗначение);
|
||
СоответствиеБДИндекс.Колонки.Добавить("КоличествоСимволов", ТипЧисло);
|
||
СоответствиеБДИндекс.Индексы.Добавить("Ключ");
|
||
СоответствиеБДИндекс.Индексы.Добавить("КоличествоСимволов");
|
||
|
||
СоответствиеБДПоля = Новый ТаблицаЗначений;
|
||
СоответствиеБДПоля.Колонки.Добавить("Ключ", ТипСтрока);
|
||
СоответствиеБДПоля.Колонки.Добавить("Значение", ТипСтрокаЗначение);
|
||
СоответствиеБДПоля.Колонки.Добавить("КоличествоСимволов", ТипЧисло);
|
||
СоответствиеБДПоля.Индексы.Добавить("Ключ");
|
||
СоответствиеБДПоля.Индексы.Добавить("КоличествоСимволов");
|
||
|
||
СоответствиеБД = Новый ТаблицаЗначений;
|
||
СоответствиеБД.Колонки.Добавить("Ключ", ТипСтрока);
|
||
СоответствиеБД.Колонки.Добавить("Значение", ТипСтрокаЗначение);
|
||
СоответствиеБД.Колонки.Добавить("КоличествоСимволов", ТипЧисло);
|
||
СоответствиеБД.Индексы.Добавить("Ключ");
|
||
СоответствиеБД.Индексы.Добавить("КоличествоСимволов");
|
||
|
||
Для каждого Строка Из СтруктураБД Цикл
|
||
НоваяСтрока = СоответствиеБД.Добавить();
|
||
НоваяСтрока.Ключ = Строка.ИмяТаблицыХранения;
|
||
НоваяСтрока.Значение = Строка.ИмяТаблицы;
|
||
НоваяСтрока.КоличествоСимволов = СтрДлина(Строка.ИмяТаблицыХранения);
|
||
КонецЦикла;
|
||
СоответствиеБД.Сортировать("КоличествоСимволов Убыв, Ключ Убыв");
|
||
|
||
Для каждого Строка Из СтруктураБД Цикл
|
||
Для каждого Индекс Из Строка.Индексы Цикл
|
||
НоваяСтрока = СоответствиеБДИндекс.Добавить();
|
||
НоваяСтрока.Ключ = Индекс.ИмяИндексаХранения;
|
||
СписокПоле = "";
|
||
Разделитель = "";
|
||
Для каждого Поле Из Индекс.Поля Цикл
|
||
Если ЗначениеЗаполнено(Поле.ИмяПоля) Тогда
|
||
СписокПоле = СписокПоле + Разделитель + Поле.ИмяПоля; // + "(" + Поле.Метаданные + ")";
|
||
//Если ЗначениеЗаполнено(Поле.Метаданные) Тогда
|
||
КонецЕсли;
|
||
Разделитель = ", ";
|
||
КонецЦикла;
|
||
НоваяСтрока.Значение = СписокПоле;
|
||
НоваяСтрока.КоличествоСимволов = СтрДлина(Индекс.ИмяИндексаХранения);
|
||
КонецЦикла;
|
||
|
||
Для каждого Поле Из Строка.Поля Цикл
|
||
Если ЗначениеЗаполнено(Поле.ИмяПоля) Тогда
|
||
НоваяСтрока = СоответствиеБДПоля.Добавить();
|
||
НоваяСтрока.Ключ = Поле.ИмяПоляХранения;
|
||
НоваяСтрока.Значение = Поле.ИмяПоля;
|
||
НоваяСтрока.КоличествоСимволов = СтрДлина(Поле.ИмяПоляХранения);
|
||
Иначе
|
||
Позиция = Найти(Поле.ИмяПоляХранения, "_IDRRef");
|
||
Если Позиция > 1 Тогда
|
||
ИмяОбъекта = Лев(Поле.ИмяПоляХранения, Позиция-1);
|
||
ИмяТаблицы = СоответствиеБД.Найти(ИмяОбъекта, "Ключ").Значение;
|
||
НоваяСтрока = СоответствиеБДПоля.Добавить();
|
||
НоваяСтрока.Ключ = Поле.ИмяПоляХранения;
|
||
НоваяСтрока.Значение = "Ссылка(" + ИмяТаблицы + ")";
|
||
НоваяСтрока.КоличествоСимволов = СтрДлина(Поле.ИмяПоляХранения);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
СоответствиеБДПоля.Сортировать("КоличествоСимволов Убыв, Ключ УБЫВ");
|
||
СоответствиеБДИндекс.Сортировать("КоличествоСимволов Убыв, Ключ УБЫВ");
|
||
|
||
Если ТипСУБД = "DBPOSTGRS" Тогда
|
||
ПланЗапросаВМетаданных = НРег(ПланЗапросаВМетаданных);
|
||
ИначеЕсли ТипСУБД = "DBMSSQL" Тогда
|
||
// Очистка запроса
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, "[" + ИмяСУБД() + "].[dbo].", "");
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, "[tempdb].[dbo].", "");
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, "#tt", "ВременнаяТаблица");
|
||
ТекстЗапросаВМетаданных = СтрЗаменить(ТекстЗапросаВМетаданных, "dbo.", "");
|
||
ТекстЗапросаВМетаданных = СтрЗаменить(ТекстЗапросаВМетаданных, "#tt", "ВременнаяТаблица");
|
||
|
||
КонецЕсли;
|
||
|
||
Для каждого Поле Из СоответствиеБДИндекс Цикл
|
||
Если Найти(ПланЗапросаВМетаданных, Поле.Ключ) Тогда
|
||
Если ТипСУБД = "DBPOSTGRS" Тогда
|
||
Ключ = НРег(Поле.Ключ);
|
||
Иначе
|
||
Ключ = Поле.Ключ;
|
||
КонецЕсли;
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, Ключ, НСтр("ru = 'Индекс по'") + " " + Поле.Значение + "");
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
Для каждого Поле Из СоответствиеБДПоля Цикл
|
||
Если Найти(ТекстЗапросаВМетаданных, Поле.Ключ) Тогда
|
||
ТекстЗапросаВМетаданных = СтрЗаменить(ТекстЗапросаВМетаданных, Поле.Ключ, Поле.Значение);
|
||
Если ТипСУБД = "DBPOSTGRS" Тогда
|
||
Ключ = НРег(Поле.Ключ);
|
||
Иначе
|
||
Ключ = Поле.Ключ;
|
||
КонецЕсли;
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, Ключ, Поле.Значение);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Для каждого Поле Из СоответствиеБД Цикл
|
||
Если Найти(ТекстЗапросаВМетаданных, Поле.Ключ) Тогда
|
||
ТекстЗапросаВМетаданных = СтрЗаменить(ТекстЗапросаВМетаданных, Поле.Ключ, Поле.Значение);
|
||
Если ТипСУБД = "DBPOSTGRS" Тогда
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, НРег(Поле.Ключ), Поле.Значение);
|
||
ИначеЕсли ТипСУБД = "DBMSSQL" Тогда
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, "[" + Поле.Ключ + "]", Поле.Значение);
|
||
Иначе
|
||
ПланЗапросаВМетаданных = СтрЗаменить(ПланЗапросаВМетаданных, Поле.Ключ, Поле.Значение);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
ВВидеМетаданных = Новый Структура();
|
||
ВВидеМетаданных.Вставить("ТекстЗапросаВВидеМетаданных", ТекстЗапросаВМетаданных);
|
||
ВВидеМетаданных.Вставить("ПланВыполненияЗапросаВМетаданных", ПланЗапросаВМетаданных);
|
||
|
||
Возврат ВВидеМетаданных;
|
||
КонецФункции
|
||
|
||
// Создает дерево плана выполнения запроса по данным из файла технологического журнала.
|
||
//
|
||
Процедура ПолучитьДеревоПланаВыполненияЗапроса(Знач ПланЗапросаТекст, Знач ПланЗапросаМетаданные, ДеревоПланЗапроса, СуммарнаяСтоимостьОбщая) Экспорт
|
||
|
||
СуммарнаяСтоимостьОбщая = 0;
|
||
|
||
КореньПланаЗапроса = Неопределено;
|
||
СтрокиДерева = Неопределено;
|
||
Позиция = 1;
|
||
Родитель = Неопределено;
|
||
ПредыдущаяПозиция = 0;
|
||
СтрокаДерево = ДеревоПланЗапроса;
|
||
Пока Позиция > 0 Цикл
|
||
МассивЯчеек = Новый Массив;
|
||
Для Индекс = 1 По 8 Цикл
|
||
Позиция = Найти(ПланЗапросаТекст, ",");
|
||
МассивЯчеек.Добавить(СокрЛП(Лев(ПланЗапросаТекст, Позиция-1)));
|
||
ПланЗапросаТекст = Сред(ПланЗапросаТекст, Позиция + 1);
|
||
КонецЦикла;
|
||
Позиция = Найти(ПланЗапросаТекст, Символы.ПС);
|
||
Если Позиция = 0 Тогда
|
||
Оператор = ПланЗапросаТекст;
|
||
Иначе
|
||
Оператор = Лев(ПланЗапросаТекст, Позиция - 1);
|
||
КонецЕсли;
|
||
ПланЗапросаТекст = Сред(ПланЗапросаТекст, Позиция + 1);
|
||
|
||
Для Индекс = 1 По 8 Цикл
|
||
ПозицияМетаданные = Найти(ПланЗапросаМетаданные, ",");
|
||
ПланЗапросаМетаданные = Сред(ПланЗапросаМетаданные, ПозицияМетаданные + 1);
|
||
КонецЦикла;
|
||
ПозицияМетаданные = Найти(ПланЗапросаМетаданные, Символы.ПС);
|
||
Если ПозицияМетаданные > 0 Тогда
|
||
ОператорМетаданные = Лев(ПланЗапросаМетаданные, ПозицияМетаданные - 1);
|
||
ПланЗапросаМетаданные = Сред(ПланЗапросаМетаданные, ПозицияМетаданные + 1);
|
||
Иначе
|
||
ОператорМетаданные = ПланЗапросаМетаданные;
|
||
КонецЕсли;
|
||
|
||
ПозицияМетаданные = Найти(ОператорМетаданные, "|--") - 4;
|
||
|
||
Если ПозицияМетаданные = 0 Тогда
|
||
СтрокаДерево = ДеревоПланЗапроса.Строки.Добавить();
|
||
КореньПланаЗапроса = СтрокаДерево;
|
||
Иначе
|
||
Если ПредыдущаяПозиция < ПозицияМетаданные Тогда
|
||
СтрокаДерево = СтрокаДерево.Строки.Добавить();
|
||
ИначеЕсли ПредыдущаяПозиция > ПозицияМетаданные Тогда
|
||
СтрокаДерево = НайтиПозициюВВетке(СтрокаДерево, ПозицияМетаданные);
|
||
Если СтрокаДерево <> Неопределено Тогда
|
||
СтрокаДерево = СтрокаДерево.Строки.Добавить();
|
||
Иначе
|
||
СтрокаДерево = ДеревоПланЗапроса.Строки.Добавить();
|
||
КонецЕсли;
|
||
Иначе
|
||
СтрокаДерево = СтрокаДерево.Родитель.Строки.Добавить();
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Если СтрокаДерево.Родитель = Неопределено Тогда
|
||
СуммарнаяСтоимостьОбщая = СуммарнаяСтоимостьОбщая + ПреобразоватьВЧисло(МассивЯчеек[6]);
|
||
КонецЕсли;
|
||
|
||
ПозицияSQL = Найти(Оператор, "|--");
|
||
СтрокаДерево.Оператор = Сред(Оператор, ПозицияSQL + 3);
|
||
СтрокаДерево.ОператорМетаданные = Сред(ОператорМетаданные, ПозицияМетаданные + 7);
|
||
СтрокаДерево.Отступ = ПозицияМетаданные;
|
||
СтрокаДерево.СтрокиФакт = МассивЯчеек[0];
|
||
СтрокаДерево.ВызовыФакт = МассивЯчеек[1];
|
||
СтрокаДерево.СтрокиПлан = МассивЯчеек[2];
|
||
СтрокаДерево.ЗатратыВводаВывода = МассивЯчеек[3];
|
||
СтрокаДерево.ЗагрузкаЦП = МассивЯчеек[4];
|
||
СтрокаДерево.СреднийРазмерСтрок = МассивЯчеек[5];
|
||
СтрокаДерево.СтоимостьОбщая = ПреобразоватьВЧисло(МассивЯчеек[6]);
|
||
СтрокаДерево.ВызовыПлан = МассивЯчеек[7];
|
||
ПредыдущаяПозиция = ПозицияМетаданные;
|
||
КонецЦикла;
|
||
|
||
РассчитатьСтоимостьОператоров(ДеревоПланЗапроса.Строки);
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция РассчитатьСтоимостьОператоров(ВеткаДерева)
|
||
Сумма = 0;
|
||
|
||
Для каждого строка Из ВеткаДерева Цикл
|
||
АккумуляторСтоимости = 0;
|
||
Если Строка.Строки.Количество() > 0 Тогда
|
||
АккумуляторСтоимости = РассчитатьСтоимостьОператоров(строка.Строки);
|
||
КонецЕсли;
|
||
|
||
СтоимостьОператора = Строка.СтоимостьОбщая - АккумуляторСтоимости;
|
||
Строка.Стоимость = ?(СтоимостьОператора < 0, 0, СтоимостьОператора);
|
||
Сумма = Сумма + Строка.СтоимостьОбщая;
|
||
КонецЦикла;
|
||
|
||
Возврат Сумма;
|
||
КонецФункции
|
||
|
||
Функция НайтиПозициюВВетке(Ветка, НомерПозиции)
|
||
Если Ветка.Отступ > НомерПозиции Тогда
|
||
Возврат НайтиПозициюВВетке(Ветка.Родитель, НомерПозиции);
|
||
ИначеЕсли Ветка.Отступ = НомерПозиции Тогда
|
||
Возврат Ветка.Родитель;
|
||
КонецЕсли;
|
||
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПреобразоватьВЧисло(ЧислоСтрокой)
|
||
|
||
Результат = 0;
|
||
ЧислоСтрокой = СокрЛП(ВРег(ЧислоСтрокой));
|
||
Если СтрДлина(ЧислоСтрокой) > 0 Тогда
|
||
ПозицияЕ = Найти(ЧислоСтрокой, "E");
|
||
Если ПозицияЕ = 0 Тогда
|
||
Результат = Число(ЧислоСтрокой);
|
||
Иначе
|
||
ЧислоДоЕ = Число(Лев(ЧислоСтрокой, ПозицияЕ - 1));
|
||
ЧислоПослеЕ = Число(Сред(ЧислоСтрокой, ПозицияЕ + 1));
|
||
Результат = ЧислоДоЕ * Pow(10 ,ЧислоПослеЕ);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ДоработкиSPS
|
||
|
||
Функция SPS_ИдентификаторЗапроса(ПараметрыЗапроса)
|
||
Результат = ТекИдентификаторЗапроса;
|
||
Если Не ЗначениеЗаполнено(Результат) Тогда
|
||
Результат = Новый УникальныйИдентификатор;
|
||
КонецЕсли;
|
||
|
||
|
||
Попытка
|
||
Результат = ПараметрыЗапроса[0].ИдентификаторЗапроса;
|
||
Исключение
|
||
;
|
||
КонецПопытки;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
Процедура SPS_ЗаполнитьЗначениеПараметра_ИзЗапроса(Запрос, Параметр)
|
||
Если ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Запрос.Параметры, Параметр.Имя) Тогда
|
||
ЗначениеПараметра = Запрос.Параметры[Параметр.Имя];
|
||
Если Тип("Массив") = ТипЗнч(ЗначениеПараметра) Тогда
|
||
// в этой консоли запросов нельзя редактировать параметры с типом массив
|
||
// и сохранять такие запросы тоже нельзя
|
||
Список = Новый СписокЗначений;
|
||
Список.ЗагрузитьЗначения(ЗначениеПараметра);
|
||
ЗначениеПараметра = Список;
|
||
Список = Неопределено;
|
||
КонецЕсли;
|
||
|
||
Параметр.Значение = ЗначениеВСтрокуВнутр(ЗначениеПараметра);
|
||
Параметр.Тип = ТипЗнч(ЗначениеПараметра);
|
||
КонецЕсли;
|
||
КонецПроцедуры
|
||
|
||
Процедура SPS_ЗаполнитьЗначенияПараметровИзЗапроса(Запрос, ПараметрыЗапроса)
|
||
ПарЗап = Запрос.НайтиПараметры();
|
||
ПараметрыВЗапросе = Новый Массив;
|
||
|
||
Для каждого СтрПараметры Из ПарЗап Цикл
|
||
РезультатСтруктура = ДобавлениеНовогоПараметра(СтрПараметры, SPS_ИдентификаторЗапроса(ПараметрыЗапроса));
|
||
ПараметрыВЗапросе.Добавить(РезультатСтруктура);
|
||
КонецЦикла;
|
||
|
||
Для Каждого ТекПараметр_ВЗапросе Из ПараметрыВЗапросе Цикл
|
||
УжеЕсть = Ложь;
|
||
Для Каждого ТекПараметр ИЗ ПараметрыЗапроса Цикл
|
||
Если ТекПараметр_ВЗапросе.Имя = ТекПараметр.Имя Тогда
|
||
УжеЕсть = Истина;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если УжеЕсть Тогда Продолжить КонецЕсли;
|
||
|
||
ТекПараметр = ТекПараметр_ВЗапросе;
|
||
SPS_ЗаполнитьЗначениеПараметра_ИзЗапроса(Запрос, ТекПараметр);
|
||
|
||
ПараметрыЗапроса.Добавить(ТекПараметр);
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
Процедура SPS_ЗаполнениеОбщихНаборовДанных(ЗапросОбъект, ЗаполнениеПараметров=Ложь, ИдентификаторЗапроса=Неопределено)
|
||
Если ИспользоватьПредставления Тогда
|
||
Попытка
|
||
Модуль_ЗарплатаКадрыОбщиеНаборыДанных = ОбщегоНазначения.ОбщийМодуль("ЗарплатаКадрыОбщиеНаборыДанных");
|
||
Исключение
|
||
Возврат;
|
||
КонецПопытки;
|
||
|
||
ТекстЗапроса = ЗапросОбъект.Текст;
|
||
|
||
Если ЗаполнениеПараметров И НЕ Неопределено = ИдентификаторЗапроса Тогда
|
||
ПараметрыЗапроса = Параметры.НайтиСтроки(Новый Структура("ИдентификаторЗапроса", ИдентификаторЗапроса));
|
||
ЗагрузкаПараметровВЗапрос(ЗапросОбъект, ПараметрыЗапроса);
|
||
КонецЕсли;
|
||
|
||
SPS_ЗаменитьОбщийТекстЗапросаОбщиеЗапросы(ТекстЗапроса, Ложь);
|
||
Модуль_ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапроса, ЗапросОбъект);
|
||
|
||
ЗапросОбъект.Текст = ТекстЗапроса;
|
||
КонецЕсли;
|
||
КонецПроцедуры
|
||
|
||
Функция SPS_ВосстановитьЗначениеИзСтрокиВнутр(Знач Значение)
|
||
Результат = Значение;
|
||
Если Не Тип("Строка") = ТипЗнч(Значение) Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
Если НЕ ( СтрНачинаетсяС(Значение, "{""") И СтрЗаканчиваетсяНа(Значение, "}") ) Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
Попытка
|
||
Результат = ЗначениеИзСтрокиВнутр(Значение);
|
||
Исключение
|
||
;
|
||
КонецПопытки;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
Функция SPS_ИмяТипаИзЗначения(Знач Значение) Экспорт
|
||
Значение = SPS_ВосстановитьЗначениеИзСтрокиВнутр(Значение);
|
||
|
||
Если ТипЗнч(Значение) = Тип("Строка") Тогда
|
||
ИмяТипа = "Строка";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда
|
||
ИмяТипа = "Число";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Булево") Тогда
|
||
ИмяТипа = "Булево";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Дата") Тогда
|
||
ИмяТипа = "Дата";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("МоментВремени") Тогда
|
||
ИмяТипа = "МоментВремени";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Неопределено") Тогда
|
||
ИмяТипа = "Строка";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
|
||
ИмяТипа = "СписокЗначений";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("ТаблицаЗначений") Тогда
|
||
ИмяТипа = "ТаблицаЗначений";
|
||
ИначеЕсли ТипЗнч(Значение) = Тип("Массив") Тогда
|
||
ИмяТипа = "Массив";
|
||
Иначе
|
||
ИмяТипа = xmlТип(ТипЗнч(Значение)).ИмяТипа;
|
||
КонецЕсли;
|
||
|
||
Возврат ИмяТипа;
|
||
КонецФункции
|
||
|
||
// Выполняется запрос
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - текст запроса.
|
||
// ПараметрыЗапроса - массив параметров запроса.
|
||
// ТДРезультатаЗапроса - табличный документ результата запроса.
|
||
// ПараметрыВыводаЗапроса - Структура - Параметры вывода запроса.
|
||
// * ВыводитьВременныеТаблицы - выводить временные таблицы или нет.
|
||
// * ВыводитьИдентификатор - выводить GUID для ссылок или нет.
|
||
// * ПорядокОбхода - порядок обхода результата запроса.
|
||
// * ИспользованиеЧередования - использовать чередование или нет в результирующем табличном документе.
|
||
// ОтчетПоВыполнениюЗапроса - Структура - Статистика о выполнение запроса.
|
||
// * ВремяВыполнения - время выполнения запроса.
|
||
// * КоличествоСтрок - Количество строк в результате запроса.
|
||
// * ТекстСообщения - текст сообщения об ошибке.
|
||
// Метка запроса - Строка - Метка запроса для поиска его в технологическом журнале.
|
||
//
|
||
Функция SPS_ВыполнитьЗапрос_ВыгрузитьТаблицу(ТекстЗапроса, ПараметрыЗапроса, ТЗРезультатаЗапроса, ПараметрыВыводаЗапроса, ОтчетПоВыполнениюЗапроса, МеткаЗапроса) Экспорт
|
||
|
||
Если ЗначениеЗаполнено(МеткаЗапроса) Тогда
|
||
ЗаписатьМеткуЗапроса(ТекстЗапроса, МеткаЗапроса, "begin");
|
||
КонецЕсли;
|
||
|
||
Если ЗначениеЗаполнено(МеткаЗапроса) Тогда
|
||
ЗаписатьМеткуЗапроса(ТекстЗапроса, МеткаЗапроса, "end");
|
||
КонецЕсли;
|
||
|
||
// Массив текстов запросов.
|
||
МассивТекстов = ПостроитьМассивТекстовЗапросов(ТекстЗапроса);
|
||
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса ,"\;", ";"); // Экранирование точки с запятой.
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
|
||
|
||
// Загрузка параметров.
|
||
ЗагрузкаПараметровВЗапрос(Запрос, ПараметрыЗапроса);
|
||
|
||
///SPS
|
||
SPS_ЗаполнениеОбщихНаборовДанных(Запрос);
|
||
МассивТекстов = ПостроитьМассивТекстовЗапросов(Запрос.Текст);
|
||
SPS_ЗаполнитьЗначенияПараметровИзЗапроса(Запрос, ПараметрыЗапроса);
|
||
///SPS||
|
||
|
||
// Проверка на правильность запросов.
|
||
Попытка
|
||
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
||
МассивЗапросов = Запрос.ВыполнитьПакет();
|
||
Конец = ТекущаяУниверсальнаяДатаВМиллисекундах() ;
|
||
ОтчетПоВыполнениюЗапроса.ВремяВыполнения = (Конец - Начало) / 1000;
|
||
Исключение
|
||
ТекстСообщения = ОписаниеОшибки();
|
||
Возврат Неопределено;
|
||
КонецПопытки;
|
||
|
||
МассивДанныхПоЗапросу = Новый Структура;
|
||
МассивДанныхПоЗапросу.Вставить("Запрос", Запрос);
|
||
МассивДанныхПоЗапросу.Вставить("МассивТекстов", МассивТекстов);
|
||
МассивДанныхПоЗапросу.Вставить("МассивЗапросов", МассивЗапросов);
|
||
МассивДанныхПоЗапросу.Вставить("МеткаЗапроса", МеткаЗапроса);
|
||
|
||
Успешно = SPS_Выгрузить_РезультатЗапросов(ТЗРезультатаЗапроса, МассивДанныхПоЗапросу, ПараметрыЗапроса, ПараметрыВыводаЗапроса, ОтчетПоВыполнениюЗапроса);
|
||
Если Не Успешно Тогда
|
||
Если ВозможноОшибкаИзЗаТочкиСЗапятой(ТекстЗапроса) Тогда
|
||
ОтчетПоВыполнениюЗапроса.ТекстСообщения = НСтр("ru = 'Результат запроса не был выведен. Возможно не экранирована точка с запятой. Для экранирования точки с запятой используется обратный слеш -""\;""(см. справку)'");
|
||
Иначе
|
||
ОтчетПоВыполнениюЗапроса.ТекстСообщения = НСтр("ru = 'Запрос не был выполнен, т.к. текст запроса некорректный'");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Возврат МассивЗапросов;
|
||
КонецФункции
|
||
|
||
// Вывод результата последнего запроса в ТЗ.
|
||
//
|
||
// Если временная таблица, то выполняется запрос из массива текстов и формируется результат.
|
||
// Если не временная таблица, то результат берется из МассиваРезультатов.
|
||
//
|
||
// Параметры:
|
||
// ТЗРезультатаЗапроса - таблица результата запроса.
|
||
// МассивДанныхПоЗапросу - Структура - Содержит данные по запроса.
|
||
// * Запрос - Запрос - передаваемый запрос.
|
||
// * МассивТекстов - Массив - массив текстов запросов.
|
||
// * МассивЗапросов - Массив - массив результатов запросов.
|
||
// ПараметрыЗапроса - массив параметров запросов.
|
||
// ПараметрыВыводаЗапроса - Структура - Параметры вывода запроса.
|
||
// * ВыводитьВременныеТаблицы - выводить временные таблицы или нет.
|
||
// * ВыводитьИдентификатор - выводить GUID для ссылок или нет.
|
||
// * ПорядокОбхода - порядок обхода результата запроса.
|
||
// * ИспользованиеЧередования - использовать чередование или нет в результирующем табличном документе.
|
||
// ОтчетПоВыполнениюЗапроса - Структура - Статистика о выполнение запроса.
|
||
// * ВремяВыполнения - время выполнения запроса.
|
||
// * КоличествоСтрок - Количество строк в результате запроса.
|
||
// * ТекстСообщения - текст сообщения об ошибке.
|
||
//
|
||
Функция SPS_Выгрузить_РезультатЗапросов(ТЗРезультатаЗапроса, МассивДанныхПоЗапросу, ПараметрыЗапроса, ПараметрыВыводаЗапроса, ОтчетПоВыполнениюЗапроса)
|
||
|
||
МассивТекстов = МассивДанныхПоЗапросу.МассивТекстов;
|
||
МассивЗапросов = МассивДанныхПоЗапросу.МассивЗапросов;
|
||
МеткаЗапроса = МассивДанныхПоЗапросу.МеткаЗапроса;
|
||
|
||
КоличествоТекстовЗапросов = МассивТекстов.Количество();
|
||
КоличествоРезультатовЗапросов = МассивЗапросов.Количество();
|
||
|
||
Если КоличествоРезультатовЗапросов <> КоличествоТекстовЗапросов Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Для Индекс = 0 По КоличествоТекстовЗапросов - 1 Цикл
|
||
ТекстЗапросаМассива = МассивТекстов.Получить(Индекс);
|
||
|
||
Если ЗначениеЗаполнено(МеткаЗапроса) И Найти(ТекстЗапросаМассива, МеткаЗапроса) > 0 Тогда
|
||
КоличествоРезультатовЗапросов = КоличествоРезультатовЗапросов - 1;
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
КоличествоСтрокОдногоЗапроса = 0;
|
||
МассивШириныКолонок = Новый Массив;
|
||
Свертка = ОпределитьСвертку(Индекс, КоличествоРезультатовЗапросов);
|
||
|
||
Если Индекс = 0 Тогда
|
||
СимволРазделенияЗапросов = "";
|
||
Иначе
|
||
СимволРазделенияЗапросов = ";";
|
||
КонецЕсли;
|
||
|
||
РезультатЗапроса = МассивЗапросов.Получить(Индекс);
|
||
|
||
ТЗ = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
|
||
ТЗРезультатаЗапроса = ТЗ;
|
||
|
||
ОтчетПоВыполнениюЗапроса.КоличествоСтрок = ОтчетПоВыполнениюЗапроса.КоличествоСтрок + КоличествоСтрокОдногоЗапроса;
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
КонецФункции
|
||
|
||
Функция SPS_РазвернутьТекстЗапроса(ТекстЗапроса, ПараметрыЗапроса) Экспорт
|
||
// Массив текстов запросов.
|
||
МассивТекстов = ПостроитьМассивТекстовЗапросов(ТекстЗапроса);
|
||
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса ,"\;", ";"); // Экранирование точки с запятой.
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
|
||
|
||
// Загрузка параметров.
|
||
ЗагрузкаПараметровВЗапрос(Запрос, ПараметрыЗапроса);
|
||
|
||
///SPS
|
||
SPS_ЗаполнениеОбщихНаборовДанных(Запрос);
|
||
МассивТекстов = ПостроитьМассивТекстовЗапросов(Запрос.Текст);
|
||
SPS_ЗаполнитьЗначенияПараметровИзЗапроса(Запрос, ПараметрыЗапроса);
|
||
///SPS||
|
||
|
||
Возврат Запрос.Текст;
|
||
КонецФункции
|
||
|
||
#Область Копии_ЗарплатаКадрыОбщиеНаборыДанных
|
||
Процедура SPS_ЗаменитьОбщийТекстЗапросаОбщиеЗапросы(ТекстЗапросаПриемник, ТолькоРазрешенные)
|
||
Попытка
|
||
Модуль_ЗарплатаКадрыОбщиеНаборыДанныхВнутренний = ОбщегоНазначения.ОбщийМодуль("ЗарплатаКадрыОбщиеНаборыДанныхВнутренний");
|
||
Исключение
|
||
Возврат;
|
||
КонецПопытки;
|
||
|
||
МассивЗапросов = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ТекстЗапросаПриемник, ";");
|
||
СтрокаПОМЕСТИТЬ = "ПОМЕСТИТЬ ОБЩИЕЗАПРОСЫ_";
|
||
РазделителиСлов = SPS_РазделителиСловТекстаЗапроса();
|
||
|
||
Для Каждого ТекстЗапроса Из МассивЗапросов Цикл
|
||
ПозицияСлова = СтрНайти(ВРег(ТекстЗапроса), СтрокаПОМЕСТИТЬ);
|
||
Если ПозицияСлова > 0 Тогда
|
||
ИмяИсточникаДанных = Прав(ТекстЗапроса, СтрДлина(ТекстЗапроса) - ПозицияСлова - СтрДлина(СтрокаПОМЕСТИТЬ) + 1);
|
||
Для НомерСимвола = 1 По СтрДлина(ИмяИсточникаДанных) Цикл
|
||
КодСимвола = КодСимвола(ИмяИсточникаДанных, НомерСимвола);
|
||
Если СтроковыеФункцииКлиентСервер.ЭтоРазделительСлов(КодСимвола, РазделителиСлов) Тогда
|
||
ИмяИсточникаДанных = Лев(ИмяИсточникаДанных, НомерСимвола - 1);
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ТекстЗапросаИсточник = Модуль_ЗарплатаКадрыОбщиеНаборыДанныхВнутренний.ПолучитьТекстОбщегоЗапроса(ИмяИсточникаДанных, ТолькоРазрешенные);
|
||
ТекстЗапросаПриемник = СтрЗаменить(ТекстЗапросаПриемник, ТекстЗапроса, ТекстЗапросаИсточник);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
Функция SPS_РазделителиСловТекстаЗапроса()
|
||
|
||
Возврат Символы.ПС + " .,; ()/+";
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти //Копии_ЗарплатаКадрыОбщиеНаборыДанных
|
||
|
||
#КонецОбласти //ДоработкиSPS
|
||
|
||
|
||
#КонецЕсли
|