Как в 1С определить, была ли сохранена запись регистра сведений при закрытии её формы

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

При разработке в среде 1С:Предприятие часто возникает задача: вызвать форму записи регистра сведений из обработки или другой формы и по завершении работы понять — сохранил ли пользователь данные или просто закрыл окно. Стандартное поведение метода ОткрытьФорму или устаревшего ОткрытьМодально для форм записи не подразумевает возврата результата (в отличие от форм выбора). Рассмотрим, как элегантно решить эту проблему, используя механизмы платформы 8.3.

Анализ проблемы: почему возвращается Неопределено

Когда мы открываем форму записи регистра сведений, платформа воспринимает её как самостоятельный объект управления данными. В отличие от формы выбора, где основной целью является возврат значения, форма записи предназначена для модификации базы данных. Поэтому при закрытии формы вызывающий код получает Неопределено. Это стандартное поведение, и попытки "поймать" результат через простое присваивание переменной при открытии не увенчаются успехом.

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

Решение 1: Использование механизма оповещений (Оповестить)

Этот метод считается одним из самых надежных и простых в реализации. Он основан на "широковещательном" оповещении системы. Разберем по шагам, как это реализовать.

Шаг 1. Подготовка вызывающей формы (владельца).

В форме вашей обработки, откуда происходит вызов, необходимо создать процедуру-обработчик оповещения. Она должна называться ОбработкаОповещения.


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

Шаг 2. Вызов формы записи.

При открытии формы обязательно указываем владельца (ЭтаФорма), чтобы система понимала контекст взаимодействия.


&НаКлиенте
Процедура ОткрытьФормуЗаписи()
    ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", ПередаваемыеПараметры);
    ОткрытьФорму("РегистрСведений.Штрихкоды.ФормаЗаписи", ПараметрыФормы, ЭтаФорма);
КонецПроцедуры

Шаг 3. Модификация формы записи регистра.

В самой форме записи регистра сведений (которую мы открываем) необходимо перехватить событие успешной записи. Лучше всего использовать процедуру ПослеЗаписи.


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Оповестить("ЗаписьШтрихкодаЗавершена", Истина, ЭтаФорма);
КонецПроцедуры

Таким образом, как только пользователь нажмет "Записать" или "Записать и закрыть", сработает событие ПослеЗаписи, которое пошлет сигнал всем открытым формам. Ваша обработка поймает его в ОбработкаОповещения.

Решение 2: Использование ОписанияОповещения (Асинхронный подход)

В современной платформе 1С (8.3.6 и выше) для отказа от модальности рекомендуется использовать объект ОписаниеОповещения. Это наиболее "технологичный" путь, который позволяет передать управление в конкретную процедуру при закрытии формы.

Рассмотрим, как это работает. Вместо ожидания закрытия формы в той же строке кода, мы заранее говорим системе: "Когда форма закроется, выполни вот эту процедуру".

Код в вызывающей форме:


&НаКлиенте
Процедура ОткрытьФормуСКонтролем()
    // Указываем процедуру, которая выполнится ПОСЛЕ закрытия
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияФормыЗаписи", ЭтаФорма);
    
    ПараметрыФормы = Новый Структура;
    // Передаем параметры, если нужно
    
    ОткрытьФорму("РегистрСведений.Штрихкоды.ФормаЗаписи", ПараметрыФормы, ЭтаФорма, , , , Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияФормыЗаписи(Результат, ДополнительныеПараметры) Экспорт
    Если Результат = Истина Тогда
        // Обрабатываем успешную запись
    КонецЕсли;
КонецПроцедуры

Код в форме записи регистра:

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


&НаКлиенте
Перем ЗаписьПроизведена;

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    ЗаписьПроизведена = Истина;
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
    Если ЗаписьПроизведена = Истина Тогда
        Закрыть(Истина); // Передаем результат в ОписаниеОповещения
    КонецЕсли;
КонецПроцедуры

Решение 3: Подмена стандартной команды (Кастомная кнопка)

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

  1. В форме записи регистра сведений отключаем стандартную командную панель или скрываем стандартную кнопку Записать и закрыть.
  2. Добавляем свою кнопку (команду) с названием "Записать и закрыть".
  3. В обработчике этой команды прописываем логику:

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

Важный нюанс: Метод ОповеститьОВыборе работает корректно только в том случае, если форма была открыта с параметром РежимВыбора = Истина. Для обычных форм записи регистра этот метод может не сработать, если не соблюдены условия владельца формы. Поэтому использование Закрыть(Результат) в связке с ОписаниеОповещения является более универсальным.

Выясним причину частых ошибок

Проанализируем ситуацию, описанную в обсуждении: почему ОбработкаОповещения может не срабатывать? Выделим основные причины:

Резюме по лучшей практике

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

  1. Всегда используйте ОписаниеОповещения для работы с закрытием форм. Это делает код устойчивым к работе в веб-клиенте и соответствует стандартам разработки 1С.
  2. Используйте событие ПослеЗаписи для фиксации факта сохранения данных в переменную модуля формы.
  3. В событии ПриЗакрытии передавайте накопленный статус (была запись или нет) обратно через метод Закрыть(Значение).

Этот подход не является "костылем", а представляет собой грамотное использование событийной модели 1С:Предприятия 8.3.

← На главную