Как проверить, что объект является новым в управляемой форме 1С?

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

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

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

Способ 1. Проверка на пустоту ссылки (Универсальный метод)

Самым простым, быстрым и рекомендуемым способом определения новизны объекта как на клиенте, так и на сервере является проверка его ссылки на пустоту. Если объект еще ни разу не был записан в базу данных, его ссылка будет пустой.

Рассмотрим пример реализации этого метода в коде управляемой формы:


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

Преимущества данного подхода:

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

Тем не менее, у этого способа есть один важный «подводный камень», связанный с предварительно сгенерированными ссылками. Мы подробно разберем его ниже.

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

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

Разберем по шагам, как это выглядит в обработчике ПриСозданииНаСервере:


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

Важные нюансы работы с параметрами:

Способ 3. Преобразование реквизита в прикладной объект (Серверный метод)

Некоторые разработчики используют явное получение полноценного прикладного объекта из данных формы на сервере, чтобы вызвать стандартный метод ЭтоНовый(). Это делается с помощью встроенной функции платформы РеквизитФормыВЗначение.

Давайте посмотрим, как выглядит этот код на сервере:


&НаСервере
Функция ПроверитьНовыйЛиОбъектНаСервере()
    ПрикладнойОбъект = РеквизитФормыВЗначение("Объект");
    Возврат ПрикладнойОбъект.ЭтоНовый();
КонецФункции

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

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

Подводный камень: Предустановленные ссылки

Вернемся к рекомендуемому способу Объект.Ссылка.Пустая(). В платформе «1С» существует механизм предварительного назначения уникального идентификатора (ссылки) для еще не записанного в базу объекта. Это реализуется методом УстановитьСсылкуНового(). Такой подход часто применяется при программном создании документов, интеграционных обменах или при необходимости привязать прикрепляемые файлы к документу до его первой физической записи.

В этой ситуации возникает следующая проблема:

Если в вашей конфигурации могут использоваться предустановленные ссылки, надежно проверить существование записи можно только выполнением легкого запроса к СУБД на сервере:


&НаСервере
Функция ОбъектДействительноСуществуетВБазе(СсылкаНаОбъект)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Ссылка
        |ИЗ
        |   Справочник.Номенклатура // Укажите ваш тип метаданных
        |ГДЕ
        |   Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);
    Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции

Стандарты разработки 1С: Как делать правильно?

Методологи фирмы «1С» рекомендуют разделять задачи инициализации данных и управления интерфейсом:

А. Если нужно заполнить реквизиты нового объекта при создании:

Не пишите этот код в модуле формы. Используйте предопределенный обработчик ОбработкаЗаполнения в модуле самого объекта. Этот обработчик гарантированно вызывается платформой только для новых объектов (как при интерактивном открытии формы, так и при программном создании). В нем не требуется использовать проверку ЭтоНовый(), так как сам факт вызова процедуры подтверждает создание нового элемента.

Б. Если нужно управлять видимостью или доступностью полей формы:

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

← На главную