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