Как заменить оператор Выполнить() в веб-клиенте 1С

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

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

Выясним причину: почему Выполнить() не работает в веб-клиенте

Разберем, как устроен веб-клиент 1С на техническом уровне. В отличие от тонкого или толстого клиента, в браузерной среде код клиентских модулей транслируется платформой 1С в язык JavaScript. На стороне веб-браузера полноценный интерпретатор встроенного языка 1С отсутствует, поэтому динамическая компиляция и исполнение произвольного текста программы через оператор Выполнить() технически невозможны.

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


Форма = ПолучитьФорму("ЖурналДокументов.СкладскиеОрдераНаИзлишкиНедостачиПорчи.Форма.ФормаСписка");
Форма.Открыть();

Прямой вызов метода ОткрытьФорму() с динамическим именем

Рассмотрим наилучший способ решения задачи, если оператор Выполнить() использовался для динамического открытия окон по строковому имени. В управляемом приложении нет необходимости генерировать строковый код и выполнять его. Метод ОткрытьФорму() штатно умеет принимать полное имя формы в виде обычной строковой переменной.

Посмотрим на пример правильного вызова формы списка без использования динамического кода:


&НаКлиенте
Процедура ОткрытьФормуПоИмени(ИмяФормы)
    
    // Переменная ИмяФормы содержит строку, например:
    // "Документ.ЗаказНаПеремещение.ФормаСписка"
    
    ОткрытьФорму(ИмяФормы);

КонецПроцедуры

Разберем важный момент: если для открываемой формы требуется передать отборы или специфические параметры, их следует передавать во второй параметр метода ОткрытьФорму() в виде структуры:


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

КонецПроцедуры

Отказ от устаревшего метода ПолучитьФорму()

Выясним, почему схемы с вызовом ПолучитьФорму() вызывают сложности в управляемом приложении. Использование ПолучитьФорму() порождает лишние вызовы сервера для инициализации формы до ее открытия. В тонком и веб-клиенте рекомендуется использовать только ОткрытьФорму(), доверяя платформе оптимизацию передачи данных между клиентом и сервером.

Перенос динамического выполнения алгоритмов на сервер

Если бизнес-логика вашей задачи действительно требует исполнения произвольного текста программы 1С из текстовой строки, разделим выполнение на две части по контекстам:

  1. На сервере: вызовем оператор Выполнить() внутри процедуры с директивой &НаСервере или &НаСервереБезКонтекста, где полнофункциональный интерпретатор 1С работает без ограничений веб-клиента. В результате выполнения формируется структура данных с именем формы и нужными параметрами.
  2. На клиенте: получим структуру от сервера и передадим готовое имя в клиентский метод ОткрытьФорму().

Посмотрим на пример такого разделения:


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

КонецФункции

&НаКлиенте
Процедура ЗапуститьКоманду()
    
    СтруктураДанных = ВычислитьПараметрыНаСервере(ТекстКоманды);
    Если СтруктураДанных.Свойство("ИмяФормы") Тогда
        ОткрытьФорму(СтруктураДанных.ИмяФормы, СтруктураДанных.Параметры);
    КонецЕсли;

КонецПроцедуры

Таким образом, для веб-клиента следует отказаться от динамического формирования кода интерфейсных команд и использовать штатные методы платформы 1С — ОткрытьФорму() и передачу параметров через структуры.

← На главную