В процессе разработки управляемых форм в системе «1С:Предприятие 8.3» программисты часто сталкиваются с вопросом: какое ключевое слово использовать для обращения к контексту самой формы — ЭтотОбъект или ЭтаФорма? На первый взгляд они кажутся идентичными, однако за ними скрывается история развития платформы, стандарты разработки фирмы «1С» и критически важные нюансы, которые могут приводить к трудночитаемым ошибкам при обновлении конфигураций.
В этой статье мы подробно разберем, откуда появились эти свойства, чем они отличаются, почему использование одного из них теперь считается грубой ошибкой и с какими подводными камнями можно столкнуться на практике.
Чтобы понять логику платформы, нам необходимо вернуться к концепции обычных (деревянных) форм, которые использовались в версии 1С:Предприятие 8.2 и более ранних. В обычном приложении в модуле формы существовало два абсолютно разных контекста:
ЭтаФорма.ЭтотОбъект.Разработчик мог легко оперировать обоими контекстами в рамках одного модуля. Однако с приходом управляемого приложения (управляемых форм) архитектура кардинально изменилась. Данные формы были отделены от интерфейса. Модуль управляемой формы теперь исполняется в контексте самого клиента или сервера формы, а прикладной объект (например, документ) «живет» на сервере базы данных в виде реквизита формы с типом ДанныеФормыСтруктура (обычно это реквизит с именем Объект).
По инерции в первых версиях управляемого приложения разработчики продолжали использовать ключевое слово ЭтаФорма для обращения к свойствам и методам управляемой формы. Ключевое слово ЭтотОбъект в модуле управляемой формы изначально вообще не было зарезервировано платформой.
Начиная с версии платформы 1С:Предприятие 8.3.3 (при условии отключения режима совместимости с версией 8.2), фирма «1С» официально признала свойство управляемой формы ЭтаФорма устаревшим. Вместо него было введено единое универсальное свойство ЭтотОбъект.
Давайте выясним причину такого решения платформы. Ключевое слово ЭтотОбъект является более логичным и универсальным. Оно подходит для любого программного модуля в системе:
ЭтотОбъект возвращает саму управляемую форму.ЭтотОбъект возвращает сам прикладной объект.Именно поэтому использование ЭтаФорма в современном коде управляемого приложения признано нарушением стандартов разработки фирмы «1С». Современные инструменты статического анализа (такие как АПК — Автоматизированная проверка конфигураций, SonarQube или BSL Language Server) при проверке кода выдают предупреждение средней тяжести: «Использование устаревшего свойства "ЭтаФорма" (актуальное — "ЭтотОбъект")». Для такой задачи можно использовать инструмент для автоматического анализа конфигураций и обработок.
Рассмотрим доступность свойства ЭтотОбъект в управляемой форме. Согласно актуальной документации Синтакс-помощника, оно доступно во всех типах клиентов: Тонкий клиент, веб-клиент, сервер, толстый клиент (управляемое приложение), мобильное приложение (клиент). Таким образом, аргументы о том, что это свойство не работает в Тонком клиенте, являются устаревшими и неактуальными.
Внедрение ключевого слова ЭтотОбъект в контекст управляемых форм привело к массовым сбоям в старом коде (особенно во внешних обработках и отчетах) при обновлении конфигураций и отключении совместимости с 8.2. Разберем по шагам, почему это происходило.
Раньше, когда имя ЭтотОбъект не было системно зарезервировано в управляемой форме, разработчики часто использовали его в качестве обычной локальной переменной на сервере для получения прикладного объекта базы данных. Типичный пример старого кода выглядел так:
&НаСервере
Процедура ЗаполнитьДокументНаСервере()
// ПОДХОД, КОТОРЫЙ ВЫЗОВЕТ ОШИБКУ В 8.3:
ЭтотОбъект = РеквизитФормыВЗначение("Объект");
ЭтотОбъект.ЗаполнитьТабличнуюЧасть();
ЗначениеВРеквизитФормы(ЭтотОбъект, "Объект");
КонецПроцедуры
В современных версиях платформы 8.3 при попытке выполнить этот код система выдаст критическую ошибку выполнения: «Поле объекта недоступно для записи (ЭтотОбъект)». Это происходит потому, что платформа видит в левой части выражения системное свойство формы ЭтотОбъект, которое доступно только для чтения, и запрещает перезаписывать его значение.
Для решения этой проблемы необходимо принудительно переименовать локальную переменную. Проанализируем правильный вариант написания кода:
&НаСервере
Процедура ЗаполнитьДокументНаСервере()
// ПРАВИЛЬНЫЙ СОВРЕМЕННЫЙ ПОДХОД:
ДокументОбъект = РеквизитФормыВЗначение("Объект");
ДокументОбъект.ЗаполнитьТабличнуюЧасть();
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедуры
Использование понятных имен переменных (например, ДокументОбъект, СправочникОбъект или просто ОбъектБД) полностью исключает конфликт имен с системными свойствами платформы.
При работе с данными в модуле формы критически важно понимать контекстную разницу при вызове методов записи. Ошибочное понимание того, у какого именно объекта вызывается метод сохранения, может привести к некорректному поведению программы и потере данных.
Когда мы вызываем метод записи у управляемой формы:
// Использование современного свойства формы
ЭтотОбъект.Записать();
// Или устаревшего свойства
ЭтаФорма.Записать();
В этот момент инициализируется полный интерактивный цикл записи. Платформа выполняет следующие действия:
ПередЗаписью, ПередЗаписьюНаСервере, ПриЗаписиНаСервере, ПослеЗаписиНаСервере).Если разработчик получает прикладной объект из реквизита формы и вызывает метод записи непосредственно у него:
&НаСервере
Процедура ЗаписатьНапрямую()
ДокументОбъект = РеквизитФормыВЗначение("Объект");
// Запись происходит минуя интерфейс формы:
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедуры
При таком подходе запись происходит на уровне базы данных, минуя все интерфейсные механизмы управляемой формы. События формы (например, ПередЗаписьюНаСервере) вызваны не будут. Это может привести к тому, что вспомогательные данные формы, рассчитываемые динамически при интерактивном сохранении, не будут учтены.
Подводя итог нашему анализу, зафиксируем основные правила работы со свойствами контекста в 1С:Предприятии 8.3:
ЭтаФорма в новом коде и заменяйте его при рефакторинге старого кода. Это свойство устарело и не соответствует современным стандартам разработки 1С.ЭтотОбъект для обращения к методам и свойствам текущей управляемой формы (например, ЭтотОбъект.Закрыть(), ЭтотОбъект.Модифицированность).ЭтотОбъект в качестве локальной переменной для хранения прикладных объектов (справочников, документов), полученных через функцию РеквизитФормыВЗначение. Всегда называйте такие переменные осмысленно (например, ТекущийЗаказ, НоменклатураОбъект).