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

16.02.12

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

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

Скачать исходный код

Наименование Файл Версия Размер
down.zip
.zip 10,52Kb
19
.zip 10,52Kb 19 Скачать

Суть метода

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Пример:

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

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

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

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

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

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

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

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

См. также

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

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

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    129276    700    390    

749

Как посмотреть итоговый запрос в отчете СКД

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

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

15.05.2024    1208    implecs_team    4    

20

Пропорциональное распределение в запросе с использованием АвтоНомерЗаписи()

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

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

11.04.2024    2599    andrey_sag    10    

32

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    6282    KawaNoNeko    23    

26

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2274    2    Yashazz    0    

31

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Бесплатно (free)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

15.01.2024    7061    38    mkalimulin    32    

53

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    2010    vandalsvq    7    

29

Консоль запросов УФ 8.3.2.24.12 (мод от Dr.Zombi)

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Запросы Россия Абонемент ($m)

Работа с запросом и СКД, Полная поддержка пакетных запросов, временных таблиц. Главное скорость отладки запроса и данных, а красота вторична.

1 стартмани

07.12.2023    3468    52    DrZombi    54    

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

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

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