Как в расширении 1С перехватить нажатие кнопки «Записать и закрыть»

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

При разработке расширений для 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью изменить логику сохранения объекта. Типичный вопрос: как определить, нажал ли пользователь просто «Записать» или выбрал «Записать и закрыть»? На первый взгляд кажется, что стандартные события ведут себя по-разному, но это не совсем так. Рассмотрим подробно, как работает механизм записи в расширениях и какие инструменты у нас есть для решения этой задачи.

Стандартное поведение события ПередЗаписью

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

Чаще всего это связано с тем, что при нажатии «Записать и закрыть» форма закрывается сразу после успешного завершения транзакции. Если в коде расширения есть ошибки или логика, которая должна визуально отображаться на форме, вы можете просто не успеть заметить её выполнение. Проверим это, установив точку останова в процедуре расширения — вы увидите, что отладчик остановится в обоих случаях.

Способ 1. Использование параметров записи на форме

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

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

Пример реализации в модуле формы расширения:


&НаКлиенте
Процедура ИСТ_ЗаписатьИЗакрытьВыполнить(Команда)
    // Устанавливаем специальный флаг в параметрах записи
    ПараметрыЗаписи = Новый Структура;
    ПараметрыЗаписи.Вставить("ЗакрытьПослеЗаписи", Истина);
    
    // Вызываем стандартный метод записи объекта
    Записать(ПараметрыЗаписи);
КонецПроцедуры

Затем в серверном событии ПередЗаписьюНаСервере мы сможем проанализировать этот параметр:


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

Способ 2. Режимы применения расширения: Исправление vs Адаптация

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

  1. Адаптация: основной режим для добавления нового функционала.
  2. Исправление (Patch): режим с наивысшим приоритетом.

Иногда в версиях платформы (например, ветки 8.3.21–8.3.23) наблюдаются особенности, когда события формы в режиме «Адаптация» могут игнорироваться, если они перекрываются другими расширениями или сложной логикой основной конфигурации. Посмотрим на практику: установка свойства расширения Назначение = Исправление часто решает проблему «невидимости» обработчиков. Это связано с тем, что исправления компилируются и применяются платформой в последнюю очередь, перекрывая все остальные слои кода.

Способ 3. Создание собственных командных панелей

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

Алгоритм действий:

  1. В расширении формы установите у командной панели свойство Автозаполнение = Ложь (или скройте стандартные кнопки).
  2. Добавьте свои команды: КомандаЗаписать и КомандаЗаписатьИЗакрыть.
  3. В обработчике каждой команды вызывайте метод Записать(), передавая в него структуру ПараметрыЗаписи с нужными вам флагами.

Этот подход позволяет избежать «магии» платформенных механизмов и делает код прозрачным для поддержки другими программистами. Мы точно контролируем, какой код выполняется до записи, в процессе и после неё. Для ускорения программного добавления команд и элементов управления можно использовать общий модуль для программного изменения форм и команд.

Нюансы клиент-серверного взаимодействия

Важно помнить последовательность вызовов при нажатии «Записать и закрыть». Разберем по шагам:

  1. Выполняется код на клиенте (команда формы).
  2. Управление передается на сервер в ПередЗаписьюНаСервере формы.
  3. Открывается транзакция базы данных, и управление переходит в Модуль объекта расширения (процедура ПередЗаписью).
  4. Если запись успешна, выполняется ПослеЗаписиНаСервере.
  5. Управление возвращается на клиент, и форма инициирует процедуру закрытия.

Если ваша задача — выполнить действие именно перед закрытием, но после успешного сохранения, попробуйте проанализировать состояние формы в обработчике ПередЗакрытием. Если объект не модифицирован (Модифицированность = Ложь) и последним действием была запись, это косвенно подтверждает отработку команды «Записать и закрыть».

Заключение

Мы выяснили, что основная проблема с перехватом «Записать и закрыть» часто кроется либо в невнимательности при отладке (форма закрывается, и кажется, что код не сработал), либо в приоритетах работы самого расширения. Использование Параметров записи является наиболее «элегантным» и правильным с точки зрения архитектуры 1С способом разделения логики различных команд сохранения.

← На главную