При разработке функциональности в 1С:Предприятие 8.3 с использованием управляемых форм часто возникает задача динамического изменения значений элементов формы, например, в зависимости от ввода пользователя. Быстрее подготовить шаблоны кода для таких задач поможет консоль кода с ИИ-помощником — есть инструменты для разработки и отладки кода 1С. Рассмотрим подробнее, как мы можем программно влиять на содержимое полей формы, учитывая клиент-серверную архитектуру платформы.
Прежде чем менять значения, иногда требуется добавление реквизитов и элементов на управляемые формы программным путем, если они не были созданы в конфигураторе — для этого подойдёт управление элементами форм без изменения конфигурации.
Представим ситуацию: у нас есть управляемая форма записи регистра сведений, содержащая три поля, которые являются ресурсами регистра. Для описания логики взаимосвязей между ними удобно использовать подход, в основе которого лежит модель объекта. Наша задача – при изменении значений в первом или втором поле автоматически вычислять их произведение и записывать результат в третье поле (поможет автоматическое заполнение реквизитов объектов по условиям). При этом все действия должны происходить интерактивно, без обязательного обращения к серверу для каждого изменения.
Платформа 1С:Предприятие 8.3 в управляемых формах предоставляет удобный механизм для работы с данными на клиенте. Если элемент формы привязан к реквизиту данных формы (например, к свойству объекта или набора записей регистра), то его значение доступно непосредственно в клиентском контексте формы.
Для нашего случая, где поля 1, 2 и 3 являются ресурсами регистра, мы можем получить и изменить их значения прямо на клиенте. Предположим, что поля регистра называются Ресурс1, Ресурс2 и Ресурс3. Доступ к этим ресурсам осуществляется через объект формы ЭтаФорма.ЭтотОбъект.Запись.
Рассмотрим пример кода, который мы могли бы разместить в обработчиках событий ПриИзменении для полей Ресурс1 и Ресурс2.
В модуле формы создадим функцию, например, ВычислитьТретьеПоле(), которая будет выполнять расчеты. Эта функция может быть клиентской.
&НаКлиенте
Процедура Ресурс1ПриИзменении(Элемент)
ВычислитьТретьеПоле();
КонецПроцедуры
&НаКлиенте
Процедура Ресурс2ПриИзменении(Элемент)
ВычислитьТретьеПоле();
КонецПроцедуры
&НаКлиенте
Процедура ВычислитьТретьеПоле()
// Получаем текущие значения ресурсов напрямую из объекта формы
// ЭтаФорма.ЭтотОбъект обращается к основному объекту формы,
// которым в данном случае является НаборЗаписей регистра сведений.
// .Запись. обращается к конкретной записи внутри набора,
// если форма работает с одной записью или является элементом списка.
// Если форма работает непосредственно с объектом, например, документа,
// то можно использовать ЭтаФорма.Объект.ИмяРеквизита.
// В данном контексте, где поля 1,2,3 являются ресурсами регистра,
// ЭтаФорма.ЭтотОбъект, скорее всего, является НаборомЗаписей.
// Доступ к полям осуществляется через имя ресурса.
// Для набора записей регистра сведений, который редактируется в форме,
// прямой доступ к ресурсам возможен через ЭтаФорма.ЭтотОбъект.ИмяРесурса
// или, как было подсказано, упрощенно Запись.ИмяРесурса,
// если платформа автоматически связывает контекст.
// Рассмотрим вариант с ЭтаФорма.ЭтотОбъект, как наиболее явный:
Значение1 = ЭтаФорма.ЭтотОбъект.Ресурс1;
Значение2 = ЭтаФорма.ЭтотОбъект.Ресурс2;
// Также можно использовать более короткий синтаксис, как подсказали в обсуждении:
// Значение1 = Запись.Ресурс1;
// Значение2 = Запись.Ресурс2;
// Это возможно, если в контексте формы переменная 'Запись'
// неявно ссылается на редактируемый набор записей или его элемент.
Если Значение1 = Неопределено Тогда
Значение1 = 0;
КонецЕсли;
Если Значение2 = Неопределено Тогда
Значение2 = 0;
КонецЕсли;
// Выполняем вычисление
Произведение = Значение1 * Значение2;
// Присваиваем результат третьему полю
ЭтаФорма.ЭтотОбъект.Ресурс3 = Произведение;
// Использование короткого синтаксиса:
// Запись.Ресурс3 = Произведение;
// Важно: Изменения, внесенные таким образом,
// отображаются на форме, но не сохраняются в базе данных.
// Для сохранения данных потребуется вызвать серверный метод Записать()
// или ЗаписатьВБазуДанных() для объекта формы.
КонецПроцедуры
Важный момент: Хотя мы успешно изменяем значения элементов формы на клиенте и видим эти изменения в интерфейсе, эти изменения не сохраняются автоматически в базе данных (в некоторых случаях может также потребоваться сохранение настроек формы для всех пользователей). Для фактического сохранения данных в регистре сведений нам потребуется вызвать серверный метод сохранения. Обычно это происходит при нажатии кнопок "Записать", "ОК" или "Записать и закрыть" на форме, которые имеют свои обработчики событий, вызывающие серверные процедуры.
Если нам необходимо при каждом изменении полей сразу сохранять данные (что не всегда рекомендуется из-за производительности), то в процедуре ВычислитьТретьеПоле после присвоения значения Ресурс3 нам нужно было бы вызвать серверную процедуру для записи:
&НаКлиенте
Процедура ВычислитьТретьеПоле()
// ... получение и расчет значений ...
ЭтаФорма.ЭтотОбъект.Ресурс3 = Произведение;
// Вызываем серверную процедуру для записи изменений в базу данных
ЗаписатьИзмененияНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗаписатьИзмененияНаСервере()
ЭтаФорма.Записать(); // Или ЭтаФорма.ЗаписатьВБазуДанных()
КонецПроцедуры
Этот подход гарантирует, что и отображение на клиенте, и данные в базе будут актуальными.
Иногда на форме присутствуют элементы (например, поля ввода, надписи), которые не привязаны напрямую к реквизитам данных формы через свойство ПутьКДанным. Эти элементы используются для временного хранения информации, отображения сообщений или промежуточных результатов. Для работы с такими элементами мы обращаемся к коллекции Элементы формы.
Например, если у нас есть поле ввода с именем ВременноеПоле, мы можем установить его значение следующим образом:
&НаКлиенте
Процедура УстановитьЗначениеВременногоПоля()
ЭтаФорма.Элементы.ВременноеПоле.Значение = "Это новое значение!";
КонецПроцедуры
Таким образом, мы напрямую управляем отображением элемента на форме. Однако, важно помнить, что изменения, внесенные таким способом, относятся только к интерфейсу и не имеют связи с данными, сохраняемыми в базе данных.
В процессе обсуждения поднялся вопрос о доступности свойства ПутьКДанным (DataPath) элемента формы на клиенте. Свойство ПутьКДанным определяет, какой реквизит формы является источником данных для конкретного элемента. Оно содержит строковое представление пути к данным, например, "Объект.Наименование" или "РегистрСведенийНаборЗаписей.Ресурс1".
Важный нюанс: Сама *строка* ПутьКДанным элемента формы не доступна для чтения на клиенте напрямую. Это является одной из особенностей платформы, вызывающей дискуссии среди разработчиков. Основная причина в том, что ПутьКДанным – это свойство, тесно связанное с метаданными и конфигурацией формы, доступ к которым более логичен на сервере. На клиенте платформа предоставляет данные, на которые этот путь указывает, но не сам путь как таковой.
Почему это так? Принципы клиент-серверной архитектуры 1С:Предприятие 8.3 разделяют зоны ответственности:
ЭтаФорма.Объект), кэшируются на клиенте для быстрого доступа.Таким образом, если нам потребуется получить строковое значение ПутьКДанным элемента формы, нам придется обратиться к серверу. Например, в клиентской процедуре мы можем вызвать серверную процедуру, которая уже на сервере получит это свойство и, возможно, вернет его на клиент или выполнит какие-либо действия на основе полученного пути.
Рассмотрим пример, если бы нам понадобилось получить ПутьКДанным (это гипотетический пример, так как напрямую его на клиенте получить нельзя, но на сервере можно):
// В модуле формы
&НаКлиенте
Процедура ПолучитьПутьКДаннымНаСервере()
ИмяЭлемента = "МоеПоле"; // Имя элемента, для которого хотим получить путь
Путь = ПолучитьПутьКДаннымЭлементаСервер(ИмяЭлемента);
Сообщить("Путь к данным для элемента " + ИмяЭлемента + ": " + Путь);
КонецПроцедуры
&НаСервере
Функция ПолучитьПутьКДаннымЭлементаСервер(ИмяЭлемента)
ЭлементФормы = ЭтаФорма.Элементы[ИмяЭлемента];
Если ЭлементФормы <> Неопределено Тогда
Возврат ЭлементФормы.ПутьКДанным;
Иначе
Возврат "Элемент не найден";
КонецЕсли;
КонецФункции
Как мы видим, сама строка ПутьКДанным доступна на сервере, но не на клиенте. Это решение разработчиков платформы направлено на оптимизацию и безопасность клиентской части, позволяя ей работать с данными, а не с их метаописаниями.
Мы рассмотрели ключевые аспекты программного изменения значений элементов управляемой формы в 1С:Предприятие 8.3:
ЭтаФорма.ЭтотОбъект.Запись.ИмяРесурса или ЭтаФорма.Объект.ИмяРеквизита. Эти изменения будут немедленно отображены в интерфейсе.ЭтаФорма.Записать()).Элементы формы (ЭтаФорма.Элементы.ИмяЭлемента.Значение). Эти изменения влияют только на отображение и не связаны с базой данных.ПутьКДанным элемента формы доступно для чтения только на сервере, что соответствует общей логике разделения клиентской и серверной ответственности в работе с данными и метаданными.Понимание этих принципов позволяет нам эффективно разрабатывать интерактивные и отзывчивые формы, используя всю мощь клиент-серверной архитектуры 1С:Предприятие 8.3.