Почему внешняя печатная форма не предлагает сохранить измененный документ перед печатью в 1С?

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

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

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

Причина №1: Программное изменение данных без установки флага модифицированности

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

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

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

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


// ... код, который изменяет реквизиты объекта на форме ...
Объект.Контрагент = НовыйКонтрагент;
Объект.СуммаДокумента = НоваяСумма;
// ... и так далее

// После всех программных изменений ОБЯЗАТЕЛЬНО добавляем эту строку
ЭтаФорма.Модифицированность = Истина;

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

Причина №2: Путаница между модифицированностью формы и объекта

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

Давайте разберемся в двух разных понятиях "модифицированности":

  1. Свойство формы ЭтаФорма.Модифицированность

    Это свойство существует только на клиенте. Оно отражает состояние данных, которые видит пользователь в окне программы. Именно это свойство отвечает за появление звездочки (*) в заголовке окна и за вопрос "Сохранить изменения?" при закрытии. Когда мы говорим о проверке перед печатью, БСП проверяет именно это клиентское свойство формы-владельца команды.

  2. Метод объекта Объект.Модифицированность()

    Это метод самого объекта данных (документа, справочника и т.д.), и он выполняется на сервере. Он сравнивает текущее состояние объекта в оперативной памяти сервера с его версией, сохраненной в базе данных.

Когда вы из формы документа вызываете команду печати внешней формы, происходит следующее:

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

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

Проверка корректности регистрации ВПФ

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


Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = Новый Структура;
    МассивНазначений = Новый Массив;
    МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг");
    
    ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
    ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
    ПараметрыРегистрации.Вставить("Наименование", "Договор розничной купли-продажи");
    ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
    ПараметрыРегистрации.Вставить("Версия", "1.0");
    ПараметрыРегистрации.Вставить("Информация", "Договор (Приложение №1)");
    
    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    
    ДобавитьКоманду(ТаблицаКоманд,
        "Договор (Приложение №1)",
        "ДоговорКуплиПродажиВРТУ",
        "ВызовСерверногоМетода", // Стандартный вызов серверного метода печати
        Истина,
        "ПечатьMXL");
        
    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
    
    Возврат ПараметрыРегистрации;

КонецФункции

Как мы видим, здесь нет никаких специальных параметров для управления проверкой модифицированности. Это подтверждает, что механизм является встроенным в БСП и должен работать "из коробки" при условии, что платформа "знает" об изменениях на форме.

Итоги и рекомендации

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

  1. Найдите код, который меняет данные. Внимательно проанализируйте, нет ли в конфигурации (или в других расширениях/обработках) кода, который программно заполняет или изменяет реквизиты документа на форме.
  2. Установите флаг вручную. В конце процедуры, которая выполняет программные изменения, обязательно добавьте строку ЭтаФорма.Модифицированность = Истина;.
  3. Не пытайтесь проверять модифицированность на сервере. Помните о разнице между состоянием формы на клиенте и состоянием объекта в базе данных. Проверка внутри серверного модуля ВПФ бессмысленна для отслеживания несохраненных пользовательских изменений.

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

← На главную