Как программно вызвать процедуру формы элемента в обычных формах 1С?

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

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

Почему не стоит вызывать процедуру формы напрямую?

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

  1. Ошибка параметров: Процедура-обработчик НаименованиеПриИзменении(Элемент) ожидает в качестве параметра объект элемента формы (например, ПолеВвода). При программном вызове передать корректный элемент формы затруднительно, а передача Неопределено вызовет критическую ошибку при попытке обращения к свойствам элемента.
  2. Проблемы с сервером и фоновыми заданиями: Обычные формы и интерфейсные объекты не существуют на сервере, в регламентных и фоновых заданиях. Попытка получить форму в серверном контексте завершится ошибкой.
  3. Падение производительности и утечка памяти: Вызов ПолучитьФорму() внутри цикла по множеству элементов создает в памяти полноценный объект интерфейса для каждой записи. Это приводит к колоссальному перерасходу ОЗУ и катастрофическому замедлению работы.
  4. Данные не сохраняются в базу: Код формы оперирует элементами управления (ЭлементыФормы), а не реквизитами информационной базы. Даже если процедура формы выполнится, данные не записаны в базу данных без явного вызова Записать().

Архитектурное решение: Разделение интерфейса и бизнес-логики

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

Вариант 1. Экспортная процедура в модуле объекта

Разберем по шагам перенос алгоритма в модуль объекта справочника:

  1. В модуле объекта создаем экспортную процедуру, которая выполняет заполнение реквизитов ЭтотОбъект:

Процедура ЗаполнитьПоНаименованию() Экспорт
    // Алгоритм заполнения реквизитов на основе Наименования
    Если Найти(Наименование, "Товар") > 0 Тогда
        ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Товар;
    КонецЕсли;
КонецПроцедуры
  1. В модуле формы элемента вызываем эту процедуру из интерактивного обработчика:

Процедура НаименованиеПриИзменении(Элемент)
    ЭтотОбъект.ЗаполнитьПоНаименованию();
КонецПроцедуры
  1. Для массовой программной обработки элементов создаем обработку или вызов из нужного контекста:

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    Объект = Выборка.Ссылка.ПолучитьОбъект();
    Объект.ЗаполнитьПоНаименованию();
    Объект.Записать();
КонецЦикла;

Вариант 2. Использование обработчика события «ПередЗаписью»

Если данные должны пересчитываться автоматически при любом изменении наименования, логику можно вынести в обработчик события ПередЗаписью модуля объекта.

Проанализируем пример реализации:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПро проведения)
    // Пропускаем выполнение при загрузке данных
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Проверяем, изменилось ли наименование
    Если ЭтоНовый() ИЛИ Наименование <> Ссылка.Наименование Тогда
        // Выполняем заполнение реквизитов
        ЗаполнитьПоНаименованию();
    КонецЕсли;
КонецПроцедуры

При таком подходе достаточно в программной обработке просто прочитать объект и вызвать Объект.Записать(). Алгоритм сработает автоматически как при изменении из формы, так и при программной записи.

Рекомендации по оптимизации массовой перезаписи

При обработке большого количества записей соблюдайте следующие правила:

← На главную