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