Автоматизация печатной формы (автоформирование табличного документа на основе любой таблицы значений)


Автоматическое формирование табличного документа из выбранной таблицы значений.
Пример как можно рутинные действия по оформлению внешнего вида печатной формы переложить на программу.
Статья предназначена в первую очередь для тех, кто не сильно владеет СКД (как я, например), но которым не хочется тратить свое время на формирование разных макетов, если вывести документ нужно в стандартном виде.

Код полностью открыт, пользуйтесь на здоровье. 🙂

Доброе время суток всем.

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

  1. Выводятся только видимые колонки
  2. Ширина колонок рассчитывается из максимальной ширины данных в колонке ( если не указана фикс. ширина)
  3. Формат вывода и (печатное наименование) для каждой колонки можно задать произвольно
  4. По тем колонкам, где нужно, выводятся итоги.

Код рекомендуется подключить как дополнительный общий модуль в конфигурацию.

Для примеры показан вывод списка реализаций из демонстрационной базы "Комплексной автоматизации".

Но применить можно в любой конфигурации с УФ.

 

Описание:

 


&НаСервере
//*** формат входных данных: ПечатьПоШаблону(Знач Табл,НКолонки,ТекстЗаголовка,ПоляВывода,ТекстПодвала)
// (     Табл      - исходная таблица
//         НКолонки - первая строка ШАПКИ вывода
//         ТекстЗаголовка ...
//         ПоляВывода - список выводимых колонок , в представлении значения - формат вывода:
//                        "Вес","Вес|10|ЧДЦ=2|*"
//                        |     |   |   |    | выводим итог по этой колонке
//                        |     |   |   | формат вывода колонки
//                          |     |   | фикс. ширина колонки ( если не указана, то - рассчитывается автоматически )
//                          |     | представление колонки при выводе на печать
//                        | выводимая колонка ( имя должно совпадать с именем в исходной таблице)
//        ТекстПодвала ...
//      )
//Пример 1:
//*********************************
//ПоляВывода = Новый СписокЗначений;
//ПоляВывода.Добавить("Заказ","Заказ||");
//ПоляВывода.Добавить("СкладКорр","Склад (корр)|10|ДФ=гггг-ММ-дд");
//ПоляВывода.Добавить("СкладФакт","Склад (факт)|10|ДФ=гггг-ММ-дд");
//ПоляВывода.Добавить("Контейнер","Контейнер||");
//Если фВесОбъем Тогда
//    ПоляВывода.Добавить("Объем","Объем|12|ЧДЦ=4");
//    ПоляВывода.Добавить("Вес","Вес|10|ЧДЦ=2|*");
//КонецЕсли;
//ТекстПодвала="";
//*********************************
//
//ПечатнаяФорма = ПечатьПоШаблону(ТаблицаДокументов,4,"Заказы на поставку",ПоляВывода,ТекстПодвала);
//
//Пример 2:
//*********************************
//ПоляВывода = Новый СписокЗначений;
//ПоляВывода.Добавить("Артикул","Артикул||");
//ПоляВывода.Добавить("Номенклатура","Номенклатура||");
//ПоляВывода.Добавить("КоличествоОжидаемое","Кол.(ожидаемое)|||*");
//ТекстПодвала = "Вес: "+Строка(ИтогоВес)+" (кг)  ;  объем : "+Строка(ИтогоОбъем)+" (м.куб).";
//*********************************
//
//ПечатнаяФорма = ПечатьПоШаблону(ТаблицаПрогнозаПоступлений,4,"Ожидаемые поставки на : "+Формат(ДатаПрогнозаПоступлений,"ДФ=гггг-ММ-дд"),ПоляВывода,ТекстПодвала);

Пример кода формата вывода:

 


&НаКлиенте
Процедура Печать(Команда)
ПоляВывода = Новый СписокЗначений;

//*** автопечать всего видимого из таблицы
ВывТаблица="ТабДокументов";
Для каждого Т Из Элементы Цикл
Если Т.Имя=ВывТаблица Тогда
Для каждого Эл Из Т.ПодчиненныеЭлементы Цикл
Если Эл.Видимость Тогда
ВывПоле=Прав(Эл.Имя,СтрДлина(Эл.Имя)-СтрДлина(ВывТаблица));
ПоляВывода.Добавить(ВывПоле,ВывПоле+"||")
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;

//*** корректировка избранных полей
Для каждого Эл Из ПоляВывода Цикл
Если       Эл.Значение="СкладКорр" Тогда
Эл.Представление="Склад (корр)|10|ДФ=гггг-ММ-дд";
ИначеЕсли Эл.Значение="СкладФакт" Тогда
Эл.Представление="Склад (факт)|10|ДФ=гггг-ММ-дд";
ИначеЕсли Эл.Значение="ОтгрФакт" Тогда
Эл.Представление="Отгр (Факт)|10|ДФ=гггг-ММ-дд";
ИначеЕсли Эл.Значение="Дата" Тогда
Эл.Представление="Дата|10|ДФ=гггг-ММ-дд";
ИначеЕсли Эл.Значение="Сумма" Тогда
Эл.Представление="Сумма|12|ЧДЦ=2|*";
ИначеЕсли Эл.Значение="Объем" Тогда
Эл.Представление="Объем|12|ЧДЦ=4|*";
ИначеЕсли Эл.Значение="Вес" Тогда
Эл.Представление="Вес|10|ЧДЦ=2|*";
КонецЕсли;
КонецЦикла;

//////*** печать только выбранных колонок
////ПоляВывода.Очистить();
////ПоляВывода.Добавить("Заказ","Заказ||");
////ПоляВывода.Добавить("СкладКорр","Склад (корр)|10|ДФ=гггг-ММ-дд");
////ПоляВывода.Добавить("СкладФакт","Склад (факт)|10|ДФ=гггг-ММ-дд");
////ПоляВывода.Добавить("Контейнер","Контейнер||");
////Если фВесОбъем Тогда
////    ПоляВывода.Добавить("Объем","Объем|12|ЧДЦ=4");
////    ПоляВывода.Добавить("Вес","Вес|10|ЧДЦ=2");
////КонецЕсли;

ТекстЗаголовка="Реализации: ("+Формат(ДатаНачалаПериода,"ДФ=гггг-ММ-дд")+"-"+Формат(ДатаКонцаПериода,"ДФ=гггг-ММ-дд")+") :";;
//Для каждого Эл Из Элементы.Фильтр1.ПодчиненныеЭлементы Цикл
//    Если НЕ ПустаяСтрока(Эл.ВыделенныйТекст) Тогда
//        ТекстЗаголовка=ТекстЗаголовка+" "+Эл.ВыделенныйТекст+" ; ";
//    КонецЕсли;
//КонецЦикла;

ТекстПодвала="";

//непосредственно обработка:
ПечатнаяФорма = ПечатьПоШаблону(ТабДокументов,4,ТекстЗаголовка,ПоляВывода,ТекстПодвала);

ПечатнаяФорма.Показать(
"Печать. "  // заголовок окна с отчётом
);
КонецПроцедуры

&НаСервере
Функция ПечатьПоШаблону(Знач Табл,НКолонки,ТекстЗаголовка,ПоляВывода,ТекстПодвала)экспорт

Н=Табл.Выгрузить();

спШирКол=Новый СписокЗначений;
спИтого=Новый СписокЗначений;

спШирКол=ПоляВывода.Скопировать();

Для К=1 По спШирКол.Количество() Цикл
ОписаниеКолонки=СтрРазделить(спШирКол[К-1].Представление,"|");
Если ОписаниеКолонки.Количество()>3 тогда
//проверим на итоги
Если ОписаниеКолонки[3] = "*" тогда
//выводим итоги по колонке
спИтого.Добавить(спШирКол[К-1].Значение,"0");
КонецЕсли;
КонецЕсли;
ШирИмениКолонки=СтрДлина(спШирКол[К-1].Значение);
ШирПредставления=ШирИмениКолонки;
Если ОписаниеКолонки.Количество()>1 тогда
//Ширина представления колонки
Если ПустаяСтрока(ОписаниеКолонки[1]) Тогда
//нет фикс. длины
ШирПредставления=СтрДлина(ОписаниеКолонки[0]);
Иначе
ШирПредставления=Число(ОписаниеКолонки[1]);
КонецЕсли;
КонецЕсли;
Если ШирПредставления>ШирИмениКолонки Тогда
ШирИмениКолонки=ШирПредставления;
КонецЕсли;
спШирКол[К-1].Представление=Строка(ШирИмениКолонки+1);
КонецЦикла;


