Метаданные 1с. Работа с метаданными. Получение метаданных по полному имени

Метаданные 1С – это список справочников, документов, их реквизитов и прочего, составляющего конфигурацию. Список метаданных 1С правится программистов в конфигураторе в окне конфигурации.

Из программы на языке 1С доступен список метаданных 1С и их свойства.

Это удобно, когда требуется получить список документов в конфигурации или отработать все реквизиты документа.

Рассмотрим, как работать с метаданными 1С конфигурации из языка 1С.

Метаданные 1С конфигурации

Глобальная переменная Метаданные дает доступ к метаданным 1С всей конфигурации (т.е. к «корню» конфигурации). Далее через точку можно обращаться к «коллекциям» — документы, справочники и т.п., чтобы выйти на конкретный справочник или документ, у которых соответственно есть «коллекции» реквизиты, табличные части и т.п. – все, как в конфигураторе, в дереве конфигурации.

Пример – создадим список всех документов конфигурации для того, чтобы пользователь мог выбрать нужный документ из списка:
спДокументовКонфигурации = Новый СписокЗначений(); //сюда будем сохранять список

//Метаданные - глобальная переменная, которая дает доступ ко всем метаданным 1С конфигурации
//Метаданные.Документы - коллекция документов конфигурации
Для каждого Документ из Метаданные.Документы Цикл
//Документ - это метаданные 1С документа (каждого, так как мы обходим их в цикле)
//.Имя - наименование документа так, как оно задано в конфигурации
//.Синоним - "человеческое" наименование документа, которое отображается пользователю
//список значений может хранить значение (имя документа) и "представление для пользователя" (как раз - синоним документа)
спДокументовКонфигурации.Добавить(Документ.Имя, Документ.Синоним);
КонецЦикла;

//даем возможность пользователю выбрать из списка нужный документ
элДокумент = спДокументовКонфигурации.ВыбратьЭлемент();

//если пользователь нажал "Отмена", то результатом выбора будет значение НЕОПРЕДЕЛЕНО, иначе результатом будет - выбранный элемент
Если элДокумент Неопределено Тогда
//в.Значение списка значений мы записывали имя документа "как в конфигурации"
//создадим новый документ с таким именем, напомним - к документам можно обращаться Документы.ИмяДокумента или Документы[ИмяДокумента]
обДокумент = Документы[элДокумент.Значение].СоздатьДокумент();
//ДокументОбъект.ПолучитьФорму() - возвращает форму с указанным именем, а если имя не указано - то форму "по-умолчанию"
обДокумент.ПолучитьФорму().Открыть();
КонецЕсли;

Пример – для общего журнала документов (отображающего все виды документов) создадим запрос, который вернет список всех документов:

Метаданные 1С объекта

Большинство объектов 1С, сохраняемых в базе данных (справочники, документы и т.д.) представлены ссылками и объектами (подробнее см. «Ссылки и объекты»).

У ссылок и объектов есть метод.Метаданные(), который позволяет выйти на метаданные 1С этого объекта.

Пример – проверка на наличие реквизитов с типом «Справочник.Организация» в документе и обнуление значения этих реквизитов:
//ДокументОбъект - документ, полученный на изменение или создание
//аналогичным образом можно работать со ссылками, например: ДокументСсылка = Документ.ИмяДокумента.ПустаяСсылка().Метаданные()
ДокументОбъект = Документы.ПоступлениеТоваров.СоздатьДокумент();

//цикл по реквизитам
Для каждого Реквизит из ДокументОбъект.Метаданные().Реквизиты Цикл
//у каждого реквизита может быть как один, так и несколько типов, подробнее см. "ОписаниеТипов"

//проверяем по каждому типу - тот ли это нужный нам?


