Как открывать разные формы в зависимости от версии клиента 1С (Веб-клиент или Тонкий клиент)?

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

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

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

Рассмотрим стандартный и наиболее правильный механизм переопределения форм в 1С — это использование события ОбработкаПолученияФормы в модуле менеджера объекта (например, документа).

Многие разработчики, пытаясь определить тип клиента, пишут примерно следующий код:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    Если ВидФормы = "ФормаСписка" Тогда
        #Если ВебКлиент Тогда
            ВыбраннаяФорма = "ФормаСпискаДляВебКлиента";
            СтандартнаяОбработка = Ложь;
        #КонецЕсли
    КонецЕсли;
КонецПроцедуры

Однако при тестировании выясняется, что подмена не происходит. Выясним причину такого поведения. Дело в том, что конструкции вида #Если ВебКлиент Тогда являются инструкциями препроцессора. Они обрабатываются платформой в момент компиляции модуля.

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

Оптимальное решение с использованием БСП (Библиотека стандартных подсистем)

Посмотрим на пример решения для современных типовых конфигураций (таких как 1С:УНФ, ERP, УТ, БП и других), построенных на базе БСП. Разработчикам не нужно самостоятельно "изобретать велосипед", так как в библиотеке уже встроены готовые механизмы определения типа клиентского приложения на сервере.

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


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    Если ВидФормы = "ФормаСписка" Тогда
        // Используем встроенную функцию БСП для проверки типа клиента
        Если ОбщегоНазначения.ЭтоВебКлиент() Тогда
            ВыбраннаяФорма = "ФормаСпискаДляВебКлиента";
            СтандартнаяОбработка = Ложь;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Рассмотрим подробнее, как это работает "под капотом". При старте приложения 1С на стороне клиента, механизмы БСП определяют, в каком приложении запущен сеанс. Затем эта информация передается на сервер и записывается в параметры сеанса текущего пользователя. Функция ОбщегоНазначения.ЭтоВебКлиент() обращается к функции СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере(), которая извлекает эти кэшированные данные. Это позволяет серверу моментально получить информацию об интерфейсе пользователя.

Решение для самописных конфигураций (без использования БСП)

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

  1. Создание параметра сеанса: Добавим в дерево конфигурации новый параметр сеанса. Назовем его, например, ЗапущенИзВебКлиента и установим ему тип Булево.
  2. Инициализация при старте: В модуле управляемого приложения (который компилируется и выполняется на клиенте) мы можем корректно использовать директивы препроцессора. Найдем процедуру ПриНачалеРаботыСистемы.
  3. Передача данных на сервер: Напишем код, который проверит тип клиента и вызовет серверную процедуру для установки параметра сеанса:

// В модуле управляемого приложения
Процедура ПриНачалеРаботыСистемы()
    #Если ВебКлиент Тогда
        УстановитьПараметрСеансаВебКлиент(Истина);
    #Иначе
        УстановитьПараметрСеансаВебКлиент(Ложь);
    #КонецЕсли
КонецПроцедуры

// В серверном общем модуле (например, ОбщийМодульСервер)
Процедура УстановитьПараметрСеансаВебКлиент(Значение) Экспорт
    ПараметрыСеанса.ЗапущенИзВебКлиента = Значение;
КонецПроцедуры

Теперь в модуле менеджера документа мы можем безопасно обращаться к параметру сеанса:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    Если ВидФормы = "ФормаСписка" И ПараметрыСеанса.ЗапущенИзВебКлиента Тогда
        ВыбраннаяФорма = "ФормаСпискаДляВебКлиента";
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
КонецПроцедуры

Почему не стоит переопределять форму на клиенте (Антипаттерн)

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


// В модуле основной формы списка (Антипаттерн!)
&НаКлиенте
Процедура ПриОткрытии(Отказ)
    #Если ВебКлиент Тогда
        Отказ = Истина; // Запрещаем открытие основной формы
        ПараметрыФормы = Новый Структура;
        ОткрытьФорму("Документ.НашДокумент.Форма.ФормаСпискаДляВебКлиента", ПараметрыФормы);
    #КонецЕсли
КонецПроцедуры

Строго не рекомендуем использовать данный подход по следующим причинам:

  1. Проблема с прямыми ссылками (Навигационные ссылки): В веб-клиенте пользователи часто делятся прямыми URL-ссылками на документы или списки. При переходе по такой ссылке платформе нужно открыть конкретное окно. Перехват через Отказ = Истина в браузере может отработать некорректно — старая форма закроется, а новая так и не откроется, оставив пользователя перед пустым экраном.
  2. Снижение производительности: Прежде чем система вызовет событие ПриОткрытии на клиенте, сервер 1С уже проделает огромную работу: получит данные из базы, сформирует дерево элементов управления формы и передаст этот объемный пакет по сети в браузер. И только после этого мы "отменяем" эту работу и заставляем сервер делать всё заново для второй формы. Это критически сказывается на скорости работы.
  3. Визуальные артефакты: При медленном интернет-соединении пользователь может на долю секунды увидеть интерфейс старой формы до того, как сработает код отмены, после чего экран моргнет и начнет загружаться нужная форма. Это сильно ухудшает пользовательский опыт (UX).

Подводя итог, мы выяснили, что наиболее надежным, производительным и правильным с точки зрения архитектуры 1С является метод подмены формы на стороне сервера через событие ОбработкаПолученияФормы с использованием механизмов проверки параметров сеанса.

← На главную