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