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