Как через метаданные определить, подчинён ли регистр регистратору в 1С?

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

При разработке универсальных механизмов, обработок переноса данных или процедур группового перепроведения документов часто возникает задача программно выяснить: связан ли конкретный регистр с документом-регистратором или же он может записываться независимо. Разберем особенности платформы 1С:Предприятие при работе с метаданными регистров, типичные ошибки разработчиков и несколько корректных способов решения этой задачи.

Архитектурные особенности регистров в платформе 1С

Прежде чем приступать к написанию программного кода, проанализируем структуру регистров платформы 1С:Предприятие:

  1. Регистры накопления, Регистры бухгалтерии, Регистры расчета всегда жестко подчинены регистратору. В платформе они не могут существовать в независимом режиме. Попытка обратиться к свойству РежимЗаписи у таких регистров вызовет исключение «Поле агрегатного объекта не обнаружено».
  2. Регистры сведений могут быть как подчиненными регистратору, так и независимыми. Именно у них присутствует свойство метаданных РежимЗаписи.

Таким образом, если перед нами регистр накопления, бухгалтерии или расчета — он гарантированно подчинен регистратору. Основная задача проверки сводится к анализу регистров сведений либо к созданию универсального алгоритма для произвольного объекта метаданных.

Способ 1. Проверка режима записи регистра сведений

Рассмотрим самый распространенный случай, когда мы работаем с объектом метаданных регистра сведений. Обратите внимание на важную тонкость: системное перечисление РежимЗаписиРегистра недоступно напрямую в глобальном контексте платформы. Обращение к его значениям должно выполняться строго через ветку Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.

Посмотрим на пример правильной проверки:


Если Метаданное.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
    // Регистр сведений подчинен регистратору
    Подчинен = Истина;
Иначе
    // Регистр сведений является независимым
    Подчинен = Ложь;
КонецЕсли;

Чтобы избежать ошибок при анализе имени метаданного через строковые функции (например, через Лев() или ПолноеИмя()), правильнее использовать проверку на принадлежность к коллекции метаданных с помощью метода Содержит():


Если Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда
    Если ОбъектМетаданных.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
        // Обработка подчиненного регистра сведений
    КонецЕсли;
КонецЕсли;

Способ 2. Универсальная проверка для любого объекта метаданных

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


Функция РегистрПодчиненРегистратору(ОбъектМетаданных) Экспорт

    Если Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных)
       Или Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных)
       Или Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных) Тогда
        Возврат Истина;
    ИначеЕсли Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда
        Возврат ОбъектМетаданных.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору;
    КонецЕсли;

    Возврат Ложь;

КонецФункции

Этот метод безопасен, так как проверяет тип объекта метаданных перед обращением к специфическим свойствам и исключает возникновение непредвиденных ошибок времени выполнения.

Способ 3. Анализ стандартных реквизитов регистра

Часто программисты пытаются проверить подчиненность через коллекцию СтандартныеРеквизиты, обращаясь напрямую: ОбъектМетаданных.СтандартныеРеквизиты.Регистратор. Разберем, почему этот подход требует осторожности.

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


ПодчиненРегистратору = Ложь;

Для Каждого СтандартныйРеквизит Из ОбъектМетаданных.СтандартныеРеквизиты Цикл
    Если СтандартныйРеквизит.Имя = "Регистратор" Тогда
        ПодчиненРегистратору = Истина;
        Прервать;
    КонецЕсли;
КонецЦикла;

Если в коллекции стандартных реквизитов присутствует реквизит Регистратор, значит, данный объект метаданных гарантированно подчинен регистратору.

Как быстро определить список допустимых регистраторов

Если установлено, что регистр подчинен регистратору, следующей задачей обычно становится выяснение списка документов, которые могут делать в него записи. Чтобы не перебирать все документы конфигурации и их коллекции Движения, достаточно получить типы документов напрямую из реквизита Регистратор:


Если РегистрПодчиненРегистратору(ОбъектМетаданных) Тогда
    МассивТиповРегистратора = ОбъектМетаданных.СтандартныеРеквизиты.Регистратор.Тип.Типы();
    
    Для Каждого ТекущийТип Из МассивТиповРегистратора Цикл
        МетаданныеДокумента = Метаданные.НайтиПоТипу(ТекущийТип);
        Если МетаданныеДокумента <> Неопределено Тогда
            // Получили объект метаданных документа-регистратора
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

Такой подход работает быстрее полного перебора дерева конфигурации и обеспечивает надежный результат при работе с любыми прикладными решениями.

← На главную