IE2017

Динамическое изменение функции формирования табличного документа внешней обработки без конфигуратора.

Печать - Печатные формы документов

Продолжение направления статьи "УТ 11. Динамическое изменение MXL-макета внешней печатной формы" в режиме 1С.
http://infostart.ru/public/92500/
Там рассказывалось, как изменять макеты внешних печатных форм.
В этой статье я динамически изменяю процедуру формирования Табличного документа.

Цель направления исследования: одна-две внешние обработки, 5-10 алгоритмов заполнения табличного документа, 20-50-100 макетов MXL.
И все менять удобно и визуально(кроме добавления 2-х обработок)

В общем, добавляем справочник абАлгоритмы, добавляем реквизит Алгоритм, вид Строка неограниченной длины.

Наименование элемента справочника СформироватьПечатнуюФорму

В этот реквизит в режиме 1С предприятие добавляем следующий код

//Значение Реквизита начало

    //Инициализируем и устанавливаем параметры таблибличного документа для печати
    //ТабДокумент = Новый ТабличныйДокумент;
   
ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_Товарный_Чек";
   
ТабДокумент.АвтоМасштаб = Истина;
   
ТабДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;

   
Колонка = ФормированиеПечатныхФорм.ИмяДополнительнойКолонки();
   
ВыводитьКоды = ЗначениеЗаполнено(Колонка);

   
ПервыйДокумент = Истина;

   
//Делаем запрос к объектам, указанным в массиве МассивОбъектов
   
Запрос = Новый Запрос;
   
Запрос.УстановитьПараметр("МассивДокументов", МассивОбъектов);

   
Запрос.Текст =
   
"ВЫБРАТЬ
    |   ДокЧек.Номер                     КАК Номер,
    |   ДокЧек.Дата                      КАК Дата,
    |   ДокЧек.Ссылка                    КАК Ссылка,
    |   ДокЧек.КассаККМ                  КАК КассаККМ,
    |   ДокЧек.Валюта                    КАК Валюта,
    |   ДокЧек.ЦенаВключаетНДС           КАК ЦенаВключаетНДС,
    |   ДокЧек.КассаККМ.Представление    КАК Покупатель,
    |   ДокЧек.НомерЧекаККМ              КАК НомерЧекаККМ,
    |   ДокЧек.Склад.Представление       КАК Магазин,
    |   ДокЧек.Организация               КАК Организация,
    |   ДокЧек.Организация.Префикс       КАК Префикс,
    |   ДокЧек.Организация.Представление КАК Поставщик,
    |   ДокЧек.СуммаДокумента            КАК СуммаДокумента,
    |   ДокЧек.Товары.(
    |       НомерСтроки                     КАК НомерСтроки,
    |       Номенклатура                    КАК Номенклатура,
    |       Номенклатура.Представление      КАК Товар,
    |       Номенклатура.НаименованиеПолное КАК ТоварПолноеНаименование,
    |       Номенклатура.Код                КАК Код,
    |       Номенклатура.Артикул            КАК Артикул,
    |       Характеристика                  КАК Характеристика,
    |       КоличествоУпаковок              КАК Количество,
    |       Номенклатура.ЕдиницаИзмерения.Представление КАК ЕдиницаИзмерения,
    |       Цена КАК Цена,
    |       ДокЧек.Товары.КоличествоУпаковок * ДокЧек.Товары.Цена - ДокЧек.Товары.Сумма КАК Скидка,
    |       Сумма    КАК Сумма,
    |       СуммаНДС КАК СуммаНДС
    |   )
    |ИЗ
    |   Документ.ЧекККМ КАК ДокЧек
    |ГДЕ
    |   ДокЧек.Ссылка В (&МассивДокументов)
    |"
;

   
Выборка = Запрос.Выполнить().Выбрать();

   
//Обработка результата запроса и формирование табличного документа
   
Пока Выборка.Следующий() Цикл

       
// Макет необходимо получать для каждого документа в выборке, т.к. размеры колонок изменяются динамически
       
Макет = ПолучитьМакет("ПФ_MXL_ТоварныйЧек");

        Если Не
ПервыйДокумент Тогда
           
ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;

       
ПервыйДокумент = Ложь;
       
НомерСтрокиНачало = ТабДокумент.ВысотаТаблицы + 1;

       
// Выводим шапку накладной.
       
ОбластьМакета = Макет.ПолучитьОбласть("Заголовок");
       
ОбластьМакета.Параметры.ТекстЗаголовка = ФормированиеПечатныхФорм.СформироватьЗаголовокДокумента(Выборка, "Товарный чек");
       
ОбластьМакета.Параметры.НомерЧекаККМ = Выборка.НомерЧекаККМ;
       
ТабДокумент.Вывести(ОбластьМакета);

       
ОбластьМакета = Макет.ПолучитьОбласть("Поставщик");
       
