RDT1C/CommonModules/ирОтладка/Ext/Module.bsl
2016-12-04 00:14:16 +03:00

831 lines
64 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#Если Не ТонкийКлиент И Не ВебКлиент Тогда
////////////////////////////////////////////////////////////////////////////////
// ПОДСКАЗКА
Функция ПолучитьЗначениеПеременнойИзТаблицыЛокальногоКонтекстаЛкс(ИмяПеременной, ТаблицаЛокальногоКонтекста) Экспорт
СтруктураКлюча = Новый Структура("нСлово, ТипСлова", НРег(ИмяПеременной), "Свойство");
НайденныеСтроки = ТаблицаЛокальногоКонтекста.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
Возврат НайденныеСтроки[0].Значение;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьЗначениеПеременнойИзТаблицыЛокальногоКонтекста()
// Вычисляет тип значения функции УК по внутренним параметрам и аргументам.
// Предназначена для вызвова из ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.
//
// Параметры:
// ТаблицаЛокальногоКонтекста ТаблицаЗначений (см. ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой);
// МассивПараметров - Массив - выражений параметров.
//
// Возвращаемое значение:
// ТаблицаЗначений - ТаблицаСтруктурТипов (см. ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой).
//
Функция ПравилоВычисленияТипаЗначенияКПА(ТаблицаЛокальногоКонтекста, МассивПараметров) Экспорт
лПлатформа = ирКэш.Получить();
ТаблицаСтруктурТипов = лПлатформа.ПолучитьНовуюТаблицуСтруктурТипа();
Алгоритм = ПолучитьЗначениеПеременнойИзТаблицыЛокальногоКонтекстаЛкс(МассивПараметров[0], ТаблицаЛокальногоКонтекста);
Если Алгоритм <> Неопределено Тогда
Структура = ирКПА(Алгоритм);
СтруктураТипа = лПлатформа.ПолучитьСтруктуруТипаИзЗначения(Структура);
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), СтруктураТипа);
КонецЕсли;
Возврат ТаблицаСтруктурТипов;
КонецФункции // ПравилоВычисленияТипаЗначенияУК()
// Добавляет глобальные переменные и методы в контекст поля текстового документа с контекстной подсказкой.
//
// Параметры
// ПолеТекстовогоДокументаСКонтекстнойПодсказкой - ОбработкаОбъект.ПолеТекстовогоДокументаСКонтекстнойПодсказкой.
//
Процедура ИнициализироватьГлобальныйКонтекстПодсказки(ПолеТекстовогоДокументаСКонтекстнойПодсказкой) Экспорт
#Если _ Тогда
ПолеТекстовогоДокументаСКонтекстнойПодсказкой = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
Если ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ЯзыкПрограммы = 1 Тогда
Возврат;
КонецЕсли;
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ОчиститьТаблицуСловЛокальногоКонтекста();
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьПравилоВычисленияФункции(
"ирКПА", "ПравилоВычисленияТипаЗначенияКПА");
МассивГлобальныхПеременных = Новый Массив;
МассивГлобальныхПеременных.Добавить("ирПлатформа");
Для Каждого ИмяГлобальнойПеременной Из МассивГлобальныхПеременных Цикл
Попытка
ГлобальнаяПеременная = ирНеглобальный.ВычислитьВыражение(ИмяГлобальнойПеременной);
Исключение
// ирПлатформа может отсутствовать
Продолжить;
КонецПопытки;
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(ГлобальнаяПеременная));
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста(
ИмяГлобальнойПеременной, "Свойство", Новый ОписаниеТипов(МассивТипов), ГлобальнаяПеременная, Истина);
КонецЦикла;
СтруктураГлобальныхФункций = Новый Структура;
СтруктураГлобальныхФункций.Вставить("Исследовать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Отладить", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Оперировать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Наблюдать");
СтруктураГлобальныхФункций.Вставить("ЛксОбработатьИндикатор");
СтруктураГлобальныхФункций.Вставить("ЛксСообщитьИтогИндикации");
СтруктураГлобальныхФункций.Вставить("ЛксСравнитьЗначенияСвойств");
СтруктураГлобальныхФункций.Вставить("ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля");
СтруктураГлобальныхФункций.Вставить("ЛксИнтерактивноЗаписатьВЭлементУправления");
СтруктураГлобальныхФункций.Вставить("ЛксПолучитьСтруктуруСвойствОбъекта", Тип("Структура"));
СтруктураГлобальныхФункций.Вставить("ЛксПолучитьИндикаторПроцесса", Тип("Структура"));
СтруктураГлобальныхФункций.Вставить("ЛксПолучитьМассивИзСтрокиСРазделителем", Тип("Массив"));
СтруктураГлобальныхФункций.Вставить("ЛксПолучитьПредставлениеИзИдентификатора", Тип("Строка"));
СтруктураГлобальныхФункций.Вставить("ЛксПолучитьПоследнийФрагмент");
СтруктураГлобальныхФункций.Вставить("ЛксПолучитьПервыйФрагмент");
СтруктураГлобальныхФункций.Вставить("ЛксСкопироватьОтбор");
СтруктураГлобальныхФункций.Вставить("ЛксСкопироватьУниверсальнуюКоллекцию");
Для Каждого ЭлементГлобальнойФункции Из СтруктураГлобальныхФункций Цикл
Если ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("Тип") Тогда
МассивТипов = Новый Массив;
МассивТипов.Добавить(ЭлементГлобальнойФункции.Значение);
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
ИначеЕсли ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("ОписаниеТипов") Тогда
ОписаниеТипов = ЭлементГлобальнойФункции.Значение;
КонецЕсли;
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста(
ЭлементГлобальнойФункции.Ключ, "Метод", ОписаниеТипов);
КонецЦикла;
КонецПроцедуры // ИнициализироватьГлобальныйКонтекстПодсказки()
////////////////////////////////////////////////////////////////////////////////
// ОТЛАДКА
// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
//
// Параметры:
// П1 Произвольный параметр1;
// П2 Произвольный параметр2;
//
// Возвращаемое значение:
// П2 Не используется.
//
Функция Пр(п1, п2 = Неопределено) Экспорт
п1 = п2;
Возврат п1;
КонецФункции // Присвоить()
// Выполняет программный код, переданный как параметр.
// Остальные Параметры могут участвовать в теле этого кода.
// Удобно использовать в отладчике.
//
// Параметры:
// П1 Произвольный параметр1;
// П2 Произвольный параметр2;
// П3 Произвольный параметр3;
// П4 Произвольный параметр4;
//
// Возвращаемое значение:
// Неопределено Не используется.
//
Функция Ду(Знач ТекстПрограммы, п1 = 0, п2 = 0, п3 = 0, п4 = 0) Экспорт
Перем Р;
Попытка
Выполнить(ТекстПрограммы);
Исключение
Возврат ОписаниеОшибки();
КонецПопытки;
Возврат Р;
КонецФункции // Ду()
// На клиенте открывает консоль кода с передачей туда всех своих параметров. На сервере сразу выполняет код.
// Изменения параметров возвращаются в вызывающий контекст в модальном режиме.
//
// Параметры:
// ТекстПрограммы - Строка - программный код для передачи в консоль кода или выполнения;
// РежимОперации Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
// СтрокаИменПараметров Строка - имена параметров для консоли кода через запятую, если не указаны, то будут оригинальные П*;
// П* Произвольный - параметры для использования при выполнении программного кода;
//
// Возвращаемое значение:
// Строка - описание ошибок.
//
Функция Оперировать(Знач ТекстПрограммы = "", Знач РежимОперации = 0, СтрокаИменПараметров= "",
П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null, П6 = Null, П7 = Null, П8 = Null, П9 = Null) Экспорт
Если Не ПравоДоступа("Использование", Метаданные.ОбщиеФормы.ирКонсольКода) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
#Если Сервер И Не Клиент Тогда
РежимОперации = 2;
#КонецЕсли
МассивИмен = ЛксПолучитьМассивИзСтрокиСРазделителем(СтрокаИменПараметров, ",", Истина);
Если МассивИмен.Количество() > 0 Тогда
Если МассивИмен[0] = "" Тогда
МассивИмен.Удалить(0);
КонецЕсли;
КонецЕсли;
ЧислоПараметров = 9;
ПереданныеПараметры = Новый СписокЗначений;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
ЗначениеПараметра = Вычислить(ИмяПараметра);
Если Ложь
Или ЗначениеПараметра <> Null // Опасный трюк в интерактивном режиме. Отрезает параметры, переданные, но имеющие значение Null.
Или РежимОперации = 2
Тогда
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ПереданныеПараметры.Добавить(ЗначениеПараметра, ПсевдонимПараметра);
КонецЕсли;
КонецЦикла;
Если РежимОперации < 2 Тогда
ФормаОтладки = ПолучитьОбщуюФорму("ирКонсольКода", , Новый УникальныйИдентификатор);
ФормаОтладки.мСписокВнешнихПараметров = ПереданныеПараметры;
ФормаОтладки.Текст = ТекстПрограммы;
Если РежимОперации = 0 Тогда
ФормаОтладки.Открыть();
Возврат Неопределено;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Иначе
ТекстПрограммы = ТекстПрограммы + ";";
Для Индекс = 0 По ПереданныеПараметры.Количество() - 1 Цикл
ВнешнийПараметр = ПереданныеПараметры[Индекс];
ТекстПрограммы = ВнешнийПараметр.Представление + "=" + "_АлгоритмОбъект[" + Индекс + "].Значение;" + Символы.ПС + ТекстПрограммы;
ТекстПрограммы = ТекстПрограммы + Символы.ПС + "_АлгоритмОбъект[" + Индекс + "].Значение = " + ВнешнийПараметр.Представление + ";";
КонецЦикла;
ирНеглобальный.ВыполнитьАлгоритм(ТекстПрограммы, ПереданныеПараметры);
ПолученныеПараметры = ПереданныеПараметры;
КонецЕсли;
ОписаниеОшибок = "";
НовоеЗначение = Неопределено;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
НовоеЗначение = Неопределено;
Если ПолученныеПараметры.Количество() > Счетчик - 1 Тогда
НовоеЗначение = ПолученныеПараметры[Счетчик - 1].Значение;
КонецЕсли;
Если Вычислить(ИмяПараметра) <> НовоеЗначение Тогда
Попытка
Выполнить(ИмяПараметра + " = НовоеЗначение");
Исключение
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ОписаниеОшибки = "Ошибка возвращения параметра " + ПсевдонимПараметра + ": " + ОписаниеОшибки();
ОписаниеОшибок = ОписаниеОшибок + ОписаниеОшибки;
Сообщить(ОписаниеОшибки);
КонецПопытки;
КонецЕсли;
КонецЦикла;
Возврат ОписаниеОшибок;
КонецФункции // РП()
// Подготавливает строку для помещения всех переменных в структуру с целью ее дальнейшего вычисления в отладчике "Вычислить(Пер())".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - программный код для анализа, берется из буфера обмена если пустой.
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция Пер(Знач ТекстПрограммы = "") Экспорт
Параметры = ирНеглобальный.ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(ТекстПрограммы);
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
НовыйТекст = ирНеглобальный.ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы);
СтрокаРезультата = "Новый Структура(""" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Функция получает таблицу значений из указанной временной таблицы из менеджера временных таблиц,
// либо структуру из всех входящих в запрос временных таблиц.
// Используется для просмотра временных таблиц серверного менеджера временных таблиц в отладчике.
// Параметры:
// ЗапросИлиМенеджерВременныхТаблиц - Запрос, МенеджерВременныхТаблиц
// ИмяВременнойТаблицы - Строка, *"" - можно не указывать для запроса, тогда будут получены все временные таблицы
// ДопустимоеЧислоСтрок - Число, *500000 - выбирать из временной таблицы не более этого числа строк
//
// Результат - ТаблицаЗначений, Структура
//
Функция ПолВТ(ЗапросИлиМенеджерВременныхТаблиц, ИмяВременнойТаблицы = "", ДопустимоеЧислоСтрок = 500000) Экспорт
ТекстЗапроса = "
|ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(ДопустимоеЧислоСтрок) + "
| *
|ИЗ
| ИмяВременнойТаблицы
|";
Запрос = Новый Запрос;
Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда
Результат = Новый Структура();
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц.МенеджерВременныхТаблиц;
Платформа = ирКэш.Получить();
Имена = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст);
Для Каждого ИмяВременнойТаблицы Из Имена Цикл
Запрос.Текст = СтрЗаменить(ТекстЗапроса, "ИмяВременнойТаблицы", ИмяВременнойТаблицы);
Попытка
РезультатЗапроса = Запрос.Выполнить();
Исключение
Продолжить;
КонецПопытки;
Результат.Вставить(ИмяВременнойТаблицы, РезультатЗапроса.Выгрузить());
КонецЦикла;
Иначе
Запрос.Текст = СтрЗаменить(ТекстЗапроса, "ИмяВременнойТаблицы", ИмяВременнойТаблицы);
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц;
Результат = Запрос.Выполнить().Выгрузить();
КонецЕсли;
Возврат Результат;
КонецФункции // ПолВТ()
#Если Клиент Тогда
// Начать трассу в технологическом журнале. Сам технологический журнал надо заранее включить.
Функция ТехН() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.НачатьТрассу("Отладчик") Тогда
Возврат "Трасса техножурнала начата";
Иначе
Возврат "Техножурнал не включен. Невозможно начать трассу.";
КонецЕсли;
КонецФункции
// Кончить трассу в технологическом журнале и показать ее анализ
Функция ТехК() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.КончитьТрассу() Тогда
//АнализТехножурнала.ПоказатьТрассу();
Возврат "Трасса техножурнала кончена. Для ее анализа откройте в режиме предприятия ""Анализ техножурнала""";
Иначе
Возврат "Трасса техножурнала не была начата ранее.";
КонецЕсли;
КонецФункции
// Подготавливает строку для вызова Оперировать() в отладчике. Вызвается путем вычисления "Вычислить(Поп())".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - программный код для передачи в консоль кода или выполнения, берется из буфера обмена если пустой;
// РежимОперации Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция Поп(Знач ТекстПрограммы = "", РежимОперации = 1) Экспорт
Если ПустаяСтрока(ТекстПрограммы) Тогда
ТекстПрограммы = ирНеглобальный.ПолучитьТекстИзБуфераОбменаОСЛкс();
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
Пока Истина Цикл
ИнформацияОбОшибке = ПолеВстроенногоЯзыка.ПолучитьИнформациюОбОшибке(ТекстПрограммы);
Если ИнформацияОбОшибке = Неопределено Тогда
Прервать;
КонецЕсли;
НеопределеннаяПеременная = ирКэш.Получить().ПолучитьИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке);
Если Не ЗначениеЗаполнено(НеопределеннаяПеременная) Тогда
Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
Если Не Параметры.Свойство(НеопределеннаяПеременная) Тогда
Параметры.Вставить(НеопределеннаяПеременная);
ПолеВстроенногоЯзыка.ДобавитьСловоЛокальногоКонтекста(НеопределеннаяПеременная);
КонецЕсли;
КонецЦикла;
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
НовыйТекст = ирНеглобальный.ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы);
СтрокаРезультата = "Оперировать(" + НовыйТекст + ", " + РежимОперации + ", " + """" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Обертка Оперировать. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// П* Произвольный;
//
// Возвращаемое значение:
// Неопределено.
//
Функция Оп(П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null) Экспорт
Возврат Оперировать(, Истина, , П1, П2, П3, П4, П5);
КонецФункции // Оп()
// Открывает консоль кода с передачей туда структуры параметров.
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка;
// Модально Булево - открывать окно модально;
// СтруктураПараметров Структура - ключи соответсвуют именам параметов, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОперироватьСтруктурой(Знач ТекстПрограммы = "", Модально = Ложь, СтруктураПараметров) Экспорт
Если Не ПравоДоступа("Использование", Метаданные.ОбщиеФормы.ирКонсольКода) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
Если Истина
И ПустаяСтрока(ТекстПрограммы)
И СтруктураПараметров.Количество() = 1
Тогда
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ТекстПрограммы = КлючИЗначение.Ключ;
КонецЦикла;
КонецЕсли;
ФормаОтладки = ПолучитьОбщуюФорму("ирКонсольКода", , Новый УникальныйИдентификатор);
//ФормаОтладки.мСписокВнешнихПараметров = ЛксСкопироватьУниверсальнуюКоллекцию(СтруктураПараметров);
ПередаваемыеПараметры = Новый СписокЗначений;
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ПередаваемыеПараметры.Добавить(КлючИЗначение.Значение, КлючИЗначение.Ключ);
КонецЦикла;
ФормаОтладки.мСписокВнешнихПараметров = ПередаваемыеПараметры;
ФормаОтладки.Текст = ТекстПрограммы;
Если Не Модально Тогда
ФормаОтладки.Открыть();
Возврат ФормаОтладки;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
//ЗаполнитьЗначенияСвойств(СтруктураПараметров, ПолученныеПараметры);
Для Каждого ПолученныйПараметр Из ПолученныеПараметры Цикл
СтруктураПараметров.Вставить(ПолученныйПараметр.Представление, ПолученныйПараметр.Значение);
КонецЦикла;
Возврат Неопределено;
КонецФункции // РП()
// Обертка ОперироватьСтруктурой. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// СтруктураПараметров Структура - ключи соответсвуют именам параметов, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция Опс(СтруктураПараметров) Экспорт
Возврат ОперироватьСтруктурой(, Истина, СтруктураПараметров);
КонецФункции // Опс()
// Выводит в окно сообщений переданное значение вместе с типом и заданным представлением.
//
// Параметры:
// Значение - Произвольный;
// *Представление Строка, *"" - представление наблюдаемого значения.
//
Процедура Наблюдать(Значение, Представление = "") Экспорт
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат;
КонецЕсли;
Строка = Представление + " = " + "<" + ТипЗнч(Значение) + ">" + "[" + Значение + "]";
Сообщить(Строка);
КонецПроцедуры // Наблюдать()
// <Описание процедуры>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Процедура ОтложенноеОткрытиеИсточникаОшибки() Экспорт
ирПлатформа = ирНеглобальный.ВычислитьВыражение("ирПлатформа");
ОтложенноеОткрытиеИсточникаОшибки = ирКэш.Получить().ОтложенноеОткрытиеИсточникаОшибки;
Если ирКэш.Получить().Это2iS Тогда
Попытка
ФормаСтека = Вычислить("УФ(Перечисления.Сервисы2iS.ПолучитьФормуПоНастройкеФормы, ""СтекСервисов"", , Новый УникальныйИдентификатор)");
ФормаСтека.РежимВыбора = Истина;
ФормаСтека.Открыть();
Исключение
Сообщить("Ошибка при открытии стека ошибки: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Иначе
СписокВыбора = Новый СписокЗначений;
Для Каждого СтрокаИсточникаОшибки Из ОтложенноеОткрытиеИсточникаОшибки Цикл
СписокВыбора.Добавить(СтрокаИсточникаОшибки, СтрокаИсточникаОшибки.АлгоритмОбъект);
КонецЦикла;
СтопСтрока = ОтложенноеОткрытиеИсточникаОшибки.Вставить(0); // Для прекращения обработки вложенных ошибок
СтопСтрока.АлгоритмОбъект = Неопределено;
// Здесь может при открытии формы пойти обновление табличных полей в формах и новые вложенные ошибки в ПриПолученииДанных.
ЭлементСписка = СписокВыбора.ВыбратьЭлемент("Открыть сервис из стека", СписокВыбора[0]);
Если ЭлементСписка <> Неопределено Тогда
СтрокаИсточникаОшибки = ЭлементСписка.Значение;
АлгоритмОбъект = СтрокаИсточникаОшибки.АлгоритмОбъект;
ИнформацияОбОшибке = СтрокаИсточникаОшибки.ИнформацияОбОшибке;
РежимВыполнения = СтрокаИсточникаОшибки.РежимВыполнения;
Смещение = СтрокаИсточникаОшибки.Смещение;
ФормаСервиса = АлгоритмОбъект.Ссылка.ПолучитьФорму();
ФормаСервиса.Открыть();
Если ФормаСервиса.Модифицированность Тогда
ФормаСервиса = АлгоритмОбъект.Ссылка.ПолучитьФорму(,, "ТолькоПросмотр");
ФормаСервиса.Открыть();
КонецЕсли;
Пустышка = ПолучитьОбщуюФорму("ирПустышка", ФормаСервиса);
СтруктураОшибки = Новый Структура;
СтруктураОшибки.Вставить("ИнформацияОбОшибке", ИнформацияОбОшибке);
СтруктураОшибки.Вставить("РежимВыполнения", РежимВыполнения);
СтруктураОшибки.Вставить("СтартоваяСтрока", -Смещение);
Пустышка.ОповеститьОВыборе(СтруктураОшибки);
КонецЕсли;
КонецЕсли;
ОтложенноеОткрытиеИсточникаОшибки.Очистить();
КонецПроцедуры // ОтложенноеОткрытиеИсточникаОшибки()
#КонецЕсли
// Открывает нужную консоль для редактирования сложного объекта.
// Варианты использования в зависимости от типа параметра Объект:
// Запрос, COMОбъект - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов
// ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов
// ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов
// СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
//
// Параметры:
// Объект Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных, COMОбъект.ADODB.Command - исследуемый объект;
// Модально Булево - открывать окно модально, должно быть Истина для использования функции в отладчике;
// НастройкаКомпоновкиИлиТекстЗапроса - НастройкиКомпоновкиДанных, Строка, *Неопределено - настройки для схемы компоновки, текст запроса для WMI или ADODB.Connection;
// ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище;
// ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки - Число, *500000 - допустимое количество строк во всех временных таблицах запроса
// для отложенной отладки, больше этого количества строки не сохраняются, о чем сообщается в результате;
//
// Возвращаемое значение:
// Неопределено.
//
Функция Отладить(Объект, Модально = Ложь, НастройкаКомпоновкиИлиТекстЗапроса = Неопределено, ВнешниеНаборыДанных = Неопределено,
ОтложенноеВыполнение = Ложь, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000) Экспорт
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольЗапросов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
Если ТипЗнч(Модально) <> Тип("Булево") Тогда
ВызватьИсключение "Неправильный тип второго параметра (Модально) метода Отладить. Должен быть Булево";
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
Если Ложь
Или ТипЗнч(Объект) = Тип("Запрос")
Или ТипЗнч(Объект) = Тип("COMОбъект")
Тогда
Результат = Обработки.ирКонсольЗапросов.Создать().ОткрытьДляОтладки(Объект, , , Модально, НастройкаКомпоновкиИлиТекстЗапроса);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
Результат = Обработки.ирКонсольЗапросов.Создать().ОткрытьДляОтладки(Объект.ПолучитьЗапрос(), , , Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
Результат = Обработки.ирКонсольЗапросов.Создать().ОткрытьПоМакетуКомпоновки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
Результат = Обработки.ирКонсольПостроителейОтчетов.Создать().ОткрытьДляОтладки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
Результат = Отчеты.ирКонсольКомпоновокДанных.Создать().ОткрытьДляОтладки(Объект, НастройкаКомпоновкиИлиТекстЗапроса, ВнешниеНаборыДанных, Модально);
Иначе
Возврат "Не поддерживаемый тип " + ТипЗнч(Объект) + " первого параметра";
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, НастройкаКомпоновки, ВнешниеНаборыДанных", , Модально);
Результат = Неопределено;
Если ТипЗнч(Объект) = Тип("Запрос") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
ВременныеТаблицы = Неопределено;
Если Объект.МенеджерВременныхТаблиц <> Неопределено Тогда
ВременныеТаблицы = ПолВТ(Объект, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
Результат = "";
Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
Результат = Результат + КлючИЗначение.Ключ;
КонецЕсли;
КонецЦикла;
Если Результат <> "" Тогда
Результат = Результат + Символы.ПС + "Временные таблицы " + Результат + " были сохранены частично!";
КонецЕсли;
СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
КонецЕсли;
СтруктураЗапроса.Текст = Объект.Текст;
СтруктураЗапроса.ТипЗапроса = "Обычный";
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = ЛксПолучитьКопиюОбъекта(Объект.Параметры);
СтруктураЗапроса.Параметры = Новый Структура();
Для Каждого КлючИЗначение Из Объект.Параметры Цикл
СтруктураЗапроса.Параметры.Вставить(КлючИЗначение.Ключ, ЗначениеВСтрокуВнутр(КлючИЗначение.Значение));
КонецЦикла;
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("COMОбъект") Тогда
Попытка
Пустышка = Объект.CommandText;
ЭтоКомандаADO = Истина;
Исключение
ЭтоКомандаADO = Ложь;
Попытка
Пустышка = Объект.ConnectionString;
ЭтоСоединениеADO = Истина;
Исключение
ЭтоСоединениеADO = Ложь;
КонецПопытки;
КонецПопытки;
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
Если Ложь
Или ЭтоКомандаADO
Или ЭтоСоединениеADO
Тогда
Если ЭтоСоединениеADO Тогда
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапроса;
Иначе
СтруктураЗапроса.Текст = Объект.CommandText;
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = ЛксПолучитьКопиюОбъекта(Объект.Параметры);
СтруктураЗапроса.Параметры = Новый Структура();
Для Каждого Parameter Из Объект.Parameters Цикл
КлючПараметра = Parameter.Name;
Если Не ЛксЛиИмяПеременной(КлючПараметра) Тогда
КлючПараметра = "_" + КлючПараметра;
КонецЕсли;
Если Не ЛксЛиИмяПеременной(КлючПараметра) Тогда
КлючПараметра = КлючПараметра + XMLСтрока(СтруктураЗапроса.Параметры.Количество());
КонецЕсли;
Если СтруктураЗапроса.Параметры.Свойство(КлючПараметра) Тогда
ВызватьИсключение "Не удалось назначить параметру уникальное имя";
КонецЕсли;
СтруктураЗапроса.Параметры.Вставить(КлючПараметра, ЗначениеВСтрокуВнутр(Parameter.Value));
КонецЦикла;
КонецЕсли;
СтруктураЗапроса.ТипЗапроса = "ADO";
//ВременныеТаблицы = Неопределено;
//ВременныеТаблицы = ПолВТ(Объект, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
//Результат = "";
//Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
// Если Результат <> "" Тогда
// Результат = Результат + ", ";
// КонецЕсли;
// Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
// Результат = Результат + КлючИЗначение.Ключ;
// КонецЕсли;
//КонецЦикла;
//Если Результат <> "" Тогда
// Результат = Результат + Символы.ПС + "Временные таблицы " + Результат + " были сохранены частично!";
//КонецЕсли;
//СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
СтруктураПараметров.Объект = СтруктураЗапроса;
Иначе
СтруктураЗапроса.ТипЗапроса = "WQL";
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапроса;
КонецЕсли;
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры");
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект.ПолучитьЗапрос());
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
Результат = "Отложенная отладка построителя отчета не поддерживается";
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновкиИлиТекстЗапроса);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
#Если Не Сервер Тогда
Возврат "Отладка динамического списка доступна только на сервере";
#КонецЕсли
ТекстЗапроса = Объект.ТекстЗапроса;
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + Объект.ОсновнаяТаблица;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ТекущаяГруппировка = НастройкаКомпоновки;
Для Каждого ПолеГруппировки Из Объект.Группировка.Элементы Цикл
Если ПолеГруппировки.Использование Тогда
ТекущаяГруппировка = ирНеглобальный.НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле);
КонецЕсли;
КонецЦикла;
ирНеглобальный.НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура);
Для Каждого ДоступноеПоле Из Объект.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл
Если ДоступноеПоле.Папка Тогда
Продолжить;
КонецЕсли;
ирНеглобальный.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ДоступноеПоле.Поле);
КонецЦикла;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(НастройкаКомпоновки);
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(Объект.Отбор);
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(Объект.Параметры);
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(Объект.Порядок);
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(Объект.УсловноеОформление);
НастройкаКомпоновки = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
Схема = ирНеглобальный.ПолучитьСхемуКомпоновкиПоЗапросуЛкс(Запрос);
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
КонецЕсли;
Если СтруктураПараметров.Объект <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Отладить");
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
ХранимоеЗначение = ирНеглобальный.СериализоватьЗначениеЛкс(ОбъектXDTO);
ОбъектДляОтладки = Справочники.ирОбъектыДляОтладки.СоздатьЭлемент();
ОбъектДляОтладки.Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + СтруктураПараметров.Объект;
ОбъектДляОтладки.XML = ХранимоеЗначение;
ирНеглобальный.ЗаписатьОбъектДляОтладкиЛкс(ОбъектДляОтладки);
Результат = "Создан объект """ + ОбъектДляОтладки + """ в справочнике ""Объекты для отладки"". Далее используйте команду ""Отладить"" в его форме списка.";
Иначе
Если Результат = Неопределено Тогда
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Обертка Отладить. Модально открывает нужную консоль для редактирования объекта.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Варианты использования в зависимости от типа параметра Объект:
// Запрос - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов
// ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов
// ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов
// СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
//
// Параметры:
// Объект Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных - исследуемый объект;
// НастройкаКомпоновкиИлиТекстЗапроса - НастройкиКомпоновкиДанных, Строка, *Неопределено - настройки для схемы компоновки, текст запроса для WMI или ADODB.Connection;
// ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище
//
// Возвращаемое значение:
// Неопределено.
//
Функция От(Объект, НастройкаКомпоновкиИлиТекстЗапроса = Неопределено, ВнешниеНаборыДанных = Неопределено, ОтложеннаяОтладка = Ложь) Экспорт
Возврат Отладить(Объект, Истина, НастройкаКомпоновкиИлиТекстЗапроса, ВнешниеНаборыДанных, ОтложеннаяОтладка);
КонецФункции // ОО()
// Открывает исследователь объектов.
//
// Параметры:
// Объект Произвольный, *Неопределено - объект, который будет исследован;
// Модально Булево - открывать окно модально;
// КакКоллекцию Булево, *Ложь - исследовать как коллекцию вместо объекта.
//
// Возвращаемое значение:
// Сам объект.
//
Функция Исследовать(Объект = Неопределено, Модально = Ложь, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
ИсследовательОбъектов = Обработки.ирИсследовательОбъектов.Создать();
Если КакКоллекцию Тогда
Результат = ИсследовательОбъектов.ИсследоватьКоллекцию(Объект, Модально);
Иначе
Результат = ИсследовательОбъектов.ИсследоватьОбъект(Объект, Модально);
КонецЕсли;
Если Результат <> Неопределено Тогда
Объект = Результат;
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, КакКоллекцию", Объект, Модально, КакКоллекцию);
Попытка
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
Исключение
ОбъектXDTO = Неопределено;
КонецПопытки;
Если ОбъектXDTO <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Исследовать");
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
ХранимоеЗначение = ирНеглобальный.СериализоватьЗначениеЛкс(ОбъектXDTO);
ОбъектДляОтладки = Справочники.ирОбъектыДляОтладки.СоздатьЭлемент();
ОбъектДляОтладки.Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + СтруктураПараметров.Объект;
ОбъектДляОтладки.XML = ХранимоеЗначение;
ирНеглобальный.ЗаписатьОбъектДляОтладкиЛкс(ОбъектДляОтладки);
Результат = "Создан объект """ + ОбъектДляОтладки + """ в справочнике ""Объекты для отладки"". Далее используйте команду ""Отладить"" в его форме списка.";
Иначе
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // Исследовать()
// Обертка Исследовать. Модально открывает объект в исследователе объектов
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция Ис(Объект = Неопределено, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Возврат Исследовать(Объект, Истина, КакКоллекцию, ОтложенноеВыполнение);
КонецФункции // Ис()
#КонецЕсли