Пример как можно рутинные действия по оформлению внешнего вида печатной формы переложить на программу.
Статья предназначена в первую очередь для тех, кто не сильно владеет СКД (как я, например), но которым не хочется тратить свое время на формирование разных макетов, если вывести документ нужно в стандартном виде.
Код полностью открыт, пользуйтесь на здоровье. 🙂
Доброе время суток всем.
Для упрощения вывода информации в табличный документ предлагается следующий код, выводящий таблицу значений с формы на экране в некий стандартный табличный документ по определенным правилам:
- Выводятся только видимые колонки
- Ширина колонок рассчитывается из максимальной ширины данных в колонке ( если не указана фикс. ширина)
- Формат вывода и (печатное наименование) для каждой колонки можно задать произвольно
- По тем колонкам, где нужно, выводятся итоги.
Код рекомендуется подключить как дополнительный общий модуль в конфигурацию.
Для примеры показан вывод списка реализаций из демонстрационной базы "Комплексной автоматизации".
Но применить можно в любой конфигурации с УФ.
Описание:
&НаСервере
//*** формат входных данных: ПечатьПоШаблону(Знач Табл,НКолонки,ТекстЗаголовка,ПоляВывода,ТекстПодвала)
// ( Табл - исходная таблица
// НКолонки - первая строка ШАПКИ вывода
// ТекстЗаголовка ...
// ПоляВывода - список выводимых колонок , в представлении значения - формат вывода:
// "Вес","Вес|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".
На другом не проверялась, но работать должна на любых, где используются управляемые формы.