//Определим оптимальную ширину колонок
Для СтрокаН=1  По Н.Количество() Цикл
Для К=1 По Н.Колонки.Количество() Цикл
ИмяКолонки=Н.Колонки[К-1].Имя;
Имя = спШирКол.НайтиПоЗначению(ИмяКолонки);
Если Имя <> НЕОПРЕДЕЛЕНО  Тогда
ШирКол=СтрДлина(СокрЛП(Строка(Н[СтрокаН-1][К-1])));
Если ШирКол > Число(Имя.Представление) Тогда
Имя.Представление = Строка(ШирКол);
КонецЕсли;
Иначе
//*** запрет доступа
КонецЕсли;
КонецЦикла;
КонецЦикла;


ТабДок = Новый ТабличныйДокумент;
//*** сначала - Заголовок
ТекущаяДата="Печать: "+Строка(ТекущаяДата());

ТабДок.Область(1,1).Шрифт = Новый Шрифт(,7,Ложь,) ;
//ТабДок.Область("R2C1").Шрифт = Новый Шрифт(<Имя шрифта>, <Размер>, <Жирный>, <Наклонный>, <Подчеркнутый>, <Зачеркнутый>) ;
//Рамка = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
//ТабДок.Область(3,Сч).Обвести(Рамка,Рамка,Рамка,Рамка);
ТабДок.Область(1,1).Текст = ТекущаяДата;

ТабДок.Область(2,1).Шрифт = Новый Шрифт(,10,Истина,) ;
ТабДок.Область(2,1).ЦветТекста = Новый Цвет(,,152) ;
//ТабДок.Область("R2C1").Шрифт = Новый Шрифт(<Имя шрифта>, <Размер>, <Жирный>, <Наклонный>, <Подчеркнутый>, <Зачеркнутый>) ;
//Рамка = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
//ТабДок.Область(3,Сч).Обвести(Рамка,Рамка,Рамка,Рамка);
ТабДок.Область(2,1).Текст = ТекстЗаголовка;

Сч=1;
Для Каждого Эл из ПоляВывода Цикл
ИмяКолонки=Эл.Значение;
Для Каждого Нкол из Н.Колонки Цикл
Имя = Нкол.Имя;
Если Имя = ИмяКолонки  Тогда
ОписаниеКолонки=СтрРазделить(Эл.Представление,"|");
ШиринаКолонки = "";
Если ОписаниеКолонки.Количество()>1 Тогда
ИмяКолонки=ОписаниеКолонки[0];
ШиринаКолонки=ОписаниеКолонки[1];
ФорматКолонки=ОписаниеКолонки[2];
КонецЕсли;

ТабДок.Область(НКолонки,Сч).Шрифт = Новый Шрифт(,9,Истина,) ;
//ТабДок.Область("R2C1").Шрифт = Новый Шрифт(<Имя шрифта>, <Размер>, <Жирный>, <Наклонный>, <Подчеркнутый>, <Зачеркнутый>) ;
Рамка = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
ТабДок.Область(НКолонки,Сч).Обвести(Рамка,Рамка,Рамка,Рамка);

ТабДок.Область(НКолонки,Сч).Текст = ИмяКолонки;
Если ПустаяСтрока(ШиринаКолонки) Тогда
ТабДок.Область(НКолонки,Сч).ШиринаКолонки = Число(спШирКол.НайтиПоЗначению(Имя).Представление);
//ТабДок.Область(НКолонки,Сч).ШиринаКолонки = Число(спШирКол.НайтиПоЗначению(ИмяКолонки).Представление);
Иначе
ТабДок.Область(НКолонки,Сч).ШиринаКолонки = ШиринаКолонки;
КонецЕсли;
Сч=Сч+1;
Прервать;
Иначе
//*** запрет доступа
КонецЕсли;
КонецЦикла;
КонецЦикла;


