Переход с конфигурации 1С:Управление торговлей 10.3 на версию 11.4 (или любую другую современную систему на базе Библиотеки стандартных подсистем — БСП) часто сопровождается трудностями при адаптации внешних печатных форм. Проблема заключается в том, что механизмы работы печатных форм в обычном и управляемом приложении кардинально различаются. Проанализируем основные ошибки и разберем по шагам, как заставить вашу старую печатную форму работать в новой среде.
Рассмотрим ситуацию: при попытке вызвать печать система выдает ошибку в общем модуле ДополнительныеОтчетыИОбработкиКлиент, связанную с методом ПолучитьФорму. Это происходит потому, что современные конфигурации при выполнении команды печати пытаются инициализировать форму обработки, если в параметрах регистрации не указано иное. Если в вашей обработке формы нет (есть только модуль и макет), система заходит в тупик.
Для решения этой проблемы выясним причину в функции СведенияОВнешнейОбработке. Чтобы обработка вызывала серверный метод модуля объекта без поиска формы, необходимо правильно настроить колонку Использование в таблице команд. Вместо открытия формы мы должны использовать тип ВызовСерверногоМетода.
Посмотрим на правильный пример формирования таблицы команд в функции СведенияОВнешнейОбработке:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
Назначение = Новый Массив;
Назначение.Добавить("Документ.ЗаказПоставщику");
ПараметрыРегистрации.Вставить("Назначение", Назначение);
ПараметрыРегистрации.Вставить("Наименование", "Заказ Ара (внешний)");
ПараметрыРегистрации.Вставить("Версия", "1.1");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
ПараметрыРегистрации.Вставить("Информация", "Дополнительная печатная форма для Заказа поставщику");
Команды = ПолучитьТаблицуКоманд();
// Обратите внимание на параметр "ВызовСерверногоМетода"
ДобавитьКоманду(Команды, "Заказ Ара", "ЗаказПоставщикуВнешний", "ВызовСерверногоМетода", Ложь, "ПечатьXML");
ПараметрыРегистрации.Вставить("Команды", Команды);
Возврат ПараметрыРегистрации;
КонецФункции
В УТ 10.3 внешние формы часто полагались на реквизит СсылкаНаОбъект. В управляемом приложении (БСП) механизм иной: в экспортную процедуру Печать передается массив ссылок МассивОбъектов. Это позволяет печатать сразу несколько документов из списка.
Проанализируем ситуацию, когда код падает с ошибкой «Переменная не определена (СсылкаНаОбъект)». Нам необходимо изменить логику получения данных. Теперь мы не обращаемся к реквизиту объекта, а перебираем переданный массив. Выясним, как должна выглядеть структура основной процедуры Печать в модуле объекта:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыПечати) Экспорт
// 1. Проверяем, нужно ли печатать наш макет
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ЗаказПоставщикуВнешний") Тогда
// 2. Формируем табличный документ
ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
// 3. САМЫЙ ВАЖНЫЙ ШАГ: Выводим результат в коллекцию БСП
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ЗаказПоставщикуВнешний",
"Заказ Ара",
ТабличныйДокумент);
КонецЕсли;
КонецПроцедуры
Это одна из самых частых ошибок. Она сигнализирует о том, что процедура Печать завершилась, но в параметре КоллекцияПечатныхФорм не появилось записи с результатом. Рассмотрим подробнее причины:
СведенияОВнешнейОбработке (например, "ЗаказПоставщикуВнешний"), должен в точности совпадать с тем, который вы проверяете в функции НужноПечататьМакет и используете в ВывестиТабличныйДокументВКоллекцию.ТабличныйДокумент осталась пустой, БСП выдаст исключение.УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию, полагая, что достаточно просто вернуть значение из функции.Посмотрим на пример того, как переписать старую логику формирования под массив объектов. Нам нужно подготовить макет, выполнить запрос по всем ссылкам из массива и вывести области. Проанализируем пример кода:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.АвтоМасштаб = Истина;
// Получаем макет из состава самой внешней обработки
Макет = ЭтотОбъект.ПолучитьМакет("СчетЗаказ");
Для Каждого ТекущийОбъект Из МассивОбъектов Цикл
// Устанавливаем точку начала печати для каждого объекта
НомерСтрокиНачало = ТабДокумент.РезультатТаблица.КоличествоСтрок() + 1;
// Здесь мы адаптируем ваш запрос из УТ 10.3
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Заказ.Номер КАК Номер,
| Заказ.Дата КАК Дата,
| Заказ.Организация КАК Организация
|ИЗ
| Документ.ЗаказПоставщику КАК Заказ
|ГДЕ
| Заказ.Ссылка = &ТекущийДокумент";
Запрос.УстановитьПараметр("ТекущийДокумент", ТекущийОбъект);
Шапка = Запрос.Выполнить.Выбрать();
Если Шапка.Следующий() Тогда
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьЗаголовок.Параметры.Заполнить(Шапка);
ТабДокумент.Вывести(ОбластьЗаголовок);
// Далее следует логика вывода строк (Товары, Услуги)
// ... (аналогично через макет и параметры)
КонецЕсли;
// Сообщаем системе, к какому объекту относится данный диапазон строк
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабДокумент, НомерСтрокиНачало, ОбъектыПечати, ТекущийОбъект);
// Если печатаем несколько документов, добавляем разделитель
Если МассивОбъектов.Количество() > 1 И ТекущийОбъект <> МассивОбъектов[МассивОбъектов.Количество()-1] Тогда
ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
КонецЦикла;
Возврат ТабДокумент;
КонецФункции
Безопасный режим: В функции СведенияОВнешнейОбработке параметр БезопасныйРежим лучше устанавливать в значение Ложь, если ваша печатная форма требует обращения к методам, которые могут быть ограничены (например, работа с файловой системой или специфическими общими модулями). Однако помните, что в облачных сервисах (1С:Фреш) разрешен только безопасный режим.
Использование Менеджера объекта: В некоторых случаях программисты пытаются вызвать типовые функции печати через МенеджерОбъекта.ПолучитьДанныеДляПечатнойФормы.... Рассмотрим этот момент: если вы используете стандартный макет конфигурации, это сработает. Но если ваш макет находится внутри внешней обработки, типовой менеджер его "не увидит". Вам необходимо использовать ЭтотОбъект.ПолучитьМакет().
Отладка: Для отладки внешних печатных форм в управляемом приложении рекомендуется использовать специальную обработку "Консоль отладки печатных форм". Она позволяет эмулировать передачу параметров МассивОбъектов и КоллекцияПечатныхФорм, что невозможно сделать, просто открыв внешнюю обработку через "Файл - Открыть".
Подводя итог, можно сказать, что основная сложность адаптации заключается в переходе от работы с одиночным объектом к работе с коллекциями БСП. Соблюдение структуры СведенияОВнешнейОбработке и корректное заполнение КоллекцияПечатныхФорм гарантируют успешную работу вашей формы в УТ 11.4.