При формировании печатных форм в платформе «1С:Предприятие 8» разработчики часто сталкиваются с задачей, когда необходимо изменить данные в ячейке, которая уже была выведена в итоговый табличный документ. Классический пример — вывод на первой странице отчета информации о количестве листов в документе. Так как общее количество страниц становится известно только после полного формирования отчета, разработчику приходится возвращаться к уже сформированным и выведенным ячейкам и динамически менять их содержимое.
В этой статье мы подробно разберем, почему возникают популярные ошибки при попытке изменить текст выведенной области, и рассмотрим четыре надежных способа решения этой задачи.
Попытки изменить текст «напрямую» часто приводят к ошибкам конфигуратора или времени выполнения. Выясним причину их возникновения, чтобы не допускать их в своей практике.
Ошибка 1. «Метод объекта не обнаружен (Область)»
Эта ошибка возникает, когда разработчик пытается вызвать метод Область() у результата метода Вывести(). Рассмотрим некорректный код:
МояОбласть = ТабДокумент.Вывести(ОбластьСтрока);
МояОбласть.Область(1, 1, 1, 1).Текст = "Привет, Вася!"; // Ошибка!
Дело в том, что метод Вывести() возвращает объект типа ОбластьЯчеекТабличногоДокумента. У этого объекта нет собственного метода Область() — данный метод доступен только у самого объекта ТабличныйДокумент.
Ошибка 2. «Поле объекта недоступно для записи (Текст)»
Эта ошибка чаще всего возникает в двух случаях:
СодержитЗначение = Истина). В этом случае платформа ожидает заполнения свойства Значение, а не Текст. Для исправления ситуации нужно либо присваивать данные свойству Значение, либо предварительно программно отключить этот признак: МояОбласть.СодержитЗначение = Ложь;.ТабличныйДокумент.Когда мы выводим область в табличный документ с помощью метода Вывести(), возвращаемый объект ОбластьЯчеекТабличногоДокумента содержит свои точные координаты на итоговом листе. Мы можем использовать свойства области Верх, Лево, Низ и Право для точного позиционирования.
Проанализируем этот подход на примере кода:
ТабДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьОбщийМакет("ТестМакет");
// Получаем область из макета и выводим её
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ВыведеннаяОбласть = ТабДокумент.Вывести(ОбластьСтрока);
// ... Тут происходит вывод остальной части документа ...
// Возвращаемся к сохраненной области, используя её точные координаты
Ячейка = ТабДокумент.Область(ВыведеннаяОбласть.Верх, ВыведеннаяОбласть.Лево, ВыведеннаяОбласть.Низ, ВыведеннаяОбласть.Право);
Ячейка.Текст = "Измененный текст";
Этот способ является наиболее безопасным и производительным, так как нам не нужно заново вычислять высоту таблицы или искать строки по всему документу.
Если вам нужно обратиться к выведенной ячейке в самом конце формирования сложного отчета, отличным решением будет присвоение этой области уникального имени прямо в процессе вывода. После этого вы сможете обратиться к ней по имени из любого места кода.
Рассмотрим, как это реализовать на практике:
ТабДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьОбщийМакет("ТестМакет");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ВыведеннаяОбласть = ТабДокумент.Вывести(ОбластьСтрока);
// Назначаем уникальное имя выведенной области в результирующем документе
ВыведеннаяОбласть.Имя = "УникальнаяОбластьПодписи";
// ... Формируем документ далее ...
// Обращаемся к области напрямую по имени
ТабДокумент.Область("УникальнаяОбластьПодписи").Текст = "Новое значение подписи";
Использование именованных областей делает код более читаемым и защищает от ошибок при изменении структуры макета (например, при добавлении новых колонок или строк).
Этот метод основан на фиксации высоты таблицы в момент вывода области. Он часто используется разработчиками, хотя и требует внимательности при работе с индексами строк и колонок.
Разберем пример реализации этого алгоритма:
ТабДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьОбщийМакет("ТестМакет");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ТабДокумент.Вывести(ОбластьСтрока);
// Запоминаем текущую высоту таблицы (это будет номер строки нашей выведенной области)
НомерСтроки = ТабДокумент.ВысотаТаблицы;
НомерКолонки = 1; // Указываем индекс нужной колонки
// ... Продолжаем вывод документа ...
// Меняем текст в зафиксированной ячейке
ТабДокумент.Область(НомерСтроки, НомерКолонки).Текст = "Текст изменен";
Важное замечание: Обратите внимание на правильный порядок аргументов в методе Область(НомерСтроки, НомерКолонки). Ошибка в очередности параметров — частая причина того, что текст выводится не в ту ячейку или вызывает ошибку выхода за границы таблицы.
Если макет разрабатывается пользователями или часто меняется, жестко прописывать координаты в коде не рекомендуется. В такой ситуации лучше использовать текстовые маркеры (например, {КоличествоЛистов}) прямо в тексте ячейки макета, а в конце генерации отчета заменить их автозаменой.
Посмотрим на пример реализации поиска и замены:
ТабДокумент = Новый ТабличныйДокумент;
// ... Полностью сформировали и вывели весь документ ...
// Выполняем поиск ячейки с маркером по всему документу
НайденнаяОбласть = ТабДокумент.НайтиТекст("{КоличествоЛистов}");
Если НайденнаяОбласть <> Неопределено Тогда
// Заменяем маркер на нужное значение
НайденнаяОбласть.Текст = "5";
КонецЕсли;
Этот способ крайне удобен, так как позволяет вообще не заботиться о координатах, строках и колонках в процессе вывода данных.
Применим полученные знания для решения реальной практической задачи. Нам необходимо полностью сформировать отчет, посчитать итоговое количество страниц и вывести эту информацию в шапке документа на первом листе.
Разберем готовое решение по шагам:
ТабДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьОбщийМакет("ТестМакет");
// Шаг 1. Выводим шапку документа, где должна быть информация о страницах
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ВыведеннаяШапка = ТабДокумент.Вывести(ОбластьШапка);
// Запоминаем координаты ячейки, куда запишем количество страниц
СтрокаДляЗаписи = ВыведеннаяШапка.Верх;
КолонкаДляЗаписи = 2; // Предположим, это вторая колонка шапки
// Шаг 2. Выводим все остальные разделы документа (строки, таблицы, подвалы)
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");Для Каждого СтрокаДанных Из РезультатЗапроса Цикл
ОбластьСтрока.Параметры.Заполнить(СтрокаДанных);
ТабДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
// Шаг 3. Документ полностью сформирован. Рассчитываем итоговое количество страниц
// Метод КоличествоСтраниц() сработает корректно только на полностью готовом документе!
ВсегоСтраниц = ТабДокумент.КоличествоСтраниц();
// Шаг 4. Возвращаемся к сохраненной ячейке в шапке по координатам и записываем текст
ТабДокумент.Область(СтрокаДляЗаписи, КолонкаДляЗаписи).Текст = "Приложение на " + ВсегоСтраниц + " листах";
// Шаг 5. Выводим документ на экран для пользователя
ТабДокумент.Показать("Печать отчета");
Используя данный алгоритм, вы гарантированно получите точное количество страниц в сформированном документе и сможете корректно отобразить его в любой части печатной формы.