Использование менеджера временных таблиц весьма эфективно при больших объемах данных.
Приведу пример как рационально применять даный метод запроса. Есть определенные задачи которые нельзя решить одним запросом и приходится делать не очень красивые решения. запросы в цикле например. И даже если к такому приходится "опустится" то надо уже подумать о максимуме оптимизации. Возможно менеджер временных таблиц и будет ящиком пандоры для спасения.
Важным есть удаление временных таблиц и закрытие менеджера временных таблиц.
Важным есть удаление временных таблиц и закрытие менеджера временных таблиц.
МенВрТаб = Новый МенеджерВременныхТаблиц;
Счет6202 = ПланыСчетов.Хозрасчетный.НайтиПоКоду("62.02");
Счет76АВ = ПланыСчетов.Хозрасчетный.НайтиПоКоду("76.АВ");
Счет6202 = ПланыСчетов.Хозрасчетный.НайтиПоКоду("62.02");
Счет76АВ = ПланыСчетов.Хозрасчетный.НайтиПоКоду("76.АВ");
//->запрос ищет основные проблемные контрагенты и документы расчетов
ТекстЗапроса = "ВЫБРАТЬ
| &Счет76АВ КАК СчетДт,
| &Счет6202 КАК СчетКт,
| ЕСТЬNULL(Остатки6202.Субконто1, Остатки76АВ.Субконто1) КАК Контрагент,
| ЕСТЬNULL(Остатки6202.Субконто3, Остатки76АВ.Субконто2) КАК ДокументРасчетов,
| ЕСТЬNULL(ВЫРАЗИТЬ(Остатки6202.СуммаОстатокКт / 118 * 18 КАК ЧИСЛО(15, 2)), 0) КАК РасчетнаяСумма,
| ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0) КАК СуммаОстатокДт,
| ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) КАК СуммаОстатокКт
|ПОМЕСТИТЬ ВремТаблРасхождения
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаАнализа, Счет = &Счет6202, , Организация = &Организация) КАК Остатки6202
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаАнализа, Счет = &Счет76АВ, , Организация = &Организация) КАК Остатки76АВ
| ПО Остатки6202.Субконто1 = Остатки76АВ.Субконто1
| И Остатки6202.Субконто3 = Остатки76АВ.Субконто2
|ГДЕ
| ВЫБОР
| КОГДА ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) > 0
| И (ВЫРАЗИТЬ(Остатки6202.СуммаОстатокКт / 118 * 18 КАК ЧИСЛО(15, 2))) <> ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0)
| ТОГДА ИСТИНА
| КОГДА ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) = 0
| И ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0) > 0
| ТОГДА ИСТИНА
| КОГДА ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) < 0
| И ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0) = 0
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
|
|ИНДЕКСИРОВАТЬ ПО
| Контрагент,
| ДокументРасчетов";
Запрос = Новый Запрос();
Запрос.УстановитьПараметр("ДатаАнализа", Новый Граница(КонецДня(ДатаАнализа), ВидГраницы.Включая));
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("Счет6202", Счет6202);
Запрос.УстановитьПараметр("Счет76АВ", Счет76АВ);
Запрос.МенеджерВременныхТаблиц = МенВрТаб;
Запрос.Текст = ТекстЗапроса;
Запрос.Выполнить(); //<-
ОсновнойМенВрТаб = Запрос.МенеджерВременныхТаблиц; //сохраняем ссылку на основную таблицу менеджера
ТабличноеПоле.Очистить();
//-> обходим периоды в цикле пытаясь найти все проблемные периоды
ЕщеЕстьРасхождения = Истина;
РасчетнаяДата = ДатаАнализа;
Пока ЕщеЕстьРасхождения Цикл
ОбработкаПрерыванияПользователя();
ЗапросПериоды = Новый Запрос;
ЗапросПериоды.Текст = "ВЫБРАТЬ
| ДанныеСчетов.Контрагент,
| ДанныеСчетов.ДокументРасчетов,
| СУММА(ДанныеСчетов.КонечныйОстатокКт) КАК КонечныйОстатокКт,
| СУММА(ДанныеСчетов.КонечныйОстатокДт) КАК КонечныйОстатокДт
|ПОМЕСТИТЬ ОстаткиПоСчетам
|ИЗ
| (ВЫБРАТЬ
| Остатки6202.Субконто1 КАК Контрагент,
| Остатки6202.Субконто3 КАК ДокументРасчетов,
| ВЫРАЗИТЬ(Остатки6202.СуммаОстатокКт / 118 * 18 КАК ЧИСЛО(15, 2)) КАК КонечныйОстатокКт,
| 0 КАК КонечныйОстатокДт
| ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(
| &ДатаАнализа,
| Счет = &Счет6202,
| ,
| Организация = &Организация
| И Субконто1 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.Контрагент
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)
| И Субконто3 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.ДокументРасчетов
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)) КАК Остатки6202
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| Остатки76АВ.Субконто1,
| Остатки76АВ.Субконто2,
| 0,
| Остатки76АВ.СуммаОстатокДт
| ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(
| &ДатаАнализа,
| Счет = &Счет76АВ,
| ,
| Организация = &Организация
| И Субконто1 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.Контрагент
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)
| И Субконто2 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.ДокументРасчетов
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)) КАК Остатки76АВ) КАК ДанныеСчетов
|
|СГРУППИРОВАТЬ ПО
| ДанныеСчетов.Контрагент,
| ДанныеСчетов.ДокументРасчетов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ ВремТаблРасхождения
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ОстаткиПоСчетам.Контрагент КАК Контрагент,
| ОстаткиПоСчетам.ДокументРасчетов КАК ДокументРасчетов,
| ОстаткиПоСчетам.КонечныйОстатокКт,
| ОстаткиПоСчетам.КонечныйОстатокДт
|ПОМЕСТИТЬ ВремТаблРасхождения
|ИЗ
| ОстаткиПоСчетам КАК ОстаткиПоСчетам
|ГДЕ
| ВЫБОР
| КОГДА ОстаткиПоСчетам.КонечныйОстатокКт < 0
| И ОстаткиПоСчетам.КонечныйОстатокДт = 0
| ТОГДА ЛОЖЬ
| КОГДА ОстаткиПоСчетам.КонечныйОстатокКт <> ОстаткиПоСчетам.КонечныйОстатокДт
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
|
|ИНДЕКСИРОВАТЬ ПО
| Контрагент,
| ДокументРасчетов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| &Период,
| ОстаткиПоСчетам.Контрагент,
| ОстаткиПоСчетам.ДокументРасчетов
|ИЗ
| ОстаткиПоСчетам КАК ОстаткиПоСчетам
|ГДЕ
| (ОстаткиПоСчетам.КонечныйОстатокКт = ОстаткиПоСчетам.КонечныйОстатокДт
| ИЛИ ВЫБОР
| КОГДА ОстаткиПоСчетам.КонечныйОстатокКт < 0
| И ОстаткиПоСчетам.КонечныйОстатокДт = 0
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ ОстаткиПоСчетам";
РасчетнаяДата = НачалоМесяца(РасчетнаяДата)-1;
ЗапросПериоды.УстановитьПараметр("Период", КонецДня(РасчетнаяДата)+1);
ЗапросПериоды.УстановитьПараметр("ДатаАнализа", Новый Граница(КонецДня(РасчетнаяДата), ВидГраницы.Включая));
ЗапросПериоды.УстановитьПараметр("Организация", Организация);
ЗапросПериоды.УстановитьПараметр("Счет6202", Счет6202);
ЗапросПериоды.УстановитьПараметр("Счет76АВ", Счет76АВ);
ЗапросПериоды.МенеджерВременныхТаблиц = ОсновнойМенВрТаб;
Рез = ЗапросПериоды.ВыполнитьПакет();
ЕщеЕстьРасхождения = Булево(Рез.Получить(2).Выгрузить().Получить(0).Количество>0); //[ВремТаблРасхождения] таблица уменшается при переходящем периоде.
Таблица = Рез.Получить(3).Выгрузить(); //таблица найденных ПРОБЛЕМНЫХ периодов (к этому периоду прибавлен месяц и это будет проблемный месяц)
Для Каждого Выборка Из Таблица Цикл
НоваяСтрока = ТабличноеПоле.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
КонецЦикла;
ОсновнойМенВрТаб = ЗапросПериоды.МенеджерВременныхТаблиц;
КонецЦикла; //<-
//->уничтожаем временну таблицу и закрываем менеджер!
УдалениеМенеджераВТ = Новый Запрос();
УдалениеМенеджераВТ.МенеджерВременныхТаблиц = ОсновнойМенВрТаб;
УдалениеМенеджераВТ.Текст = "УНИЧТОЖИТЬ ВремТаблРасхождения";
УдалениеМенеджераВТ.Выполнить();
ОсновнойМенВрТаб.Закрыть(); //<-
ТекстЗапроса = "ВЫБРАТЬ
| &Счет76АВ КАК СчетДт,
| &Счет6202 КАК СчетКт,
| ЕСТЬNULL(Остатки6202.Субконто1, Остатки76АВ.Субконто1) КАК Контрагент,
| ЕСТЬNULL(Остатки6202.Субконто3, Остатки76АВ.Субконто2) КАК ДокументРасчетов,
| ЕСТЬNULL(ВЫРАЗИТЬ(Остатки6202.СуммаОстатокКт / 118 * 18 КАК ЧИСЛО(15, 2)), 0) КАК РасчетнаяСумма,
| ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0) КАК СуммаОстатокДт,
| ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) КАК СуммаОстатокКт
|ПОМЕСТИТЬ ВремТаблРасхождения
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаАнализа, Счет = &Счет6202, , Организация = &Организация) КАК Остатки6202
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаАнализа, Счет = &Счет76АВ, , Организация = &Организация) КАК Остатки76АВ
| ПО Остатки6202.Субконто1 = Остатки76АВ.Субконто1
| И Остатки6202.Субконто3 = Остатки76АВ.Субконто2
|ГДЕ
| ВЫБОР
| КОГДА ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) > 0
| И (ВЫРАЗИТЬ(Остатки6202.СуммаОстатокКт / 118 * 18 КАК ЧИСЛО(15, 2))) <> ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0)
| ТОГДА ИСТИНА
| КОГДА ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) = 0
| И ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0) > 0
| ТОГДА ИСТИНА
| КОГДА ЕСТЬNULL(Остатки6202.СуммаОстатокКт, 0) < 0
| И ЕСТЬNULL(Остатки76АВ.СуммаОстатокДт, 0) = 0
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
|
|ИНДЕКСИРОВАТЬ ПО
| Контрагент,
| ДокументРасчетов";
Запрос = Новый Запрос();
Запрос.УстановитьПараметр("ДатаАнализа", Новый Граница(КонецДня(ДатаАнализа), ВидГраницы.Включая));
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("Счет6202", Счет6202);
Запрос.УстановитьПараметр("Счет76АВ", Счет76АВ);
Запрос.МенеджерВременныхТаблиц = МенВрТаб;
Запрос.Текст = ТекстЗапроса;
Запрос.Выполнить(); //<-
ОсновнойМенВрТаб = Запрос.МенеджерВременныхТаблиц; //сохраняем ссылку на основную таблицу менеджера
ТабличноеПоле.Очистить();
//-> обходим периоды в цикле пытаясь найти все проблемные периоды
ЕщеЕстьРасхождения = Истина;
РасчетнаяДата = ДатаАнализа;
Пока ЕщеЕстьРасхождения Цикл
ОбработкаПрерыванияПользователя();
ЗапросПериоды = Новый Запрос;
ЗапросПериоды.Текст = "ВЫБРАТЬ
| ДанныеСчетов.Контрагент,
| ДанныеСчетов.ДокументРасчетов,
| СУММА(ДанныеСчетов.КонечныйОстатокКт) КАК КонечныйОстатокКт,
| СУММА(ДанныеСчетов.КонечныйОстатокДт) КАК КонечныйОстатокДт
|ПОМЕСТИТЬ ОстаткиПоСчетам
|ИЗ
| (ВЫБРАТЬ
| Остатки6202.Субконто1 КАК Контрагент,
| Остатки6202.Субконто3 КАК ДокументРасчетов,
| ВЫРАЗИТЬ(Остатки6202.СуммаОстатокКт / 118 * 18 КАК ЧИСЛО(15, 2)) КАК КонечныйОстатокКт,
| 0 КАК КонечныйОстатокДт
| ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(
| &ДатаАнализа,
| Счет = &Счет6202,
| ,
| Организация = &Организация
| И Субконто1 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.Контрагент
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)
| И Субконто3 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.ДокументРасчетов
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)) КАК Остатки6202
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| Остатки76АВ.Субконто1,
| Остатки76АВ.Субконто2,
| 0,
| Остатки76АВ.СуммаОстатокДт
| ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(
| &ДатаАнализа,
| Счет = &Счет76АВ,
| ,
| Организация = &Организация
| И Субконто1 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.Контрагент
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)
| И Субконто2 В
| (ВЫБРАТЬ
| ВремТаблРасхождения.ДокументРасчетов
| ИЗ
| ВремТаблРасхождения КАК ВремТаблРасхождения)) КАК Остатки76АВ) КАК ДанныеСчетов
|
|СГРУППИРОВАТЬ ПО
| ДанныеСчетов.Контрагент,
| ДанныеСчетов.ДокументРасчетов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ ВремТаблРасхождения
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ОстаткиПоСчетам.Контрагент КАК Контрагент,
| ОстаткиПоСчетам.ДокументРасчетов КАК ДокументРасчетов,
| ОстаткиПоСчетам.КонечныйОстатокКт,
| ОстаткиПоСчетам.КонечныйОстатокДт
|ПОМЕСТИТЬ ВремТаблРасхождения
|ИЗ
| ОстаткиПоСчетам КАК ОстаткиПоСчетам
|ГДЕ
| ВЫБОР
| КОГДА ОстаткиПоСчетам.КонечныйОстатокКт < 0
| И ОстаткиПоСчетам.КонечныйОстатокДт = 0
| ТОГДА ЛОЖЬ
| КОГДА ОстаткиПоСчетам.КонечныйОстатокКт <> ОстаткиПоСчетам.КонечныйОстатокДт
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
|
|ИНДЕКСИРОВАТЬ ПО
| Контрагент,
| ДокументРасчетов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| &Период,
| ОстаткиПоСчетам.Контрагент,
| ОстаткиПоСчетам.ДокументРасчетов
|ИЗ
| ОстаткиПоСчетам КАК ОстаткиПоСчетам
|ГДЕ
| (ОстаткиПоСчетам.КонечныйОстатокКт = ОстаткиПоСчетам.КонечныйОстатокДт
| ИЛИ ВЫБОР
| КОГДА ОстаткиПоСчетам.КонечныйОстатокКт < 0
| И ОстаткиПоСчетам.КонечныйОстатокДт = 0
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ ОстаткиПоСчетам";
РасчетнаяДата = НачалоМесяца(РасчетнаяДата)-1;
ЗапросПериоды.УстановитьПараметр("Период", КонецДня(РасчетнаяДата)+1);
ЗапросПериоды.УстановитьПараметр("ДатаАнализа", Новый Граница(КонецДня(РасчетнаяДата), ВидГраницы.Включая));
ЗапросПериоды.УстановитьПараметр("Организация", Организация);
ЗапросПериоды.УстановитьПараметр("Счет6202", Счет6202);
ЗапросПериоды.УстановитьПараметр("Счет76АВ", Счет76АВ);
ЗапросПериоды.МенеджерВременныхТаблиц = ОсновнойМенВрТаб;
Рез = ЗапросПериоды.ВыполнитьПакет();
ЕщеЕстьРасхождения = Булево(Рез.Получить(2).Выгрузить().Получить(0).Количество>0); //[ВремТаблРасхождения] таблица уменшается при переходящем периоде.
Таблица = Рез.Получить(3).Выгрузить(); //таблица найденных ПРОБЛЕМНЫХ периодов (к этому периоду прибавлен месяц и это будет проблемный месяц)
Для Каждого Выборка Из Таблица Цикл
НоваяСтрока = ТабличноеПоле.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
КонецЦикла;
ОсновнойМенВрТаб = ЗапросПериоды.МенеджерВременныхТаблиц;
КонецЦикла; //<-
//->уничтожаем временну таблицу и закрываем менеджер!
УдалениеМенеджераВТ = Новый Запрос();
УдалениеМенеджераВТ.МенеджерВременныхТаблиц = ОсновнойМенВрТаб;
УдалениеМенеджераВТ.Текст = "УНИЧТОЖИТЬ ВремТаблРасхождения";
УдалениеМенеджераВТ.Выполнить();
ОсновнойМенВрТаб.Закрыть(); //<-
Вывод результата менеджера временных таблиц в таблицу значений (отладка данных МВТ)
Иногда предстоит отлаживать запросы которые содержат менеджеры временных таблиц. И чтобы увидеть результат менеджера необходим еще один запрос к этому менеджеру. Пример функции которая выводит результат менеджера в таблицу значений:
Функция ВывестиРезультатМенеджераВременныхТаблиц(МенеджерВременныхТаблиц, ИмяТаблицы) Экспорт
//Получаем таблицу из менеджера временных таблиц запроса
Запрос = Новый Запрос("ВЫБРАТЬ * ИЗ "+ИмяТаблицы);
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
//Получаем таблицу из менеджера временных таблиц запроса
Запрос = Новый Запрос("ВЫБРАТЬ * ИЗ "+ИмяТаблицы);
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Вывод дополнительных полей МВТ.
Подобная функция, только в третий параметр передаются дополнительные поля. При необходимости увидеть для целей отладки какой-то реквизит после точки.В параметр ДополнительныеПоля передаем например "Номенклатура.Поставщик, Номенклатура.Менеджер" и т.д.
Функция ВывестиРезультатМенеджераВременныхТаблиц(МенеджерВременныхТаблиц, ИмяТаблицы, ДополнительныеПоля="") Экспорт
//Получаем таблицу из менеджера временных таблиц запроса
Запрос = Новый Запрос("ВЫБРАТЬ *"+?(Не ПустаяСтрока(ДополнительныеПоля), ", "+ДополнительныеПоля, "")+" ИЗ "+ИмяТаблицы);
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
//Получаем таблицу из менеджера временных таблиц запроса
Запрос = Новый Запрос("ВЫБРАТЬ *"+?(Не ПустаяСтрока(ДополнительныеПоля), ", "+ДополнительныеПоля, "")+" ИЗ "+ИмяТаблицы);
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Этот комментарий был удален администратором блога.
ОтветитьУдалить