Как отключить автоматическую запись объекта при выполнении команды в 1С

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

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

Почему происходит автоматическая запись: логика платформы

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

Рассмотрим основной триггер записи — свойство команды Изменяет данные. Рассмотрим подробнее, как оно работает:

  1. Если у команды в дереве объектов (или в редакторе формы) установлено свойство Изменяет данные в значение Истина, платформа перед выполнением кода команды автоматически инициирует метод Записать() для формы.
  2. Это делается для того, чтобы алгоритм команды работал с актуальным состоянием объекта, которое уже зафиксировано в СУБД.
  3. Если запись по каким-то причинам невозможна (например, не заполнены обязательные поля), выполнение команды будет прервано с ошибкой.

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

Влияние Библиотеки стандартных подсистем (БСП)

В современных конфигурациях (ЕРП, КА, УТ 11, БП 3.0) большинство команд не являются «чистыми» командами платформы, а управляются программными механизмами БСП, в частности подсистемой «Дополнительные отчеты и обработки». Проанализируем, как БСП влияет на процесс записи:

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

Чтобы избежать этого при разработке своих обработок, разберем следующий программный прием. В модуле регистрации обработки можно использовать параметр ЗаписыватьДанные. Посмотрим на пример кода:


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

Проблема команды «Связанные документы»

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

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

  1. Необходимо найти общую команду СтруктураПодчиненности или соответствующую процедуру в модуле формы.
  2. Через расширение (используя аннотацию &Вместо или &Перед) можно изменить логику вызова.
  3. Однако помните: если вы откроете отчет по связям для незаписанного объекта, отчет будет пустым или покажет неактуальные данные.

Программные способы обхода записи

Если стандартные настройки не помогают, и мы имеем дело с жестко зашитым поведением в коде конфигурации, разберем «хакерский», но рабочий метод — временный сброс флага модифицированности.

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


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

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

Рекомендации по реализации команд

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

  1. Проверьте свойство «Изменяет данные»: Это первое, на что стоит обратить внимание. Для чисто информационных команд (отчеты, справки) этот флаг должен быть выключен.
  2. Используйте «ВызовКлиентскогоМетода»: Если вы пишете внешнюю обработку по стандартам БСП, старайтесь выполнять основную логику на клиенте, обращаясь к серверу только при необходимости и передавая данные в виде структур или значениий, а не через ссылку Объект.Ссылка.
  3. Создавайте собственные команды формы: Вместо использования стандартных команд объекта, которые тянут за собой платформенные ограничения, создавайте команды непосредственно в форме документа. Это даст вам полный контроль над тем, когда вызывать ЭтотОбъект.Записать().
  4. Анализируйте метод «ПередЗаписью»: Если запись все же инициируется, вы можете в процедуре ПередЗаписью на стороне клиента или сервера проверить ПараметрыЗаписи. В некоторых случаях там можно найти информацию о том, какая команда инициировала запись, и при определенных условиях установить Отказ = Истина.

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

← На главную