Как запретить печать модифицированного документа и настроить запрос на сохранение в 1С?

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

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

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

Почему при печати не запрашивается сохранение документа?

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

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

Решение проблемы с печатью

У нас есть два пути решения этой задачи. Рассмотрим подробнее каждый из них.

Способ 1: Интеграция через механизмы БСП (Рекомендуемый)

Чтобы ваш документ вел себя как типовой, откажитесь от ручного создания кнопок печати на форме. Команду печати необходимо регистрировать программно через модуль менеджера документа.

  1. Перейдите в модуль менеджера вашего документа.
  2. Определите экспортную процедуру ДобавитьКомандыПечати.
  3. Подключите ваш документ к подсистеме печати через общие модули БСП, например, добавив его в процедуру ПриОпределенииОбъектовСКомандамиПечати в модуле УправлениеПечатьюПереопределяемый.

При таком подходе платформа сама разместит кнопку в меню «Печать» и автоматически обеспечит проверку на наличие изменений перед выводом печатной формы.

Способ 2: Ручной контроль модифицированности

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

Посмотрим на пример кода, который необходимо разместить в клиентском обработчике вашей команды печати:


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

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

Почему при закрытии окна не предлагается сохранение?

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

Разберем основные причины, почему форма может не фиксировать изменения:

  1. Программное изменение данных. Если строки в табличную часть добавляются или удаляются не интерактивно (не руками пользователя через интерфейс), а программно (например, при нажатии на кнопку "Заполнить" или при обработке сканирования штрихкода), платформа не всегда автоматически взводит флаг изменений.
  2. Отсутствие флага «Изменяет сохраняемые данные». У каждого элемента управления на управляемой форме (полей ввода, флажков, колонок таблиц) есть специальное свойство. Если при разработке расширения этот флаг оказался снят, то редактирование этих полей пользователем не будет переводить форму в статус измененной.
  3. Работа с локальными реквизитами формы. Убедитесь, в какие именно реквизиты вносятся изменения. Если данные пишутся в локальные переменные или реквизиты самой формы, а не в основной реквизит Объект (в котором хранятся данные документа базы данных), система закономерно не считает объект измененным.
  4. Использование нестандартных форм. Если документ открывается не в стандартной «Форме документа», а, например, в форме обработки или общей форме, платформа не будет автоматически отслеживать изменения документа.

Как исправить проблему с закрытием формы?

В зависимости от причины, мы применим разные способы решения.

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


&НаКлиенте
Процедура ЗаполнитьТабличнуюЧасть()
    // Ваш код заполнения данных...
    
    // Принудительно устанавливаем признак изменения
    ЭтаФорма.Модифицированность = Истина;
КонецПроцедуры

Проверка свойств элементов формы:
Откройте вашу форму в конфигураторе. Пройдитесь по всем добавленным полям ввода и колонкам табличной части. В палитре свойств найдите раздел «Использование» и убедитесь, что установлена галочка напротив свойства Изменяет сохраняемые данные. Без этого свойства платформа будет игнорировать ввод текста пользователем.

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


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

Альтернативный подход: Запрет редактирования проведенного документа

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

Логика работы следующая: при открытии формы мы проверяем статус проведения. Если документ проведен, мы блокируем форму для редактирования (устанавливаем свойство ТолькоПросмотр). Если пользователю действительно нужно изменить данные, он должен будет сначала осознанно отменить проведение документа, внести изменения, напечатать его и провести заново. Это жесткий, но методически очень правильный подход, который исключает рассинхронизацию между печатной формой и движениями документа в регистрах.

Настроим это в обработчике события формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Объект.Проведен Тогда
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецЕсли;
    
КонецПроцедуры

Применяя описанные выше методы, вы сможете гарантировать, что пользователи вашей базы 1С всегда будут распечатывать только актуальные и сохраненные данные, а случайное закрытие окна не приведет к потере результатов их труда.

← На главную