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

01.09.15

Разработка - Механизмы платформы 1С

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

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

Файлы

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

Наименование Скачано Купить файл
ТоварныйЧекУТ11 - копия.epf
.epf 19,06Kb
27 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        КонецЦикла;

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

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

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

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

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

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

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

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

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

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

    КонецЦикла;

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

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

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

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

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

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

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

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

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

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

 

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

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


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

 


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

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Механизмы платформы 1С Программист Бесплатно (free)

Разберем 15 мифов о работе платформы «1С:Предприятие 8» – как распространенных, так и малоизвестных. Начнем с классики: «Код, написанный в одну строку, работает быстрее, чем многострочный». Так ли это на самом деле?

16.07.2025    31733    TitanLuchs    108    

149

Механизмы платформы 1С Работа с интерфейсом Программист Стажер 1С:Предприятие 8 Бесплатно (free)

Про ООП в 1С и о том, как сделать свой код более кратким и выразительным при помощи использования текучего интерфейса (fluent interface).

03.02.2025    17361    bayselonarrend    127    

68

Механизмы платформы 1С Программист 1С:Предприятие 8 Бесплатно (free)

В этой статье подробно рассматривается работа с JSON в XDTO в 1С:Предприятие. Вы узнаете, как сериализовать и десериализовать объекты XDTO в JSON, интегрировать 1С с веб-сервисами и API, а также корректно обрабатывать данные при обмене. Разбираются особенности работы с коллекциями, использование функций восстановления и частые ошибки при работе с JSON и XDTO.

30.01.2025    21305    user2122906    9    

66

Механизмы платформы 1С Файловый обмен (TXT, XML, DBF), FTP Программист 1С:Предприятие 8 Бесплатно (free)

Этот материал познакомит вас с механизмом XDTO (XML Data Transfer Objects) в 1С и научит эффективно использовать его возможности. Мы разберёмся, как работать с XML-схемами, создавать модели данных, манипулировать объектами XDTO, а также сериализовать и десериализовать их в XML. Вы узнаете, как использовать XDTO для интеграции с внешними системами, избегать типичных ошибок и оптимизировать код. К концу вы будете уверенно применять XDTO для решения сложных задач обмена данными и автоматизации процессов.

17.01.2025    37289    user2122906    12    

62

Механизмы платформы 1С WEB-интеграция Программист 1С:Предприятие 8 Бесплатно (free)

В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.

14.01.2025    32384    dsdred    106    

148

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    28396    bayselonarrend    22    

177

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    15396    dsdred    22    

86
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. anton.fly7 174 13.10.11 11:28 Сейчас в теме
еде полной для красоты выводить на форму текст процедуры разукрашеным ))))
2. Magister 134 13.10.11 11:38 Сейчас в теме
Ничего так, хорошенькая дырочка получается. Если, конечно, не дать прав на изменение кода только админу.
3. Поручик 4610 13.10.11 11:52 Сейчас в теме
(2) Я тоже сразу не мог понять, что же мне не нравится в этом методе.
4. gavrikprog 118 13.10.11 12:00 Сейчас в теме
Ну с правами то не проблемка решить, можно создать роль специально для этого
5. fomix 33 13.10.11 12:59 Сейчас в теме
6. gavrikprog 118 13.10.11 16:54 Сейчас в теме
Сделал все-таки решение - до ума доведу - опубликую.

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