При программном формировании табличных документов, например, для выгрузки в Excel, часто возникает задача: в шапке отчета нужно видеть человекопонятное название колонки, например, "Дата акта передачи", а для заполнения данными из запроса использовать программное имя параметра без пробелов, например, "ДатаАктаПередачи". Попытка присвоить одной и той же ячейке и текст, и параметр, приводит к некорректному результату. Разберем, почему так происходит и как правильно решить эту задачу.
Основная ошибка заключается в смешении двух разных типов заполнения ячейки табличного документа. Каждая ячейка может иметь только один тип заполнения, который определяет ее поведение.
Проанализируем ключевые свойства объекта ОбластьЯчеекТабличногоДокумента:
<strong>Заполнение</strong>: Это свойство определяет, как будет обрабатываться ячейка. Нас интересуют два основных значения из перечисления ТипЗаполненияОбластиТабличногоДокумента:
<strong>Текст</strong>: Ячейка содержит статичный текст. То, что вы запишете в свойство Текст, будет отображено "как есть". Это идеальный вариант для заголовков, подписей и любого другого неизменяемого контента.<strong>Параметр</strong>: Ячейка является плейсхолдером (шаблоном), который ожидает заполнения данными. В свойство Параметр записывается идентификатор этого плейсхолдера (например, "ДатаАктаПередачи"). Этот идентификатор используется для связи с полем выборки из запроса или ключом структуры при заполнении через коллекцию Параметры.Таким образом, одна и та же ячейка не может быть одновременно и статичным заголовком, и параметром для вывода данных. Попытка сделать так, как в первоначальном коде, приведет к тому, что одно свойство перезапишет другое, и результат будет непредсказуемым.
// Неправильный подход, который не работает
НоваяОбласть = ТабДок.Область("R1C1:R1C1");
НоваяОбласть.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Параметр;
НоваяОбласть.Параметр = "ДатаАктаПередачи";
// Эта строка либо будет проигнорирована, либо изменит тип заполнения на "Текст",
// из-за чего ячейка перестанет быть параметром.
НоваяОбласть.Текст = "Дата акта передачи";
Правильное решение — четко разделить области: одна область для шапки (с типом заполнения "Текст"), а другая, шаблонная область, для строк данных (с типом заполнения "Параметр").
Этот способ подходит, когда макет не хочется или нет возможности создавать в конфигураторе. Вся структура отчета формируется исключительно программно.
Шаг 1. Формируем и выводим шапку.
Сначала создадим область для заголовка. Установим ей тип заполнения "Текст" (обычно это значение по умолчанию) и запишем туда нужный нам красивый заголовок. Сразу после этого выведем эту область в итоговый табличный документ.
&НаСервере
Функция СформироватьОтчетДинамически()
// Создаем итоговый табличный документ
ТабДок = Новый ТабличныйДокумент;
// 1. Создаем и настраиваем область для шапки
// Получаем область первой ячейки в первой строке
ОбластьШапка = ТабДок.Область("R1C1");
// Записываем в нее текст, который увидит пользователь
ОбластьШапка.Текст = "Дата акта передачи";
// Применим форматирование для красоты, например, сделаем текст жирным
ОбластьШапка.Шрифт = Новый Шрифт(,,Истина);
ОбластьШапка.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
// Выводим готовую шапку в наш документ.
// Теперь первая строка заполнена и готова.
ТабДок.Вывести(ОбластьШапка);
// ... дальнейший код ...
Возврат ТабДок;
КонецФункции
Шаг 2. Создаем шаблонную область для строк данных.
Теперь нам нужен шаблон, который мы будем многократно использовать в цикле для вывода данных. Для этого возьмем область из следующей строки, настроим ее как параметр и будем использовать в дальнейшем. Важно: эту шаблонную область мы не выводим в документ сразу, она остается "в памяти".
// ... продолжение функции СформироватьОтчетДинамически() ...
// 2. Создаем шаблонную область для строк данных
// Возьмем ячейку из второй строки как шаблон
ОбластьСтрока = ТабДок.Область("R2C1");
// Указываем, что это будет параметр
ОбластьСтрока.Заполнение = ТипЗаполненияОбластиТабличногоДокумента.Параметр;
// Задаем программное имя параметра, которое совпадает с именем поля в запросе
ОбластьСтрока.Параметр = "ДатаАктаПередачи";
// ... дальнейший код ...
Шаг 3. Получаем данные и выводим их в цикле.
Выполняем запрос к базе данных. Затем в цикле обходим результат запроса, на каждой итерации заполняем нашу шаблонную ОбластьСтрока данными и выводим ее в итоговый ТабДок.
// ... продолжение функции СформироватьОтчетДинамически() ...
// 3. Выполняем запрос для получения данных
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| МойРегистр.Период КАК ДатаАктаПередачи
|ИЗ
| РегистрСведений.МойРегистр КАК МойРегистр";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
// 4. В цикле обходим результат запроса и выводим строки
Пока Выборка.Следующий() Цикл
// Заполняем параметры шаблонной области данными из текущей записи выборки.
// Метод Заполнить() автоматически сопоставит имена полей выборки с именами параметров.
ОбластьСтрока.Параметры.Заполнить(Выборка);
// Выводим заполненную данными область в итоговый документ.
// Она будет добавлена в следующую свободную строку.
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
Возврат ТабДок;
КонецФункции
В итоге мы получим табличный документ, где в первой строке будет красивый заголовок "Дата акта передачи", а в последующих строках — данные, выведенные с помощью параметра "ДатаАктаПередачи".
Это классический и наиболее правильный способ формирования печатных форм в 1С. Он позволяет отделить визуальное представление (дизайн отчета) от программной логики его заполнения.
Шаг 1. Создание макета в Конфигураторе.
Заполнение и установите его в значение Параметр. Ниже появится свойство Параметр — впишите туда программное имя: ДатаАктаПередачи.Теперь у вас есть готовый шаблон, который очень легко использовать в коде.
Шаг 2. Программное заполнение и вывод макета.
Код для вывода отчета по макету становится значительно проще и чище.
&НаСервере
Функция СформироватьОтчетПоМакету()
// Создаем итоговый табличный документ
ТабДок = Новый ТабличныйДокумент;
// Получаем макет, созданный в конфигураторе
// Вместо "МояОбработка" и "ИмяМакета" подставьте свои имена
Макет = Обработки.МояОбработка.ПолучитьМакет("ИмяМакета");
// Получаем и выводим область шапки из макета
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(ОбластьШапка);
// Получаем область для строк данных
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
// Выполняем запрос для получения данных (аналогично первому решению)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| МойРегистр.Период КАК ДатаАктаПередачи
|ИЗ
| РегистрСведений.МойРегистр КАК МойРегистр";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
// В цикле обходим результат запроса и выводим строки
Пока Выборка.Следующий() Цикл
// Заполняем параметры области "Строка" данными из выборки
ОбластьСтрока.Параметры.Заполнить(Выборка);
// Выводим заполненную область в итоговый документ
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
// Возвращаем сформированный документ
Возврат ТабДок;
КонецФункции
Этот подход является предпочтительным, так как он более гибкий. Если в будущем потребуется изменить текст заголовка, добавить еще одну колонку или поменять шрифты, достаточно будет отредактировать макет в конфигураторе, не затрагивая программный код.