Виртуализация документов в запросах

16.02.12

Разработка - Запросы

В типовых конфигурациях при печати документов обычно используется запрос к базе данных для получения данных о документе. Это не всегда удобно, когда требуется вместо реального объекта отправить на печать модифицированный, измененный объект. В таких случаях рекомендую не переписывать запросы типовых, а использовать виртуализацию запросов.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
down.zip
.zip 10,52Kb
19
19 Скачать (1 SM) Купить за 1 850 руб.

Суть метода

Суть метода заключается в том, чтобы точечно вставить изменение непосредственно перед выполнением кода запроса.

Например, в типовой конфигурации УТ есть запрос по печати расходной накладной в модуле объекта:

ВЫБРАТЬ
    РеализацияТоваровУслуг.Номенклатура,
ИЗ Документ.РеализацияТоваровУслуг.ВозвратнаяТара КАК РеализацияТоваровУслуг
ГДЕ
    РеализацияТоваровУслуг.Ссылка = &ТекущийДокумент    
УПОРЯДОЧИТЬ ПО    
    Метка,    
    НомерСтроки

Этот запрос помещается в текст запроса Запрос.Текст, затем вызывается выполнение:     

ЗапросТовары = Запрос.Выполнить().Выгрузить();

Для того, чтобы воспользоваться виртуализацией и напечатать текущий модифицированный документ из памяти, а не хранящийся в  базе данных, достаточно вызвать метод перед выполнением запроса:

ОбработатьЗапросПоВиртуальномуДокументу(Запрос, Ссылка.ПолучитьОбъект(), ЭтотОбъект());

Этот метод заменяет обращения к таблицам документа на обращения к виртуальным таблицам, помещаемым в менеджер временных таблиц.

Функция позволяет можно заменить табличные части и реквизиты шапки документа.

Более интересное применение виртуализации – модификация документа перед его проведением.

Например, в УТ серии должны храниться в документе по одной строке на каждую серию. Это неудобно для пользователей. Поэтому можно серии вынести в отдельную таблицу, но при проведении эмулировать документ с заполненными сериями, т.е. проставлять для каждой строки серию. В этом случае и пригодится вызов виртуализации при контроле остатков, запросе по табличной части документа и т.п.

Демонстрационная обработка для УТ

В обработке-примере используется документ РеализацияТоваровУслуг из УТ.

В обработку скопирована процедура печати накладной.

Перед вызовом каждого из двух запросов добавлена строка:

ОбработатьЗапросПоВиртуальномуДокументу(Запрос, Ссылка.ПолучитьОбъект(), ЭтотОбъект);

Этого достаточно, чтобы печатная форма брала объект из памяти, а не из базы данных. Сравните с трудоемкостью изменения запроса, если бы вы захотели сделать это другим способом!

В форме можно нажать кнопку «Показать форму документа», внести изменения в документ, затем, не закрывая форму документа, нажать кнопку «Распечатать документ» и получить печатную форму накладной по несохраненному в базе объекту.

Пример:

Открываем обработку, выбираем документ:

Открываем документ:

Нажимаем распечатать:

Модифицируем номер, контрагента и количество товара в первой строке:

Нажимаем распечатать:

Как видно, изменения, сделанные в памяти, отобразились в печатной форме, минуя базу данных.

Код процедуры виртуализации

