Top.Mail.Ru

Как при записи передать параметр из формы в модуль объекта 1С и обратно: "ПараметрыЗаписи" и "ДополнительныеСвойства"

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

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

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

Что такое "ПараметрыЗаписи"?

ПараметрыЗаписи — это структура, которая существует только в контексте формы. Она предназначена для хранения параметров, управляющих процессом записи на стороне интерфейса.

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

  1. ПередЗаписью (на клиенте);
  2. ПередЗаписьюНаСервере (на сервере);
  3. ПриЗаписиНаСервере (на сервере);
  4. ПослеЗаписиНаСервере (на сервере);
  5. ПослеЗаписи (на клиенте).

Поскольку ПараметрыЗаписи живут только в форме, модуль объекта напрямую не имеет к ним доступа. Чтобы передать эти данные в транзакцию записи, их переносят в сам объект.


Что такое "ДополнительныеСвойства"?

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

Эта коллекция доступна везде, где доступен сам прикладной объект:

  • В событиях модуля объекта (ПередЗаписьюПриЗаписиПриКопировании и др.);
  • В процедурах-обработчиках подписок на события.

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

Учебный пример: расчет бонусов при покупке (двусторонний цикл)

Бизнес-задача: Кассир пробивает документ «Реализация товаров».

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

  2. Обратный поток: Расчет бонусных баллов происходит строго на сервере внутри транзакции проведения (чтобы избежать мошенничества и коллизий). Нам нужно вернуть количество реально начисленных бонусов на клиент и показать кассиру красивое всплывающее окно «Начислено 150 бонусов».
    Важно: Окно должно показаться только в том случае, если документ действительно записался и провелся (транзакция зафиксирована).

Шаг 1. Прямой поток: Передаем флаг с клиента на сервер формы

В модуле формы перехватываем событие ПередЗаписью и добавляем наш флаг в структуру ПараметрыЗаписи

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    
    // ЭтотОбъект.ПовышенныйКэшбэк — реквизит формы (флажок на интерфейсе)
    Если ЭтотОбъект.ПовышенныйКэшбэк Тогда
        ПараметрыЗаписи.Вставить("ПрименитьПовышенныйКэшбэк", Истина);
    КонецЕсли;
    
КонецПроцедуры

Шаг 2. Переносим флаг в свойства прикладного объекта

В событии формы ПередЗаписьюНаСервере переносим значение из параметров записи в свойства самого объекта

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

Шаг 3. Обрабатываем данные на сервере и готовим обратный поток

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

Процедура ПриЗаписи(Отказ)
    
    // 1. Считываем входящий параметр
    ПовышенныйТариф = Ложь;
    ДополнительныеСвойства.Свойство("ПрименитьПовышенныйКэшбэк", ПовышенныйТариф);
    
    // 2. Рассчитываем бонусы (условный алгоритм)
    Коэффициент = ?(ПовышенныйТариф, 2, 1);
    НачисленныеБонусы = РассчитатьБонусыПоДокументу(ЭтотОбъект) * Коэффициент;
    
    // ... логика записи бонусов в регистры базы данных ...
    
    // 3. Записываем результат расчета, чтобы вернуть его на форму
    ДополнительныеСвойства.Вставить("РезультатРасчетаБонусов", НачисленныеБонусы);
    
КонецПроцедуры

Шаг 4. Обратный поток: Забираем результат расчета после фиксации транзакции

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

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

Шаг 5. Показываем результат пользователю на клиенте

Событие ПослеЗаписи срабатывает на клиенте в самом конце цепочки. Поскольку мы передали данные в ПараметрыЗаписи, они доступны здесь без совершения дополнительных серверных вызовов

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    
    НачисленоБонусов = Неопределено;
    Если ПараметрыЗаписи.Sвойство("НачисленоБонусовДляКлиента", НачисленоБонусов) Тогда
        
        // Показываем красивое всплывающее оповещение в углу экрана
        ПоказатьОповещениеПользователя(
            "Начисление бонусов", 
            , 
            СтрШаблон("Покупателю успешно начислено %1 бонусов!", НачисленоБонусов), 
            БиблиотекаКартинок.Информация
        );
        
    КонецЕсли;
    
КонецПроцедуры

Заключение и некоторые рекомендации

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

  1. Безопасное извлечение данных: Во избежание падения системы с ошибкой всегда используйте метод .Свойство() при обращении к ДополнительнымСвойствам или ПараметрамЗаписи.

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

  3. Не выводите интерактивные окна до завершения транзакции: не следует выводить пользователю какие-либо сообщения, связанные с бизнес-логикой, в событиях ПередЗаписьюНаСервере или ПриЗаписи. Если транзакция откатится из-за ошибки СУБД, пользователь получит недостоверную информацию. Всегда используйте клиентское событие ПослеЗаписи.

Чувствуете, что застряли в основах 1С?

Информация в интернете кажется обрывочной, а на решение простых задач уходят часы? Вы не одиноки. Я запустил Клуб для 1С разработчиков Alexcode.PRO. Внутри - продвинутые статьи, видео, материалы для скачивания, закрытый чат для резидентов и возможность влиять на контент.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *