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