Как исправить ошибку «Метод объекта не обнаружен (Печать)» во внешней печатной форме 1С 8.3?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При переносе печатных форм с обычного приложения (1С:Предприятие 8.2) на управляемые формы (1С:Предприятие 8.3 на базе Библиотеки Стандартных Подсистем) разработчики часто сталкиваются с ошибками вызова обработчиков печати. Наиболее распространенная из них — Метод объекта не обнаружен (Печать) при попытке сформировать документ из формы или списка.

Разберем причины возникновения этой ситуации, рассмотрим архитектурные требования подсистемы «Дополнительные отчеты и обработки» и составим правильный шаблон внешней печатной формы.

Причины возникновения ошибки

Проанализируем контекст выполнения кода. Ошибка Метод объекта не обнаружен (Печать) в общем модуле ДополнительныеОтчетыИОбработкиКлиент возникает из-за несовпадения настроек команды регистрации обработки и реальной реализации процедур в объекте:

  1. Неправильный способ вызова команды: в функции СведенияОВнешнейОбработке() указан вариант использования ВызовКлиентскогоМетода. В этом случае БСП пытается открыть клиентскую форму обработки и вызвать экспортную процедуру Печать в модуле этой формы. Если формы у обработки нет или процедура не объявлена, платформа генерирует исключение.
  2. Несовместимая сигнатура процедуры печати: в старых версиях печать реализовывалась как функция Печать() в модуле объекта, возвращающая ТабличныйДокумент. По стандартам БСП для серверной печати требуется экспортная процедура со строгим набором параметров: (МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода).

Шаг 1. Корректировка функции регистрации «СведенияОВнешнейОбработке»

Выясним, как правильно зарегистрировать внешнюю обработку в системе. Если обработка не требует открытия диалогового окна для ввода параметров пользователем, необходимо использовать серверный метод вызова.

Посмотрим на пример заполнения функции СведенияОВнешнейОбработке в модуле объекта обработки:


Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = Новый Структура;
    МассивНазначений = Новый Массив;
    МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг");

    ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
    ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
    ПараметрыРегистрации.Вставить("Наименование", "Акт приема-передачи КОМ");
    ПараметрыРегистрации.Вставить("Версия", "1.1");
    ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
    ПараметрыРегистрации.Вставить("Информация", "Дополнительная печатная форма к документу Реализация товаров и услуг");

    ТаблицаКоманд = Новый ТаблицаЗначений;
    ТаблицаКоманд.Колонки.Добавить("Представление");
    ТаблицаКоманд.Колонки.Добавить("Идентификатор");
    ТаблицаКоманд.Колонки.Добавить("Использование");
    ТаблицаКоманд.Колонки.Добавить("ПоказыватьОповещение");
    ТаблицаКоманд.Колонки.Добавить("Модификатор");

    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = "Акт приема-передачи КОМ";
    НоваяКоманда.Идентификатор = "АктПриемаПередачи";
    // Указываем вызов серверного метода для печати без открытия формы
    НоваяКоманда.Использование = "ВызовСерверногоМетода";
    НоваяКоманда.ПоказыватьОповещение = Истина;
    НоваяКоманда.Модификатор = "ПечатьMXL";

    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);

    Возврат ПараметрыРегистрации;

КонецФункции

Шаг 2. Реализация стандартной процедуры печати по правилам БСП

Разберем реализацию серверной процедуры Печать в модуле объекта. Обратите внимание: директивы компиляции (например, &НаСервере) в модуле объекта внешней обработки использовать нельзя, так как модуль объекта всегда выполняется на стороне сервера.

Стандартный обработчик должен проверять, требуется ли формировать макет с переданным идентификатором команды, формировать табличный документ и помещать его в коллекцию через метод УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию():


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

    ПараметрыВывода.ДоступнаПечатьПоКомплектно = Ложь;
    ИмяИдентификатора = "АктПриемаПередачи";

    Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, ИмяИдентификатора) Тогда
        
        ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
        
        УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
            КоллекцияПечатныхФорм,
            ИмяИдентификатора,
            "Акт приема-передачи КОМ",
            ТабличныйДокумент
        );
        
    КонецЕсли;

КонецПроцедуры

Шаг 3. Формирование табличного документа и пакетная печать

Рассмотрим подробнее логику функции формирования самого печатного документа. В управляемом интерфейсе пользователь может выделить сразу несколько документов в списке и отправить их на печать. Поэтому алгоритм обязательно должен обрабатывать весь переданный МассивОбъектов в цикле.

