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