Почему в коллекции метаданных справочника может отсутствовать стандартный реквизит ИмяПредопределенныхДанных и как это исправить

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При обновлении типовых конфигураций (например, Бухгалтерия предприятия КОРП) или при работе с кастомными расширениями программисты 1С иногда сталкиваются с парадоксальной ситуацией: программный код, обращающийся к стандартным реквизитам справочника, выдает ошибку. При детальном анализе выясняется, что в коллекции СтандартныеРеквизиты отсутствует реквизит ИмяПредопределенныхДанных, хотя он должен там присутствовать по умолчанию для любого справочника. Рассмотрим причины этого явления и способы решения проблемы.

Анализ проблемы и диагностика

Типичная ситуация начинается с того, что при выполнении процедур обновления информационной базы (обработчики обновления БСП) система аварийно завершает работу. Ошибка возникает в коде, который перебирает состав метаданных. Проанализируем пример кода, который позволяет выявить проблему:


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

Если в результате выполнения этого кода в списке имен не оказывается ИмяПредопределенныхДанных, значит, мы столкнулись с нарушением целостности описания метаданных. При этом физически в таблице базы данных соответствующая колонка может существовать, но программный интерфейс платформы (объектная модель метаданных) о ней "не знает".

Выясним причины возникновения ошибки

Прежде чем переходить к лечению, разберем, почему это происходит. Проанализируем несколько технических факторов:

  1. Свойство «Обновление предопределенных данных». В некоторых случаях, если у справочника установлено значение «Не обновлять» (PredefinedDataUpdate), платформа может исключать реквизит ИмяПредопределенныхДанных из коллекции доступных через метаданные, так как управление ими отключено на уровне конфигурации.
  2. Повреждение кэша метаданных или таблицы Config. При динамическом обновлении или некорректном объединении конфигураций (особенно при использовании сторонних модулей от франчайзи) запись в системной таблице DBSchema может рассинхронизироваться с реальной структурой объектов. Платформа "теряет" описание части системных полей.
  3. Влияние расширений. Если справочник заимствован в расширение с другим режимом совместимости, состав его стандартных реквизитов может отображаться некорректно при программном обходе.
  4. Способ получения метаданных. Существует разница между получением метаданных через ПустаяСсылка().Метаданные() и прямым обращением Метаданные.Справочники.ИмяСправочника. В условиях сбоя кэша эти методы могут возвращать разные наборы реквизитов.

Способ 1: Принудительная реструктуризация (Рекомендуемый метод)

Как показывает практика, наиболее эффективным способом "вернуть" пропавший реквизит является замена описания объекта в базе данных, что заставляет платформу полностью пересобрать описание стандартных реквизитов. Рассмотрим алгоритм действий, который часто называют "танцем с бубном", но который имеет под собой четкое техническое обоснование:

  1. Откройте конфигуратор и найдите проблемный справочник.
  2. Выберите любой существующий обычный (не стандартный) реквизит этого справочника и временно измените его имя (например, добавьте единицу в конце).
  3. Нажмите "Обновить конфигурацию базы данных" (F7). На этом этапе 1С пометит объект как измененный, но реструктуризация таблицы может не произойти, если изменений мало.
  4. Верните имя реквизита обратно в исходное состояние.
  5. Снова запустите обновление конфигурации базы данных.
  6. Если это не помогло, выполните более "тяжелую" операцию: измените тип какого-нибудь реквизита (сохранив совместимость) или добавьте новый временный реквизит, обновитесь, а затем удалите его. Это гарантированно вызовет реструктуризацию таблицы в SQL-базе или файловом варианте.

Почему это работает? В процессе реструктуризации платформа 1С заново формирует записи в таблицах метаданных и актуализирует состав стандартных полей объекта в соответствии с текущей версией платформы.

Способ 2: Программный обход ошибки при обновлении

Если ошибка мешает обновлению типовой конфигурации, и вы не можете оперативно менять структуру объектов (например, в облачном сервисе или при жестких регламентах), можно прибегнуть к созданию расширения-патча. Разберем, как это сделать программно.

Вместо прямого перебора коллекции СтандартныеРеквизиты, следует использовать безопасный поиск или конструкцию Попытка...Исключение. Рассмотрим пример правильной проверки:


// Вместо:
// Для Каждого Реквизит Из Метаданные.СтандартныеРеквизиты ...

// Используем безопасный поиск:
РеквизитИмяПредопределенных = Справочники.Валюты.Метаданные().СтандартныеРеквизиты.Найти("ИмяПредопределенныхДанных");
Если РеквизитИмяПредопределенных = Неопределено Тогда
    // Реквизит не найден в коллекции, пробуем обращение напрямую
    Попытка
        ТестовоеЗначение = Справочники.Валюты.ПустаяСсылка().ИмяПредопределенныхДанных;
        Сообщить("Реквизит доступен напрямую, несмотря на отсутствие в метаданных");
    Исключение
        Сообщить("Реквизит действительно отсутствует");
    КонецПопытки;
КонецЕсли;

Способ 3: Очистка серверного кэша

Иногда проблема кроется исключительно в памяти процессов сервера 1С (rphost). Если реструктуризация кажется слишком радикальным методом, попробуйте выполнить следующие шаги:

  1. Остановите службу сервера 1С:Предприятие.
  2. Удалите содержимое папок кэша (папки snccntx и другие временные файлы в каталоге пользователя, под которым запускается сервер).
  3. Запустите службу сервера.
  4. Повторите попытку обновления или проверки метаданных.

Резюме

Мы проанализировали ситуацию, когда стандартный реквизит ИмяПредопределенныхДанных "исчезает" из поля зрения платформы. Основная причина — некорректное состояние кэша метаданных или таблицы схемы базы данных. Самым быстрым и надежным решением является принудительная реструктуризация объекта через кратковременное изменение состава его реквизитов в конфигураторе. Для предотвращения падения типовых механизмов обновления в будущем, рекомендуется использовать защитный код с обработкой исключений при обращении к свойствам метаданных.

← На главную