Функция просмотра временных таблиц запроса в отладчике

Logo_1c_8_RazradotkaПри отладке сложных запросов с временными таблицами нужна возможность просматривать содержимое этих таблиц, которую отладчик не предоставляет.

Для просмотра временных таблиц запроса в отладчике удобно использовать специальную функцию. Данная функция парсит текст запроса, вычленяет все временные таблицы, вычисляет их и результат складывает в структуру.

 

 

Как уже было сказано, данная функция парсит текст запроса, вычленяет все временные таблицы, вычисляет их и результат складывает в структуру.

Для удобства использования удобно поместить процедуру в один из глобальных модулей конфигурации.

funkciya-prosmotra-vremennyx-tablic-zaprosa-v-otladchike_03

funkciya-prosmotra-vremennyx-tablic-zaprosa-v-otladchike_04

Функция предназначена для использования в окне «Вычислить выражение» отладчика — возвращает значение, удобное для просмотра в этом окне. Функция максимально автоматизирована и может работать с входными данными разных типов. Назначение аргументов функции понятно из их имён.

funkciya-prosmotra-vremennyx-tablic-zaprosa-v-otladchike_01

По кнопке «Показать значения в отдельном окне (F2)» можно просмотреть сами таблицы:

funkciya-prosmotra-vremennyx-tablic-zaprosa-v-otladchike_02

Текст процедур:

