При чтении чужого кода в управляемом приложении 1С:Предприятие 8 часто можно встретить конструкцию в процедуре ПриСозданииНаСервере, где разработчик преобразует реквизит формы в полноценный прикладной объект только для того, чтобы вызвать метод ЭтоНовый(). Рассмотрим подробнее, почему такая практика вызывает вопросы у опытных специалистов, и выясним причины появления подобного кода.
Проанализируем классический пример кода, который часто становится объектом критики:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Док = РеквизитФормыВЗначение("Объект");
Если Док.ЭтоНовый() Тогда
// Какая-то логика для нового документа
КонецЕсли;
КонецПроцедуры
На первый взгляд, код кажется логичным: программисту нужно узнать, создается ли документ сейчас или открывается уже существующий. Однако в управляемом приложении тип ДанныеФормыСтруктура (которым является Объект на форме) не имеет метода ЭтоНовый(). Этот метод доступен только для объектов типа ДокументОбъект, СправочникОбъект и т.д. Поэтому не очень опытный разработчик решает «получить» настоящий объект из данных формы, чтобы воспользоваться привычным методом.
Выясним причины появления такого кода в проектах. Зачастую это связано с тем, что программист ранее работал с «обычными» формами (например, в 1С 7.7 или 1С 8.2), где работа всегда шла напрямую с объектом (ЭтотОбъект). При переходе на управляемые формы (УФ) сохраняется привычка оперировать методами объектной модели, не учитывая архитектурное разделение данных формы и серверных объектов.
Использование метода РеквизитФормыВЗначение исключительно ради проверки новизны — это избыточная операция, которая негативно влияет на производительность системы. Разберем по шагам, что происходит на сервере при вызове этого метода:
rphost создается копия объекта, включая все его табличные части, даже если они содержат тысячи строк и не отображаются на форме.Согласно стандартам разработки 1С, метод РеквизитФормыВЗначение следует вызывать только тогда, когда вам действительно нужны методы прикладного объекта, не имеющие аналогов в данных формы (например, Заполнить() или специфические процедуры из модуля объекта).
Самый простой и эффективный способ проверить, является ли объект новым в управляемой форме, — это обратиться к его ссылке. У нового объекта, который еще не записан в базу данных, ссылка всегда будет пустой. Проанализируем правильный вариант кода:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Объект.Ссылка.Пустая() Тогда
// Это новый объект
КонецЕсли;
КонецПроцедуры
Этот способ работает мгновенно, так как Объект.Ссылка уже доступна в данных формы и не требует никаких серверных преобразований или обращений к базе для создания тяжелого объекта.
Существует еще более элегантный способ, который позволяет определить состояние объекта еще до того, как данные формы будут полностью инициализированы. В процедуре ПриСозданииНаСервере мы можем обратиться к параметрам, с которыми открывается форма. Посмотрим на пример:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Ключ.Пустая() Тогда
// Форма открыта для создания нового объекта
КонецЕсли;
КонецПроцедуры
Если в Параметры.Ключ передана пустая ссылка (или ключ пуст), это однозначно сигнализирует о создании нового элемента. Этот метод считается «чистым», так как он опирается на входные данные самой формы.
Важно понимать различие между «новым» объектом и объектом, созданным «копированием». В обоих случаях Объект.Ссылка.Пустая() вернет Истина. Если же вы используете РеквизитФормыВЗначение, метод ЭтоНовый() также вернет Истина для копии. Таким образом, даже в сценарии копирования создание тяжелого объекта не дает вам никакой дополнительной информации по сравнению с простой проверкой ссылки.
Совет: Если вам нужно отличить создание нового документа от копирования существующего, лучше проверять параметр формы ЗначениеКопирования.
Рассмотрев все варианты, мы приходим к выводу, что использование РеквизитФормыВЗначение для проверки ЭтоНовый() — это классическое «легаси», оставленное либо по неопытности, либо в результате автоматической конвертации старого кода. Постарайтесь избегать этого подхода в своей практике. Всегда отдавайте предпочтение проверке Объект.Ссылка.Пустая() или анализу Параметры.Ключ. Это сделает ваш код профессиональным, а работу системы — быстрой.