При разработке универсального функционала для управляемых форм часто возникает задача: реализовать единый алгоритм заполнения реквизитов или табличных частей (например, заполнение цен, пересчет сумм, подбор номенклатуры) для разных видов документов без внесения правок в каждый объект конфигурации. При этом важно, чтобы документ не записывался автоматически, а пользователь сохранял возможность отказаться от изменений, просто закрыв форму без сохранения.
Попытка решить эту задачу с помощью общей параметризуемой команды сталкивается с платформенным ограничением: если форма документа модифицирована, платформа 1С принудительно записывает объект в базу данных еще до выполнения обработчика команды. Проанализируем причину такого поведения и рассмотрим проверенные варианты решения.
Рассмотрим, как устроен механизм параметризуемых команд в платформе 1С:Предприятие 8.3:
Тип параметра команды (указаны ссылки на документы), платформа считает, что логика команды рассчитана на работу с актуальной записью базы данных.Модифицированность равен Истина, платформа сначала автоматически выполняет запись данных формы в информационную базу и только после успешной транзакции передает управление в процедуру ОбработкаКоманды. Если при записи возникают ошибки или срабатывают проверки, выполнение команды прерывается.Изменяет данные в свойствах команды не отменяет автозапись. Данный флаг предназначен только для управления доступностью: если свойство включено, кнопка автоматически блокируется при открытии формы в режиме «Только просмотр».В отличие от параметризуемых глобальных команд, команды, принадлежащие непосредственно форме (КомандаФормы), не инициируют автоматическую запись объекта при нажатии. Мы можем внедрить такую команду в нужные документы без снятия конфигурации с поддержки с помощью механизма расширений.
Разберем программное добавление команды и кнопки через обработчик события ПриСозданииНаСервере в расширении:
&Вместо("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПродолжитьВызов(Отказ, СтандартнаяОбработка);
// Создаем команду формы
НоваяКоманда = ЭтаФорма.Команды.Добавить("ЗаполнитьЦены");
НоваяКоманда.Заголовок = "Заполнить цены (10)";
НоваяКоманда.Действие = "Подключаемый_ВыполнитьЗаполнениеЦен";
НоваяКоманда.МодифицируетДанные = Истина;
// Добавляем кнопку на командную панель формы
ЭлементКнопка = ЭтаФорма.Элементы.Добавить("КнопкаЗаполнитьЦены", Тип("КнопкаФормы"), ЭтаФорма.Элементы.КоманднаяПанель);
ЭлементКнопка.ИмяКоманды = "ЗаполнитьЦены";
КонецПроцедуры
После создания команды реализуем обработчик на клиенте и сервере, где модифицируем данные формы напрямую через реквизит Объект:
&НаКлиенте
Процедура Подключаемый_ВыполнитьЗаполнениеЦен(Команда)
ЗаполнитьЦеныНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьЦеныНаСервере()
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
СтрокаТЧ.Цена = 10;
СтрокаТЧ.Сумма = СтрокаТЧ.Количество * СтрокаТЧ.Цена;
КонецЦикла;
// Устанавливаем признак модифицированности формы
Модифицированность = Истина;
КонецПроцедуры
Если конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), для заполнения объектов без изменения конфигурации предназначен механизм внешних обработок заполнения.
В модуле объекта внешней обработки в экспортной функции СведенияОВнешнейОбработке() необходимо зарегистрировать команду с типом ЗаполнениеФормы:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
ПараметрыРегистрации.Назначение.Добавить("Документ.ПриходнаяНакладная");
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Заполнить цены по умолчанию";
НоваяКоманда.Идентификатор = "ЗаполнитьЦеныПоУмолчанию";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидКомандыЗаполнениеФормы();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
При вызове команды с видом ЗаполнениеФормы БСП передает контекст формы в обработку без выполнения предварительной записи объекта в базу данных.
Если требуется вызывать алгоритм через интерфейсную кнопку общей команды, но избежать принудительного сохранения формы, можно использовать команду с пустым типом параметра:
Тип параметра команды пустым (команда перестает быть параметризуемой и не привязывается к ссылке).ОбработкаКоманды отправляем глобальное клиентское оповещение:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
Оповестить("ВыполнитьЗаполнениеТабличнойЧасти", Новый Структура("Цена", 10));
КонецПроцедуры
В формах документов в процедуре ОбработкаОповещения перехватываем это событие и выполняем необходимые действия над данными формы:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ВыполнитьЗаполнениеТабличнойЧасти" Тогда
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
СтрокаТЧ.Цена = Параметр.Цена;
КонецЦикла;
Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Такой подход полностью исключает автоматическую запись объекта платформой и оставляет контроль за сохранением данных пользователю.