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

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

Как из формы обратиться к модулю объекта в 1С

Как из формы 1С вызвать процедуру модуля объекта: экспортные методы, ДанныеФормыВЗначение, ПолучитьОбъект, отличия управляемой и обычной формы, типичные ошибки.

Задача вызвать из формы код, написанный в модуле объекта, возникает у каждого разработчика 1С: например, нужно из формы документа запустить проверку заполнения, реализованную в объекте, или получить рассчитанное значение, которое хранится в реквизитах объекта, а не в данных формы. Главная сложность в том, что форма и модуль объекта живут в разных контекстах: форма работает с реквизитом Объект типа «ДанныеФормыСтруктура», а модуль объекта исполняется только в контексте прикладного объекта (ДокументОбъект, СправочникОбъект и т. д.).

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

Ниже разобраны рабочие приёмы для управляемых и обычных форм, ограничения клиент-серверного взаимодействия, типичные ошибки и способы проверить, что вызов действительно отработал.

Что нужно сделать в модуле объекта перед вызовом

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

Откройте модуль объекта (в конфигураторе: объект метаданных → контекстное меню → «Открыть модуль объекта») и объявите нужный метод с экспортом:

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

ИтогСуммы = 0;

Для Каждого СтрокаТовара Из Товары Цикл

ИтогСуммы = ИтогСуммы + СтрокаТовара.Сумма;

КонецЦикла;

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

Обратите внимание: внутри модуля объекта вы работаете с реквизитами объекта напрямую по имени (Товары, Номер, Контрагент), без префиксов. Это удобно, но именно поэтому платформа требует сначала материализовать объект — без контекста объекта такой код выполнить невозможно.

Вызов модуля объекта из управляемой формы

В управляемой форме основной реквизит Объект — это не прикладной объект, а структура данных формы. Чтобы получить настоящий объект и вызвать его экспортный метод, используют метод РеквизитФормыВЗначение(). Он доступен только на сервере, поэтому обработчик вызова должен быть серверным.

Базовый сценарий: вызов с сервера

Типовая конструкция выглядит так:

&НаКлиенте

Процедура Пересчитать(Команда)

ПересчитатьНаСервере();

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

&НаСервере

Процедура ПересчитатьНаСервере()

ДокументОбъект = РеквизитФормыВЗначение("Объект");

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

ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");

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

Здесь три обязательных шага: получить объект из данных формы, вызвать его экспортный метод, вернуть изменённые данные обратно в форму через ЗначениеВРеквизитФормы(). Если третий шаг пропустить, изменения, сделанные в модуле объекта, не отобразятся на форме — типичный источник вопросов «почему процедура отработала, а на форме ничего не изменилось».

Нужно ли сохранять объект

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

Вызов модуля объекта из обычной формы

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

Процедура КнопкаПересчитатьНажатие(Кнопка)

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

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

Имя реквизита формы зависит от того, как назван основной реквизит в свойствах формы — чаще всего это ДокументОбъект, СправочникОбъект или просто Объект. Точное имя смотрите в палитре реквизитов формы в конфигураторе.

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

Альтернативы: когда лучше обойтись без модуля объекта

Не всегда вызов модуля объекта — оптимальное решение. В зависимости от задачи есть другие варианты, которые могут быть проще и безопаснее.

ПодходКогда подходитОграничение
РеквизитФормыВЗначение + экспортный метод объектаЛогика привязана к данным объекта и нужна вне формыТолько на сервере, требуется обратный перенос данных
Общий модуль (серверный)Логика используется разными объектами и формамиНет прямого доступа к реквизитам объекта по имени
Модуль менеджера объектаОперации над объектом без его открытия (печать, заполнение)Нет контекста конкретного экземпляра объекта
Код непосредственно в модуле формыЛогика нужна только в этой формеНе переиспользуется, дублирование при копировании форм

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

Сравнение вариантов

Модуль объекта через РеквизитФормыВЗначение

Подходит, когда логика неразрывно связана с данными объекта. Ограничение: только сервер, нужен возврат данных в форму.

Общий серверный модуль

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

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

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

Порядок действий и проверка результата

Соберём всё в единую последовательность для управляемой формы документа:

Порядок действий
  1. 1
    Откройте модуль объекта и объявите нужную процедуру или функцию с ключевым словом Экспорт
  2. 2
    В модуле формы создайте клиентский обработчик команды или события
  3. 3
    Из клиентского обработчика вызовите серверную процедуру формы
  4. 4
    В серверной процедуре получите объект: РеквизитФормыВЗначение("Объект")
  5. 5
    Вызовите экспортный метод объекта и верните данные через ЗначениеВРеквизитФормы
  6. 6
    Проверьте в пользовательском режиме, что данные на форме обновились

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

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

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

Попадание в точку останова в модуле объекта
Норма

Отладчик останавливается внутри экспортной процедуры

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

Точка останова не срабатывает — метод не экспортный или вызов идёт мимо

Данные на форме после вызова
Норма

Реквизиты формы обновились значениями из объекта

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

Объект изменился, но форма не обновилась — пропущен ЗначениеВРеквизитФормы

Текст ошибки при вызове
Норма

Ошибок нет

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

«Метод объекта не обнаружен» — нет Экспорт или опечатка в имени

Типичные ошибки и ограничения

Первая и самая частая ошибка — попытка вызвать метод объекта на клиенте в управляемой форме. РеквизитФормыВЗначение() недоступен в клиентском контексте, поэтому весь код получения объекта должен быть обёрнут в серверную процедуру формы.

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

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

FAQ

Можно ли вызвать модуль объекта напрямую с клиента в управляемой форме?

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

Почему возникает ошибка «Метод объекта не обнаружен»?

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

Чем РеквизитФормыВЗначение отличается от ДанныеФормыВЗначение?

РеквизитФормыВЗначение — метод формы, преобразующий основной реквизит формы в прикладной объект. ДанныеФормыВЗначение — глобальный метод, принимающий любой элемент данных формы и тип целевого объекта. Для основного реквизита Object удобнее первый вариант.

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

Нет, если процедура только вычисляет или заполняет реквизиты. Достаточно вернуть данные в форму через ЗначениеВРеквизитФормы — запись произойдёт штатно, когда пользователь нажмёт «Записать» или «Провести».

Как вызвать модуль объекта у нового, не записанного документа?

Так же, через РеквизитФормыВЗначение. У нового объекта уже есть ссылка, но в базе данных его нет — учтите это, если процедура модуля объекта выполняет запросы к собственным данным или движениям.

Когда логику лучше разместить в общем модуле, а не в модуле объекта?

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

Итог

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

Из управляемой формы к модулю объекта обращаются только через сервер: РеквизитФормыВЗначение → вызов экспортного метода → ЗначениеВРеквизитФормы. В обычной форме объект доступен напрямую. Ключевые условия успеха — слово Экспорт у процедуры и возврат изменённых данных в форму.