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

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

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

Причина 1. Разница между реквизитами объекта, реквизитами формы и элементами интерфейса

Проанализируем структуру управляемой формы. На управляемой форме данные строго отделены от элементов их визуального отображения:

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

Причина 2. Фиксированные сигнатуры стандартных событий формы

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

  1. Обработчик команды кнопки всегда принимает ровно один параметр: (Команда).
  2. Обработчик события поля ввода ПриИзменении всегда принимает ровно один параметр: (Элемент).

Попытка объявить обработчик с дополнительными переменными вида Процедура Рассчитать(Команда, Ввод) приводит к критической ошибке времени выполнения: платформа при нажатии кнопки или изменении поля передает только один системный параметр и не может вызвать процедуру с неподходящим количеством параметров.

Выясним, как правильно организовать вызов: для расчетов создается отдельная служебная процедура, в которую передаются нужные параметры, а обработчики событий лишь вызывают ее.


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

&НаКлиенте
Процедура КомандаРассчитать(Команда)
    // Из команды кнопки также вызываем общую расчетную процедуру
    ВыполнитьРасчет(Объект.ПолеВвода);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьРасчет(Знач СтрокаВыражения)
    Если ПустаяСтрока(СтрокаВыражения) Тогда
        Возврат;
    КонецЕсли;
    
    // Алгоритм обработки выражения
КонецПроцедуры

Реализация калькулятора с помощью встроенной функции Вычислить()

Разберем готовый компактный вариант вычисления строковых выражений с использованием функции глобального контекста Вычислить(). Данная функция принимает строку с математическим или логическим выражением и возвращает результат.

Посмотрим на пример безопасной реализации с перехватом ошибок через конструкцию Попытка ... Исключение и выводом сообщений пользователю:


&НаКлиенте
Процедура РассчитатьВыражение(Команда)
    СтрокаВыражения = Объект.ПолеВвода;
    
    Если ПустаяСтрока(СтрокаВыражения) Тогда
        Возврат;
    КонецЕсли;
    
    Попытка
        Результат = Вычислить(СтрокаВыражения);
        
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Результат: " + Строка(СтрокаВыражения) + " = " + Строка(Результат);
        Сообщение.Поле = "Объект.ПолеВвода";
        Сообщение.Сообщить();
    Исключение
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Ошибка при вычислении выражения: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
        Сообщение.Сообщить();
    КонецПопытки;
КонецПроцедуры

Важные особенности и риски использования функции Вычислить()

Проанализируем технические нюансы работы метода Вычислить():

  1. Уязвимость исполнения произвольного кода: функция Вычислить() выполняет любую синтаксически корректную конструкцию встроенного языка 1С. Если пользователь введет вызов системной функции, платформа выполнит ее с текущими правами сеанса. В реальных продуктивных решениях не рекомендуется применять Вычислить() для непроверенных пользовательских строк.
  2. Безопасный режим: при выполнении кода во внешних обработках, подключенных с контролем безопасности, вызовы некоторых глобальных методов через Вычислить() могут блокироваться платформой.
  3. Альтернативные подходы: для создания безопасных калькуляторов используют алгоритм разбора строки (например, алгоритм сортировочной станции с переводом в обратную польскую нотацию) либо формульный движок объекта ТабличныйДокумент, куда формула подставляется со знаком равенства в ячейку.

Рекомендации по передаче состояния в модуле формы

Чтобы избежать путаницы в передаче параметров между процедурами, придерживаемся следующих правил:

  1. Если значение должно быть доступно во всех процедурах формы и сохраняться при переходе контекста между клиентом и сервером — сохраняем его в реквизитах формы или реквизитах объекта Объект.
  2. Если переменная нужна только на стороне клиента в рамках текущего окна формы — объявляем клиентскую переменную модуля с помощью оператора Перем ИмяПеременной; в самом начале модуля формы вне процедур с директивой &НаКлиенте.
  3. Вспомогательные процедуры объявляем с явным указанием необходимых входных параметров и не смешиваем их с процедурами-обработчиками команд и событий интерфейса.
← На главную