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

Публикация № 1043728

Программирование - Практика программирования

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

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

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

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

  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".

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

2

См. также

Специальные предложения

Избранное Подписка Сортировка: Древо
В этой теме еще нет сообщений.
Оставьте свое сообщение