Статья
Версия для печати
Обсудить на форуме
Метаданные и работа с ними


 Что такое объект Метаданные и зачем он может пригодиться?
 Объект Метаданные предназначен для доступа к объектам конфигурации, объявленным при ее создании (т.е. в Конфигураторе). Одна из задач, где широко используется метаданные - универсальные обработки, где заранее не известно, с какими видами объектов придется работать. Другая, не менее часто возникающая задача, - универсальная обработка атрибутов похожих но, тем не менее, различных видов объектов (например - одинаковая обработка табличных частей документов, в одном из которых есть "лишнее" поле).
 К каким объектам мы можем доступиться, используя Метаданные?
 Практически ко всем, объявленным в Конфигураторе: Константа, Справочник, Документ, Журнал, ПланСчетов и т.д.
 Синтаксис использования объекта следующий:

Код:
Кво = Метаданные.Объект(); // получение количества элементов
МетаОб = Метаданные.Объект(Номер | Идентификатор); // объект метаданных
КвоРекв = МетаОб.Реквизит(); // количество реквизитов
// хотя в некоторых случаях может быть и такой синтаксис:
КвоРекв = МетаОб.Реквизит.Количество; // количество реквизитов
МетаРекв = МетаОб.Реквизит(Номер | Идентификатор); // реквизит объекта
// или для второго случая:
МетаРекв = МетаОб.Реквизит.Получить(Номер); // реквизит объекта

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

Код:
Если Метаданные.Объект(Идентификатор).Выбран()=1 Тогда ... // Объект существует
Если МетаОб.Реквизит(Идентификатор).Выбран()=1 Тогда ... // Реквизит существует

 Объекты метаданных имеют атрибуты, позволяющие определить подробные их характеристики. К таким атрибутам относятся стандартные (Идентификатор, Тип, Вид, Длина, Точность, ...) или специфические для конкретных объектов (ДлинаКода, ДлинаНаименования, ТипНомера, ...).
 Приведем простой пример получения списка всех справочников:

Код:
Функция СписокДокументов()
Сп=СоздатьОбъект("СписокЗначений");
Для И1=1 По Метаданные.Справочник() Цикл
МетаСпр=Метаданные.Справочник(И1);
Сп.Установить(МетаСпр.Синоним, МетаСпр);
КонецЦикла;
Возврат Сп;
КонецФункции

 Если я еще не убедил вас в полезности этого объекта - посмотрите, насколько широко он используется в стандартных конфигурациях (только "для Украины"? Или во всех? не знаю...). Это и "Обработка документов", и функции глЕстьРеквизитШапки, глЕстьРеквизитТабличнойЧасти и другие фичи.
 Напоследок рассмотрим более интересный (с практической точки зрения) пример: создание из существующего документа нового, возможно - другого вида.

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

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

Д.УстановитьАтрибут(ИдРекв, ИсхДок.ПолучитьАтрибут(ИдРекв));
КонецЦикла;

// Копируем реквизиты шапки. Несопоставленные - пропускаем
Для И1=1 По МетаДок.РеквизитШапки() Цикл
ИдРекв=МетаДок.РеквизитШапки(И1).Идентификатор;
ИдИсх=Сп.Получить(ИдРекв);
Если ПустоеЗначение(ИдИсх)=1 Тогда Продолжить; КонецЕсли;

Д.УстановитьАтрибут(ИдРекв, ИсхДок.ПолучитьАтрибут(ИдИсх));
КонецЦикла;

// Построчно копируем реквизиты табличной части.
// Как и для реквизитов шапки несопоставленные - пропускаем
ИсхДок.ВыбратьСтроки();
Пока ИсхДок.ПолучитьСтроку()=1 Цикл
Д.НоваяСтрока();
Для И1=1 По МетаДок.РеквизитТабличнойЧасти() Цикл
ИдРекв=МетаДок.РеквизитТабличнойЧасти(И1).Идентификатор;
ИдИсх=Сп.Получить(ИдРекв);
Если ПустоеЗначение(ИдИсх)=1 Тогда Продолжить; КонецЕсли;

Д.УстановитьАтрибут(ИдРекв, ИсхДок.ПолучитьАтрибут(ИдИсх));
КонецЦикла;
КонецЦикла;

// Документ скопирован. Запишем и покажем
Д.Записать();
Конт="";
ОткрытьФорму(Д.ТекущийДокумент(), Конт, );
КонецПроцедуры

 P.S.: Документацию в формате ALS (формат справки 1С) по метаданным можно найти на сайтах, посвященным 1С программированию, например в Клубе профессионалов 1С. Или воспользоваться поиском на yandex.ru.

 P.P.S.: Обработку, выполняющую копирование документов можно взять здесь.

 --

 Kivals
Версия для печати
Обсудить на форуме