Разработка и Конфигурация · 10 мин
Как из формы обратиться к модулю объекта в 1С
Как из формы 1С вызвать процедуру модуля объекта: экспортные методы, ДанныеФормыВЗначение, ПолучитьОбъект, отличия управляемой и обычной формы, типичные ошибки.
Задача вызвать из формы код, написанный в модуле объекта, возникает у каждого разработчика 1С: например, нужно из формы документа запустить проверку заполнения, реализованную в объекте, или получить рассчитанное значение, которое хранится в реквизитах объекта, а не в данных формы. Главная сложность в том, что форма и модуль объекта живут в разных контекстах: форма работает с реквизитом Объект типа «ДанныеФормыСтруктура», а модуль объекта исполняется только в контексте прикладного объекта (ДокументОбъект, СправочникОбъект и т. д.).
Прямого синтаксиса вида Объект.МояПроцедура() в управляемой форме нет — попытка такого вызова завершится ошибкой «Процедура или функция с указанным именем не определена». Чтобы обратиться к модулю объекта, нужно сначала получить сам прикладной объект из данных формы, и сделать это можно несколькими способами в зависимости от типа формы (управляемая или обычная) и места исполнения кода (клиент или сервер).
Ниже разобраны рабочие приёмы для управляемых и обычных форм, ограничения клиент-серверного взаимодействия, типичные ошибки и способы проверить, что вызов действительно отработал.
Что нужно сделать в модуле объекта перед вызовом
Обратиться из формы можно только к экспортным процедурам и функциям модуля объекта. Если процедура объявлена без ключевого слова Экспорт, она считается приватной и доступна только внутри самого модуля объекта.
Откройте модуль объекта (в конфигураторе: объект метаданных → контекстное меню → «Открыть модуль объекта») и объявите нужный метод с экспортом:
Процедура ПересчитатьИтоги() Экспорт
ИтогСуммы = 0;
Для Каждого СтрокаТовара Из Товары Цикл
ИтогСуммы = ИтогСуммы + СтрокаТовара.Сумма;
КонецЦикла;
КонецПроцедуры
Обратите внимание: внутри модуля объекта вы работаете с реквизитами объекта напрямую по имени (Товары, Номер, Контрагент), без префиксов. Это удобно, но именно поэтому платформа требует сначала материализовать объект — без контекста объекта такой код выполнить невозможно.
Вызов модуля объекта из управляемой формы
В управляемой форме основной реквизит Объект — это не прикладной объект, а структура данных формы. Чтобы получить настоящий объект и вызвать его экспортный метод, используют метод РеквизитФормыВЗначение(). Он доступен только на сервере, поэтому обработчик вызова должен быть серверным.
Базовый сценарий: вызов с сервера
Типовая конструкция выглядит так:
&НаКлиенте
Процедура Пересчитать(Команда)
ПересчитатьНаСервере();
КонецПроцедуры
&НаСервере
Процедура ПересчитатьНаСервере()
ДокументОбъект = РеквизитФормыВЗначение("Объект");
ДокументОбъект.ПересчитатьИтоги();
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедуры
Здесь три обязательных шага: получить объект из данных формы, вызвать его экспортный метод, вернуть изменённые данные обратно в форму через ЗначениеВРеквизитФормы(). Если третий шаг пропустить, изменения, сделанные в модуле объекта, не отобразятся на форме — типичный источник вопросов «почему процедура отработала, а на форме ничего не изменилось».
Нужно ли сохранять объект
Метод РеквизитФормыВЗначение() создаёт объект в памяти, но не записывает его в базу. Если экспортная процедура модуля объекта только вычисляет значения — записывать объект не нужно. Запись (ДокументОбъект.Записать()) требуется, только если результат должен сохраниться в информационной базе немедленно. Лишняя запись из формы опасна: она может вызвать повторное срабатывание обработчиков записи и проведения.
Вызов модуля объекта из обычной формы
В обычных формах (обычное приложение) всё проще: реквизит формы с типом «ДокументОбъект» или «СправочникОбъект» — это уже сам прикладной объект. Обращение к его экспортным методам выполняется напрямую, без преобразований:
Процедура КнопкаПересчитатьНажатие(Кнопка)
ДокументОбъект.ПересчитатьИтоги();
КонецПроцедуры
Имя реквизита формы зависит от того, как назван основной реквизит в свойствах формы — чаще всего это ДокументОбъект, СправочникОбъект или просто Объект. Точное имя смотрите в палитре реквизитов формы в конфигураторе.
Поскольку обычная форма исполняется в толстом клиенте, объект модифицируется «на месте», и изменения видны в форме сразу — отдельный обратный перенос данных не нужен.
Альтернативы: когда лучше обойтись без модуля объекта
Не всегда вызов модуля объекта — оптимальное решение. В зависимости от задачи есть другие варианты, которые могут быть проще и безопаснее.
| Подход | Когда подходит | Ограничение |
|---|---|---|
| РеквизитФормыВЗначение + экспортный метод объекта | Логика привязана к данным объекта и нужна вне формы | Только на сервере, требуется обратный перенос данных |
| Общий модуль (серверный) | Логика используется разными объектами и формами | Нет прямого доступа к реквизитам объекта по имени |
| Модуль менеджера объекта | Операции над объектом без его открытия (печать, заполнение) | Нет контекста конкретного экземпляра объекта |
| Код непосредственно в модуле формы | Логика нужна только в этой форме | Не переиспользуется, дублирование при копировании форм |
Если процедура не обращается к реквизитам конкретного объекта, а работает с переданными параметрами, разумнее вынести её в общий серверный модуль — такой вызов проще, не требует материализации объекта и легче тестируется.
Сравнение вариантов
Подходит, когда логика неразрывно связана с данными объекта. Ограничение: только сервер, нужен возврат данных в форму.
Подходит для логики, общей для нескольких объектов. Ограничение: реквизиты объекта придётся передавать параметром или получать запросом.
Подходит для операций уровня вида объекта: печать, создание, подбор. Ограничение: нет доступа к данным конкретного экземпляра без ссылки.
Порядок действий и проверка результата
Соберём всё в единую последовательность для управляемой формы документа:
- 1Откройте модуль объекта и объявите нужную процедуру или функцию с ключевым словом Экспорт
- 2В модуле формы создайте клиентский обработчик команды или события
- 3Из клиентского обработчика вызовите серверную процедуру формы
- 4В серверной процедуре получите объект: РеквизитФормыВЗначение("Объект")
- 5Вызовите экспортный метод объекта и верните данные через ЗначениеВРеквизитФормы
- 6Проверьте в пользовательском режиме, что данные на форме обновились
Проверить результат можно двумя способами. Первый — визуальный: после нажатия кнопки на форме должны измениться те реквизиты, которые рассчитывает процедура модуля объекта. Второй — через отладчик: поставьте точку останова внутри экспортной процедуры модуля объекта и убедитесь, что выполнение туда попадает, а переменные содержат ожидаемые значения.
Как проверить результат
Отладчик останавливается внутри экспортной процедуры
Точка останова не срабатывает — метод не экспортный или вызов идёт мимо
Реквизиты формы обновились значениями из объекта
Объект изменился, но форма не обновилась — пропущен ЗначениеВРеквизитФормы
Ошибок нет
«Метод объекта не обнаружен» — нет Экспорт или опечатка в имени
Типичные ошибки и ограничения
Первая и самая частая ошибка — попытка вызвать метод объекта на клиенте в управляемой форме. РеквизитФормыВЗначение() недоступен в клиентском контексте, поэтому весь код получения объекта должен быть обёрнут в серверную процедуру формы.
Вторая ошибка — забытый обратный перенос данных. Объект, полученный из формы, — это копия; изменения в нём не отражаются на форме автоматически. Третья ошибка — обращение к модулю объекта у нового, ещё не записанного объекта с логикой, которая опирается на существование ссылки в базе: ссылка у нового объекта есть, но данных в базе по ней нет, и запросы внутри процедуры могут вернуть пустой результат.
FAQ
Можно ли вызвать модуль объекта напрямую с клиента в управляемой форме?
Нет. Получение прикладного объекта из данных формы (РеквизитФормыВЗначение) доступно только на сервере. На клиенте можно лишь вызвать серверную процедуру формы, которая выполнит всю работу и вернёт результат.
Почему возникает ошибка «Метод объекта не обнаружен»?
Чаще всего процедура в модуле объекта объявлена без ключевого слова Экспорт, либо в имени метода опечатка. Реже причина в том, что вызов идёт у переменной не того типа — например, у структуры данных формы вместо прикладного объекта.
Чем РеквизитФормыВЗначение отличается от ДанныеФормыВЗначение?
РеквизитФормыВЗначение — метод формы, преобразующий основной реквизит формы в прикладной объект. ДанныеФормыВЗначение — глобальный метод, принимающий любой элемент данных формы и тип целевого объекта. Для основного реквизита Object удобнее первый вариант.
Нужно ли записывать объект после вызова его процедуры?
Нет, если процедура только вычисляет или заполняет реквизиты. Достаточно вернуть данные в форму через ЗначениеВРеквизитФормы — запись произойдёт штатно, когда пользователь нажмёт «Записать» или «Провести».
Как вызвать модуль объекта у нового, не записанного документа?
Так же, через РеквизитФормыВЗначение. У нового объекта уже есть ссылка, но в базе данных его нет — учтите это, если процедура модуля объекта выполняет запросы к собственным данным или движениям.
Когда логику лучше разместить в общем модуле, а не в модуле объекта?
Когда одна и та же обработка нужна нескольким видам объектов или вызывается из разных мест без привязки к конкретному экземпляру. Общий серверный модуль не требует материализации объекта и упрощает повторное использование кода.
Что важно запомнить
Из управляемой формы к модулю объекта обращаются только через сервер: РеквизитФормыВЗначение → вызов экспортного метода → ЗначениеВРеквизитФормы. В обычной форме объект доступен напрямую. Ключевые условия успеха — слово Экспорт у процедуры и возврат изменённых данных в форму.