////////////////////////////////////////////////////////////
// Глобальные процедуры и функции, выполняемые на сервере
#Область ОтладкаВременныхТаблиц
//***********************************************************
// Функция показывает все поля всех временных таблиц из менеджера временных таблиц или из самого запроса.
// Используется для просмотра временных таблиц в отладчике.
// Запрос - запрос (для вычленения текста запроса) или менеджер временных таблиц (имена временных таблиц в этом случае надо передавать явно)
// ИменаВТ - строка с именами интересующих временных таблиц (обязательный параметр при передаче менеджера ВТ вместо запроса в первом параметре)
// Пример вызова функции:
//      ПросмотрВременныхТаблиц(Запрос, "")
Функция ВТ(ЗапросИлиМенеджер, ИменаВТ="") Экспорт
// предварительная обработка параметров:
Если ТипЗнч(ЗапросИлиМенеджер) = Тип("МенеджерВременныхТаблиц") Тогда
Если ИменаВТ = "" Тогда
Возврат "Укажите имена временных таблиц через запятую";
Иначе
Запрос = новый Запрос;
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджер;
КонецЕсли;
Иначе
Запрос = ЗапросИлиМенеджер;
КонецЕсли;
ТекстЗапроса = ВРег(Запрос.Текст);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, Символы.Таб, " ");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, Символы.ВТаб, " ");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, Символы.НПП, " ");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ")", ") ");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "(", " (");
ОчищенныйТекстЗапроса = "";
Для НомерСтроки = 1 По СтрЧислоСтрок(ТекстЗапроса) Цикл
ОчереднаяСтрока = СтрПолучитьСтроку(ТекстЗапроса, НомерСтроки);
ПозицияКомментария = Найти(ОчереднаяСтрока, "//");
Если ПозицияКомментария > 0 Тогда
ОчереднаяСтрока = Лев(ОчереднаяСтрока,ПозицияКомментария-1);
КонецЕсли;
ОчищенныйТекстЗапроса = ОчищенныйТекстЗапроса + " " + ОчереднаяСтрока;
КонецЦикла;
ТекстЗапроса = ОчищенныйТекстЗапроса;
// парсинг текста запроса и получение из него имен временных таблиц
ВременныеТаблицыЗапроса = новый Массив;
Если НЕ ИменаВТ="" Тогда
СписокДополнительныхИмен = СтрЗаменить(ИменаВТ, ",", Символы.ПС);
Для Счетчик = 1 По СтрЧислоСтрок(СписокДополнительныхИмен) Цикл
ТекСтрока = СтрПолучитьСтроку(СписокДополнительныхИмен, Счетчик);
ВременныеТаблицыЗапроса.Добавить(ТекСтрока);
КонецЦикла;
КонецЕсли;
стрВременныеТаблицы = НайтиИменаТаблицПоРасположениюСлов(ТекстЗапроса, "ПОМЕСТИТЬ");
Для Каждого КлючЗначение Из стрВременныеТаблицы Цикл
ВременныеТаблицыЗапроса.Добавить(КлючЗначение.Ключ);
КонецЦикла;
стрВременныеТаблицы = НайтиИменаТаблицПоРасположениюСлов(ТекстЗапроса, "ИЗ", "КАК");
Для Каждого КлючЗначение Из стрВременныеТаблицы Цикл
ВременныеТаблицыЗапроса.Добавить(КлючЗначение.Ключ);
КонецЦикла;
стрВременныеТаблицы = НайтиИменаТаблицПоРасположениюСлов(ТекстЗапроса, "СОЕДИНЕНИЕ", "КАК");
Для Каждого КлючЗначение Из стрВременныеТаблицы Цикл
ВременныеТаблицыЗапроса.Добавить(КлючЗначение.Ключ);
КонецЦикла;
УничтожаемыеВременныеТаблицы = НайтиИменаТаблицПоРасположениюСлов(ТекстЗапроса, "УНИЧТОЖИТЬ");
Для Каждого КлючЗначение Из УничтожаемыеВременныеТаблицы Цикл
ВременныеТаблицыЗапроса.Добавить(КлючЗначение.Ключ);
КонецЦикла;
Ответ = новый Структура;
Если Запрос.МенеджерВременныхТаблиц = Неопределено тогда
// на случай, если ВТ удаляются в тексте запроса, сложнейший алгоритм предварительно скопирует их
Смещение =0;
Если УничтожаемыеВременныеТаблицы.Количество() >0 Тогда
Для Каждого КлючИЗначение Из УничтожаемыеВременныеТаблицы Цикл
ПозицияУничтожения = КлючИЗначение.Значение + Смещение;
ИмяВТ = КлючИЗначение.Ключ ;
НовыйПодзапросКопирования   = "ВЫБРАТЬ * ПОМЕСТИТЬ КОПИЯ"+ИмяВТ+" ИЗ "+ИмяВТ+";";
ТекстЗапроса = ЛЕВ(ТекстЗапроса, ПозицияУничтожения-1) + НовыйПодзапросКопирования + Прав(ТекстЗапроса, СтрДлина(ТекстЗапроса)-(ПозицияУничтожения-1));
Смещение = Смещение + НовыйПодзапросКопирования;
КонецЦикла;
КонецЕсли;
// выполняем запрос для создания интересующих нас таблиц
ЗапросТМП = новый запрос;
ЗапросТМП.МенеджерВременныхТаблиц = новый МенеджерВременныхТаблиц;
Для Каждого Пар Из Запрос.Параметры Цикл
ЗапросТМП.УстановитьПараметр(Пар.Ключ, Пар.Значение);
КонецЦикла;
ЗапросТМП.Текст = ТекстЗапроса;
ЗапросТМП.Выполнить();
ЗаполнитьТаблицыПоСпискуИмен(Ответ, ВременныеТаблицыЗапроса, ЗапросТМП.МенеджерВременныхТаблиц);
ЗапросТМП.МенеджерВременныхТаблиц.Закрыть();
Иначе
// это надо запускать после выполнения запроса, чтобы временные таблицы уже были созданы
ОтсутствующиеИменаТаблиц = ЗаполнитьТаблицыПоСпискуИмен(Ответ, ВременныеТаблицыЗапроса, Запрос.МенеджерВременныхТаблиц);
Для Каждого ИмяТаблицы Из ОтсутствующиеИменаТаблиц Цикл
Если УничтожаемыеВременныеТаблицы.Получить(ИмяТаблицы) = Неопределено Тогда
СообщениеОбОшибке = "Таблица еще не создана либо имя задано не верно";
Иначе
СообщениеОбОшибке = "Таблица уничтожается при выполнении пакета";
КонецЕсли;
Ответ.Вставить(ИмяТаблицы, СообщениеОбОшибке);
КонецЦикла;
КонецЕсли;
Возврат Ответ;
КонецФункции
//***********************************************************
Функция ЗаполнитьТаблицыПоСпискуИмен(СтруктураОтвета, МассивИменТаблиц, Менеджер)
ОтсутствующиеИменаТаблиц = Новый Массив;
ЗапросТМП = новый запрос;
ЗапросТМП.МенеджерВременныхТаблиц = Менеджер;
Для Каждого ИмяТаблицы Из МассивИменТаблиц Цикл
Если НЕ СтруктураОтвета.Свойство(ИмяТаблицы) Тогда
ЗапросТМП.Текст = "ВЫБРАТЬ * ИЗ "+ИмяТаблицы+" КАК "+ИмяТаблицы;
Попытка
СтруктураОтвета.Вставить(ИмяТаблицы, ЗапросТМП.Выполнить().Выгрузить());
Исключение
СтруктураОтвета.Вставить(ИмяТаблицы, ОписаниеОшибки());
ОтсутствующиеИменаТаблиц.Добавить(ИмяТаблицы);
КонецПопытки;
КонецЕсли;
КонецЦикла;
Возврат ОтсутствующиеИменаТаблиц;
КонецФункции 
//***********************************************************
Функция НайтиИменаТаблицПоРасположениюСлов(Знач Текст, ПервоеИскомоеСлово, ВтороеИскомоеСлово="")
СписокИгнорируемыхСимволов = новый СписокЗначений;
СписокИгнорируемыхСимволов.Добавить(Символы.ПС);
СписокИгнорируемыхСимволов.Добавить(Символы.ВК);
СписокИгнорируемыхСимволов.Добавить(Символы.НПП);
СписокИгнорируемыхСимволов.Добавить(Символы.Таб);
СписокИгнорируемыхСимволов.Добавить(" ");
СписокРазделителей = новый СписокЗначений;
СписокРазделителей.Добавить("(");
СписокРазделителей.Добавить(")");
СписокРазделителей.Добавить(".");
СписокРазделителей.Добавить(",");
СписокРазделителей.Добавить(";");
СписокРазделителей.Добавить("&");
НайденныеИмена = Новый Структура;
ПервоеИскомоеСлово = ВРег(ПервоеИскомоеСлово);
ВтороеИскомоеСлово = ВРег(ВтороеИскомоеСлово);
Пока Истина Цикл
Найдено = найти(Текст, " " + ВРег(ПервоеИскомоеСлово) + " ");
Длина = СтрДлина(Текст);
Если Найдено > 0 тогда
Текст = СОКРЛП(Прав(Текст, Длина-Найдено-СтрДлина(ПервоеИскомоеСлово)-1));
СтрДлина = СтрДлина(Текст);
СоставляемоеСлово = "";
НайденноеСлово = "";
Для ном = 1 по СтрДлина цикл
ОчереднойСимвол = Сред(Текст, ном, 1) ;
Если не СписокРазделителей.НайтиПоЗначению(ОчереднойСимвол) = Неопределено тогда
СоставляемоеСлово = "";
НайденноеСлово = "";
Прервать;
ИначеЕсли не СписокИгнорируемыхСимволов.НайтиПоЗначению(ОчереднойСимвол) = Неопределено тогда
Если СоставляемоеСлово = "" Тогда
Продолжить;
Иначе
Если НайденноеСлово = "" Тогда
НайденноеСлово = СоставляемоеСлово;
СоставляемоеСлово = "";
Если ВтороеИскомоеСлово="" Тогда
Прервать;
КонецЕсли;
Иначе
Если не СоставляемоеСлово = ВтороеИскомоеСлово Тогда
НайденноеСлово = "";
КонецЕсли;
Прервать;
КонецЕсли;
КонецЕсли;
иначе
СоставляемоеСлово = СоставляемоеСлово + ОчереднойСимвол;
КонецЕсли;
КонецЦикла;
Если НЕ НайденноеСлово = "" Тогда
НайденныеИмена.Вставить(НайденноеСлово, Найдено);
КонецЕсли;
иначе
Прервать;
КонецЕсли;
КонецЦикла;
Возврат НайденныеИмена;
КонецФункции 
#КонецОбласти
Помогла ли вам данная статья?
Да, спасибо, все получилось.
Немного помогла.
Совсем не помогла.
Не то, что я искал(а).
Смотреть результаты
Запись опубликована в рубрике Разработка в 1С с метками . Добавьте в закладки постоянную ссылку.




