Как программно изменить значения элементов управляемой формы 1С 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке функциональности в 1С:Предприятие 8.3 с использованием управляемых форм часто возникает задача динамического изменения значений элементов формы, например, в зависимости от ввода пользователя. Быстрее подготовить шаблоны кода для таких задач поможет консоль кода с ИИ-помощником — есть инструменты для разработки и отладки кода 1С. Рассмотрим подробнее, как мы можем программно влиять на содержимое полей формы, учитывая клиент-серверную архитектуру платформы.

Изменение значений элементов формы, привязанных к реквизитам

Прежде чем менять значения, иногда требуется добавление реквизитов и элементов на управляемые формы программным путем, если они не были созданы в конфигураторе — для этого подойдёт управление элементами форм без изменения конфигурации.

Представим ситуацию: у нас есть управляемая форма записи регистра сведений, содержащая три поля, которые являются ресурсами регистра. Для описания логики взаимосвязей между ними удобно использовать подход, в основе которого лежит модель объекта. Наша задача – при изменении значений в первом или втором поле автоматически вычислять их произведение и записывать результат в третье поле (поможет автоматическое заполнение реквизитов объектов по условиям). При этом все действия должны происходить интерактивно, без обязательного обращения к серверу для каждого изменения.

Платформа 1С:Предприятие 8.3 в управляемых формах предоставляет удобный механизм для работы с данными на клиенте. Если элемент формы привязан к реквизиту данных формы (например, к свойству объекта или набора записей регистра), то его значение доступно непосредственно в клиентском контексте формы.

Для нашего случая, где поля 1, 2 и 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. Клиентская часть: Отвечает за отображение данных, взаимодействие с пользователем, выполнение интерактивной логики, не требующей доступа к базе данных или сложным серверным вычислениям. Данные, привязанные к форме (например, ЭтаФорма.Объект), кэшируются на клиенте для быстрого доступа.
  2. Серверная часть: Отвечает за доступ к базе данных (чтение/запись), выполнение сложных алгоритмов, работу с метаданными конфигурации, вызовы серверных объектов и функций.

Таким образом, если нам потребуется получить строковое значение ПутьКДанным элемента формы, нам придется обратиться к серверу. Например, в клиентской процедуре мы можем вызвать серверную процедуру, которая уже на сервере получит это свойство и, возможно, вернет его на клиент или выполнит какие-либо действия на основе полученного пути.

Рассмотрим пример, если бы нам понадобилось получить ПутьКДанным (это гипотетический пример, так как напрямую его на клиенте получить нельзя, но на сервере можно):


// В модуле формы

&НаКлиенте
Процедура ПолучитьПутьКДаннымНаСервере()
    ИмяЭлемента = "МоеПоле"; // Имя элемента, для которого хотим получить путь
    Путь = ПолучитьПутьКДаннымЭлементаСервер(ИмяЭлемента);
    Сообщить("Путь к данным для элемента " + ИмяЭлемента + ": " + Путь);
КонецПроцедуры

&НаСервере
Функция ПолучитьПутьКДаннымЭлементаСервер(ИмяЭлемента)
    ЭлементФормы = ЭтаФорма.Элементы[ИмяЭлемента];
    Если ЭлементФормы <> Неопределено Тогда
        Возврат ЭлементФормы.ПутьКДанным;
    Иначе
        Возврат "Элемент не найден";
    КонецЕсли;
КонецФункции

Как мы видим, сама строка ПутьКДанным доступна на сервере, но не на клиенте. Это решение разработчиков платформы направлено на оптимизацию и безопасность клиентской части, позволяя ей работать с данными, а не с их метаописаниями.

Заключение

Мы рассмотрели ключевые аспекты программного изменения значений элементов управляемой формы в 1С:Предприятие 8.3:

  1. Для элементов, привязанных к реквизитам данных формы (например, ресурсам регистра или свойствам объекта), значения могут быть напрямую изменены на клиенте через ЭтаФорма.ЭтотОбъект.Запись.ИмяРесурса или ЭтаФорма.Объект.ИмяРеквизита. Эти изменения будут немедленно отображены в интерфейсе.
  2. Для сохранения внесенных изменений в базу данных всегда требуется вызов серверного метода записи (например, ЭтаФорма.Записать()).
  3. Для элементов формы, не привязанных к реквизитам, значения изменяются через коллекцию Элементы формы (ЭтаФорма.Элементы.ИмяЭлемента.Значение). Эти изменения влияют только на отображение и не связаны с базой данных.
  4. Свойство ПутьКДанным элемента формы доступно для чтения только на сервере, что соответствует общей логике разделения клиентской и серверной ответственности в работе с данными и метаданными.

Понимание этих принципов позволяет нам эффективно разрабатывать интерактивные и отзывчивые формы, используя всю мощь клиент-серверной архитектуры 1С:Предприятие 8.3.

← На главную