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