Зачем в 1С используют РеквизитФормыВЗначение для проверки нового объекта и почему это считается ошибкой?

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

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

Разбор ситуации: зачем так пишут?

Проанализируем классический пример кода, который часто становится объектом критики:


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

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

Выясним причины появления такого кода в проектах. Зачастую это связано с тем, что программист ранее работал с «обычными» формами (например, в 1С 7.7 или 1С 8.2), где работа всегда шла напрямую с объектом (ЭтотОбъект). При переходе на управляемые формы (УФ) сохраняется привычка оперировать методами объектной модели, не учитывая архитектурное разделение данных формы и серверных объектов.

Почему это является грубой ошибкой (антипаттерном)

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

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

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

Решение №1: Использование проверки ссылки

Самый простой и эффективный способ проверить, является ли объект новым в управляемой форме, — это обратиться к его ссылке. У нового объекта, который еще не записан в базу данных, ссылка всегда будет пустой. Проанализируем правильный вариант кода:


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

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

Решение №2: Проверка через параметры ключа

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


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

Если в Параметры.Ключ передана пустая ссылка (или ключ пуст), это однозначно сигнализирует о создании нового элемента. Этот метод считается «чистым», так как он опирается на входные данные самой формы.

Тонкий нюанс: Новый объект или Копия?

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

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

Резюме

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

← На главную