При разработке и сопровождении конфигураций 1С можно столкнуться с ситуацией, когда при выполнении стандартного действия (например, открытии структуры подчиненности документа) платформа аварийно завершает работу с сообщением об ошибке вида:
{ОбщийМодуль.ОбщегоНазначения(4574,8)}: Процедура или функция с указанным именем не определена (ПолучитьSIDСтудента)
При этом возникают сопутствующие странности: в коде вызываемого действия эта функция явно не фигурирует, режим «Остановка по ошибке» не срабатывает, а установленные точки останова просто игнорируются. Разберем по шагам, почему возникает такое поведение платформы и как правильно устранить проблему.
Проанализируем механику работы платформы 1С:Предприятие в клиент-серверном режиме. Ошибка «Процедура или функция с указанным именем не определена» является ошибкой стадии компиляции, а не исключением времени выполнения (runtime exception).
#Если Клиент Тогда, то при сборке серверного контекста модуль парсится без этого блока. Любой вызов данной функции из кода, выполняющегося на сервере (или из процедуры того же модуля без аналогичной директивы), приводит к ошибке компиляции.Посмотрим на пример ошибочного кода в общем модуле:
#Если Клиент Тогда
Функция ПолучитьSIDСтудента(Студент) Экспорт
// Клиентская логика получения идентификатора
Возврат Идентификатор;
КонецФункции
#КонецЕсли
Процедура ОбработатьДанныеСтудента(Студент) Экспорт
// Данная процедура доступна и на сервере, и на клиенте
SID = ПолучитьSIDСтудента(Студент); // На сервере этой функции не существует!
КонецПроцедуры
При открытии структуры подчиненности происходит серверный вызов (например, функции проверки прав или чтения связанных документов через ПолныеПрава.ПолучитьСписокПодчиненныхДокументов). Сервер обращается к общему модулю, пытается его скомпилировать, не находит объявленную функцию в серверном контексте и выбрасывает исключение компиляции.
Выясним причину изоляции метода. Если функция не содержит контекстно-зависимого клиентского кода (работы с интерфейсом, COM-объектами операционной системы пользователя и т.д.) и должна быть доступна на сервере, снимем ограничение препроцессора.
#Если Клиент Тогда, #Если Сервер Тогда, #Если ТолстыйКлиентОбычноеПриложениеТогда.
// Корректное объявление без блокировки серверного контекста:
Функция ПолучитьSIDСтудента(Студент) Экспорт
// Логика функции, доступная во всех разрешенных свойствами модуля контекстах
Возврат Студент.УникальныйИдентификатор();
КонецФункции
Чтобы не сталкиваться с невидимыми ошибками во время работы пользователей, используем штатный механизм превентивной проверки метаданных:
Тонкий клиент, Толстый клиент (обычное приложение), Толстый клиент (управляемое приложение), Сервер, Внешнее соединение.Данный инструмент принудительно скомпилирует все модули конфигурации во всех доступных контекстах и выведет полный список скрытых несовместимостей с точным указанием строк.
Для предотвращения подобных коллизий в дорабатываемых конфигурациях рекомендуется отказаться от смешивания разнородного кода с помощью директив препроцессора внутри одного модуля. Разделим функционал по специализированным модулям:
КлиентСервер: имеют флаги «Клиент» и «Сервер», содержат только универсальные алгоритмы без обращений к базе данных или элементам интерфейса.Сервер или СерверПовтИсп: содержат логику работы с базой данных и метаданными, выполняются только на стороне сервера.Клиент: содержат пользовательские интерфейсные обработчики и вызовы интерактивных диалогов.Также важно помнить, что очистка локального кэша пользователя в каталогах AppData\Local\1C и AppData\Roaming\1C не устраняет проблемы серверной компиляции. При внесении масштабных изменений в общие модули в клиент-серверном режиме всегда выполняйте полное обновление конфигурации базы данных без использования динамического обновления («демонского обновления»), чтобы исключить рассинхронизацию серверного кэша метаданных.