ПредставлениеПоставщика = ФормированиеПечатныхФорм.ОписаниеОрганизации(ФормированиеПечатныхФорм.СведенияОЮрФизЛице(Выборка.Организация, Выборка.Дата), "ПолноеНаименование,ИНН,ЮридическийАдрес,Телефоны");
       
ОбластьМакета.Параметры.ПредставлениеПоставщика = ПредставлениеПоставщика;
       
ОбластьМакета.Параметры.Поставщик = Выборка.Организация;
       
ТабДокумент.Вывести(ОбластьМакета);

       
ОбластьМакета = Макет.ПолучитьОбласть("Магазин");
       
ОбластьМакета.Параметры.Магазин = Выборка.Магазин;
       
ТабДокумент.Вывести(ОбластьМакета);

       
ЕстьСкидки = Ложь;
       
ЕстьНДС = Ложь;
       
ВыборкаСтрокТовары = Выборка.Товары.Выбрать();
        Пока
ВыборкаСтрокТовары.Следующий() Цикл
            Если
ВыборкаСтрокТовары.Скидка <> 0 Тогда
               
ЕстьСкидки = Истина;
            КонецЕсли;
            Если
ВыборкаСтрокТовары.СуммаНДС <> 0 Тогда
               
ЕстьНДС = Истина;
            КонецЕсли;
        КонецЦикла;

       
ОбластьНомера   = Макет.ПолучитьОбласть("ШапкаТаблицы|НомерСтроки");
       
ОбластьКодов    = Макет.ПолучитьОбласть("ШапкаТаблицы|КолонкаКодов");
       
ОбластьАртикулов= Макет.ПолучитьОбласть("ШапкаТаблицы|КолонкаАртикулов");
       
ОбластьДанных   = Макет.ПолучитьОбласть("ШапкаТаблицы|Данные");
       
ОбластьСкидок   = Макет.ПолучитьОбласть("ШапкаТаблицы|Скидка");
       
ОбластьСуммыНДС = Макет.ПолучитьОбласть("ШапкаТаблицы|СуммаНДС");
       
ОбластьСуммы    = Макет.ПолучитьОбласть("ШапкаТаблицы|Сумма");

       
ТабДокумент.Вывести(ОбластьНомера);
        Если
ВыводитьКоды Тогда
           
ОбластьКодов.Параметры.ИмяКолонкиКодов = Колонка;
           
ТабДокумент.Присоединить(ОбластьКодов);
        КонецЕсли;

       
ТабДокумент.Присоединить(ОбластьАртикулов);

       
ТабДокумент.Присоединить(ОбластьДанных);
        Если
ЕстьСкидки Тогда
           
ТабДокумент.Присоединить(ОбластьСкидок);
        КонецЕсли;
        Если
ЕстьНДС Тогда
           
ТабДокумент.Присоединить(ОбластьСуммыНДС);
        КонецЕсли;

       
ТабДокумент.Присоединить(ОбластьСуммы);

       
ОбластьКолонкаТовар = Макет.Область("Товар");
        Если Не
ВыводитьКоды Тогда
           
ОбластьКолонкаТовар.ШиринаКолонки = ОбластьКолонкаТовар.ШиринаКолонки
                                              + Макет.Область("КолонкаКодов").ШиринаКолонки;
        КонецЕсли;
        Если Не
ЕстьСкидки Тогда
           
ОбластьКолонкаТовар.ШиринаКолонки = ОбластьКолонкаТовар.ШиринаКолонки
                                              + Макет.Область("СуммаБезСкидки").ШиринаКолонки
                                              + Макет.Область("СуммаСкидки").ШиринаКолонки;
        КонецЕсли;

       
ОбластьНомера   = Макет.ПолучитьОбласть("Строка|НомерСтроки");
       
ОбластьКодов    = Макет.ПолучитьОбласть("Строка|КолонкаКодов");
       
ОбластьАртикулов= Макет.ПолучитьОбласть("Строка|КолонкаАртикулов");
       
ОбластьДанных   = Макет.ПолучитьОбласть("Строка|Данные");
       
ОбластьСкидок   = Макет.ПолучитьОбласть("Строка|Скидка");
       
ОбластьСуммыНДС = Макет.ПолучитьОбласть("Строка|СуммаНДС");
       
ОбластьСуммы    = Макет.ПолучитьОбласть("Строка|Сумма");

       
Сумма          = 0;
       
ВсегоСкидок    = 0;
       
ВсегоБезСкидок = 0;

       
ВыборкаСтрокТовары = Выборка.Товары.Выбрать();
        Пока
ВыборкаСтрокТовары.Следующий() Цикл
            Если Не
ЗначениеЗаполнено(ВыборкаСтрокТовары.Номенклатура) Тогда
               
