При разработке отчетов и печатных форм в управляемом приложении разработчики часто сталкиваются с ситуацией, когда стандартный метод Показать() объекта ТабличныйДокумент вызывает исключение времени выполнения, либо сформированный отчет открывается в режиме «только просмотр» без возможности ручной правки ячеек. Разберем по шагам, почему возникают эти ошибки, как устроена клиент-серверная работа с табличными документами и как предоставить пользователям возможность редактировать результат.
Рассмотрим две ключевые проблемы, с которыми сталкиваются при попытке отобразить и отредактировать печатную форму на управляемых формах:
Показать() для реквизита формы: в платформе 1С:Предприятие 8.3 метод Показать() предназначен исключительно для вывода табличного документа в отдельном независимом окне на стороне клиента. Если табличный документ привязан к реквизиту управляемой формы (например, отображается в поле табличного документа на самой форме отчета), вызов метода Показать() гарантированно приводит к возникновению системного исключения.&НаКлиенте не могут находиться в модуле объекта отчета или обработки. Формирование данных (запросы, обход выборок, макеты) должно выполняться на сервере, а вывод окна — исключительно на клиенте.ТолькоПросмотр = Ложь, редактирование может блокироваться свойством Защита у ячеек макета или самого табличного документа, а также свойством ТолькоПросмотр элемента управляемой формы.Если в вашем отчете уже есть управляемая форма с полем табличного документа (обычно это реквизит Результат), вызывать метод Показать() не требуется вовсе. Платформа сама выводит сформированный документ в поле формы.
Чтобы пользователи могли вручную изменять данные в сформированном отчете, снимем ограничения в модуле объекта и модуле формы. Проанализируем реализацию в модуле объекта отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Формируем табличный документ собственным алгоритмом
СформироватьОтчет(ДокументРезультат);
// Снимаем блокировку редактирования на уровне самого документа
ДокументРезультат.ТолькоПросмотр = Ложь;
ДокументРезультат.Защита = Ложь;
КонецПроцедуры
Процедура СформироватьОтчет(ТабДокумент)
ТабДокумент.Очистить();
Макет = ПолучитьМакет("ОсновнойМакет");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ТабДокумент.Вывести(ОбластьШапка);
// Вывод строк и подвала
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
ТабДокумент.Вывести(ОбластьПодвал);
КонецПроцедуры
Теперь в модуле управляемой формы отчета проверим, чтобы элемент управления также разрешал редактирование:
&НаКлиенте
Процедура ПослеФормированияОтчета()
// Снимаем признак только для чтения с элемента формы
Элементы.Результат.ТолькоПросмотр = Ложь;
КонецПроцедуры
Если стоит задача сформировать печатную форму или отчет и показать его в отдельном всплывающем окне с возможностью редактирования, создадим независимый экземпляр объекта ТабличныйДокумент на сервере, передадим его на клиент и откроем через метод Показать().
Разберем пример кода для модуля управляемой формы:
&НаКлиенте
Процедура СформироватьИПоказатьВНовомОкне(Команда)
// Получаем полностью заполненный табличный документ с сервера
ТабДок = ПолучитьТабличныйДокументНаСервере();
// Разрешаем редактирование перед показом
ТабДок.ТолькоПросмотр = Ложь;
ТабДок.Защита = Ложь;
// Метод Показать доступен только на клиенте для независимого объекта
ТабДок.Показать("Печатная форма документа");
КонецПроцедуры
&НаСервере
Функция ПолучитьТабличныйДокументНаСервере()
ТабДок = Новый ТабличныйДокумент;
ТабДок.АвтоМасштаб = Истина;
// Получаем макет обработки или отчета
ОбъектОтчет = РеквизитФормыВЗначение("Отчет");
Макет = ОбъектОтчет.ПолучитьМакет("Макет");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(ОбластьШапка);
Возврат ТабДок;
КонецФункции
Если табличный документ уже сформирован и находится в реквизите управляемой формы, но пользователю требуется открыть его в отдельном окне, нельзя вызывать РеквизитТабДок.Показать() напрямую. Обойдем платформенное ограничение, скопировав данные в независимый объект ТабличныйДокумент прямо на клиенте:
&НаКлиенте
Процедура ПоказатьВОтдельномОкнеИзРеквизита(Команда)
// Создаем новый независимый табличный документ
АвтономныйТабДок = Новый ТабличныйДокумент;
// Копируем содержимое из реквизита формы (например, Результат)
АвтономныйТабДок.Вывести(Элементы.Результат.Документ);
// Включаем режим редактирования
АвтономныйТабДок.ТолькоПросмотр = Ложь;
АвтономныйТабДок.Защита = Ложь;
// Открываем окно
АвтономныйТабДок.Показать("Редактирование печатной формы");
КонецПроцедуры
Посмотрим на важные свойства макета, влияющие на доступность редактирования: