Как вызвать процедуру или функцию управляемой формы без её открытия

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Программисты 1С часто сталкиваются с ситуацией, когда необходимо выполнить логику, заложенную внутри модуля формы документа или справочника, но при этом саму форму открывать пользователю не требуется. Это может быть полезно для массовой обработки данных, когда нужно имитировать интерактивное изменение реквизитов (например, пересчет цен, налогов или заполнение связанных полей при изменении вида операции). Для имитации таких действий без написания программного кода используется платформа One RPA для автоматизации действий пользователя.

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

Анализ проблемы: почему метод объекта не обнаружен?

Рассмотрим классический пример кода, который успешно работал в старых версиях платформы (до версии 8.3.13 включительно):


ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Ключ", СсылкаНаДокумент);
ФормаОбъекта = ПолучитьФорму("Документ.РасходныйКассовыйОрдер.ФормаОбъекта", ПараметрыФормы);

// Попытка вызвать серверную процедуру модуля формы
ФормаОбъекта.ВидОперацииПриИзмененииСервер(); 
ФормаОбъекта.Записать();

Проанализируем ситуацию: начиная с версии платформы 8.3.14, компания «1С» внесла изменения в механизмы работы управляемых форм. Возможность вызова неэкспортных процедур и функций формы извне была официально признана ошибкой реализации и устранена. Теперь, если метод не помечен ключевым словом Экспорт, платформа выдает исключение "Метод объекта не обнаружен". Для автоматического поиска подобных ошибок в коде можно использовать инструмент для анализа конфигураций и проверки вызова процедур.

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

Способ 1. Использование ключевого слова Экспорт

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

Выясним, как это выглядит в коде модуля формы:


&НаСервере
Процедура ВидОперацииПриИзмененииСервер() Экспорт
    // Логика пересчета данных объекта при изменении вида операции
    // ...
КонецПроцедуры

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

Способ 2. Использование расширений для доступа к неэкспортным методам

Если конфигурация находится на поддержке и вы не хотите менять свойства процедур в основной базе, можно применить «хитрый» прием с использованием расширений. Рассмотрим этот алгоритм подробнее:

  1. Добавляем нужную форму в расширение.
  2. В модуле формы расширения создаем процедуру-обертку с аннотацией &НаКлиенте или &НаСервере (в зависимости от типа вызываемого метода) и помечаем её как Экспорт.
  3. Внутри этой обертки вызываем оригинальный метод.

Разберем пример реализации в расширении:


&НаСервере
Процедура Расш1_ВыполнитьПересчетЭкспорт() Экспорт
    // Вызываем оригинальную неэкспортную процедуру основной конфигурации
    ВидОперацииПриИзмененииСервер();
КонецПроцедуры

Теперь во внешнем коде (например, в обработке) мы сможем вызвать нашу обертку:


Форма = ПолучитьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", Параметры);
Форма.Расш1_ВыполнитьПересчетЭкспорт();

Важное примечание: иногда платформа блокирует прямой вызов процедур расширения, если они перекрывают основные методы. В таком случае может потребоваться использование аннотации &Вместо, но для простых задач проброса Экспорт обычно достаточно.

Способ 3. Рефакторинг и вынос логики (Лучшая практика)

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

Рассмотрим правильный архитектурный подход:

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


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

Нюансы работы с ПолучитьФорму() без открытия

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

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

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

Рекомендации по выбору решения

Подведем итог и выберем стратегию действий:

  1. Если конфигурация ваша (самописная) — всегда делайте нужные методы экспортными или выносите их в модули объектов. При разработке точечной миграции между такими базами удобно использовать обработку для переноса данных между похожими конфигурациями 1С с настройкой произвольных полей поиска.
  2. Если конфигурация типовая и задача разовая — используйте расширение с экспортной процедурой-оберткой; для комплексных переходов предусмотрен раздел с решениями Переносы данных 1С, тариф PRO.
  3. Если вы планируете тиражируемое решение — лучше потратить время на изучение кода формы и найти процедуры в общих модулях, которые выполняют ту же работу, чтобы вызывать их напрямую.

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

← На главную