Разработка внешних печатных форм (ВПФ) на базе Библиотеки стандартных подсистем (БСП) в современных конфигурациях 1С, таких как «Управление торговлей 11», «ERP Управление предприятием» или «Комплексная автоматизация», — стандартная задача для разработчика. Однако в процессе переноса кода из типовой конфигурации во внешнюю обработку часто возникают неочевидные ошибки. Рассмотрим две наиболее распространенные проблемы, с которыми сталкиваются как начинающие, так и опытные программисты, и подробно разберем способы их решения. В качестве готовой альтернативы ручной разработке можно использовать комплект внешних печатных форм для УТ 11.
Эта ошибка возникает на этапе вызова печати из интерфейса документа. Система выдает системное сообщение, указывающее на общий модуль УправлениеПечатью:
Метод объекта не обнаружен (Печать) {ОбщийМодуль.УправлениеПечатью.Модуль(1510)}: ВнешняяОбработкаОбъект.Печать(
Выясним причину этой неисправности. Механизм БСП при вызове внешней печатной формы динамически загружает обработку во временное хранилище на стороне сервера, создает экземпляр объекта этой обработки и пытается выполнить экспортную процедуру Печать. Для успешного выполнения должны соблюдаться два строгих правила:
Печать должна быть расположена строго в Модуле объекта внешней обработки, а не в модуле формы.Экспорт. Использование директив компиляции, таких как &НаКлиенте или &НаСервере, в модуле объекта недопустимо — весь код модуля объекта по умолчанию компилируется на сервере.Проанализируем ошибку автора темы. Он объявил процедуру следующим образом:
&НаКлиенте
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
...
КонецПроцедуры
Из-за директивы &НаКлиенте (и, скорее всего, размещения кода в модуле формы) серверный контекст БСП просто «не видит» данный метод внутри объекта обработки, что и приводит к критической ошибке.
При переносе кода формирования печатной формы из модуля менеджера документа (например, документа «Реализация товаров и услуг») разработчики часто сталкиваются с ошибкой компиляции на сервере:
Процедура или функция с указанным именем не определена (УстановитьПараметр) (Проверка: Сервер)
Давайте разберем по шагам, почему это происходит. Существует принципиальная разница между методом встроенного языка 1С Запрос.УстановитьПараметр() и вызовом локальной процедуры УстановитьПараметр() для области макета.
В типовых конфигурациях фирмы «1С» для безопасного заполнения параметров в областях табличного документа используется специальная вспомогательная процедура-посредник. Если присваивать значения параметрам напрямую, например: ОбластьНомераСтроки.Параметры.НомерСтроки = НомерСтроки, то при случайном удалении этого параметра из макета (или при его редактировании пользователем) программа завершит работу аварийно с ошибкой «Поле объекта не обнаружено».
Чтобы избежать подобных падений, разработчики «1С» используют процедуру УстановитьПараметр, которая безопасно записывает данные в параметры области макета через структуру. При копировании алгоритма печати из модуля менеджера документа во внешнюю обработку программисты часто забывают скопировать эту маленькую служебную процедуру, которая обычно располагается в самом низу модуля менеджера.
Для того чтобы исправить обе ошибки, нам необходимо правильно спроектировать Модуль объекта нашей внешней обработки. Рассмотрим готовый и корректный шаблон модуля объекта, который содержит все необходимые процедуры и функции.
// Функция обязательна для интеграции внешней обработки с БСП
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
ПараметрыРегистрации.Наименование = "Реализация товаров и услуг (Внешний макет)";
ПараметрыРегистрации.БезопасныйРежим = Ложь;
ПараметрыРегистрации.Версия = "1.0";
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Печать накладной (внешняя)";
НоваяКоманда.Идентификатор = "УПДВнешний";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипВызоваВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
НоваяКоманда.Модификатор = "ПечатьMXL";
Возврат ПараметрыРегистрации;
КонецФункции
// Основная экспортная процедура печати (вызывается БСП на сервере)
// Обратите внимание: никаких директив компиляции (&НаКлиенте, &НаСервере) перед процедурой быть не должно!
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
ПараметрыПечати = Новый Структура;
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "УПДВнешний") Тогда
// Формируем табличный документ на сервере
ТабличныйДокумент = СформироватьПечатнуюФормуНакладная(МассивОбъектов, ОбъектыПечати, ПараметрыПечати);
// Выводим результат в коллекцию печатных форм для отображения пользователю
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"УПДВнешний",
НСтр("ru = 'Реализация товаров'"),
ТабличныйДокумент,
,
"УниверсальныйПередаточныйДокумент");
КонецЕсли;
КонецПроцедуры
// Функция формирования печатной формы
Функция СформироватьПечатнуюФормуНакладная(МассивОбъектов, ОбъектыПечати, ПараметрыПечати)
ТабДок = Новый ТабличныйДокумент;
ТабДок.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг_Макета";
// Получаем макет внешней обработки
Макет = ПолучитьМакет("УПДВнешний");
// Получаем области макета
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьНомераСтроки = Макет.ПолучитьОбласть("Строка");
// Пример работы с запросом на сервере
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| РеализацияТоваровУслуг.Номер КАК Номер,
| РеализацияТоваровУслуг.Дата КАК Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Ссылка В(&МассивОбъектов)";
// Здесь используется встроенный метод запроса:
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Выборка = Запрос.Выполнить().Выбрать();
НомерСтроки = 0;
Пока Выборка.Следующий() Цикл
// Выводим заголовок документа
ТабДок.Вывести(ОбластьЗаголовок);
// Пример вывода строк с использованием нашей безопасной процедуры заполнения параметров
НомерСтроки = НомерСтроки + 1;
УстановитьПараметр(ОбластьНомераСтроки, "НомерСтроки", НомерСтроки);
ТабДок.Вывести(ОбластьНомераСтроки);
КонецЦикла;
Возврат ТабДок;
КонецФункции
// Вспомогательная процедура для безопасного заполнения параметров макета табличного документа.
// Мы переносим её из модуля менеджера документа конфигурации-источника.
Процедура УстановитьПараметр(ОбластьМакета, ИмяПараметра, ЗначениеПараметра)
ОбластьМакета.Параметры.Заполнить(Новый Структура(ИмяПараметра, ЗначениеПараметра));
КонецПроцедуры
Рассмотрим более детально, как работает процедура УстановитьПараметр, которую мы добавили в самый конец нашего модуля объекта:
Процедура УстановитьПараметр(ОбластьМакета, ИмяПараметра, ЗначениеПараметра)
ОбластьМакета.Параметры.Заполнить(Новый Структура(ИмяПараметра, ЗначениеПараметра));
КонецПроцедуры
Этот метод использует стандартную функцию Заполнить() коллекции параметров области табличного документа. В качестве источника данных передается Новый Структура(ИмяПараметра, ЗначениеПараметра). Метод Заполнить сопоставляет ключи структуры с именами параметров области. Если параметр с именем, указанным во втором аргументе, отсутствует в макете, платформа 1С просто проигнорирует его заполнение и не вызовет критического исключения. Это делает печатную форму гораздо более устойчивой к изменениям макета пользователями.
Чтобы избежать описанных в статье проблем при создании новых внешних отчетов и обработок, рекомендуем придерживаться следующего алгоритма проверки:
Печать и вспомогательные функции, должны находиться исключительно в модуле объекта обработки (не в модуле формы!).Печать в модуле объекта нет директивы &НаКлиенте.Печать обязательно должно быть прописано ключевое слово Экспорт.УстановитьПараметр, ВывестиСтроку и т. д.) в свою внешнюю обработку.Применяя данные правила и используя предложенный шаблон модуля объекта, вы сможете успешно создавать надежные внешние печатные формы БСП, избегая типичных ошибок компиляции и контекстных вызовов. Для автоматизированного создания обработок с корректной структурой БСП можно использовать конструктор внешних печатных форм.