//обнуляем реквизит с этим именем в документе
//для "обнуления" можно приравнивать его к Неопределено,
//по факту значение будет установлено не Неопределено, а "пустое значение" типа реквизита
//Неопределено только если у реквизита несколько типов
ДокументОбъект[Реквизит.Имя] = Неопределено;
КонецЕсли;
КонецЦикла;
КонецЦикла;

//цикл по табличным частям
Для каждого ТабЧасть из ДокументОбъект.Метаданные().ТабличныеЧасти Цикл
//в табличной части тоже реквизиты (колонки таб.части)
Для каждого Реквизит из ТабЧасть.Реквизиты Цикл
//здесь аналогично
мТипов = Реквизит.Тип.Типы();
Для каждого Тип из мТипов Цикл
Если Тип = Тип("СправочникСсылка.Организации") Тогда
//так как это таб.часть, то мы должны пройтись по всем строкам этой тач. части
Для каждого Строка из ДокументОбъект[ТабЧасть.Имя] Цикл
Строка[Реквизит.Имя] = Неопределено;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла; 

Что такое метаданные

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

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

Зачем нужна работа с метаданными

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

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

Примеры

Обход метаданных в цикле

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

Для каждого МетаданныеСправочника Из Метаданные. Справочники Цикл Сообщить(МетаданныеСправочника. Имя) ; Сообщить(МетаданныеСправочника. Синоним) ; Для каждого РеквизитСправочника Из МетаданныеСправочника. Реквизиты Цикл Сообщить(РеквизитСправочника. Имя) ; Сообщить(РеквизитСправочника. Синоним) ; КонецЦикла ; КонецЦикла ;

Получение метаданных по ссылке объекта

Зачастую возникает ситуация когда надо получить метаданные по ссылке какого-нибудь объекта. Это может быть элемент справочника, документ и т.д. И здесь нам поможет метод НайтиПоТипу() . Этот метод позволяет получить метаданные по типу объекта. Соответственно если у нас есть ссылка нам надо сначала узнать ее тип. Сделать это поможет функция ТипЗнч() . В качестве примера возьмем справочник Пользователи (т.к. он есть наверное во всех конфигурациях). Выберем из него первый попавшийся элемент и получим по нему метаданные.

Запрос = Новый Запрос; Запрос. Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | Пользователи.Ссылка |ИЗ | Справочник.Пользователи КАК Пользователи" ; Результат = Запрос. Выполнить () ; Выборка = Результат. Выбрать() ; Пока Выборка. Следующий() Цикл МетаданныеОбъекта = Метаданные. НайтиПоТипу(ТипЗнч(Выборка. Ссылка) ) ; Сообщить(МетаданныеОбъекта. Имя) ; Сообщить(МетаданныеОбъекта. Синоним) ; КонецЦикла ;

Получение метаданных по полному имени

Cуществует еще один метод, который позволяет получить метаданные по полному имени объекта. Речь идет о методе НайтиПоПолномуИмени() . Если взять тот же справочник Пользователи , то его полное имя выглядить как Справочник.Пользователи . Соответственно код для получения метаданных справочника Пользователи по полному имени выглядит вот так

МетаданныеПользователи = Метаданные. НайтиПоПолномуИмени("Справочник.Пользователи" ) ;

Если выбирать между получением метаданных по ссылке и по полному имени, то мне больше по душе метод НайтиПоТипу() .

Конечно Имя и Синоним , в примерах выше — это лишь малая часть информации, которую можно извлечь из метаданных. Но тут как говориться в помощь.

В документации не приводится полный перечень возможных значений атрибутов. Полный перечень атрибутов метаданных можно получить, сформировав в конфигураторе текстовый файл "Описание метаданных". Установленные значения атрибутов можно также узнать из текстового описания структуры метаданных.

Атрибуты, являющиеся по сути признаками с двумя возможными значениями имеют числовой тип и принимают значения 0 или 1. Атрибуты, которые могут иметь несколько возможных значений, выдают строку, отражающую установленный вариант. Атрибуты, отражающие свойство метаданных, выбираемое как ссылка на другой объект метаданных (например, журнал документа) имеют тип "Метаданные".

