Разработка и Конфигурация · 12 мин
Как записать реквизит формы в 1С
Как записать реквизит формы в 1С: программное создание через ИзменитьРеквизиты, присвоение значений, работа с динамическими списками и типичные ошибки.
Реквизит формы в 1С — это именованное хранилище данных, которое существует только в контексте конкретной формы и живёт, пока форма открыта. Разработчики сталкиваются с задачей записать значение в реквизит формы в двух ситуациях: когда реквизит уже создан в конфигураторе и нужно просто присвоить ему значение, и когда реквизит требуется создать программно в момент выполнения. Подходы в этих случаях принципиально различаются.
Основная сложность работы с реквизитами формы — разделение контекстов клиента и сервера. Простое присвоение вида РеквизитФормы = Значение работает в любом контексте, но создание новых реквизитов и изменение их состава возможно только на сервере через метод ИзменитьРеквизиты(). Игнорирование этого правила — самая частая причина ошибок «Метод объекта не обнаружен» у начинающих разработчиков.
Материал рассчитан на разработчиков и внедренцев, работающих с управляемыми формами в платформе 1С:Предприятие 8.3. Рассмотрены оба сценария: запись в существующий реквизит и динамическое создание реквизитов программно, а также особенности работы с таблицами значений и динамическими списками на форме.
Что такое реквизит формы и чем он отличается от реквизита объекта
Реквизит формы хранится в данных формы и не связан напрямую с базой данных. Он нужен для промежуточных вычислений, отображения служебной информации, хранения настроек отбора, флагов состояния и других данных, которые не должны сохраняться вместе с объектом. После закрытия формы значения её реквизитов теряются.
Реквизит объекта (справочника, документа) хранится в базе данных и записывается методом Записать() объекта. Путаница между этими сущностями приводит к типичной ошибке: разработчик присваивает значение реквизиту формы и ожидает, что оно сохранится в базе. Этого не произойдёт — для сохранения значение нужно перенести в реквизит объекта и записать объект.
Как записать значение в существующий реквизит формы
Если реквизит создан в конфигураторе через панель «Реквизиты» формы, запись значения выполняется обычным присвоением по имени. Имя реквизита становится свойством объекта формы:
&НаКлиенте
Процедура УстановитьПризнак(Команда)
ПоказыватьДетали = Истина;
ТекстСтатуса = "Загружено строк: " + Формат(ТаблицаСтрок.Количество(), "ЧГ=");
КонецПроцедуры
Здесь ПоказыватьДетали и ТекстСтатуса — реквизиты формы, объявленные в конфигураторе. Присвоение выполняется на клиенте без обращения к серверу, если тип значения простой (строка, число, булево, дата) или является сериализуемой ссылкой.
Обращаться к реквизиту можно и через коллекцию ЭтаФорма["ИмяРеквизита"], что удобно, когда имя формируется динамически. Этот приём используется в универсальных механизмах, где имена реквизитов генерируются по шаблону:
ЭтаФорма["Настройка_" + ИмяКлюча] = НовоеЗначение;
Как программно создать реквизит формы через ИзменитьРеквизиты
Когда реквизит нужен только в определённых условиях или его состав зависит от данных (например, колонки динамического отчёта), реквизиты создают программно. Это делается методом ИзменитьРеквизиты(), который доступен только в серверном контексте формы.
Метод принимает два параметра: массив добавляемых реквизитов (объекты типа ОписаниеРеквизитаФормы) и массив имён удаляемых реквизитов. Типичный сценарий — создать реквизит и сразу записать в него значение:
&НаСервере
Процедура СоздатьРеквизитИЗаписать()
Добавляемые = Новый Массив;
Описание = Новый ОписаниеРеквизитаФормы(
"РезультатРасчета",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Добавляемые.Добавить(Описание);
ИзменитьРеквизиты(Добавляемые);
// Теперь реквизит существует — можно записать значение
ЭтаФорма["РезультатРасчета"] = 1250.75;
КонецПроцедуры
Конструктор ОписаниеРеквизитаФормы принимает имя, описание типов, путь к данным (для вложенных реквизитов), заголовок и признак сохраняемости. После вызова ИзменитьРеквизиты() реквизит доступен по имени как обычное свойство формы.
- 1Сформируйте массив объектов ОписаниеРеквизитаФормы с именами и типами
- 2Вызовите ИзменитьРеквизиты() в серверной процедуре формы
- 3Проверьте, что реквизит с таким именем не существовал ранее — иначе будет ошибка
- 4Запишите значение присвоением по имени реквизита
- 5При необходимости создайте элемент формы и свяжите его с реквизитом через ПутьКДанным
Как записать данные в таблицу значений на форме
Реквизит формы типа «ТаблицаЗначений» — частый способ показать пользователю редактируемый список строк. Запись в такой реквизит выполняется через методы коллекции: Добавить(), Очистить(), ЗаполнитьЗначения(). Работа с содержимым таблицы не требует серверного вызова, если структура колонок не меняется:
&НаКлиенте
Процедура ДобавитьСтроку(Команда)
НоваяСтрока = ТоварыКОтгрузке.Добавить();
НоваяСтрока.Номенклатура = ТекущаяНоменклатура;
НоваяСтрока.Количество = 1;
КонецПроцедуры
Если нужно загрузить в таблицу результат запроса, потребуется серверная процедура, потому что запросы выполняются только на сервере. Результат передаётся через ЗначениеВДанныеФормы() или загружается методом Загрузить():
&НаСервере
Процедура ЗагрузитьДанные()
РезультатЗапроса = ВыполнитьЗапросКДанным();
ТоварыКОтгрузке.Загрузить(РезультатЗапроса.Выгрузить());
КонецПроцедуры
Добавление новых колонок в таблицу значений формы выполняется тем же ИзменитьРеквизиты(): в описании реквизита указывается путь к таблице, а имя — это имя новой колонки.
Особенности записи в реквизит типа «Динамический список»
Динамический список — особый реквизит формы, содержимое которого платформа формирует автоматически по запросу. Напрямую записать строки в динамический список нельзя: он не хранит данные, а отображает результат запроса. Изменить можно только параметры, отбор, порядок и текст запроса:
&НаСервере
Процедура УстановитьОтборСписка()
Список.Параметры.УстановитьЗначениеПараметра("Организация", ТекущаяОрганизация);
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Проведен");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Истина;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Если требуется показать произвольные данные, которых нет в одной таблице базы, динамический список не подходит — используйте реквизит типа «ТаблицаЗначений» и заполняйте его программно.
Как проверить, что значение записано корректно
Простейшая проверка — вывести значение реквизита в элемент формы (поле ввода или надпись), связанный через свойство ПутьКДанным. Если элемент отображает ожидаемое значение сразу после присвоения, запись прошла корректно. Для программной проверки используйте отладчик: поставьте точку останова после присвоения и посмотрите значение через табло.
При работе с динамически созданными реквизитами полезно проверять их наличие перед записью. Прямого метода «НайтиРеквизит» у формы нет, поэтому используют функцию ПолучитьРеквизиты() и перебирают результат по имени:
Функция РеквизитСуществует(ИмяРеквизита)
Для Каждого Реквизит Из ПолучитьРеквизиты() Цикл
Если Реквизит.Имя = ИмяРеквизита Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Как проверить результат
Элемент показывает новое значение сразу после присвоения
Элемент пуст или показывает старое значение — проверьте ПутьКДанным и имя реквизита
ПолучитьРеквизиты() возвращает реквизит с нужным именем и типом
Реквизита нет в списке — ИзменитьРеквизиты() не выполнился или вызван в другом экземпляре формы
Количество строк соответствует источнику, типы колонок корректны
Строки есть, но значения пустые — не совпадают имена колонок источника и реквизита
Ограничения и когда выбрать другой подход
Реквизиты формы не подходят для хранения больших объёмов данных: значения передаются между клиентом и сервером при каждом серверном вызове, что замедляет форму. Таблицы на тысячи строк лучше заменить динамическим списком с запросом к базе или временным хранилищем.
Для передачи данных между формами реквизиты формы тоже не лучший инструмент — используйте параметры формы при открытии (Параметры.ПередатьЗначение), оповещения (Оповестить) или временное хранилище (ПоместитьВоВременноеХранилище).
Если значение должно сохраняться между сеансами пользователя, рассмотрите хранение в регистре сведений, константе или настройках пользователя через ХранилищеОбщихНастроек.
Как выбрать подход
Часто задаваемые вопросы
Можно ли вызвать ИзменитьРеквизиты() в клиентской процедуре?
Нет, метод доступен только в серверном контексте формы. Если логика начинается на клиенте (например, по нажатию кнопки), создайте клиентскую процедуру-обёртку, которая вызывает серверную процедуру с директивой &НаСервере, и выполняйте изменение состава реквизитов там.
Почему после ИзменитьРеквизиты() присвоение по имени выдаёт ошибку?
Чаще всего присвоение выполняется в другом контексте или до фактического создания реквизита. Убедитесь, что присвоение идёт после вызова ИзменитьРеквизиты() в той же серверной процедуре, либо обращайтесь через ЭтаФорма["ИмяРеквизита"] из последующих серверных вызовов. Также проверьте, что имя не содержит опечаток и не конфликтует с существующими свойствами формы.
Как записать значение в реквизит формы из модуля объекта?
Напрямую из модуля объекта к реквизитам формы обратиться нельзя — у объекта нет ссылки на открытую форму. Передайте нужные данные в форму через параметры при открытии, через оповещение Оповестить() с обработчиком ОбработкаОповещения в форме, либо выполните логику в серверной процедуре самой формы, обратившись к объекту через РеквизитФормыВЗначение().
Сохранится ли реквизит формы при переоткрытии формы?
Нет, при закрытии формы все её реквизиты уничтожаются. Исключение — реквизиты с установленным признаком «Сохраняемые данные», значения которых платформа восстанавливает при повторном открытии в рамках механизма сохранения настроек формы. Для надёжного долгосрочного хранения используйте базу данных или хранилища настроек.
Как удалить программно созданный реквизит формы?
Вызовите ИзменитьРеквизиты() со вторым параметром — массивом строк с именами удаляемых реквизитов: ИзменитьРеквизиты(Новый Массив, МассивИменДляУдаления). Удалять можно только реквизиты, созданные программно; реквизиты, добавленные в конфигураторе, удалить в режиме выполнения нельзя.
Чем реквизит формы отличается от параметра формы?
Параметр формы передаётся при открытии и предназначен для начальной настройки формы; его состав задаётся в конфигураторе. Реквизит — это рабочее хранилище данных формы, доступное для редактирования и привязки к элементам в течение всего времени жизни формы. Параметры после открытия обычно переносят в реквизиты для дальнейшей работы.
Что важно запомнить
Запись в существующий реквизит формы — простое присвоение по имени в любом контексте. Создание новых реквизитов выполняется только на сервере через ИзменитьРеквизиты() с массивом ОписаниеРеквизитаФормы. Динамический список заполнить напрямую нельзя — управляйте его запросом и отбором. Реквизиты формы не сохраняются в базе: для долговременного хранения записывайте данные объекта или используйте хранилища настроек.