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