20 июн. 2013 г.

Работа с менеджером временных таблиц


В 1С есть такая замечательная вещь, как МенеджерВременныхТаблиц.  Этот объект позволяет передавать временные таблицы из одного запроса в другой. То есть, мы можем создать временную таблицу в запросе, прерваться, выполнить какой-нибудь код, и продолжить работу с этой временной таблицей дальше. Например, в отчете в зависимости от выбранных настроек первичные данные обрабатываются тем или иным способом. Тогда имеет смысл в одной процедуре сформировать эти данные и поместить их во временную таблицу, которую уже передаем через менеджер временных таблиц в другую процедуру, отвечающую за выбранный способ обработки. Это позволит сократить код, сделать запросы более читаемыми. А так же в случае, если возникнут изменения в методике подготовки первичных данных для обработки, то потребуется внести изменения только в один запрос, а не в каждый.
В качестве примера работы с менеджером временных таблиц приведу следующую обработку.


Я создаю менеджер временных таблиц, и передаю его последовательно в каждую процедуру, для создания и объединения временных таблиц. Результат выводится в сводную таблицу.

&НаКлиенте
Процедура ЗаполнитьСводную(Команда)
 ЗаполнитьСводнуюНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьСводнуюНаСервере()
 
 МенВТ = Новый МенеджерВременныхТаблиц;
 ПолучитьДанныеА(МенВТ);
 ПолучитьДанныеБ(МенВТ);
 ЗагрузитьСводные(МенВТ);
 МенВТ.Закрыть();
 
КонецПроцедуры

&НаСервере
Процедура ПолучитьДанныеА(МенВремТаб)

 Запрос = Новый Запрос;
 Запрос.МенеджерВременныхТаблиц = МенВремТаб;
 Запрос.Текст = "ВЫБРАТЬ
                | ТаблицаА.Контрагент КАК Контрагент,
                | ТаблицаА.Сумма
                |ПОМЕСТИТЬ ТабА
                |ИЗ
                | &ТаблицаА КАК ТаблицаА
                |
                |ИНДЕКСИРОВАТЬ ПО
                | Контрагент";
 Запрос.УстановитьПараметр("ТаблицаА", ТаблицаА.Выгрузить());
 Запрос.Выполнить();
 

КонецПроцедуры // ПолучитьДанныеА()

&НаСервере
Процедура ПолучитьДанныеБ(МенВремТаб)

 Запрос = Новый Запрос;
 Запрос.МенеджерВременныхТаблиц = МенВремТаб;
 Запрос.Текст = "ВЫБРАТЬ
                | ТаблицаБ.Контрагент КАК Контрагент,
                | ТаблицаБ.Комментарий
                |ПОМЕСТИТЬ ТабБ
                |ИЗ
                | &ТаблицаБ КАК ТаблицаБ
                |
                |ИНДЕКСИРОВАТЬ ПО
                | Контрагент";
 Запрос.УстановитьПараметр("ТаблицаБ", ТаблицаБ.Выгрузить());
 Запрос.Выполнить();
 

КонецПроцедуры // ПолучитьДанныеА()

&НаСервере
Процедура ЗагрузитьСводные(МенВремТаб)

 Запрос = Новый Запрос;
 Запрос.МенеджерВременныхТаблиц = МенВремТаб;
 Запрос.Текст = "ВЫБРАТЬ
                | ЕСТЬNULL(ТабА.Контрагент, ТабБ.Контрагент) КАК Контрагент,
                | ЕСТЬNULL(ТабА.Сумма, 0) КАК Сумма,
                | ЕСТЬNULL(ТабБ.Комментарий, """") КАК Комментарий
                |ИЗ
                | ТабА КАК ТабА
                |  ПОЛНОЕ СОЕДИНЕНИЕ ТабБ КАК ТабБ
                |  ПО ТабА.Контрагент = ТабБ.Контрагент
                |
                |УПОРЯДОЧИТЬ ПО
                | Контрагент
                |АВТОУПОРЯДОЧИВАНИЕ";
       
 ТаблицаСводная.Загрузить(Запрос.Выполнить().Выгрузить());

КонецПроцедуры // ЗагрузитьСводные()
 

3 комментария:

  1. В типовых временные таблицы используются при проведении документов, контроль остатков. Хотя на ИнфоСтарте отзывались негативно про использование ВТ, т.к. висят в памяти и сокращают быстродействие. ВТ таблицы надо удалять после использования. Например :
    Запрос = Новый Запрос("УНИЧТОЖИТЬ ДвиженияЗапасыНаСкладахПередЗаписью");

    ОтветитьУдалить
  2. Запрос = Новый Запрос("УНИЧТОЖИТЬ ДвиженияЗапасыНаСкладахПередЗаписью");
    Запрос.МенеджерВременныхТаблиц = СтруктураВременныеТаблицы.МенеджерВременныхТаблиц;
    Запрос.Выполнить();

    ОтветитьУдалить
    Ответы
    1. Ок, тогда от себя добавлю, что использование в запросе "УНИЧТОЖИТЬ Имя_ВТ" лучше применять, когда надо подчистить промежуточные ВТ, а сам менеджер ВТ с конечными данными использовать в других запросах. В случае же, когда менеджер ВТ уже не нужен, можно использовать его метод Закрыть() для уничтожения находящихся в нем ВТ.

      Удалить