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