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

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

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

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

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

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

Посмотрим на пример заполнения списка выбора на форме для регистра накопления ТоварыНаСкладах:


СписокВыбора = Элементы.ВидДокументаОтбор.СписокВыбора;
СписокВыбора.Очистить();

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

Способ 2. Получение массива типов через стандартные реквизиты метаданных

Проанализируем альтернативный подход через описание стандартного реквизита Регистратор. Метод Типы() объекта ОписаниеТипов возвращает массив всех типов, входящих в составной тип реквизита.

Разберем пример получения массива типов и их преобразования в человекопонятные синонимы с помощью метода Метаданные.НайтиПоТипу():


МассивТипов = Метаданные.РегистрыНакопления.ТоварыНаСкладах.СтандартныеРеквизиты["Регистратор"].Тип.Типы();

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

Способ 3. Получение доступных типов через отбор Набора записей

Выясним, как получить типы регистраторов через объектные сущности прикладного объекта. Если создать экземпляр набора записей регистра, его коллекция отборов уже содержит настроенное описание типов для поля Регистратор:


НаборЗаписей = РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей();
МассивТипов = НаборЗаписей.Отбор.Регистратор.Тип.Типы();

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

Способ 4. Получение только фактически присутствующих типов через запрос

Методы чтения метаданных возвращают полный перечень всех документов, потенциально способных формировать движения. Если в отчете требуется предоставить пользователю выбор только из тех видов документов, которые реально присутствуют в базе данных в текущий момент, используем запрос с функцией ТИПЗНАЧЕНИЯ:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	ТИПЗНАЧЕНИЯ(ТоварыНаСкладах.Регистратор) КАК ТипРегистратора
    |ИЗ
    |	РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах";

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

СписокФактическихТипов = Новый СписокЗначений;
Пока Выборка.Следующий() Цикл
    Если Выборка.ТипРегистратора <> Неопределено Тогда
        ОбъектМетаданных = Метаданные.НайтиПоТипу(Выборка.ТипРегистратора);
        Если ОбъектМетаданных <> Неопределено Тогда
            СписокФактическихТипов.Добавить(Выборка.ТипРегистратора, ОбъектМетаданных.Синоним);
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Если требуется категоризировать регистраторы непосредственно внутри текста запроса по числовым кодам или текстовым группам, применим конструкцию ССЫЛКА:


ВЫБРАТЬ
	ТоварыНаСкладах.Период КАК Период,
	ТоварыНаСкладах.Регистратор КАК Регистратор,
	ВЫБОР
		КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.ПриходнаяНакладная ТОГДА 1
		КОГДА ТоварыНаСкладах.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг ТОГДА 2
		ИНАЧЕ 0
	КОНЕЦ КАК КодВидаРегистратора
ИЗ
	РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

Способ 5. Использование возможностей Системы компоновки данных (СКД)

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

  1. В схеме компоновки данных переходим на закладку Настройки.
  2. В окне Отбор добавляем новое поле отбора Регистратор.
  3. В качестве вида сравнения выбираем Тип (или В списке типов).
  4. В правой колонке платформа автоматически предоставит диалоговое окно со списком всех допустимых видов документов для данного регистра.

Важные ограничения и особенности работы

  1. Особенности регистров сведений: Свойство Регистраторы и стандартный реквизит Регистратор существуют у регистра сведений только тогда, когда свойство РежимЗаписи установлено в значение РежимЗаписиРегистра.ПодчинениеРегистратору. Для независимых регистров обращение к этим свойствам вызовет ошибку времени выполнения.
  2. Производительность СУБД: Поле Регистратор имеет составной тип. Выполнение запросов с условиями по полям регистратора без явного ограничения типа приводит к тому, что СУБД генерирует множественные соединения (LEFT JOIN) со всеми таблицами возможных документов. Для оптимизации запросов к большим таблицам движений рекомендуется ограничивать тип через оператор ССЫЛКА или функцию ВЫРАЗИТЬ(Таблица.Регистратор КАК Документ.ИмяДокумента).
  3. Ограничения прав доступа (RLS): Получение списка через метаданные возвращает структуру конфигурации независимо от прав текущего пользователя. Однако при попытке чтения самих записей через запрос будут применены ограничения RLS, что может исключить документы определенных видов из итоговой выборки.
← На главную