При переходе с обычных форм на управляемые или при разработке внешних печатных форм для современных конфигураций (ERP, КА, УТ, БП 3.0) разработчики часто сталкиваются с ошибкой при попытке вызвать метод Показать(). Раньше, в толстом клиенте, мы могли написать ТабДок.Показать() в любом месте кода, и платформа открывала окно. Однако в управляемом приложении архитектура стала строже: сервер отвечает за данные, а клиент — за интерфейс.
Рассмотрим подробно, почему возникает эта проблема, и разберем несколько проверенных способов решения задачи для комфортной отладки печатных форм.
Ошибка возникает, когда в процедуре или функции, выполняемой на стороне сервера (директивы &НаСервере, модуль объекта, общий модуль с галочкой "Сервер"), вызывается интерактивный метод.
Давайте разберемся в сути ограничения. Сервер 1С Предприятия часто работает как служба Windows или процесс Linux (daemon). У этого процесса нет "экрана" или графического интерфейса пользователя. Ему просто некуда "показать" окно. Даже если вы запускаете файловую базу на своем компьютере, контекст сервера эмулирует это поведение, запрещая использование визуальных методов.
Метод ТабличныйДокумент.Показать() предназначен исключительно для клиентского приложения. Поэтому, если нам нужно увидеть результат формирования (например, макет внешней печатной формы), нам необходимо передать этот результат с сервера на клиент.
Если вы разрабатываете внешнюю печатную форму «Заявление на отпуск» или другую обработку и хотите быстро проверить, как заполняется макет, самым простым решением будет создание временной формы для отладки. Этот метод позволяет "обернуть" серверный код вызова печати в клиентскую процедуру.
Рассмотрим алгоритм действий:
СсылкаНаОбъект (тип вашего документа) и перетащим его на форму, чтобы выбирать тестовый документ.Печать и поместим кнопку на форму.Посмотрим на пример реализации кода в модуле формы:
&НаКлиенте
Процедура Печать(Команда)
// 1. Вызываем функцию, которая выполнится на сервере и вернет готовый ТабДок
ТабДок = ПечатьНаСервере();
// 2. Показываем результат уже на клиенте
ТабДок.Показать("Тестовая печать");
КонецПроцедуры
&НаСервере
Функция ПечатьНаСервере()
// Получаем объект обработки для доступа к её методам
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
// Здесь вызываем вашу основную экспортную функцию печати,
// которую вы обычно используете для БСП
// Предположим, она называется СформироватьПечатнуюФорму
СформированныйТабДок = ОбработкаОбъект.СформироватьПечатнуюФорму(СсылкаНаОбъект);
Возврат СформированныйТабДок;
КонецФункции
Этот способ хорош тем, что он прост в реализации. В качестве примера можно взять готовый шаблон, такой как Заявление на отпуск без сохранения оплаты, где уже реализована структура для удобной отладки. Однако стоит помнить, что передача большого табличного документа напрямую через Возврат может нагрузить систему.
В стандартах разработки 1С рекомендуется не гонять "тяжелые" объекты через контекст формы напрямую. Правильнее поместить данные во временное хранилище на сервере, передать на клиент адрес, а на клиенте получить данные обратно.
Давайте адаптируем наш пример под этот стандарт:
&НаКлиенте
Процедура Печать(Команда)
// Получаем адрес хранилища, где лежит наш ТабДок
АдресХранилища = ПечатьНаСервере();
// Получаем ТабДок из хранилища уже на клиенте
ТабДок = ПолучитьИзВременногоХранилища(АдресХранилища);
If ТабДок <> Неопределено Тогда
ТабДок.Показать();
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПечатьНаСервере()
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
СформированныйТабДок = ОбработкаОбъект.СформироватьПечатнуюФорму(СсылкаНаОбъект);
// Помещаем результат во временное хранилище.
Адрес = ПоместитьВоВременноеХранилище(СформированныйТабДок, УникальныйИдентификатор);
Возврат Адрес;
КонецФункции
Такой подход считается наиболее грамотным и стабильным при работе с управляемыми формами.
Бывают ситуации, когда код выполняется глубоко на сервере (например, в регламентном задании), и передать управление на клиент невозможно. Как посмотреть результат? В этом случае можно использовать метод Записать().
При отладке на сервере мы сохраним табличный документ в файл формата MXL прямо на диске:
// Этот код выполняется &НаСервере
ТабДок = Новый ТабличныйДокумент;
// ... (заполнение макета, вывод областей) ...
Попытка
ПутьКФайлу = "C:\Temp\Debug_PrintForm_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".mxl";
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.MXL);
Исключение
ЗаписьЖурналаРегистрации("Отладка", УровеньЖурналаРегистрации.Ошибка, , , "Не удалось записать файл: " + ОписаниеОшибки());
КонецПопытки;
После выполнения вы можете открыть файл вручную. Подобный подход часто применяется в сложных складских формах, например, когда отлаживается Задание на отбор / размещение товара.
Итак, мы выяснили, что ошибка при вызове ТабДок.Показать() на сервере — это не сбой, а особенность архитектуры 1С. Для решения задачи отладки вывода данных:
Записать(), если отладка происходит в фоновых заданиях.