При разработке интерфейсных решений в управляемом приложении разработчики часто сталкиваются с ситуацией, когда код с оператором Выполнить() или Вычислить() перестает работать при запуске программы через веб-клиент. Проанализируем технические причины этого ограничения и рассмотрим правильные архитектурные альтернативы для динамического вызова функций и открытия форм.
Разберем, как устроен веб-клиент 1С на техническом уровне. В отличие от тонкого или толстого клиента, в браузерной среде код клиентских модулей транслируется платформой 1С в язык JavaScript. На стороне веб-браузера полноценный интерпретатор встроенного языка 1С отсутствует, поэтому динамическая компиляция и исполнение произвольного текста программы через оператор Выполнить() технически невозможны.
Попытка заменить Выполнить() на функцию Вычислить() решает задачу лишь частично. Функция Вычислить() в веб-клиенте умеет обрабатывать только простые выражения, возвращающие значение (например, математические операции или вызовы функций), но не позволяет исполнять многострочные конструкты, объявлять переменные или выполнять присваивание вида:
Форма = ПолучитьФорму("ЖурналДокументов.СкладскиеОрдераНаИзлишкиНедостачиПорчи.Форма.ФормаСписка");
Форма.Открыть();
Рассмотрим наилучший способ решения задачи, если оператор Выполнить() использовался для динамического открытия окон по строковому имени. В управляемом приложении нет необходимости генерировать строковый код и выполнять его. Метод ОткрытьФорму() штатно умеет принимать полное имя формы в виде обычной строковой переменной.
Посмотрим на пример правильного вызова формы списка без использования динамического кода:
&НаКлиенте
Процедура ОткрытьФормуПоИмени(ИмяФормы)
// Переменная ИмяФормы содержит строку, например:
// "Документ.ЗаказНаПеремещение.ФормаСписка"
ОткрытьФорму(ИмяФормы);
КонецПроцедуры
Разберем важный момент: если для открываемой формы требуется передать отборы или специфические параметры, их следует передавать во второй параметр метода ОткрытьФорму() в виде структуры:
&НаКлиенте
Процедура ОткрытьФормуСПараметрами(ИмяФормы, ЗначениеОтбора)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", Новый Структура("Организация", ЗначениеОтбора));
ОткрытьФорму(ИмяФормы, ПараметрыФормы);
КонецПроцедуры
Выясним, почему схемы с вызовом ПолучитьФорму() вызывают сложности в управляемом приложении. Использование ПолучитьФорму() порождает лишние вызовы сервера для инициализации формы до ее открытия. В тонком и веб-клиенте рекомендуется использовать только ОткрытьФорму(), доверяя платформе оптимизацию передачи данных между клиентом и сервером.
Если бизнес-логика вашей задачи действительно требует исполнения произвольного текста программы 1С из текстовой строки, разделим выполнение на две части по контекстам:
Выполнить() внутри процедуры с директивой &НаСервере или &НаСервереБезКонтекста, где полнофункциональный интерпретатор 1С работает без ограничений веб-клиента. В результате выполнения формируется структура данных с именем формы и нужными параметрами.ОткрытьФорму().Посмотрим на пример такого разделения:
&НаСервереБезКонтекста
Функция ВычислитьПараметрыНаСервере(СтрокаКода)
Результат = Новый Структура;
// На сервере оператор Выполнить() работает в полном объеме
Выполнить(СтрокаКода);
Возвращать Результат;
КонецФункции
&НаКлиенте
Процедура ЗапуститьКоманду()
СтруктураДанных = ВычислитьПараметрыНаСервере(ТекстКоманды);
Если СтруктураДанных.Свойство("ИмяФормы") Тогда
ОткрытьФорму(СтруктураДанных.ИмяФормы, СтруктураДанных.Параметры);
КонецЕсли;
КонецПроцедуры
Таким образом, для веб-клиента следует отказаться от динамического формирования кода интерфейсных команд и использовать штатные методы платформы 1С — ОткрытьФорму() и передачу параметров через структуры.