Пример :

ВыбМетодУдаления=Метаданные.НепосредственноеУдалениеОбъектов;

У объекта "Метаданные" могут существовать методы для доступа к массивам подчиненных метаданных. Например, для глобального атрибута "Метаданные" для обращения к документам используется метод "Документ".

В качестве параметра методов для доступа к массивам подчиненных метаданных передается:

  • число - выдает объект метаданных по указанному номеру;
  • строка - выдает объект метаданных по указанному идентификатору;
  • параметр не указан - выдает количество подчиненных объектов этого типа.

Пример получения списка документов конфигурации:

Для Инд = 1 По Метаданные.Документ() Цикл Сообщить(Метаданные.Документ(Инд).Идентификатор); КснецЦикла;

У объекта типа "Метаданные" могут существовать атрибуты, содержащие массив ссылок на объекты метаданных, к ним применяются методы Количество() и Получить(Ном) для перебора ссылок. Например, для граф отбора таким атрибутом является атрибут "Ссылки", позволяющий получить объекты метаданных включенные в данную графу отбора (реквизиты документов и др.).

Пример :

Для Инд = 1 До Метаданные.ГрафаОтбора(Идент).Ссылки.Количество() Цикл Сообщить(Метаданные.ГрафаОтбора(Идент). Ссылки.Получить(Инд).ПолныйИдентификатор()); КонецЦикла;

Не так давно пришлось приводить конфигурацию заказчика в соответствие с законом «О защите персональных данных», который гласит, что при отказе клиенту в одобрении заявки все личные данные о нем должны удаляться из информационной системы обработки персональных данных, которой является 1С. Реквизитов и таблиц с личными данными было достаточно много, поэтому вручную прописывать очистку было нецелесообразно. А удалять сам элемент справочника было нельзя, потому что к нему был привязан документ рассмотрения заявки, и удаление нарушило бы логическую целостность информационной базы.

Поэтому необходим был механизм, который позволил бы получить полный список реквизитов и табличных частей. Для этого у объектов 1С существует встроенная функция Метаданные().

Эта функция возвращает значение особого типа — ОбъектМетаданных. В нем содержатся практически все свойства объекта. Например для элемента справочника это будут: длина наименования и кода, автонумерация, основные формы, вообще все существующие формы, представление объекта, иерархичность, макеты и многое другое.

В нашем случае потребуются Реквизиты и Табличные части. Эти компоненты метаданных содержат значение КоллекцияОбъектовМетаданных , которую можно обойти в цикле Для каждого .

У каждого из элементов коллекции тоже много свойств, в частности есть очень полезное свойство Тип , через которое можно получить тип того или иного реквизита. Полный список свойств можно узнать, например, в режиме отладки через команду Вычислить выражение . Мне же для обращения к реквизиту или табличной части потребуется свойство Имя.

В итоге модуль, очищающий реквизиты и табличные части, выглядит так:


Для Каждого Реквизит Из Контрагент. Метаданные() . Реквизиты Цикл
Контрагент[ Реквизит. Имя] = Неопределено ;
КонецЦикла ;

Для Каждого ТаблЧасть Из Контрагент. Метаданные() . ТабличныеЧасти Цикл
Контрагент[ ТаблЧасть. Имя] . Очистить() ;
КонецЦикла ;

Контрагент. Записать() ;

Функция Метаданные() применяется как для самого объекта, так и для ссылки на него. В нашем случае необходимо было изменить значения реквизитов, поэтому объект нужно было получить. Данная функция работает не только для справочников, но и для других объектов конфигурации 1С, но состав свойств будет иным.

Приведенный в заметке пример — это только один из многочисленных способов применения функции Метаданные() . Другие варианты и проблемы с использованием метаданных готов обсудить в комментариях.