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

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

В разработке на платформе 1С:Предприятие 8.3 вопрос взаимодействия клиента и сервера является базовым, но зачастую вызывает трудности даже у опытных разработчиков. Одной из таких «камней преткновения» становится работа с реквизитами формы. Давайте разберем, как устроена эта механика, почему иногда не удается «увидеть» нужные данные и как правильно организовать код, чтобы избежать ошибок производительности и логических тупиков.

Понятие контекста и жизненный цикл реквизитов формы

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

Важно понимать: реквизиты формы — это временные данные. Если вы находитесь внутри модуля формы, доступ к ним осуществляется напрямую по имени. Но как только мы выходим за пределы модуля (например, в общий модуль или модуль менеджера), ситуация меняется. Рассмотрим основные сценарии доступа.

Сценарий 1: Работа внутри модуля формы (Контекстный вызов)

Это самый простой вариант. Когда мы вызываем серверную процедуру из модуля формы, мы можем использовать директиву &НаСервере. В этом случае контекст формы передается на сервер автоматически. Мы можем обращаться к реквизитам так, будто мы все еще находимся на клиенте.

Проанализируем пример кода:


&НаСервере
Процедура РассчитатьСуммуНаСервере()
    // РеквизитФормы "КурсВалюты" доступен напрямую
    ИтоговаяСумма = Объект.Товары.Итог("Сумма") * КурсВалюты;
КонецПроцедуры

В данном примере КурсВалюты — это реквизит формы, а не документа. Платформа сама заботится о том, чтобы его значение было доступно на сервере в рамках этого вызова.

Сценарий 2: Вызов без контекста (Оптимизация)

Для ускорения работы системы часто применяют директиву &НаСервереБезКонтекста. В этом случае контекст формы (все её реквизиты и данные табличных частей) не передается на сервер. Это значительно экономит трафик и время сериализации данных.

Выясним причину, почему в такой процедуре нельзя просто написать имя реквизита. Ответ прост: сервер «не знает», из какой формы пришел запрос, так как данные ему не прислали. Чтобы решить эту задачу, мы должны передать нужные значения явно через параметры:


&НаКлиенте
Процедура КомандаВыполнить(Команда)
    Результат = ВычислитьЗначениеНаСервере(Объект.Ссылка, РеквизитФормы1);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ВычислитьЗначениеНаСервере(СсылкаНаОбъект, ЗначениеРеквизита)
    // Здесь мы работаем только с тем, что передали в параметрах
    Возврат СсылкаНаОбъект.ОсновнойСклад.Код + ЗначениеРеквизита;
КонецФункции

Сценарий 3: Доступ из внешних обработок и общих модулей

Рассмотрим ситуацию, описанную в обсуждении: вы программно получили объект документа во внешней обработке и хотите узнать значение какого-то реквизита его формы. Здесь кроется главная архитектурная ловушка. Реквизитов формы не существует, если сама форма не создана.

Если вам нужно получить данные, которые вычисляются динамически только «в интерфейсе», у вас есть два пути:

  1. Программное создание формы: Мы можем использовать метод ПолучитьФорму(). Однако помните: на сервере этот метод создаст новый экземпляр формы. Он не будет содержать тех данных, которые, возможно, ввел пользователь в свое открытое окно, но еще не сохранил.
  2. Перенос логики (Рекомендуемый путь): Если значение реквизита формы вычисляется по какой-то формуле, эту формулу следует вынести в МодульМенеджера или ОбщийМодуль. Таким образом, и форма, и ваша внешняя обработка смогут вызвать одну и ту же функцию для получения результата.

Использование методов преобразования данных

Разберем инструменты, которые предоставляет платформа для работы с данными объекта внутри формы. Иногда нам нужно вызвать метод объекта (например, документа), который недоступен у ДанныеФормыСтруктура. Для этого используются функции преобразования.

Рассмотрим по шагам процесс трансформации:

  1. Используем РеквизитФормыВЗначение("Объект"), чтобы получить полноценный объект ДокументОбъект.
  2. Выполняем необходимые действия или расчеты.
  3. Если данные изменились, используем ЗначениеВРеквизитФормы(Объект, "Объект"), чтобы обновить экранную форму.

&НаСервере
Процедура ЗаполнитьПоЦенеНоменклатуры()
    // Преобразуем данные формы в объект для доступа к его методам
    ДокОбъект = РеквизитФормыВЗначение("Объект");
    
    // Вызываем метод, описанный в модуле объекта
    ДокОбъект.ЗаполнитьЦены();
    
    // Возвращаем изменения назад в форму
    ЗначениеВРеквизитФормы(ДокОбъект, "Объект");
КонецПроцедуры

Архитектурный подход: Паттерн MVC в 1С

Как упоминалось в обсуждении, умные люди придумали паттерн MVC (Model-View-Controller). В контексте 1С:

Если вы сталкиваетесь с необходимостью получать «значения из формы» вне этой самой формы, значит, ваша бизнес-логика слишком сильно привязана к «Представлению». Постарайтесь проанализировать ситуацию и перенести расчеты в «Модель» (модуль менеджера или объекта). Это сделает ваш код универсальным: он будет работать и в интерактивном режиме, и при вызове из фоновых заданий, и во внешних обработках.

Работа с Временным хранилищем

Выясним, как передавать большие объемы данных формы на сервер, не перегружая контекстный вызов. Если у вас на форме есть тяжелая таблица значений (не реквизит объекта), передавать ее параметром в процедуру &НаСервереБезКонтекста неэффективно.

Правильным подходом будет:

  1. Поместить таблицу во ВременноеХранилище на клиенте (или в контекстной серверной процедуре).
  2. Передать на сервер только Адрес во временном хранилище.
  3. На сервере извлечь данные по адресу, обработать их и, при необходимости, положить результат обратно.

Итоги

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

← На главную