При эксплуатации информационных баз 1С:Предприятия 8.3 иногда возникает плавающая ошибка: у части пользователей при определенных действиях система сообщает о том, что имя общего модуля не определено, либо процедура не найдена. При этом очистка локального кэша пользователя и серверного кэша метаданных не решает проблему, а ошибка продолжает воспроизводиться спонтанно. Разберем подробно механику возникновения этой ошибки, выясним причину такого поведения платформы и рассмотрим практические способы ее полного устранения.
Проанализируем архитектурную особенность работы платформы в режиме управляемого приложения. В режиме Тонкий клиент архитектура строго разделена: клиентская часть не компилирует и не исполняет код модулей менеджеров, объектов или наборов записей. Любое обращение к серверным данным или логике менеджера перенаправляется на сервер 1С:Предприятия, где все чисто серверные общие модули гарантированно доступны.
Ситуация кардинально меняется, если сеанс запускается в режиме Толстый клиент (управляемое приложение). В этом случае на стороне рабочей станции запускается полноценная среда исполнения встроенного языка 1С. Платформа при определенных сценариях выполняет компиляцию модуля менеджера целиком на стороне клиента. К таким сценариям относятся неявные клиентские вызовы, например:
ОбработкаПолученияПредставления или ОбработкаПолученияПолейПредставления.ОбработкаПолученияДанныхВыбора.Когда толстый клиент начинает компилировать модуль менеджера, он анализирует все содержащиеся в нем процедуры, функции и внешние вызовы. Если модуль менеджера содержит код печати или экспортируемые методы, обращающиеся к общему модулю, у которого в свойствах отключен флаг Клиент (управляемое приложение) (например, чисто серверный модуль формирования печатных форм), синтаксический анализатор толстого клиента завершает работу аварийно: переменная или модуль признаются неопределенными.
Выясним причину, почему ошибка воспроизводится «через раз» и не у всех сотрудников:
Рассмотрим основной способ исправления ошибки на уровне программного кода конфигурации или расширения. Нам необходимо явно указать компилятору толстого клиента, что код формирования печатных форм и вызовы серверных процедур не должны обрабатываться на клиенте.
Посмотрим на пример правильного оформления кода в модуле менеджера объекта. Весь функционал печати и логику, работающую с сервером баз данных, оборачиваем в инструкции препроцессора:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
Процедура СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати) Экспорт
// Вызов чисто серверного общего модуля формирования печатных форм
ФормированиеПечатныхФорм.ПечатьНакладной(МассивОбъектов, ОбъектыПечати);
КонецПроцедуры
#КонецЕсли
При такой структуре кода платформа в режиме толстого клиента управляемого приложения исключит данные строки из синтаксического анализа на стороне клиентской машины, и модуль менеджера будет скомпилирован без исключений.
Если в модуле менеджера переопределены методы формирования представлений, обратим внимание на правила работы с ними. Эти методы обязаны быть легковесными и доступными во всех контекстах выполнения.
Проанализируем реализацию обработчика получения представления:
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
// В данном обработчике запрещено вызывать чисто серверные процедуры формирования форм
СтандартнаяОбработка = Истина;
КонецПроцедуры
Если внутри обработчиков представлений требуется вызывать вспомогательные методы, их необходимо размещать исключительно в общих модулях с установленными признаками Сервер, Клиент (управляемое приложение) и обязательным свойством Вызов сервера, либо в модулях с флагом Клиент, сервер.
Разберем по шагам, как решить проблему системно без внесения изменений в метаданные конфигурации, если редактирование модулей временно заблокировано регламентом сопровождения.
Администрирование -> Пользователи. В карточке проблемного пользователя откроем вкладку «Прочие» и в поле «Режим запуска» вместо значения «Авто» или «Толстый клиент» установим значение Тонкий клиент./RunModeManagedRunMode.Перевод всех рабочих мест на использование тонкого клиента является рекомендуемым архитектурным стандартом для любых управляемых конфигураций: это полностью исключает компиляцию серверных модулей на клиенте и стабилизирует потребление оперативной памяти.