Сообщить("В одной из строк не заполнено значение номенклатуры - строка при печати пропущена.", СтатусСообщения.Важное);
                Продолжить;
            КонецЕсли;

           
ОбластьНомера.Параметры.Заполнить(ВыборкаСтрокТовары);
           
ТабДокумент.Вывести(ОбластьНомера);

            Если
ВыводитьКоды Тогда
                Если
Колонка = "Артикул" Тогда
                   
ОбластьКодов.Параметры.Артикул = ВыборкаСтрокТовары.Артикул;
                Иначе
                   
ОбластьКодов.Параметры.Артикул = ВыборкаСтрокТовары.Код;
                КонецЕсли;
               
ТабДокумент.Присоединить(ОбластьКодов);
            КонецЕсли;

           
ОбластьАртикулов.Параметры.Артикул = ВыборкаСтрокТовары.Артикул;
           
ТабДокумент.Присоединить(ОбластьАртикулов);

           
ОбластьДанных.Параметры.Заполнить(ВыборкаСтрокТовары);
           
ОбластьДанных.Параметры.Товар = ?(Не ЗначениеЗаполнено(ВыборкаСтрокТовары.ТоварПолноеНаименование),
                                           
ВыборкаСтрокТовары.Товар, ВыборкаСтрокТовары.ТоварПолноеНаименование);

        
// + ФормированиеПечатныхФорм.ПредставлениеХарактеристик(ВыборкаСтрокТовары);

           
ТабДокумент.Присоединить(ОбластьДанных);

            Если
ЕстьСкидки Тогда
               
ОбластьСкидок.Параметры.Скидка         = ВыборкаСтрокТовары.Скидка;
               
ОбластьСкидок.Параметры.СуммаБезСкидки = ВыборкаСтрокТовары.Сумма + ВыборкаСтрокТовары.Скидка;
               
ТабДокумент.Присоединить(ОбластьСкидок);
            КонецЕсли;

            Если
ЕстьНДС Тогда
               
ОбластьСуммыНДС.Параметры.СуммаНДС = ВыборкаСтрокТовары.СуммаНДС;
               
ТабДокумент.Присоединить(ОбластьСуммыНДС);
            КонецЕсли;

            Если Не
Выборка.ЦенаВключаетНДС Тогда
               
СуммаСНДС = ВыборкаСтрокТовары.Сумма + ВыборкаСтрокТовары.СуммаНДС;
            Иначе
               
СуммаСНДС = ВыборкаСтрокТовары.Сумма;
            КонецЕсли;

           
ОбластьСуммы.Параметры.Сумма = СуммаСНДС;
           
ТабДокумент.Присоединить(ОбластьСуммы);

           
ВсегоСкидок    = ВсегоСкидок    + ВыборкаСтрокТовары.Скидка;
           
ВсегоБезСкидок = ВсегоБезСкидок + ВыборкаСтрокТовары.Сумма + ВыборкаСтрокТовары.Скидка;

        КонецЦикла;

       
Товары = Выборка.Товары.Выгрузить();

       
// Вывести Итого.
       
ОбластьНомера   = Макет.ПолучитьОбласть("Итого|НомерСтроки");
       
ОбластьКодов    = Макет.ПолучитьОбласть("Итого|КолонкаКодов");
       
ОбластьАртикулов= Макет.ПолучитьОбласть("Итого|КолонкаАртикулов");
       
ОбластьДанных   = Макет.ПолучитьОбласть("Итого|Данные");
       
ОбластьСкидок   = Макет.ПолучитьОбласть("Итого|Скидка");
       
ОбластьСуммы    = Макет.ПолучитьОбласть("Итого|Сумма");
       
ОбластьСуммыНДС = Макет.ПолучитьОбласть("Итого|СуммаНДС");

       
ТабДокумент.Вывести(ОбластьНомера);
        Если
ВыводитьКоды Тогда
           
ТабДокумент.Присоединить(ОбластьКодов);
        КонецЕсли;
       
ТабДокумент.Присоединить(ОбластьАртикулов);
       
ТабДокумент.Присоединить(ОбластьДанных);
        Если
ЕстьСкидки Тогда
           
ОбластьСкидок.Параметры.ВсегоСкидок    = ВсегоСкидок;
           
ОбластьСкидок.Параметры.ВсегоБезСкидок = ВсегоБезСкидок;
           
ТабДокумент.Присоединить(ОбластьСкидок);
        КонецЕсли;

       
СуммаНДС = Товары.Итог("СуммаНДС");
       
Сумма    = Товары.Итог("Сумма");

        Если
ЕстьНДС Тогда
           
ОбластьСуммыНДС.Параметры.СуммаНДС = СуммаНДС;
           
ТабДокумент.Присоединить(ОбластьСуммыНДС);
        КонецЕсли;

        Если Не
