Как вызвать процедуру печати из модуля объекта одного документа в управляемой форме другого в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В практике разработки на платформе 1С:Предприятие 8 часто возникают ситуации, когда необходимо использовать уже готовую логику одного документа внутри другого. Типичный пример — вызов процедуры Печать из типового документа (например, Реализация товаров и услуг в УТ 10.3) при работе в новом документе на управляемых формах. Несмотря на то, что процедура помечена как Экспорт, разработчики часто сталкиваются с ошибкой "Метод объекта не обнаружен". Разберем подробно, почему это происходит и как правильно организовать взаимодействие между объектами.

Анализ причины ошибки: почему платформа «не видит» метод?

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


&НаСервере
Процедура ПечатьРеализацииНаСервере()
    // Получаем объект документа по ссылке из реквизита
    ДокОбъект = Объект.Реализация.ПолучитьОбъект();
    // Пытаемся вызвать экспортную процедуру модуля объекта
    ДокОбъект.Печать(); 
КонецПроцедуры

Если при выполнении этого кода возникает ошибка Метод объекта не обнаружен (Печать), первым делом проанализируем контекст исполнения. В конфигурациях, которые переводились с версии 8.1 на 8.2/8.3 (как УТ 10.3), модули объектов часто содержат директивы препроцессора.

Выясним причину: в модуле объекта документа РеализацияТоваровУслуг процедура Печать может быть обернута в блок:


#Если Клиент Тогда
Процедура Печать() Экспорт
    // Логика формирования и вывода на печать
КонецПроцедуры
#КонецЕсли

Важный момент: когда мы вызываем код из управляемой формы с директивой &НаСервере, платформа выполняет код на стороне сервера. Если процедура в модуле объекта ограничена директивой #Если Клиент, то для серверного контекста её просто не существует. Именно поэтому возникает ошибка, несмотря на наличие ключевого слова Экспорт.

Решение №1: Корректировка директив компиляции

Проанализируем содержимое процедуры Печать. Если внутри неё нет специфических клиентских методов (например, Предупреждение(), Вопрос() или работы с формами), мы можем изменить условия компиляции. Однако в старых конфигурациях процедура печати часто напрямую вызывает метод ТабличныйДокумент.Показать().

Посмотрим на ограничения: метод Показать() работает только на клиенте. Если мы просто удалим #Если Клиент, серверная часть кода «упадет» при попытке вывести окно печати, так как на сервере нет интерфейса. Правильным подходом будет разделение логики формирования данных и логики отображения.

Решение №2: Вынос логики в модуль менеджера (Рекомендуемое)

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

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

Пример кода в модуле менеджера Реализации:


Функция СформироватьПечатнуюФорму(СсылкаНаДокумент) Экспорт
    ТабДок = Новый ТабличныйДокумент;
    // ... здесь логика запроса данных и заполнения макета ...
    Возврат ТабДок;
КонецФункции

Теперь проанализируем, как вызвать это из нашей управляемой формы:


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

&НаКлиенте
Процедура КомандаПечать(Команда)
    ТабДок = ПолучитьПечатнуюФормуНаСервере();
    // На клиенте метод Показать() отработает без ошибок
    ТабДок.Показать("Печать реализации");
КонецПроцедуры

Решение №3: Использование функции РеквизитФормыВЗначение

В некоторых обсуждениях упоминается метод РеквизитФормыВЗначение. Рассмотрим, применим ли он здесь. Этот метод используется для преобразования данных текущей формы (объекта, с которым мы работаем прямо сейчас) в прикладной объект 1С на сервере.

Внимание: Если нам нужно вызвать метод другого документа (по ссылке из реквизита), то РеквизитФормыВЗначение нам не поможет. Этот метод работает только для основного реквизита текущей формы. Для внешних документов всё равно придется использовать либо ПолучитьОбъект(), либо (что лучше) обращаться к Модулю Менеджера.

Особенности работы в гибридных конфигурациях (УТ 10.3)

Поскольку УТ 10.3 изначально строилась на обычных формах, вызов типовых процедур печати из управляемых форм часто требует "прослойки". Если вы не хотите глубоко переделывать типовой механизм, можно попробовать следующее:

  1. Проверьте, нет ли в конфигурации общего модуля, отвечающего за печать (например, УниверсальныеМеханизмы).
  2. Посмотрите, как реализована кнопка печати в самой Реализации. Часто там используется вызов внешней печатной формы или экспортная процедура, принимающая массив ссылок.
  3. Если процедура Печать в модуле объекта обязательна для использования, убедитесь, что она доступна серверу (директивы #Если Сервер Или ТолстыйКлиентОбычноеПриложение Тогда).

Подведем итог: ошибка Метод объекта не обнаружен почти всегда связана с тем, что код написан внутри блока #Если Клиент. Для решения задачи в управляемом приложении необходимо либо пересмотреть директивы компиляции, либо (что архитектурно правильнее) вынести логику формирования печатной формы в модуль менеджера, разделяя подготовку данных на сервере и визуализацию на клиенте.

← На главную