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