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

Продолжение направления статьи "УТ 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 не будет опубликован. Обязательные поля помечены *