Имя: Пароль:
1C
 
Функция, которая сама вставляет уничтожение ВТ в тексте запроса
0 SeiOkami
 
14.10.15
09:52
Кто-нить где-нить видел функцию, которая в передаваемый текст запроса сама подставляет где нужно "УНИЧТОЖИТЬ" ?
1 ДенисЧ
 
14.10.15
09:53
Я видел...
МВТ = Неопределено;
Запрос = Неопределено;
2 rozer76
 
14.10.15
10:28
УНИЧТОЖИТЬ актуальна только для 8.1 если что
3 Горогуля
 
14.10.15
10:29
(2) чо?
4 chelentano
 
14.10.15
10:31
МВТ.Закрыть()
Закрывает менеджер временных таблиц. При этом удаляются все временные таблицы, в нем находящиеся. Дальнейшая работа с данным объектом невозможна.
5 rozer76
 
14.10.15
10:35
(3) в случае использования менеджера - в 8.1 это обязательно нужно делать, т.к. таблицы хранятся до закрытия последнего соединения; в 8.2 это желательно, но необязательно, т.к. разработчики платформы сделали автоочистку таблиц
6 Горогуля
 
14.10.15
10:37
нда.. интересно, много ли я нехорошего после себя в 8.1 оставил... ;)
7 Лефмихалыч
 
14.10.15
11:13
(1) (2) (4) думаю, что это все автору известно, но у него есть туева хуча иппанутых регламентов, которые требуют уничтожать явно.
(0) сочувствую
8 SeiOkami
 
03.11.15
10:44
Вот, набросал механизм.
Может кому пригодится


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

Процедура ОбработатьПакет(СхемаЗапроса, ПакетЗапроса, ТаблицаЗапроса, ИндексПакетаЗапроса = Неопределено)
    
    Если  Ложь Тогда  СхемаЗапроса = Новый СхемаЗапроса; ПакетЗапроса = СхемаЗапроса.ПакетЗапросов.Получить(0) КонецЕсли;    //Для того, чтобы работали подсказки 1С
    
    Если ТипЗнч(ПакетЗапроса) = Тип("ЗапросВыбораСхемыЗапроса") Тогда
        
        ИндексПакетаЗапроса                = ?(ИндексПакетаЗапроса = Неопределено, СхемаЗапроса.ПакетЗапросов.Индекс(ПакетЗапроса), ИндексПакетаЗапроса);
        АнализируемыеВременныеТаблицы    = ДоступныеВременныеТаблицыПакета(ПакетЗапроса);
        АнализируемыеВыражения            = Новый Массив;
        
        
        Если Ложь Тогда АнализируемыеВременныеТаблицы = Новый Массив КонецЕсли;
        
        Для Каждого Оператор Из ПакетЗапроса.Операторы Цикл
            
            Для Каждого Источник Из Оператор.Источники Цикл
                
                //Источник
                Если ТипЗнч(Источник.Источник) = Тип("ТаблицаСхемыЗапроса") Тогда
                    ИмяИспользуемойТаблицы    = Источник.Источник.ИмяТаблицы;
                    Если Найти(Источник.Источник.ИмяТаблицы, ".") = 0 Тогда    //Это обращение к ВТ
                        ДобавитьСтрокуВТаблицуЗапроса(ТаблицаЗапроса, ИмяИспользуемойТаблицы, ИндексПакетаЗапроса);
                    КонецЕсли;
                ИначеЕсли ТипЗнч(Источник.Источник) = Тип("ВложенныйЗапросСхемыЗапроса") Тогда
                    ОбработатьПакет(СхемаЗапроса, Источник.Источник.Запрос, ТаблицаЗапроса, ИндексПакетаЗапроса);
                КонецЕсли;
                
                //Удаляем найденные ВТ из массива искомых, потому что они уже и так используются
                ИспользуемыеВТ    = ТаблицаЗапроса.НайтиСтроки(Новый Структура("ИндексПакетаЗапроса", ИндексПакетаЗапроса));
                Для Каждого ИспользуемаяВТ Из ИспользуемыеВТ Цикл
                    ИндексЭлемента    = АнализируемыеВременныеТаблицы.Найти(ИспользуемаяВТ.ИспользуемаяВременнаяТаблица);
                    Если ИндексЭлемента <> Неопределено Тогда
                        АнализируемыеВременныеТаблицы.Удалить(ИндексЭлемента);
                    КонецЕсли;
                КонецЦикла;
                
                //Соединения
                Если АнализируемыеВременныеТаблицы.Количество() > 0 Тогда
                    Для Каждого Соединение Из Источник.Соединения Цикл
                        ИспользуемыеВТ    = ИспользуемыеВременныеТаблицыВВыражении(АнализируемыеВременныеТаблицы, Соединение.Условие);
                        Для Каждого ИспользуемаяВТ Из ИспользуемыеВТ Цикл
                            ДобавитьСтрокуВТаблицуЗапроса(ТаблицаЗапроса, ИспользуемаяВТ, ИндексПакетаЗапроса);
                            ИндексЭлемента    = АнализируемыеВременныеТаблицы.Найти(ИспользуемаяВТ);
                            Если ИндексЭлемента <> Неопределено Тогда
                                АнализируемыеВременныеТаблицы.Удалить(ИндексЭлемента);
                            КонецЕсли;
                        КонецЦикла;
                        Если АнализируемыеВременныеТаблицы.Количество() = 0 Тогда
                            Прервать;
                        КонецЕсли;
                    КонецЦикла;
                КонецЕсли;
                                
            КонецЦикла;
            
            //Отборы
            Если АнализируемыеВременныеТаблицы.Количество() > 0 Тогда
                Для Каждого Отбор Из Оператор.Отбор Цикл
                    ИспользуемыеВТ    = ИспользуемыеВременныеТаблицыВВыражении(АнализируемыеВременныеТаблицы, Отбор);
                    Для Каждого ИспользуемаяВТ Из ИспользуемыеВТ Цикл
                        ДобавитьСтрокуВТаблицуЗапроса(ТаблицаЗапроса, ИспользуемаяВТ, ИндексПакетаЗапроса);
                        ИндексЭлемента    = АнализируемыеВременныеТаблицы.Найти(ИспользуемаяВТ);
                        Если ИндексЭлемента <> Неопределено Тогда
                            АнализируемыеВременныеТаблицы.Удалить(ИндексЭлемента);
                        КонецЕсли;
                    КонецЦикла;
                    Если АнализируемыеВременныеТаблицы.Количество() = 0 Тогда
                        Прервать;
                    КонецЕсли;
                КонецЦикла;
            КонецЕсли;
            
        КонецЦикла;
        
    ИначеЕсли ТипЗнч(ПакетЗапроса) = Тип("ЗапросУничтоженияТаблицыСхемыЗапроса") Тогда
        
        УдаляемыеСтроки    = ТаблицаЗапроса.НайтиСтроки(Новый Структура("ИспользуемаяВременнаяТаблица", ПакетЗапроса.ИмяТаблицы));
        Для Каждого УдаляемаяСтрока Из УдаляемыеСтроки Цикл
            ТаблицаЗапроса.Удалить(УдаляемаяСтрока);
        КонецЦикла;
        
    КонецЕсли;
    
КонецПроцедуры

Функция ИспользуемыеВременныеТаблицыВВыражении(АнализируемыеВременныеТаблицы, Выражение)
    
    ИспользуемыеВременныеТаблицыВВыражении    = Новый Массив;
    
    ТекстВыражения    = ВРег(Строка(Выражение));
    Если Найти(ТекстВыражения, "ВЫБРАТЬ") <> 0
        И Найти(ТекстВыражения, "ИЗ") <> 0
        И Найти(ТекстВыражения, "КАК") <> 0 Тогда
        
        Для Каждого ВременнаяТаблица Из АнализируемыеВременныеТаблицы Цикл
            КоординатаИспользованияВТ    = Найти(ТекстВыражения, ВРег(ВременнаяТаблица) + " КАК");
            Если КоординатаИспользованияВТ <> 0 Тогда
                Если Сред(ТекстВыражения, КоординатаИспользованияВТ-1, 1) <> "." Тогда    //отсекаем выражения "Таблица.ИмяВТ КАК ИмяВТ" И "Документ.ИмяВТ КАК ИмяВТ"
                    ИспользуемыеВременныеТаблицыВВыражении.Добавить(ВременнаяТаблица);
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
        
    КонецЕсли;
    
    Возврат ИспользуемыеВременныеТаблицыВВыражении;
    
КонецФункции

Процедура ДобавитьСтрокуВТаблицуЗапроса(ТаблицаЗапроса, ИспользуемаяВременнаяТаблица, ИндексПакетаЗапроса)
    
    //Добавляем, если такой ещё нет
    Если ТаблицаЗапроса.НайтиСтроки(
        Новый Структура("ИспользуемаяВременнаяТаблица, ИндексПакетаЗапроса", ИспользуемаяВременнаяТаблица, ИндексПакетаЗапроса)
        ).Количество() = 0 Тогда
        стрТаблицаЗапроса                                = ТаблицаЗапроса.Добавить();
        стрТаблицаЗапроса.ИндексПакетаЗапроса            = ИндексПакетаЗапроса;
        стрТаблицаЗапроса.ИспользуемаяВременнаяТаблица    = ИспользуемаяВременнаяТаблица;
    КонецЕсли;
    
КонецПроцедуры

Функция ДоступныеВременныеТаблицыПакета(ПакетЗапроса)
    
    ДоступныеВременныеТаблицыПакета    = Новый Массив;
    
    ДоступныеТаблицы    = ПакетЗапроса.ДоступныеТаблицы.Найти("Временные таблицы");
    Если ДоступныеТаблицы <> Неопределено Тогда
        Для Каждого ДоступнаяТаблица Из ДоступныеТаблицы.Состав Цикл
            ДоступныеВременныеТаблицыПакета.Добавить(ДоступнаяТаблица.Имя);
        КонецЦикла;
    КонецЕсли;
    
    Возврат ДоступныеВременныеТаблицыПакета;
    
КонецФункции
9 SeiOkami
 
03.11.15
10:51
Забыл сказать. Может косячить в определении обращений к ВТ в подзапросах в условиях и звязях. Мои примеры все отработали, но всякое возможно
Программист всегда исправляет последнюю ошибку.