Функция ОбработатьЗапросПоВиртуальномуДокументу(Запрос, ДокументОбъект, ДокументОбъектНовый) Экспорт
    
    ЗапросТМП = Новый Запрос();
    Если Запрос.МенеджерВременныхТаблиц = Неопределено Тогда
        ЗапросТМП.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
        Запрос.МенеджерВременныхТаблиц = ЗапросТМП.МенеджерВременныхТаблиц;
    Иначе
        ЗапросТМП.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
    КонецЕсли;
    
    //Заменяем запрос к документу на запрос к таблице...
    ИмяДокумента = ДокументОбъект.Метаданные().Имя;
    МД = ДокументОбъект.Метаданные();
    ТипСсылка = Новый ОписаниеТипов("ДокументСсылка." + ИмяДокумента);
    Для Каждого МДТЧ ИЗ МД.ТабличныеЧасти Цикл
        
        ИмяТЧ = МДТЧ.Имя; //Идентификатор табличной части
        МаскаТЧ = "Документ." + ИмяДокумента + "." + ИмяТЧ;
        Если Найти(Запрос.Текст, МаскаТЧ) = 0 Тогда Продолжить; КонецЕсли;
        ИмяВТ = "ВТТаб" + ИмяТЧ; //Идентификатор временной таблицы
        Запрос.Текст = СтрЗаменить(Запрос.Текст, МаскаТЧ, " " + ИмяВТ + " ");
        
        ТЗТабличнаяЧасть = ДокументОбъектНовый[ИмяТЧ].Выгрузить();
        ТЗТабличнаяЧасть.Колонки.Добавить("Ссылка", ТипСсылка);
        ТЗТабличнаяЧасть.ЗаполнитьЗначения(ДокументОбъект.Ссылка, "Ссылка");
        
        ЗапросТМП.Текст = "Выбрать * ПОМЕСТИТЬ " + ИмяВТ + " Из &Таб Как Т";
        ЗапросТМП.УстановитьПараметр("Таб", ТЗТабличнаяЧасть);
        ЗапросТМП.Выполнить();
        
    КонецЦикла;
    
    //Заменяем запросы к шапке
    МаскаШапки = "Документ." + ИмяДокумента;
    Если Найти(Запрос.Текст, МаскаШапки) <> 0 Тогда
        
        ИмяВТ = "ВТТабШапка"; //Идентификатор временной таблицы
        Запрос.Текст = СтрЗаменить(Запрос.Текст, МаскаШапки, " " + ИмяВТ + " ");
        
        //Делаем одну строку таблицы на шапку
        ТЗШапка = Новый ТаблицаЗначений();
        СтрокаШапки = ТЗШапка.Добавить();
        
        //Берем реквизиты шапки
        Для Каждого МДРеквизит ИЗ МД.Реквизиты Цикл
            ТЗШапка.Колонки.Добавить(МДРеквизит.Имя, МДРеквизит.Тип);
        КонецЦикла;
        
        //Берем ссылку
        ТЗШапка.Колонки.Добавить("Ссылка", ТипСсылка);
        
        //СтрокаШапки.Ссылка = ДокументОбъект.Ссылка;
        
        //Берем номер
        Если МД.ТипНомера = Метаданные.СвойстваОбъектов.ТипНомераДокумента.Строка Тогда
            ТЗШапка.Колонки.Добавить("Номер", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(МД.ДлинаНомера)));
        Иначе
            ТЗШапка.Колонки.Добавить("Номер", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(МД.ДлинаНомера)));
        КонецЕсли;
        
        //СтрокаШапки.Номер = ДокументОбъектНовый.Номер;
        
        //Берем дату
        ТЗШапка.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
        
        //СтрокаШапки.Дата = ДокументОбъектНовый.Дата;
        
        ЗаполнитьЗначенияСвойств(СтрокаШапки, ДокументОбъектНовый);
        
        ЗапросТМП.Текст = "Выбрать * ПОМЕСТИТЬ " + ИмяВТ + " Из &Таб Как Т";
        ЗапросТМП.УстановитьПараметр("Таб", ТЗШапка);
        ЗапросТМП.Выполнить();
        
    КонецЕсли;
    
    Возврат ДокументОбъектНовый;
    
КонецФункции

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

12000 руб.

02.09.2020    169295    937    403    

905

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    11394    sergey279    18    

65

Запросы Программист Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    6339    XilDen    36    

83

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    9070    user1840182    5    

28

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    2727    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    10220    implecs_team    6    

48

Запросы Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    3624    andrey_sag    10    

38
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Модератор раздела 17.02.12 10:09 Сейчас в теме
Подход давно известен, конечно, применимость его очень редкая :)
Но для начинающих подойдет.
Но обязательно нужно упомянуть, что печать незаписанных документов может приводить к расхождениям бумажных документов и документов в базе.
ИМХО Название "виртуальный документ" нужно заменить на более точный термин - типа "Незаписанный документ" и т.п.
2. fixin 4277 17.02.12 10:34 Сейчас в теме
(1) не знаю, не знаю. я допёр сам до этого "широко известного подхода".

Здесь вроде бы были еще комменты про то, как начать транзакцию, изменить и распечатать. У меня глюки, происки модеров или глюк форума?
4. Модератор раздела 22.02.12 13:02 Сейчас в теме
(2) когда сообщение скрыто, нумерация остается:

3. iov 407 17.02.12 13:01 Сейчас в теме
(0) Конечно подход интересен но учитывая присутствие в типовых механизмов проверки на модифицированность объекта
сводит на нет многие потуги. и приходится добавлять разнообразно извращенные механизмы.
Почти согласен с применением серийных номеров/серий/характеристик и прочая типовая_геммороидальная_супер_нано_техноголия которая дает нам работу (можно как молитву перед едой читать) но самый частый вопрос - кто изменил документ и что там изменилось.
Но это нисколько не принижает достоинства приведенного метода.
+ в карму
Оставьте свое сообщение