Как изменить данные формы документа через команду без автоматической записи?

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

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

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

Почему платформа принудительно записывает модифицированный документ

Рассмотрим, как устроен механизм параметризуемых команд в платформе 1С:Предприятие 8.3:

  1. Передача ссылочного типа в команду: Если в свойствах общей команды или команды объекта заполнен Тип параметра команды (указаны ссылки на документы), платформа считает, что логика команды рассчитана на работу с актуальной записью базы данных.
  2. Неявная запись перед вызовом: Когда пользователь нажимает кнопку такой команды в форме, где флаг Модифицированность равен Истина, платформа сначала автоматически выполняет запись данных формы в информационную базу и только после успешной транзакции передает управление в процедуру ОбработкаКоманды. Если при записи возникают ошибки или срабатывают проверки, выполнение команды прерывается.
  3. Назначение свойства «Изменяет данные»: Снятие флага Изменяет данные в свойствах команды не отменяет автозапись. Данный флаг предназначен только для управления доступностью: если свойство включено, кнопка автоматически блокируется при открытии формы в режиме «Только просмотр».

Вариант 1. Добавление команды формы через расширение конфигурации

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

Разберем программное добавление команды и кнопки через обработчик события ПриСозданииНаСервере в расширении:


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

После создания команды реализуем обработчик на клиенте и сервере, где модифицируем данные формы напрямую через реквизит Объект:


&НаКлиенте
Процедура Подключаемый_ВыполнитьЗаполнениеЦен(Команда)
    ЗаполнитьЦеныНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьЦеныНаСервере()
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        СтрокаТЧ.Цена = 10;
        СтрокаТЧ.Сумма = СтрокаТЧ.Количество * СтрокаТЧ.Цена;
    КонецЦикла;
    
    // Устанавливаем признак модифицированности формы
    Модифицированность = Истина;
КонецПроцедуры

Вариант 2. Использование механизма дополнительных отчетов и обработок (БСП)

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

В модуле объекта внешней обработки в экспортной функции СведенияОВнешнейОбработке() необходимо зарегистрировать команду с типом ЗаполнениеФормы:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    ПараметрыРегистрации.Назначение.Добавить("Документ.ПриходнаяНакладная");
    ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Заполнить цены по умолчанию";
    НоваяКоманда.Идентификатор = "ЗаполнитьЦеныПоУмолчанию";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидКомандыЗаполнениеФормы();
    НоваяКоманда.ПоказыватьОповещение = Истина;
    
    Возврат ПараметрыРегистрации;
КонецФункции

При вызове команды с видом ЗаполнениеФормы БСП передает контекст формы в обработку без выполнения предварительной записи объекта в базу данных.

Вариант 3. Непараметризуемая общая команда с механизмом оповещений

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

  1. В общей команде оставляем свойство Тип параметра команды пустым (команда перестает быть параметризуемой и не привязывается к ссылке).
  2. В процедуре ОбработкаКоманды отправляем глобальное клиентское оповещение:

&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    Оповестить("ВыполнитьЗаполнениеТабличнойЧасти", Новый Структура("Цена", 10));
КонецПроцедуры

В формах документов в процедуре ОбработкаОповещения перехватываем это событие и выполняем необходимые действия над данными формы:


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

Такой подход полностью исключает автоматическую запись объекта платформой и оставляет контроль за сохранением данных пользователю.

← На главную