К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как обратиться к процедуре другого документа в 1С

Как вызвать процедуру или функцию другого документа в 1С: через модуль менеджера, общий модуль и объект документа. Примеры кода, ошибки и ограничения.

Задача обратиться к процедуре другого документа возникает у разработчиков 1С постоянно: нужно переиспользовать готовый алгоритм расчёта, проверки или заполнения, уже написанный в модуле одного документа, из кода другого объекта. Главное, что нужно понять сразу: напрямую вызвать процедуру, объявленную в модуле объекта или модуле формы другого документа, «извне» нельзя — эти модули существуют только в контексте конкретного объекта или формы.

Правильное решение зависит от того, где именно объявлена нужная процедура и откуда вы хотите её вызвать. В типовой практике есть три рабочих пути: вынести логику в модуль менеджера документа, перенести её в общий модуль или получить объект документа по ссылке и вызвать его экспортный метод. Каждый вариант имеет свои условия применения и ограничения.

Ниже разобраны все способы с примерами кода, указаны типичные ошибки (вроде попытки вызвать процедуру формы с сервера или обратиться к несуществующему контексту) и критерии выбора подходящего варианта.

Почему нельзя просто вызвать процедуру из модуля другого документа

В 1С каждый модуль имеет свою область видимости. Модуль объекта документа компилируется и исполняется только тогда, когда создан экземпляр объекта — например, при открытии документа, его записи или программном создании через СоздатьДокумент(). Пока объекта нет в памяти, его процедур «не существует» для остального кода конфигурации.

Модуль формы ещё более изолирован: он живёт только внутри конкретной открытой формы и привязан к её контексту. Обратиться к процедуре формы другого документа извне технически невозможно, даже если она объявлена с ключевым словом Экспорт. Форму можно открыть программно и передать ей параметры, но вызывать её методы напрямую — нет.

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

Способ 1: вызов через модуль менеджера документа

Если процедура не использует реквизиты конкретного объекта (не обращается к ЭтотОбъект, табличным частям, движениям), её правильное место — модуль менеджера документа. Откройте в конфигураторе нужный документ, перейдите на вкладку «Прочее» → «Модули» → «Модуль менеджера» и разместите там процедуру или функцию с ключевым словом Экспорт.

// Модуль менеджера документа "РеализацияТоваровУслуг"

Функция РассчитатьСуммуСНДС(Сумма, СтавкаНДС) Экспорт

Возврат Сумма + Сумма * СтавкаНДС / 100;

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

Теперь из любого другого документа, обработки или отчёта эту функцию можно вызвать так:

// Модуль объекта другого документа

ИтоговаяСумма = Документы.РеализацияТоваровУслуг.РассчитатьСуммуСНДС(СуммаДокумента, 20);

Обратите внимание: обращение идёт через менеджер Документы.ИмяДокумента, а не через ссылку или объект. Это серверный вызов — он работает в серверном контексте и в фоновых заданиях. Из клиентского кода тонкого клиента вызвать модуль менеджера напрямую нельзя, потребуется серверная процедура-обёртка.

Способ 2: перенос логики в общий модуль

Если процедура по смыслу нужна нескольким документам (а не является спецификой одного), правильнее вынести её в общий модуль. Это стандартный подход в типовых конфигурациях: общая бизнес-логика живёт в общих модулях, а документы лишь вызывают её, передавая свои данные параметрами.

Создайте общий модуль (например, РаботаСДокументами), установите флажки «Сервер» и, при необходимости, «Вызов сервера» — если к модулю нужно обращаться с клиента. Процедуры, доступные извне, объявляйте с Экспорт:

// Общий модуль РаботаСДокументами

Процедура ЗаполнитьДанныеКонтрагента(ДокументОбъект, Контрагент) Экспорт

// логика заполнения реквизитов объекта

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

Вызов из любого документа становится тривиальным: РаботаСДокументами.ЗаполнитьДанныеКонтрагента(ЭтотОбъект, Контрагент);. Такой код легче тестировать, он не дублируется между документами и не нарушает границы модулей.

Куда поместить процедуру

Модуль менеджера документа

Когда логика относится только к этому виду документов и не требует экземпляра объекта: расчёты, запросы к данным, подбор значений.

Общий модуль

Когда процедура нужна нескольким видам документов или другим объектам. Требует передачи данных параметрами.

Модуль объекта (Экспорт)

Когда процедура работает с реквизитами и табличными частями конкретного документа. Вызов только после получения объекта.

Способ 3: вызов экспортного метода через объект документа

Когда процедура обращается к данным конкретного документа — его реквизитам, табличным частям, движениям — она должна остаться в модуле объекта. Чтобы вызвать её извне, сначала получите объект по ссылке, а затем обратитесь к методу, объявленному с Экспорт:

// В модуле объекта документа "ЗаказПокупателя"

Процедура ПересчитатьИтоги() Экспорт

СуммаДокумента = Товары.Итог("Сумма");

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

// Вызов из другого документа или обработки

ДокОбъект = СсылкаНаЗаказ.ПолучитьОбъект();

ДокОбъект.ПересчитатьИтоги();

