В практике разработки на платформе 1С:Предприятие 8 часто возникают ситуации, когда необходимо использовать уже готовую логику одного документа внутри другого. Типичный пример — вызов процедуры Печать из типового документа (например, Реализация товаров и услуг в УТ 10.3) при работе в новом документе на управляемых формах. Несмотря на то, что процедура помечена как Экспорт, разработчики часто сталкиваются с ошибкой "Метод объекта не обнаружен". Разберем подробно, почему это происходит и как правильно организовать взаимодействие между объектами.
Рассмотрим ситуацию: у нас есть управляемая форма документа Документ2. На сервере мы получаем объект другого документа через ПолучитьОбъект() и пытаемся вызвать его экспортную процедуру. Программный код выглядит примерно так:
&НаСервере
Процедура ПечатьРеализацииНаСервере()
// Получаем объект документа по ссылке из реквизита
ДокОбъект = Объект.Реализация.ПолучитьОбъект();
// Пытаемся вызвать экспортную процедуру модуля объекта
ДокОбъект.Печать();
КонецПроцедуры
Если при выполнении этого кода возникает ошибка Метод объекта не обнаружен (Печать), первым делом проанализируем контекст исполнения. В конфигурациях, которые переводились с версии 8.1 на 8.2/8.3 (как УТ 10.3), модули объектов часто содержат директивы препроцессора.
Выясним причину: в модуле объекта документа РеализацияТоваровУслуг процедура Печать может быть обернута в блок:
#Если Клиент Тогда
Процедура Печать() Экспорт
// Логика формирования и вывода на печать
КонецПроцедуры
#КонецЕсли
Важный момент: когда мы вызываем код из управляемой формы с директивой &НаСервере, платформа выполняет код на стороне сервера. Если процедура в модуле объекта ограничена директивой #Если Клиент, то для серверного контекста её просто не существует. Именно поэтому возникает ошибка, несмотря на наличие ключевого слова Экспорт.
Проанализируем содержимое процедуры Печать. Если внутри неё нет специфических клиентских методов (например, Предупреждение(), Вопрос() или работы с формами), мы можем изменить условия компиляции. Однако в старых конфигурациях процедура печати часто напрямую вызывает метод ТабличныйДокумент.Показать().
Посмотрим на ограничения: метод Показать() работает только на клиенте. Если мы просто удалим #Если Клиент, серверная часть кода «упадет» при попытке вывести окно печати, так как на сервере нет интерфейса. Правильным подходом будет разделение логики формирования данных и логики отображения.
Современный стандарт разработки 1С рекомендует переносить функции печати в модуль менеджера. Это позволяет вызывать печать без создания тяжелого объекта через ПолучитьОбъект(), что значительно экономит ресурсы сервера. Разберем по шагам, как это реализовать:
РеализацияТоваровУслуг.СформироватьПечатнуюФорму(СсылкаНаДокумент), которая возвращает готовый ТабличныйДокумент.Пример кода в модуле менеджера Реализации:
Функция СформироватьПечатнуюФорму(СсылкаНаДокумент) Экспорт
ТабДок = Новый ТабличныйДокумент;
// ... здесь логика запроса данных и заполнения макета ...
Возврат ТабДок;
КонецФункции
Теперь проанализируем, как вызвать это из нашей управляемой формы:
&НаСервере
Функция ПолучитьПечатнуюФормуНаСервере()
// Вызываем менеджер напрямую, не создавая объект документа
Возврат Документы.РеализацияТоваровУслуг.СформироватьПечатнуюФорму(Объект.Реализация);
КонецФункции
&НаКлиенте
Процедура КомандаПечать(Команда)
ТабДок = ПолучитьПечатнуюФормуНаСервере();
// На клиенте метод Показать() отработает без ошибок
ТабДок.Показать("Печать реализации");
КонецПроцедуры
В некоторых обсуждениях упоминается метод РеквизитФормыВЗначение. Рассмотрим, применим ли он здесь. Этот метод используется для преобразования данных текущей формы (объекта, с которым мы работаем прямо сейчас) в прикладной объект 1С на сервере.
Внимание: Если нам нужно вызвать метод другого документа (по ссылке из реквизита), то РеквизитФормыВЗначение нам не поможет. Этот метод работает только для основного реквизита текущей формы. Для внешних документов всё равно придется использовать либо ПолучитьОбъект(), либо (что лучше) обращаться к Модулю Менеджера.
Поскольку УТ 10.3 изначально строилась на обычных формах, вызов типовых процедур печати из управляемых форм часто требует "прослойки". Если вы не хотите глубоко переделывать типовой механизм, можно попробовать следующее:
УниверсальныеМеханизмы).Реализации. Часто там используется вызов внешней печатной формы или экспортная процедура, принимающая массив ссылок.Печать в модуле объекта обязательна для использования, убедитесь, что она доступна серверу (директивы #Если Сервер Или ТолстыйКлиентОбычноеПриложение Тогда).Подведем итог: ошибка Метод объекта не обнаружен почти всегда связана с тем, что код написан внутри блока #Если Клиент. Для решения задачи в управляемом приложении необходимо либо пересмотреть директивы компиляции, либо (что архитектурно правильнее) вынести логику формирования печатной формы в модуль менеджера, разделяя подготовку данных на сервере и визуализацию на клиенте.