Как отловить отказ от сохранения или проведения документа в 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Способ 1. Перенос логики изменения подчиненных объектов в процедуру проведения

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

Рассмотрим порядок реализации данного подхода:

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

Посмотрим на пример структуры процедуры проведения:


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

Способ 2. Полное переопределение действий экранных кнопок формы

Если специфика бизнес-логики требует обновления подчиненных структур именно при сохранении непроведенного документа, стандартное поведение интерактивных кнопок формы необходимо полностью заменить на программное управление.

Разберем по шагам, как перехватить весь процесс диалога с пользователем:

  1. В свойствах экранных кнопок формы («ОК», «Записать», «Провести») отключаем стандартные системные формулы платформы и назначаем собственные процедуры модуля формы.
  2. Все вопросы пользователю («Записать документ?», «Провести документ?») задаем самостоятельно через функцию Вопрос() до начала записи каких-либо данных в информационную базу.
  3. Запись основного и подчиненных документов заключаем в явный транзакционный блок с помощью операторов НачатьТранзакцию() и ЗафиксироватьТранзакцию().
  4. В случае отказа пользователя от действий или возникновения ошибки выполняем отмену транзакции через ОтменитьТранзакцию(), что гарантирует целостность базы данных.

Посмотрим на пример реализации обработки кнопки «ОК»:


Процедура ПоКнопкеОК()
    Если Модифицированность() = 1 Тогда
        Ответ = Вопрос("Записать и провести документ?", "Да+Нет+Отмена");
        Если Ответ = "Отмена" Тогда
            Возврат;
        ИначеЕсли Ответ = "Нет" Тогда
            Форма.Модифицированность(0);
            Форма.Закрыть(0);
            Возврат;
        КонецЕсли;
    КонецЕсли;
    
    НачатьТранзакцию();
    Попытка
        // Записываем текущий документ
        Записать();
        
        // Обновляем подчиненные документы
        СинхронизироватьПодчиненные();
        
        // Проводим документ программно без системных диалогов
        Провести(1);
        
        ЗафиксироватьТранзакцию();
        Форма.Модифицированность(0);
        Форма.Закрыть(0);
    Исключение
        ОтменитьТранзакцию();
        Предупреждение("Ошибка при сохранении документа: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Способ 3. Управление модифицированностью формы и блокировка ПриЗаписи

Чтобы исключить появление штатного вопроса платформы «Сохранить документ?» при интерактивном закрытии формы, необходимо управлять флагом модифицированности и блокировать несанкционированную запись.

Разберем реализацию этого механизма:

  1. В модуле формы объявляем глобальный флаг разрешения записи, например ФлагРазрешеннойЗаписи.
  2. В предопределенной процедуре ПриЗаписи() проверяем значение этого флага. Если запись вызвана не нашей процедурой управления, устанавливаем СтатусВозврата(0), прерывая сохранение.
  3. В процедуре ПриЗакрытии() проверяем состояние формы и сбрасываем модифицированность через Форма.Модифицированность(0), если пользователь решил закрыть документ без сохранения.

Посмотрим на пример программного кода процедур формы:


Перем ФлагРазрешеннойЗаписи;

Процедура ПриЗаписи()
    Если ФлагРазрешеннойЗаписи <> 1 Тогда
        // Блокируем системную запись платформы при обходе кастомных кнопок
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;
    
    // Выполняем действия, если запись санкционирована
КонецПроцедуры

Процедура ПриЗакрытии()
    Если Модифицированность() = 1 Тогда
        Ответ = Вопрос("Данные были изменены. Сохранить изменения?", "Да+Нет");
        Если Ответ = "Да" Тогда
            ФлагРазрешеннойЗаписи = 1;
            ПоКнопкеОК();
        Иначе
            Форма.Модифицированность(0);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

← На главную