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

Продолжение направления статьи "УТ 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

8 Comments

  1. anton.fly7

    еде полной для красоты выводить на форму текст процедуры разукрашеным ))))

    Reply
  2. Magister

    Ничего так, хорошенькая дырочка получается. Если, конечно, не дать прав на изменение кода только админу.

    Reply
  3. Поручик

    (2) Я тоже сразу не мог понять, что же мне не нравится в этом методе.

    Reply
  4. gavrikprog

    Ну с правами то не проблемка решить, можно создать роль специально для этого

    Reply
  5. fomix

    За идею +!

    Reply
  6. gavrikprog

    Сделал все-таки решение — до ума доведу — опубликую.

    Только хиленько народ голосует, видимо не надо.

    Reply
  7. fomix

    (6) Скорее всего этот способ не всем подходит — т.к. надо кромсать типовую конфу. Легче внешними печатными формами это реализовать!

    Reply
  8. aspirator23

    Аналогичную задачу решал через при внешние обработки.

    Есть только основная обработка — она неизменна.

    В ней только задаются входные параметры.

    Их может быть сколь угодно и любого типа.

    В этой обработке есть поле где указана ссылка на дополнительную внешнюю обработку.

    А вот в них и лежит весь код. Обработки могут быть какие угодно.

    В них весь код. В дополнительную внешнюю обработку передаются параметры.

    Мне показалось так удобно. Ничего не трогаю, только при необходимости, под разные задачи указываю разные дополнительные внешние обработки.

    Дополнительные обработки легко отлаживать.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *