Как передать значения из формы в модуль объекта 1С?

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

В практике разработки на платформе 1С:Предприятие 8 мы часто сталкиваемся с необходимостью передать определенные данные или флаги управления из формы документа (или справочника) непосредственно в модуль этого объекта при записи. Начинающие разработчики часто совершают ошибку, пытаясь обратиться к элементам формы напрямую из модуля объекта, что приводит к ошибкам вида "Переменная не определена" или "Поле объекта не обнаружено".

Разберем детально, почему возникает эта проблема, проанализируем архитектуру взаимодействия клиент-сервер в управляемых формах и рассмотрим правильные методы решения задачи с использованием коллекции ДополнительныеСвойства.

Почему модуль объекта не видит реквизиты формы?

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

  1. Контекст Формы: Здесь живут реквизиты формы, элементы управления (кнопки, поля ввода) и код модуля формы. Форма служит для визуализации данных и взаимодействия с пользователем.
  2. Контекст Объекта: Это "чистые" данные базы данных (справочника, документа). Модуль объекта выполняется на сервере и ничего не знает о том, открыта ли какая-то форма у пользователя или объект записывается программно фоновым заданием.

Когда мы пытаемся написать в модуле объекта код вроде Значение = ЭтаФорма.Элементы.МойЧекебокс.Значение, система закономерно выдает ошибку. Объект существует сам по себе, форма — сама по себе. Связь между ними осуществляется только в момент чтения данных (при открытии формы) и в момент записи (когда форма передает данные объекту).

Использование коллекции ДополнительныеСвойства

Самым надежным, "каноничным" и рекомендуемым фирмой 1С способом передачи не сохраняемых в БД данных из формы в объект является использование свойства ДополнительныеСвойства.

Рассмотрим, что это такое. Любой прикладной объект (СправочникОбъект, ДокументОбъект и т.д.) имеет системное свойство ДополнительныеСвойства. Это коллекция типа Структура, которая существует только в памяти пока живет объект. Она не сохраняется в базу данных, но доступна в подписках на события и в модуле объекта до момента завершения транзакции записи.

Посмотрим на алгоритм действий, который нам необходимо реализовать:

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

Реализация в модуле формы

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

Напишем код, который добавляет наш параметр в объект:


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    
    // Предположим, у нас на форме есть реквизит "НужноПровестиДопОбработку" (Тип Булево)
    // Мы хотим передать его значение в модуль объекта
    
    ТекущийОбъект.ДополнительныеСвойства.Вставить("ВыполнитьСпецОбработку", НужноПровестиДопОбработку);
    
    // Можно передавать не только примитивные типы, но и структуры, таблицы значений и т.д.
    СтруктураПараметров = Новый Структура;
    СтруктураПараметров.Вставить("АвторИзменений", Пользователи.ТекущийПользователь());
    
    ТекущийОбъект.ДополнительныеСвойства.Вставить("СлужебныеПараметры", СтруктураПараметров);
    
КонецПроцедуры

Давайте проанализируем, что мы сделали. Мы обратились к ТекущийОбъект — это изменяемая версия объекта, которая сейчас будет записана. Метод Вставить добавляет в структуру пару "Ключ - Значение". Ключ "ВыполнитьСпецОбработку" — это просто строковый идентификатор, который мы придумали сами.

Реализация в модуле объекта

Теперь перейдем в модуль объекта. Здесь нам нужно "поймать" переданное значение. Обычно это делается в процедуре ПередЗаписью или ОбработкаПроведения.

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


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

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

Преимущества подхода

Давайте выделим основные плюсы использования ДополнительныеСвойства:

Альтернативный вариант: Использование Экспортных переменных (Не рекомендуется)

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

В модуле объекта:


Перем МойФлаг Экспорт;

Процедура ПередЗаписью(Отказ)
    Если МойФлаг = Истина Тогда
        // Действия
    КонецЕсли;
КонецПроцедуры

В модуле формы:


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    ТекущийОбъект.МойФлаг = Истина;
КонецПроцедуры

Проанализируем минусы этого подхода. Во-первых, вы засоряете глобальное пространство имен объекта. Во-вторых, экспортные переменные могут вести себя непредсказуемо при компиляции модуля на клиенте и сервере. И в-третьих, механизм ДополнительныеСвойства является стандартом разработки 1С, и другим программистам будет проще поддерживать ваш код, если вы будете следовать стандартам.

Особенности при работе с расширениями

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

Заключение

Мы подробно разобрали проблему передачи данных из контекста формы в контекст объекта. Главное правило, которое нужно запомнить: модуль объекта должен быть самодостаточным и не зависеть от интерфейса. Используйте коллекцию ДополнительныеСвойства как безопасный буфер для передачи команд и параметров. Это сделает ваш код надежным, понятным и устойчивым к ошибкам времени выполнения.

← На главную