Итак начнем Вначале краткий ликбез по тому как храняться описания метаданных 1С. Все описания метаданных базы данных
хранятся в таблице Config, изменения внесенные в конфигурацию
конфигуратором (изменения можно вносить также с помощью Enterprise
Integrator) сохраняются в таблице ConfigSave. После обновления
конфигурации записи из таблицы ConfigSave заменяют записи из таблицы
Config. Структура обоих этих таблиц одинакова. В качестве ключа представлено поле FileName в этом поле храниться уникальный идентификатор объекта метаданных ( в данном случае это это может быть как какой-то прикладной объект, так и некоторые свойства этого объекта, такие как Макеты и Формы). Подробнее.. Нас в данном случае будут интересовать записи таблицы Config, в которых описаны реквизиты, табличные части и прочие свойства метаданных. В форме объектов конфигурации данные записи будут иметь имя «Метаданные» и будут подчинены непосредственно объекту конфигурации (описание метаданные существуют также для форм но кроме названия и версий форм они содержат мало интересного). В версии 8.0 все записи с именем «Метаданные»(описание метаданных), всех!! объектов метаданных были объединены в одну (metadata)-эта запись была самой большой в конфигурации, что и затрудняло ее редактирование. ЦелиДля изменения метаданных объекта конфигурации достаточно:
Посмотрим, что же содержит в себе запись описания метаданных. Структура запись похожа на Xml файл где вместо разделителей <> разделители {} Элементы, содержавшие набор однотипных объектов содержат флаговый идентификатор(45е46cbc-3…… или любой другой), после которого перечислено количество объектов в элементе (22). На рисунке изображен один из 22, элемент набора записей, который характеризует реквизиты объектов метаданных. Этот блок текста представляет собой внутренне значение реквизита метаданных. (Жаль что объекты метаданных не сериализуются, в противном случае вероятно данный блок текста можно было бы, получить используя следующую конструкцию ЗначениеВСтрокуВнутр(Метаданные.Документы.АВСКлассификация.Реквизиты.Комментарий)) . Изменяя состав элементов содержащихся в блоке, мы меняем состав реквизитов метаданных или их свойства в том случае если меняем значения элементов блока. Общий подходПоле того, как мы определились с целями, поговорим о текущей реализации. Не так сложно получить (прочитать внутреннее значение элементов метаданных) как их отредактировать с учетом требований.EnterpriseIntegrator предлагает следующее универсальное решение. Внутреннее представление можно представить в виде структуры значений, содержащие списки значений. В списки значений помещаются однотипные объекты элементов, во главе которых стоит флаговый идентификатор, по этому флаговому идентификатору и определяются, какое свойство объектов метаданных перечислено в списке (таблица соответствий, Флаговый идентификатор-Свойство находится Настройка - Объекты конфигурации - Обозреватель объектов). Список значений, свойств объектов метаданных, формируется таким образом, чтобы при его обратном представлении в строковое представление, было получено такое же строковое значение элемента, как и до преобразования. В рамках этой стратегии для изменения реквизитов объектов метаданных нужно выполнить следующий алгоритм. Разобрать объект метаданных и сформировать структуру, скопировать один из элементов структуры и изменить его, после чего исходное значение элемента структуры и измененное преобразовывается в строковые представления. Полученные строковые представления заменятся одно на другое в представлении объекта метаданных. Структура свойстваЧто делать с набором свойств более, менее понятно. На этом можно было бы, остановится, если бы нам требовалось только удалять элементы наборов свойств объектов метаданных. Однако это, скорее всего, делать в групповой обработке и не придется…. Большую необходимость имеют такие групповые действия с объектами метаданных как добавление или изменение, и для того, что бы осуществлять эти операции необходимо разобрать внутреннюю структуру элемента набора свойств объекта метаданных.
На рисунке представлен реквизит документа. Почти все свойства метаданных (реквизиты) разных типов прикладных объектов различны и следовательно внутренне представление этих свойств за исключением некоторых полей (UNID,Имя, Синоним, Комментарий[,Тип]) различны. Постоянной структурой любого реквизита объекта метаданных являются не затененные элементы, структура затененных элементов может меняться в зависимости от:
Причем расчет адресов элементов структуры происходить относительно уникального идентификатора, то есть вначале рассчитывается адрес Unid (0,0,1,1,2) после чего для остальных элементов рассчитывается отклонение от адреса Unid, (как я уже упоминал) «теория относительности» нам немного помогла. Объекты=ПолучитьОбъектыМетаданных(Элемент.Значение.ПолучитьТекст()); Если Объекты.Свойство("Реквизиты")Тогда
НовыйСоставОбъектов=Объекты.Реквизиты.Скопировать(); Для Каждого Свойство из НовыйСоставОбъектов Цикл
МД=ОбъектМетаданных(Свойство.Значение); МД.UNID.Значение=Новый УникальныйИдентификатор; МД.Комментарий.Значение=МД.Комментарий.Значение+" Ei;";
КонецЦикла;
КонецЕсли;Выше приведенный код изменяет для всех элементов свойства (в данном случае «реквизиты») объекта метаданных, уникальный идентификатор и добавляет к комментариям определенную строку. В данном коде следует обратить внимание на то, что обращение к свойствам объекта метаданных для чтения или записи, происходит следующим образом: ОбъектМетаданных(<Элемент коллекции (Реквизит)>).[Ключ].Значение=; МД.UNID.Значение= потому что в структуре хранится элемент списка значений. Копирование элементовНу теперь мы вплотную подошли к самому сложному. Попробуем перефразировать крылатую фразу. «Для того что бы что-то куда-то вставить нужно что то и где-то скопировать?» Вот для того, что бы определить это «что- то» и «где-то» нужно определится с источником. Источником может быть любой объект конфигурации с необходимым набором параметров, то есть источником для вставки элемента в реквизиты документа, справочника,… и т.д. может являться любое измерение или ресурс, возможно и обратное, однако измерение содержит больше свойств чем например реквизит (Ведущее, Запрет незаполненных значений), поэтому при добавлении эти свойства примут такое же значение, как и первый элемент коллекции, в которую добавляется новый элемент. Отличатся эти элементы (первый элемент коллекции и добавляемый элемент) будут только элементами постоянной структуры объектов метаданных (см. выше не затененные элементы).
На рисунке изображен результат копирования реквизита табличной части документа в измерения регистра сведений.
Однако для большей надежности рекомендуется копировать реквизиты одного типа. Это увеличит скорость копирования реквизитов и компенсирует возможные коллизии. Для того что бы определить те реквизиты которые будем копировать необходимо в форме «Объекты конфигурации» выбрать в дереве объектов источник (прикладной объект содержащий нужные реквизиты). Для каждого прикладного объекта существуют в таблице Config запись без окончания (см. Формат уникального идентификатора) в этих записях, как уже было сказано выше, и хранится описание свойств метаданных прикладного объекта. После открытия этой записи в форме «Встроенного языка», в правой части этой формы будет сформирован обозреватель объекта – дерево значений, сформированное на основе внутреннего представления свойств метаданных, строится на основании флаговых идентификаторов перечисленных в настройках Параметры – Объекты конфигурации – Обозреватель объектов, колонки этого дерева содержат все доступные свойства элемента коллекции (пока это Unid,Имя, Синоним, Комментарий и Тип). Именно в обозревателе объектов нужно выбрать необходимые элементы свойств и передать их в форму "Конструктор запросов" для групповой обработки, выбрав пункт контекстного меню в обозревателе объекта. В результаты запроса конструктора также передастся дерево конфигурации именно по нему мы можем определить, в какие прикладные объекты нам нужно добавить выбранные свойства.
Как уже упоминалось в самом начале, нас интересует только метаданные прикладных объектов, поэтому отметим только
эти строчки в результатах запроса, для нужных (редактируемых) объектов.
Это достаточно просто сделать еще количество редактируемы реквизитов не
велико… Но мы затеяли всю эту «кашу» не для того чтобы «тупо» сидеть и
выбирать 200 элементов например справочников в дереве значений.
Поскольку редактировать тексты модулей или формы в нашу задачу сейчас
не входит то по большей части нам необходимы только внутренние
идентификаторы определенных прикладных объектов. Получить соответствие ПолноеИмя -Unid можно используя шаблон «Метаданные» Действия – Шаблоны –Метаданные (перебор) в форме «Конструктор запроса» . Данный шаблон представляет из себя следующее выражение на встроенном языке:
//Для каждого Объект из Параметры.ТипыМД.Типы() Цикл //выбранные типы
Мета=Неопределено; Мета=?(ТипЗнч(Объект)=Тип("ОбъектМетаданных"),Объект,Метаданные.НайтиПоТипу(Объект)); Если Не Мета=НеопределеноТогда
НоваяСтрока=Результат.Добавить(); НоваяСтрока.Имя=Мета.ПолноеИмя(); НоваяСтрока.FileName=ПолучитьИдентификаторМД(Мета);// получаем идентификатор САМОЕ ГЛАВНОЕ
КонецЕсли;
КонецЦикла;
Заменяя заголовок цикла, мы всегда можем получить набор любых
прикладных объектов. Так же дополнительный отбор можно поставить в теле
цикла или поле выполнения шаблона в результат выбрать только нужны
строки. После выполнения шаблона мы получим минимальный набор данных
необходимый для группового редактирования реквизитов.
Теперь для любой колонки данной таблицы значений или дерева значений (если мы не использовали шаблон) применим групповую обработку «Произвольный алгоритм» со следующим выражением на встроенным языке. СписокТекстов=ПолучитьСодержаниеМетаданных(ТекущиеДанные.FileName); Для Каждого Элемент из СписокТекстов Цикл Объекты=ПолучитьОбъектыМетаданных(Элемент.Значение.ПолучитьТекст());Если Объекты.Свойство("Реквизиты")Тогда //Добавляем объекты Изменен=Ложь; НовыйСоставОбъектов=Объекты.Реквизиты.Скопировать(); Для каждого НовыйОбъект из Параметры.СписокСвойств Цикл Изменен=Истина;
МД.UNID.Значение=Новый УникальныйИдентификатор;//Установка нового уникального идентификатора обязательнаНовыйСоставОбъектов.Добавить(НовыйОбъект.Значение,НовыйОбъект.Представление,НовыйОбъект.Пометка); КонецЦикла; КонецЕсли; КонецЕсли;
КонецЦикла; Данное, выражения является практической реализацией общего подхода. Опишем используемые процедуры, и функции именно они играют ключевую роль в групповом редактировании метаданных. При копировании реквизитов необходимо проверять - не существуют ли реквизиты в прикладном объекте с одинаковыми именами. Именно для этого нам нужна колонка в «Имя»(Полное имя метаданных), по ней получается объект метаданных. ОбъектМД=Метаданные.НайтиПоПолномуИмени(ТекущиеДанные.Имя); Если ОбъектМД.Реквизиты.Найти(МД.Имя.Значение)=НеопределеноТогда//проверяем нет ли реквизитов с таким же именем После выполнения групповой обработки записи, которые были изменены, в которых окажутся новые реквизиты, будут содержатся в таблице ConfigSave. Этого в принципе достаточно для того что бы увидеть результат добавления реквизитов Конфигураторе (в том случае если конфигурация была уже открыта - ее необходимо перечитать). В том случае если внесенные изменения необходимо отменить, используйте форму «Объекты конфигурации» или другие доступные средства, для удаления записей из таблицы ConfigSave. Для того, что бы конфигуратор смог корректно провести реструктуризацию информационной базы необходимо, чтобы для измененных объектов конфигурации были установлены новые идентификаторы версий. Идентификаторы версий для всех объектов метаданных описаны в файле Versions. Версии можно регистрировать при выполнении процедуры СохранитьСодержаниеМетаданных (см 4 параметр), однако куда выгоднее зарегистрировать все идентификаторы один раз. Именно для этого в произвольном алгоритме используется следующий код. Параметры.ИзмененныеМД.Добавить(ТекущиеДанные.FileName); То есть идентификаторы накапливаются в заранее установленном параметре (устанавливается параметр при передаче выбранных реквизитов из обозревателя объектов в форму «Конструктор запроса»). После выполнения групповой обработки идентификаторы можно зарегистрировать используя следующую процедуру. ОбновитьВерсииИзменныхМетаданных(Параметры.ИзмененныеМД); Данная процедура закомментирована в шаблоне Метаданные (перебор).После регистрации версии в таблице ConfigSave появится еще 3 записи Config, ConfigSave, root. Теперь можно производить обновление информационной базы.
Разработчики Enterprise Integrator будут надеяться что данная технология найдет обширное применение в разработке конфигураций, и наконец уйдут в прошлое те времена когда конфигуратор был только «интерфейсным» объектом. |
Статьи >