ДокОбъект.Записать();

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

Как выбрать правильный способ: маршрут решения

Выбор зависит от двух вопросов: нужна ли процедуре конкретная «начинка» объекта и где она будет вызываться. Ответы на них однозначно указывают на подходящий вариант.

Маршрут решения

Как выбрать действие

Процедура не обращается к реквизитам и табличным частям объекта и нужна только этому виду документовПеренесите её в модуль менеджера и вызывайте через Документы.ИмяДокумента.ИмяПроцедуры()
Процедура нужна нескольким документам или объектамСоздайте общий модуль с флагом Сервер (и Вызов сервера при необходимости) и передавайте данные параметрами
Процедура работает с данными конкретного документаОставьте её в модуле объекта с Экспорт, получите объект через Ссылка.ПолучитьОбъект() и вызовите метод
Вызов идёт из клиентской процедуры формыДобавьте серверную процедуру-обёртку с директивой &НаСервере и вызывайте логику из неё
Нужен результат работы формы другого документаОткройте форму через ОткрытьФорму() с параметрами и обработайте результат через оповещение, а не прямым вызовом

Отдельно стоит сказать о формах. Если вам нужно не «вызвать процедуру формы», а получить от пользователя данные через форму другого документа, используйте ОткрытьФорму() с параметрами и обработку оповещения о закрытии — это единственный корректный механизм взаимодействия с чужой формой.

Проверка результата и типичные ошибки

После внедрения вызова проверьте три вещи: компилируется ли модуль без ошибок, выполняется ли вызов в нужном контексте (сервер/клиент) и возвращает ли процедура ожидаемый результат. Быстрее всего это сделать через отладку с точкой останова на строке вызова.

Контрольные точки

Как проверить результат

Доступность метода
Норма

Вызов Документы.Имя.Метод() компилируется, метод объявлен с Экспорт

Тревожный признак

Ошибка «Процедура или функция с указанным именем не определена»

Контекст выполнения
Норма

Серверный метод вызывается из серверного кода или через обёртку &НаСервере

Тревожный признак

Ошибка вида «вызов сервера запрещён» или недоступность модуля на клиенте

Сохранение данных
Норма

После ДокОбъект.Метод() вызван Записать(), изменения видны в базе

Тревожный признак

Метод отработал, но данные документа не изменились — объект не записан

Блокировки
Норма

ПолучитьОбъект() выполняется без ошибок при параллельной работе

Тревожный признак

Ошибка «Конфликт блокировок при выполнении транзакции»

Типичные ошибки
01
Попытка вызвать процедуру модуля объекта без получения объекта — код не компилируется, метод недоступен через менеджер
02
Вызов серверного метода напрямую из клиентской процедуры формы — ошибка контекста; нужна серверная обёртка
03
Забыто ключевое слово Экспорт — метод не виден извне модуля
04
Вызов ПолучитьОбъект() без последующего Записать() — изменения теряются молча
05
Перенос всей логики в модуль формы — её невозможно переиспользовать, код приходится дублировать

Частая ситуация у начинающих разработчиков: процедура написана в модуле формы документа, потому что «там было удобно отладить», а потом её пытаются вызвать из другого места. Правило простое — в модуле формы должна оставаться только логика интерфейса, вся прикладная логика уходит в модуль объекта, менеджера или общий модуль.

Итог

Что важно запомнить

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

Частые вопросы

Можно ли вызвать процедуру из модуля формы другого документа?

Нет, модуль формы доступен только внутри самой формы. Если нужна интерактивность — откройте форму через ОткрытьФорму() с параметрами и обработайте результат через оповещение. Если нужна логика — перенесите её в модуль объекта, менеджера или общий модуль.

Почему возникает ошибка «Процедура или функция не определена»?

Чаще всего метод объявлен без ключевого слова Экспорт, либо вы обращаетесь к модулю объекта через менеджер (Документы.Имя.Метод()), хотя метод находится в модуле объекта и требует ПолучитьОбъект(). Проверьте, в каком именно модуле объявлена процедура.

Как вызвать серверную процедуру из клиентского кода формы?

Напрямую — никак. Создайте в модуле формы процедуру с директивой &НаСервере, внутри неё вызовите нужный метод модуля менеджера или общего модуля, а из клиентской процедуры вызывайте эту обёртку.

Что лучше: модуль менеджера или общий модуль?

Если логика относится к одному виду документов — модуль менеджера, это сохраняет связь кода с объектом. Если процедура нужна разным объектам конфигурации — общий модуль, иначе получите дублирование или неестественные зависимости между документами.

Нужно ли записывать документ после вызова его экспортного метода?

Да, если метод изменял данные объекта. ПолучитьОбъект() создаёт копию в памяти; без Записать() все изменения пропадут при уничтожении переменной. Записывайте с обработкой возможных ошибок блокировки.

Можно ли обратиться к процедуре документа из фонового задания?

Да, фоновое задание выполняется на сервере, поэтому в нём доступны и модуль менеджера, и общие серверные модули, и ПолучитьОбъект(). Ограничение одно: из фонового задания нельзя работать с формами и клиентским контекстом.