Табличный документ 1С — объект платформы, на котором держатся печатные формы, отчёты, выгрузка в Excel и PDF, чтение таблиц из файлов. Накладная, акт сверки и оборотно-сальдовая ведомость — всё это один тип ТабличныйДокумент. Ниже — что программисту нужно знать про табличный документ 1С 8.3: области и ячейки, параметры макета, группировки, рисунки, поле на форме, файлы и печать. К каждой части есть пример и ссылка на подробную статью.
Табличный макет в конфигурации — тоже табличный документ: для макета этого типа ПолучитьМакет() возвращает ТабличныйДокумент с именованными областями. Макеты других типов дают другие объекты — ТекстовыйДокумент, ДвоичныеДанные, СхемаКомпоновкиДанных. Отличие одно: макет хранится в метаданных, а готовый документ собирается в памяти при каждом формировании.
| Тип | Что это |
|---|---|
ТабличныйДокумент | Сам документ: вывод областей, размеры (ВысотаТаблицы, ШиринаТаблицы), параметры страницы, запись и чтение файлов, печать |
ОбластьЯчеекТабличногоДокумента | Прямоугольник ячеек, набор строк или колонок; через неё меняют текст, оформление, расшифровку |
РисунокТабличногоДокумента | Картинка, надпись, фигура или диаграмма поверх ячеек; все рисунки лежат в коллекции Рисунки |
ПолеФормы (вид ПолеТабличногоДокумента) | Элемент управляемой формы, который показывает реквизит типа ТабличныйДокумент. Тип ПолеТабличногоДокумента есть только в обычных формах |
Отдельного объекта «ячейка» нет: одна ячейка — это область размером 1×1. Область получают так:
ТабДок.Область("R2C1:R10C5"); "R3" — вся третья строка, "C2" — вся вторая колонка;ТабДок.Область(2, 1, 10, 5);ТабДок.Область("Итого").Нумерация — с единицы. Чаще всего нужны такие свойства области:
| Свойство или метод | Назначение |
|---|---|
Текст | Строка, которую видит пользователь |
Значение, СодержитЗначение | Типизированное значение ячейки (число, дата, ссылка) вместо текста |
Заполнение, Параметр | Ячейка заполняется текстом, параметром или шаблоном вида «Счёт № [Номер]» |
Расшифровка, ПараметрРасшифровки | Значение, которое получит обработчик двойного щелчка |
Шрифт, ЦветТекста, ЦветФона | Оформление |
ГоризонтальноеПоложение, РазмещениеТекста | Выравнивание и перенос по словам |
ГраницаСлева … ГраницаСнизу, Обвести() | Рамки: свойства границ задаются ячейкам области, Обвести() рисует контур вокруг неё |
ШиринаКолонки, ВысотаСтроки, Объединить() | Геометрия |
Пример оформления таблицы без макета: заголовок в объединённых ячейках, сетка по диапазону и широкая колонка с переносом текста.
&НаСервере
Процедура ОформитьТаблицу(ТабДок, КоличествоСтрок)
Заголовок = ТабДок.Область("R1C1:R1C4");
Заголовок.Объединить();
Заголовок.Текст = "Остатки на складе";
Заголовок.Шрифт = Новый Шрифт(Заголовок.Шрифт, , 12, Истина);
Заголовок.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
Таблица = ТабДок.Область(3, 1, 2 + КоличествоСтрок, 4);
Таблица.ГраницаСлева = Линия;
Таблица.ГраницаСверху = Линия;
Таблица.ГраницаСправа = Линия;
Таблица.ГраницаСнизу = Линия;
КолонкаНаименование = ТабДок.Область("C2");
КолонкаНаименование.ШиринаКолонки = 40;
КолонкаНаименование.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Переносить;
КонецПроцедурыТаблицы, которые целиком строятся из кода, разобраны в статье о выводе табличного документа программно.
Основной способ наполнить документ — взять именованную область макета, заполнить её параметры и вывести. У ячейки макета со свойством Заполнение = Параметр имя параметра попадает в коллекцию Параметры области, полученной через ПолучитьОбласть(). Метод Параметры.Заполнить(Выборка) переносит значения по совпадению имён и пропускает всё лишнее. Прямое присваивание Область.Параметры.Цена = … требует, чтобы параметр существовал.
Документ растёт двумя методами: Вывести() добавляет область снизу, Присоединить() — справа от последней выведенной. Если в макете есть и горизонтальные, и вертикальные области, запрос "Шапка|Склад" вернёт их пересечение. Так строят отчёты с заранее неизвестным числом колонок:
// В макете: горизонтальная область Шапка,
// вертикальные области Товар и Склад (параметр Склад).
&НаСервере
Процедура ВывестиШапкуПоСкладам(ТабДок, Макет, Склады)
ТабДок.Вывести(Макет.ПолучитьОбласть("Шапка|Товар"));
ОбластьСклад = Макет.ПолучитьОбласть("Шапка|Склад");
Для Каждого Склад Из Склады Цикл
ОбластьСклад.Параметры.Склад = Склад;
ТабДок.Присоединить(ОбластьСклад);
КонецЦикла;
КонецПроцедурыВиды макетов, общие макеты и получение областей описаны в статье про макеты и ПолучитьМакет, а разметка областей и параметров в конструкторе — в материале о макете печатной формы.
Свёртываемые группы с кнопками «+» и «−» слева задаются парой НачатьГруппуСтрок() / ЗакончитьГруппуСтрок(): строки между вызовами попадают в группу, группы можно вкладывать друг в друга. Для вложенности по уровням запроса есть автогруппировка: НачатьАвтогруппировкуСтрок(), затем Вывести(Область, Выборка.Уровень()) и в конце ЗакончитьАвтогруппировкуСтрок(). Чтобы пользователь видел кнопки, у документа включают ОтображатьГруппировки.
Логотип, печать или штрихкод выводятся рисунком. Удобнее заранее вставить картинку в область макета, дать ей имя и подменять содержимое из кода. Если макета нет, рисунок добавляют в коллекцию и привязывают к диапазону ячеек.
// ДанныеЛоготипа - ДвоичныеДанные картинки (PNG, JPG).
// В области макета заранее вставлен рисунок с именем «Логотип».
&НаСервере
Процедура ВывестиЛоготипИзМакета(ТабДок, ОбластьЗаголовок, ДанныеЛоготипа)
ОбластьЗаголовок.Рисунки.Логотип.Картинка = Новый Картинка(ДанныеЛоготипа);
ТабДок.Вывести(ОбластьЗаголовок);
КонецПроцедуры
// Рисунок добавляется в готовый документ.
&НаСервере
Процедура ДобавитьЛоготип(ТабДок, ДанныеЛоготипа)
Рисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
Рисунок.Картинка = Новый Картинка(ДанныеЛоготипа);
Рисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
Рисунок.Расположить(ТабДок.Область("R1C5:R4C6"));
КонецПроцедуры
Обработка с формой: реквизит Результат типа ТабличныйДокумент выведен полем, команда «Сформировать» строит продажи по покупателям с группировками, повторяющейся шапкой и итогом. Области табличного макета «Макет» перечислены в комментарии к листингу.
// Обработка «Продажи по покупателям». Платформа 8.3, управляемая форма.
// Реквизиты формы:
// Результат - тип ТабличныйДокумент (выведен на форму полем табличного документа);
// Период - тип СтандартныйПериод.
// Команда формы «Сформировать» с действием Сформировать.
// Табличный макет обработки «Макет» с горизонтальными областями:
// Заголовок - параметр Период;
// Шапка - заголовки колонок;
// Покупатель - параметры Контрагент, Количество, Сумма
// (у ячейки Контрагент ПараметрРасшифровки = Контрагент);
// Строка - параметры Номенклатура, Количество, Сумма;
// Итого - параметры Количество, Сумма.
// Имена документа и полей в запросе - как в БП 3.0 и УТ 11, при необходимости замените.
&НаКлиенте
Процедура Сформировать(Команда)
СформироватьНаСервере();
КонецПроцедуры
&НаСервере
Процедура СформироватьНаСервере()
Результат.Очистить();
Результат.ИмяПараметровПечати = "ПродажиПоПокупателям";
Результат.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
Результат.АвтоМасштаб = Истина;
Результат.ОтображатьСетку = Ложь;
Результат.ОтображатьЗаголовки = Ложь;
Результат.ОтображатьГруппировки = Истина;
Результат.ТолькоПросмотр = Истина;
Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет");
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьПокупатель = Макет.ПолучитьОбласть("Покупатель");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьИтого = Макет.ПолучитьОбласть("Итого");
ДатаНачала = НачалоДня(Период.ДатаНачала);
ДатаОкончания = ?(ЗначениеЗаполнено(Период.ДатаОкончания),
КонецДня(Период.ДатаОкончания), '39991231235959');
ОбластьЗаголовок.Параметры.Период = ПредставлениеПериода(ДатаНачала, ДатаОкончания);
Результат.Вывести(ОбластьЗаголовок);
// Строки шапки повторяются вверху каждой печатной страницы.
ПерваяСтрокаШапки = Результат.ВысотаТаблицы + 1;
Результат.Вывести(ОбластьШапка);
Результат.ПовторятьПриПечатиСтрок = Результат.Область("R" + Формат(ПерваяСтрокаШапки, "ЧГ=0")
+ ":R" + Формат(Результат.ВысотаТаблицы, "ЧГ=0"));
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка.Контрагент КАК Контрагент,
| Товары.Номенклатура КАК Номенклатура,
| СУММА(Товары.Количество) КАК Количество,
| СУММА(Товары.Сумма) КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Проведен
| И Товары.Ссылка.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
|
|СГРУППИРОВАТЬ ПО
| Товары.Ссылка.Контрагент,
| Товары.Номенклатура
|
|УПОРЯДОЧИТЬ ПО
| Контрагент,
| Номенклатура
|ИТОГИ
| СУММА(Количество),
| СУММА(Сумма)
|ПО
| Контрагент";
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);
ВсегоКоличество = 0;
ВсегоСумма = 0;
ВыборкаПокупатели = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаПокупатели.Следующий() Цикл
ОбластьПокупатель.Параметры.Заполнить(ВыборкаПокупатели);
Результат.Вывести(ОбластьПокупатель);
// Строки покупателя - в свёртываемую группу.
Результат.НачатьГруппуСтрок(Строка(ВыборкаПокупатели.Контрагент), Истина);
ВыборкаСтроки = ВыборкаПокупатели.Выбрать();
Пока ВыборкаСтроки.Следующий() Цикл
ОбластьСтрока.Параметры.Заполнить(ВыборкаСтроки);
Результат.Вывести(ОбластьСтрока);
КонецЦикла;
Результат.ЗакончитьГруппуСтрок();
ВсегоКоличество = ВсегоКоличество + ВыборкаПокупатели.Количество;
ВсегоСумма = ВсегоСумма + ВыборкаПокупатели.Сумма;
КонецЦикла;
ОбластьИтого.Параметры.Количество = ВсегоКоличество;
ОбластьИтого.Параметры.Сумма = ВсегоСумма;
Результат.Вывести(ОбластьИтого);
КонецПроцедурыРезультат.Очистить() — иначе повторное формирование допишет отчёт под первым.ИмяПараметровПечати — ключ, под которым платформа запоминает настройки страницы пользователя: поля, ориентацию, принтер. У каждого отчёта свой.РеквизитФормыВЗначение("Объект").ПолучитьМакет(…) — работает и во встроенной, и во внешней обработке. Во встроенной можно короче: Обработки.ИмяОбработки.ПолучитьМакет(…).ПовторятьПриПечатиСтрок — строки шапки повторятся вверху каждой печатной страницы; на экране они не дублируются.Параметры.Заполнить() — заполняет параметры области одноимёнными полями выборки. У ячейки «Контрагент» в макете задан ПараметрРасшифровки с тем же именем, поэтому в расшифровку попадёт ссылка на контрагента.НачатьГруппуСтрок(…, Истина) — второй параметр оставляет группу раскрытой; с Ложь отчёт откроется свёрнутым до покупателей.Чтобы показать документ на управляемой форме, добавьте реквизит типа ТабличныйДокумент и перетащите его в элементы — получится поле табличного документа. Внешний вид задают свойства самого документа: ОтображатьСетку, ОтображатьЗаголовки, ТолькоПросмотр. На клиенте реквизит тоже доступен: можно читать ячейки и печатать, а формирование с запросами — только на сервере.
Двойной щелчок по ячейке с расшифровкой вызывает событие ОбработкаРасшифровки. Если в расшифровке ссылка и обработчика нет, платформа сама откроет форму объекта. Свой обработчик нужен, чтобы открыть что-то другое, например список документов по покупателю. Заготовку создаёт конфигуратор из палитры свойств поля, и сигнатуру лучше брать из неё: параметр ДополнительныеПараметры появился в 8.3.10, в режиме совместимости 8.3.9 и ниже его нет.
&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка, ДополнительныеПараметры)
Если ТипЗнч(Расшифровка) <> Тип("СправочникСсылка.Контрагенты") Тогда
Возврат;
КонецЕсли;
СтандартнаяОбработка = Ложь;
ПараметрыФормы = Новый Структура("Отбор", Новый Структура("Контрагент", Расшифровка));
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаСписка", ПараметрыФормы, ЭтотОбъект);
КонецПроцедуры
Метод Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX) сохраняет документ в файл; кроме XLSX среди форматов есть MXL, XLS, ODS, PDF, HTML, DOCX и TXT. Метод Прочитать() загружает MXL, а начиная с 8.3.6 — ещё XLSX, XLS и ODS; установленный Excel для этого не нужен.
Серверный Записать() кладёт файл на диск сервера 1С, а не пользователя. Поэтому файл пишут во временный каталог, помещают его двоичные данные во временное хранилище и отдают клиенту. Пример для формы из листинга выше:
&НаСервере
Функция АдресФайлаXLSX()
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
Результат.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяФайла), УникальныйИдентификатор);
УдалитьФайлы(ИмяФайла);
Возврат Адрес;
КонецФункции
// Асинх и Ждать - платформа 8.3.18 и выше.
&НаКлиенте
Асинх Процедура СохранитьВExcel(Команда)
Ждать ПолучитьФайлССервераАсинх(АдресФайлаXLSX(), "Продажи.xlsx", Новый ПараметрыДиалогаПолученияФайлов);
КонецПроцедурыНа 8.3.15–8.3.17 ту же задачу решает НачатьПолучениеФайлаССервера() с описанием оповещения. А пользователь и без кода может сохранить документ из поля штатной командой «Сохранить как».
Чтение идёт в обратную сторону: клиент помещает файл во временное хранилище, сервер записывает его во временный файл и читает. Второй параметр СпособЧтенияЗначенийТабличногоДокумента.Значение (тоже с 8.3.6) сохраняет числа и даты как значения — без него придётся разбирать текст с пробелами между разрядами.
// АдресФайла - адрес во временном хранилище, куда клиент поместил файл XLSX.
// В первой строке файла - заголовки, в колонке 1 - артикул, в колонке 3 - количество.
&НаСервереБезКонтекста
Функция ПрочитатьСтрокиФайла(АдресФайла)
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ПолучитьИзВременногоХранилища(АдресФайла).Записать(ИмяФайла);
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
УдалитьФайлы(ИмяФайла);
Строки = Новый Массив;
Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл
Артикул = СокрЛП(ТабДок.Область(НомерСтроки, 1, НомерСтроки, 1).Текст);
Если ПустаяСтрока(Артикул) Тогда
Продолжить;
КонецЕсли;
Ячейка = ТабДок.Область(НомерСтроки, 3, НомерСтроки, 3);
Количество = 0;
Если Ячейка.СодержитЗначение И ТипЗнч(Ячейка.Значение) = Тип("Число") Тогда
Количество = Ячейка.Значение;
КонецЕсли;
Строки.Добавить(Новый Структура("Артикул, Количество", Артикул, Количество));
КонецЦикла;
Возврат Строки;
КонецФункцииВременные каталоги и передача файлов между клиентом и сервером — в статье о работе с файлами в 1С.
Настройки страницы задаются свойствами документа: ОриентацияСтраницы, АвтоМасштаб (вписать по ширине листа), ПолеСлева и остальные поля, КоличествоЭкземпляров. Метод Напечатать() отправляет документ на принтер с диалогом или без него. В печатной форме подвал с подписями не должен остаться один на последней странице, поэтому перед выводом строки проверяют, поместится ли она вместе с подвалом:
&НаСервере
Процедура ВывестиСтрокуСПереносом(ТабДок, ОбластьСтрока, ОбластьШапка, ОбластьПодвал)
ПроверяемыеОбласти = Новый Массив;
ПроверяемыеОбласти.Добавить(ОбластьСтрока);
ПроверяемыеОбласти.Добавить(ОбластьПодвал);
Если Не ТабДок.ПроверитьВывод(ПроверяемыеОбласти) Тогда
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
ТабДок.Вывести(ОбластьШапка);
КонецЕсли;
ТабДок.Вывести(ОбластьСтрока);
КонецПроцедурыПроверитьВывод() принимает массив областей и возвращает Ложь, если они не поместятся на текущую страницу вместе с уже выведенным. Результат зависит от параметров страницы, поэтому ориентацию, поля и масштаб задают до вывода строк. Ручной вывод шапки — замена свойству ПовторятьПриПечатиСтрок из примера отчёта, а не дополнение: с обоими способами шапка задвоится.
Заполнение = Текст. Параметры.Заполнить() такие случаи молча пропускает, прямое присваивание падает.&НаКлиенте. Запрос и получение макета делают на сервере, клиенту остаётся вызов серверной процедуры.Очистить().Текст ячейки, а там «1 250,00» с неразрывным пробелом. Читайте файл со способом СпособЧтенияЗначенийТабличногоДокумента.Значение и берите Значение.Записать() выполнен на сервере, файл остался в каталоге сервера.ПовторятьПриПечатиСтрок или ручной вывод шапки после ВывестиГоризонтальныйРазделительСтраниц() по результату ПроверитьВывод(). Оба сразу дадут двойную шапку со второй страницы.Технически ничем: табличный макет — это табличный документ, сохранённый в конфигурации или во внешней обработке. В макете размечены области и параметры, а результат — новый документ, куда эти области выведены с данными.
Да: текст, оформление, объединение и границы задаются через области прямо в коде. Для простых таблиц и выгрузок так удобнее, а сложный бланк проще нарисовать в макете и править без изменения кода.
Через процессор вывода ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент: методом УстановитьДокумент() ему передают документ, методом Вывести() — процессор компоновки. Оформление в этом случае задают настройки и макет оформления СКД, а не код.
Сформируйте каждую форму отдельно и выведите их в общий документ методом Вывести(), разделяя вызовом ВывестиГоризонтальныйРазделительСтраниц(). В конфигурациях на БСП (редакции 3.x) для каждого объекта дополнительно вызывают УправлениеПечатью.ЗадатьОбластьПечатиДокумента(), чтобы подсистема печати знала, какие строки к какому документу относятся.
Сформируйте его в серверной функции, верните на клиент и вызовите ТабДок.Показать("Заголовок окна"). Откроется стандартное окно просмотра с печатью и сохранением.
Если нужна печатная форма под ваш бланк, отчёт с расшифровками или выгрузка в Excel заданного формата, а своего программиста нет, задачу быстрее отдать исполнителю по услугам «Отчёты и обработки 1С» или «Печатные формы». Опишите задачу и приложите образец через «Разместить задание» — оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.