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

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

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

Почему метод ЭтоНовый() не работает в форме

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

Проанализируем ситуацию: метод ЭтоНовый() определен только для серверных типов объектов метаданных (например, ДокументОбъект.<ИмяДокумента> или СправочникОбъект.<ИмяСправочника>). У типа ДанныеФормыСтруктура такого метода просто не существует в синтакс-помощнике. Именно поэтому конструкции типа Объект.ЭтоНовый() вызывают ошибку времени выполнения.

Основной способ: Проверка ссылки на пустоту

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

Рассмотрим пример кода, который можно использовать в процедуре ПриСозданииНаСервере или любом другом месте формы:


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

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

Использование параметров формы

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

Проанализируем программную реализацию:


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

КонецПроцедуры

Нужно учитывать тонкое различие: Параметры.Ключ — это входное значение. Если вы программно запишете объект внутри процедуры ПриСозданииНаСервере, то Объект.Ссылка заполнится, а Параметры.Ключ останется пустым до конца выполнения процедуры. В большинстве сценариев это не критично, но об этом стоит помнить.

Когда все же нужен метод ЭтоНовый(): РеквизитВЗначение

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

Выполним это с помощью функции РеквизитВЗначение. Помните, что эта операция доступна только на сервере:


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

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

Обработка создания копированием

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

Для идентификации копирования в процедуре ПриСозданииНаСервере следует проверять параметр ЗначениеКопирования:


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

Где лучше устанавливать значения по умолчанию?

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

Правильнее использовать обработчик ОбработкаЗаполнения в модуле самого объекта. Там метод ЭтоНовый() работает стандартным образом, так как контекст модуля объекта всегда оперирует типом ДокументОбъект или СправочникОбъект.

Подведем итоги

Для успешной разработки в управляемом приложении запомним следующие правила:

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

Соблюдение этих рекомендаций сделает ваш код более стабильным, быстрым и соответствующим стандартам разработки фирмы "1С".

← На главную