Выборка.ЦенаВключаетНДС Тогда
           
СуммаДокумента = Сумма + СуммаНДС;
        Иначе
           
СуммаДокумента = Сумма;
        КонецЕсли;

       
ОбластьСуммы.Параметры.Сумма = СуммаДокумента;
       
ТабДокумент.Присоединить(ОбластьСуммы);

       
// Вывести Сумму прописью.
       
ОбластьМакета = Макет.ПолучитьОбласть("СуммаПрописью");
       
ОбластьМакета.Параметры.ИтоговаяСтрока = "Всего наименований " + ВыборкаСтрокТовары.Количество()
                                               +
", на сумму " + ФормированиеПечатныхФорм.ФорматСумм(Выборка.СуммаДокумента);
       
ОбластьМакета.Параметры.СуммаПрописью  = "";
       
//ФормированиеПечатныхФорм.СформироватьСуммуПрописью(Выборка.СуммаДокумента, Выборка.Валюта);
       
ТабДокумент.Вывести(ОбластьМакета);

       
// Вывести подписи.
       
ОбластьМакета = Макет.ПолучитьОбласть("Подписи");
       
ОбластьМакета.Параметры.Заполнить(Выборка);
       
ТабДокумент.Вывести(ОбластьМакета);

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

    КонецЦикла;

   
//Возврат ТабДокумент;
    //ПоместитьВоВременноеХранилище(ТабДокумент, "аааТабДокумент");

//Значение реквизита окончание

//*********************************************************************************************

Код функции СформироватьПечатнуюФормуТоварногоЧека

Функция СформироватьПечатнуюФормуТоварногоЧека(МассивОбъектов, ОбъектыПечати)

   
////Инициализируем и устанавливаем параметры таблибличного документа для печати
   
ТабДокумент = Новый ТабличныйДокумент;   

    //Так сделано для упрощения примера, у меня один объект в справочнике

    абОбъект=Справочники.абАлгоритмы.НайтиПоНаименованию("СформироватьПечатнуюФорму");
   
абТекст=абОбъект.Алгоритм;

    Выполнить(
абТекст);

    Возврат
ТабДокумент;
  
КонецФункции
// СформироватьПечатнуюФормуТоварногоЧека()

 

Профит, можем изменять функцию формирования табличного документа без конфигуратора.

Если еще использовать механизм динамического изменения макетов(необязательно как я его пытался реализовать, а допустим все сразу хранится в регистре сведений), то имеем достаточно неплохой механизм.


P.S. заготовку печатной формы для экспериментов взял тут //infostart.ru/public/73548/ .

 


Иполнитель: 2012 г. www.rt-finance.ru

Скачать файлы

Наименование Файл Версия Размер
ТоварныйЧекУТ11 - копия.epf
.epf 19,06Kb
13.10.11
27
.epf 19,06Kb 27 Скачать

См. также

Комментарии
1. Антон (anton.fly7) 136 13.10.11 11:28 Сейчас в теме
еде полной для красоты выводить на форму текст процедуры разукрашеным ))))
2. Misha ⁠ (Magister) 133 13.10.11 11:38 Сейчас в теме
Ничего так, хорошенькая дырочка получается. Если, конечно, не дать прав на изменение кода только админу.
3. Сергей Ожерельев (Поручик) 3592 13.10.11 11:52 Сейчас в теме
(2) Я тоже сразу не мог понять, что же мне не нравится в этом методе.
4. Александр Гуляев (gavrikprog) 104 13.10.11 12:00 Сейчас в теме
Ну с правами то не проблемка решить, можно создать роль специально для этого
5. Fomix (fomix) 24 13.10.11 12:59 Сейчас в теме
6. Александр Гуляев (gavrikprog) 104 13.10.11 16:54 Сейчас в теме
Сделал все-таки решение - до ума доведу - опубликую.

Только хиленько народ голосует, видимо не надо.
7. Fomix (fomix) 24 18.10.11 10:25 Сейчас в теме
(6) gavrikprog, Скорее всего этот способ не всем подходит - т.к. надо кромсать типовую конфу. Легче внешними печатными формами это реализовать!
8. aspirator 23 (aspirator23) 303 21.10.11 07:29 Сейчас в теме
Аналогичную задачу решал через при внешние обработки.
Есть только основная обработка - она неизменна.
В ней только задаются входные параметры.
Их может быть сколь угодно и любого типа.
В этой обработке есть поле где указана ссылка на дополнительную внешнюю обработку.
А вот в них и лежит весь код. Обработки могут быть какие угодно.
В них весь код. В дополнительную внешнюю обработку передаются параметры.
Мне показалось так удобно. Ничего не трогаю, только при необходимости, под разные задачи указываю разные дополнительные внешние обработки.
Дополнительные обработки легко отлаживать.
Оставьте свое сообщение