Также оптимизируем код: вместо самописных функций преобразования номеров месяцев в строки используем встроенную функцию форматирования дат Формат(Дата, "ДФ=MMMM").


Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)

    ТабДокумент = Новый ТабличныйДокумент;
    ТабДокумент.АвтоМасштаб = Истина;
    ТабДокумент.КлючПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_АктПриемаПередачи";

    Макет = ПолучитьМакет("Макет");
    ПервыйДокумент = Истина;

    Для Каждого СсылкаНаОбъект Из МассивОбъектов Цикл

        Если Не ПервыйДокумент Тогда
            ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;

        НомерСтрокиНачало = ТабДокумент.ТаблицаВысота + 1;

        // Вывод шапки
        Шапка = Макет.ПолучитьОбласть("Шапка");
        Шапка.Параметры.Продавец = СсылкаНаОбъект.Организация.НаименованиеПолное;
        Шапка.Параметры.ИННПродавца = СсылкаНаОбъект.Организация.ИНН;
        Шапка.Параметры.Покупатель = СсылкаНаОбъект.Контрагент.НаименованиеПолное;
        Шапка.Параметры.ИННПокупателя = СсылкаНаОбъект.Контрагент.ИНН;
        ТабДокумент.Вывести(Шапка);

        // Получение ответственных лиц
        ГенДир = ОбщегоНазначения.ОтветственныеЛица(СсылкаНаОбъект.Организация, СсылкаНаОбъект.Дата);

        ОсновнойТекст = Макет.ПолучитьОбласть("ОсновнойТекст");
        ОсновнойТекст.Параметры.Дата = Формат(СсылкаНаОбъект.Дата, "ДЛФ=Д");
        ОсновнойТекст.Параметры.Номер = ОбщегоНазначения.ПолучитьНомерНаПечать(СсылкаНаОбъект);
        ОсновнойТекст.Параметры.ДатаДоговора = Формат(СсылкаНаОбъект.ДоговорКонтрагента.Дата, "ДЛФ=Д");
        ОсновнойТекст.Параметры.НомерДоговора = СсылкаНаОбъект.ДоговорКонтрагента.Наименование;
        ОсновнойТекст.Параметры.НачалоПериода = Формат(НачалоМесяца(СсылкаНаОбъект.Дата), "ДЛФ=Д");
        ОсновнойТекст.Параметры.КонецПериода = Формат(КонецМесяца(СсылкаНаОбъект.Дата), "ДЛФ=Д");
        ТабДокумент.Вывести(ОсновнойТекст);

        ШапкаСтрока = Макет.ПолучитьОбласть("ШапкаСтрока");
        ТабДокумент.Вывести(ШапкаСтрока);

        // Запрос данных табличной части
        Запрос = Новый Запрос;
        Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);
        Запрос.Текст = 
            "ВЫБРАТЬ
            |   Таб.Номенклатура КАК Номенклатура,
            |   Таб.Количество КАК Количество,
            |   Таб.СуммаНДС КАК СуммаНДС,
            |   ВЫБОР
            |       КОГДА Таб.Ссылка.СуммаВключаетНДС ТОГДА Таб.Сумма - ЕСТЬNULL(Таб.СуммаНДС, 0)
            |       ИНАЧЕ Таб.Сумма
            |   КОНЕЦ КАК Сумма,
            |   Таб.Цена КАК Цена,
            |   ВЫБОР
            |       КОГДА Таб.Ссылка.СуммаВключаетНДС ТОГДА Таб.Сумма
            |       ИНАЧЕ Таб.Сумма + Таб.СуммаНДС
            |   КОНЕЦ КАК СуммаСНДС
            |ИЗ
            |   Документ.РеализацияТоваровУслуг.Товары КАК Таб
            |ГДЕ
            |   Таб.Ссылка = &Ссылка";

        Выборка = Запрос.Выполнить().Выбрать();

        ИтогоСумма = 0;
        ИтогоСуммаНДС = 0;
        ИтогоСуммаСНДС = 0;
        НомерСтроки = 0;

        Пока Выборка.Следующий() Цикл
            Строка = Макет.ПолучитьОбласть("Строка");
            НомерСтроки = НомерСтроки + 1;
            Строка.Параметры.Заполнить(Выборка);
            Строка.Параметры.НомерСтроки = НомерСтроки;
            
            // Использование стандартного формата для вывода названия месяца
            НазваниеМесяца = Формат(СсылкаНаОбъект.Дата, "ДФ=MMMM");
            Строка.Параметры.Номенклатура = Выборка.Номенклатура.Наименование + " за " + НазваниеМесяца + " " + Формат(Год(СсылкаНаОбъект.Дата), "ЧГ=0") + "г.";

            ИтогоСумма = ИтогоСумма + Выборка.Сумма;
            ИтогоСуммаНДС = ИтогоСуммаНДС + Выборка.СуммаНДС;
            ИтогоСуммаСНДС = ИтогоСуммаСНДС + Выборка.СуммаСНДС;
            
            ТабДокумент.Вывести(Строка);
        КонецЦикла;

        ИтогоСтрока = Макет.ПолучитьОбласть("ИтогоСтрока");
        ИтогоСтрока.Параметры.ИтогоСумма = ИтогоСумма;
        ИтогоСтрока.Параметры.ИтогоСуммаНДС = ИтогоСуммаНДС;
        ИтогоСтрока.Параметры.ИтогоСуммаСНДС = ИтогоСуммаСНДС;
        ТабДокумент.Вывести(ИтогоСтрока);

        Подвал = Макет.ПолучитьОбласть("Подвал");
        Подвал.Параметры.Организация = СсылкаНаОбъект.Организация.Наименование;
        Подвал.Параметры.ГенДир = ГенДир.Руководитель;
        ТабДокумент.Вывести(Подвал);

        // Регистрация области печати для позиционирования
        УправлениеПечатью.ЗадатьОбластьПечати(ОбъектыПечати, СсылкаНаОбъект, ТабДокумент, НомерСтрокиНачало);

        ПервыйДокумент = Ложь;

    КонецЦикла;

    Возврат ТабДокумент;

КонецФункции

Важные нюансы при отладке и регистрации

  1. Точное совпадение идентификаторов: строка в НоваяКоманда.Идентификатор в функции СведенияОВнешнейОбработке должна символ в символ совпадать с идентификатором, который передается вторым параметром в УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(). Если имена различаются, система выдаст ошибку: В обработчике печати не был сформирован табличный документ для: [Идентификатор].
  2. Обновление обработки в базе данных: при внесении изменений в файл .epf обязательно перезагружайте его в справочник Дополнительные отчеты и обработки (раздел Администрирование — Печатные формы, отчеты и обработки), иначе в сеансе пользователя будут выполняться закешированные двоичные данные старой версии.
← На главную