4 комментария на «Функция просмотра временных таблиц запроса в отладчике»

  1. Иван говорит:

    Добрый день.
    Хорошая функция.

    Нужно только подправить:

    Смещение = ПозицияУничтожения+СтрДлина(» УНИЧТОЖИТЬ»)+СтрДлина(НовыйПодзапросКопирования);

  2. Иван говорит:

    И еще вот здесь

    УничтожаемыеВременныеТаблицы = НайтиИменаТаблицПоРасположениюСлов(ТекстЗапроса, «УНИЧТОЖИТЬ»);
    Для Каждого КлючЗначение Из УничтожаемыеВременныеТаблицы Цикл
    ВременныеТаблицыЗапроса.Добавить(«КОПИЯ»+КлючЗначение.Ключ);
    КонецЦикла;

  3. Иван говорит:

    И еще вот так доработать.

    Если ТипЗнч(ЗапросИлиМенеджер) = Тип(«МенеджерВременныхТаблиц») Тогда
    Если ИменаВТ = «» Тогда
    Для СчетВТ = 0 По ЗапросИлиМенеджер.Таблицы.Количество()-1 Цикл
    Если ИменаВТ = «» Тогда
    ИменаВТ = ЗапросИлиМенеджер.Таблицы[СчетВТ].ПолноеИмя;
    Иначе
    ИменаВТ = ИменаВТ+»,»+ЗапросИлиМенеджер.Таблицы[СчетВТ].ПолноеИмя;
    КонецЕсли;
    КонецЦикла;
    Если ИменаВТ = «» Тогда
    Возврат «Укажите имена временных таблиц через запятую»;
    Иначе
    Запрос = новый Запрос;
    Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджер;
    КонецЕсли;
    Иначе
    Запрос = новый Запрос;
    Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджер;
    КонецЕсли;
    Иначе
    Запрос = ЗапросИлиМенеджер;
    КонецЕсли;

  4. oleksandrhomyak@gmail.com говорит:

Добавить комментарий

Ваш e-mail не будет опубликован.