//*** теперь - строки
Для СтрокаН=1  По Н.Количество() Цикл
Сч=1;
Для Каждого Эл из ПоляВывода Цикл
ИмяКолонки=Эл.Значение;
К=0;
Для Каждого Нкол из Н.Колонки Цикл
Имя = Нкол.Имя;
К=К+1;
Если Имя = ИмяКолонки  Тогда
ОписаниеКолонки=СтрРазделить(Эл.Представление,"|");
ШиринаКолонки = "";
Если ОписаниеКолонки.Количество()>1 Тогда
ИмяКолонки=ОписаниеКолонки[0];
ШиринаКолонки=ОписаниеКолонки[1];
ФорматКолонки=ОписаниеКолонки[2];
КонецЕсли;
ТабДок.Область(НКолонки+СтрокаН,Сч).Шрифт = Новый Шрифт(,8,Ложь,) ;
//ТабДок.Область("R2C1").Шрифт = Новый Шрифт(<Имя шрифта>, <Размер>, <Жирный>, <Наклонный>, <Подчеркнутый>, <Зачеркнутый>) ;
Рамка = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
ТабДок.Область(НКолонки+СтрокаН,Сч).Обвести(Рамка,Рамка,Рамка,Рамка);
Если НЕ ПустаяСтрока(ФорматКолонки) Тогда
ТабДок.Область(НКолонки+СтрокаН,Сч).Формат = ФорматКолонки;
КонецЕсли;
ТабДок.Область(НКолонки+СтрокаН,Сч).Текст = Н[СтрокаН-1][К-1];
//ТабДок.Область(НКолонки+СтрокаН,Сч).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
Сч=Сч+1;
Прервать;
Иначе
//*** запрет доступа
КонецЕсли;
КонецЦикла;
//проверим на нужность итогов
Имя = спИтого.НайтиПоЗначению(ИмяКолонки);
Если Имя <> НЕОПРЕДЕЛЕНО  Тогда
Имя.Представление=Строка(Число(Имя.Представление)+Число(Н[СтрокаН-1][К-1]));
КонецЕсли;
КонецЦикла;
КонецЦикла;

//*** теперь итоги (если заказаны)
Если спИтого.Количество()>0 тогда
ТабДок.Область(СтрокаН+НКолонки+1,1).Шрифт = Новый Шрифт(,9,Истина,) ;
ТабДок.Область(СтрокаН+НКолонки+1,1).ЦветТекста = Новый Цвет(,,152) ;
ТабДок.Область(СтрокаН+НКолонки+1,1).Текст = "Итого: ";
ТабДок.Область(СтрокаН+НКолонки+1,1).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Лево;

Сч=1;
Для Каждого Эл из ПоляВывода Цикл
ИмяКолонки=Эл.Значение;
Имя = спИтого.НайтиПоЗначению(ИмяКолонки);
Если Имя <> НЕОПРЕДЕЛЕНО  Тогда
ФорматКолонки="";
ОписаниеКолонки=СтрРазделить(Имя.Представление,"|");
Если ОписаниеКолонки.Количество()>2 Тогда
ФорматКолонки=ОписаниеКолонки[2];
КонецЕсли;
ТабДок.Область(СтрокаН+НКолонки+1,Сч).Формат = ФорматКолонки;
ТабДок.Область(СтрокаН+НКолонки+1,Сч).Шрифт = Новый Шрифт(,9,Истина,) ;
ТабДок.Область(СтрокаН+НКолонки+1,Сч).ЦветТекста = Новый Цвет(,,152) ;
ТабДок.Область(СтрокаН+НКолонки+1,Сч).Текст = Число(Имя.Представление);
ТабДок.Область(СтрокаН+НКолонки+1,Сч).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
КонецЕсли;
Сч=Сч+1;
КонецЦикла;
КонецЕсли;

//*** теперь - подвал (если нужен)
ТабДок.Область(СтрокаН+НКолонки+2,1).Шрифт = Новый Шрифт(,9,Истина,) ;
ТабДок.Область(СтрокаН+НКолонки+2,1).ЦветТекста = Новый Цвет(,,152) ;
ТабДок.Область(СтрокаН+НКолонки+2,1).Текст = ТекстПодвала;
ТабДок.Область(СтрокаН+НКолонки+2,1).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Лево;

ТабДок.ФиксацияСверху = НКолонки;

Возврат ТабДок;



КонецФункции


Тестировалось на платформах 8.3.13.1513 и 8.3.14.1630 , конфигурация "Комплексная автоматизация 2.2 — 2.4".

На другом не проверялась, но работать должна на любых, где используются управляемые формы.

Leave a Comment

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