При обновлении типовых конфигураций (например, Бухгалтерия предприятия КОРП) или при работе с кастомными расширениями программисты 1С иногда сталкиваются с парадоксальной ситуацией: программный код, обращающийся к стандартным реквизитам справочника, выдает ошибку. При детальном анализе выясняется, что в коллекции СтандартныеРеквизиты отсутствует реквизит ИмяПредопределенныхДанных, хотя он должен там присутствовать по умолчанию для любого справочника. Рассмотрим причины этого явления и способы решения проблемы.
Типичная ситуация начинается с того, что при выполнении процедур обновления информационной базы (обработчики обновления БСП) система аварийно завершает работу. Ошибка возникает в коде, который перебирает состав метаданных. Проанализируем пример кода, который позволяет выявить проблему:
ОбъектСсылка = Справочники.Валюты.ПустаяСсылка();
Для Каждого ТекРеквизит Из ОбъектСсылка.Метаданные().СтандартныеРеквизиты Цикл
ИмяРеквизита = ТекРеквизит.Имя;
Попытка
ЗначениеРеквизита = ОбъектСсылка[ИмяРеквизита];
Сообщить(СтрШаблон("Реквизит: %1 найден", ИмяРеквизита));
Исключение
Сообщить(СтрШаблон("Ошибка обращения к реквизиту: %1", ИмяРеквизита));
КонецПопытки;
КонецЦикла;
Если в результате выполнения этого кода в списке имен не оказывается ИмяПредопределенныхДанных, значит, мы столкнулись с нарушением целостности описания метаданных. При этом физически в таблице базы данных соответствующая колонка может существовать, но программный интерфейс платформы (объектная модель метаданных) о ней "не знает".
Прежде чем переходить к лечению, разберем, почему это происходит. Проанализируем несколько технических факторов:
ИмяПредопределенныхДанных из коллекции доступных через метаданные, так как управление ими отключено на уровне конфигурации.DBSchema может рассинхронизироваться с реальной структурой объектов. Платформа "теряет" описание части системных полей.ПустаяСсылка().Метаданные() и прямым обращением Метаданные.Справочники.ИмяСправочника. В условиях сбоя кэша эти методы могут возвращать разные наборы реквизитов.Как показывает практика, наиболее эффективным способом "вернуть" пропавший реквизит является замена описания объекта в базе данных, что заставляет платформу полностью пересобрать описание стандартных реквизитов. Рассмотрим алгоритм действий, который часто называют "танцем с бубном", но который имеет под собой четкое техническое обоснование:
Почему это работает? В процессе реструктуризации платформа 1С заново формирует записи в таблицах метаданных и актуализирует состав стандартных полей объекта в соответствии с текущей версией платформы.
Если ошибка мешает обновлению типовой конфигурации, и вы не можете оперативно менять структуру объектов (например, в облачном сервисе или при жестких регламентах), можно прибегнуть к созданию расширения-патча. Разберем, как это сделать программно.
Вместо прямого перебора коллекции СтандартныеРеквизиты, следует использовать безопасный поиск или конструкцию Попытка...Исключение. Рассмотрим пример правильной проверки:
// Вместо:
// Для Каждого Реквизит Из Метаданные.СтандартныеРеквизиты ...
// Используем безопасный поиск:
РеквизитИмяПредопределенных = Справочники.Валюты.Метаданные().СтандартныеРеквизиты.Найти("ИмяПредопределенныхДанных");
Если РеквизитИмяПредопределенных = Неопределено Тогда
// Реквизит не найден в коллекции, пробуем обращение напрямую
Попытка
ТестовоеЗначение = Справочники.Валюты.ПустаяСсылка().ИмяПредопределенныхДанных;
Сообщить("Реквизит доступен напрямую, несмотря на отсутствие в метаданных");
Исключение
Сообщить("Реквизит действительно отсутствует");
КонецПопытки;
КонецЕсли;
Иногда проблема кроется исключительно в памяти процессов сервера 1С (rphost). Если реструктуризация кажется слишком радикальным методом, попробуйте выполнить следующие шаги:
snccntx и другие временные файлы в каталоге пользователя, под которым запускается сервер).Мы проанализировали ситуацию, когда стандартный реквизит ИмяПредопределенныхДанных "исчезает" из поля зрения платформы. Основная причина — некорректное состояние кэша метаданных или таблицы схемы базы данных. Самым быстрым и надежным решением является принудительная реструктуризация объекта через кратковременное изменение состава его реквизитов в конфигураторе. Для предотвращения падения типовых механизмов обновления в будущем, рекомендуется использовать защитный код с обработкой исключений при обращении к свойствам метаданных.