Как обойти все метаданные в едином цикле в 1С:Предприятие 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Ограничения модели метаданных в платформе 7.7

Проанализируем, почему стандартный подход с обращением по индексу вида Метаданные[Индекс] не работает в платформе 7.7:

  1. Отсутствие единой индексируемой коллекции: Встроенный объект Метаданные не является коллекцией значений. Для каждого типа прикладных объектов конфигурации реализован строго отдельный метод. Причем имя этого метода задается в единственном числе: Метаданные.Константа(), Метаданные.Справочник(), Метаданные.Документ(), Метаданные.Регистр(), Метаданные.Перечисление().
  2. Отсутствие операторов динамического выполнения: Во встроенном языке 1С 7.7 нет привычных функций Вычислить() или Выполнить(), которые позволяют исполнить произвольный фрагмент кода из строковой переменной.
  3. Разная внутренняя структура дочерних объектов: Даже если динамически обратиться к объекту верхнего уровня, имена методов для доступа к их реквизитам отличаются. Например, у справочников это Реквизит(), у документов — РеквизитШапки() и РеквизитТабличнойЧасти(), а у регистров — Измерение() и Ресурс().

Стандартный путь «в лоб» требует написания десятка отдельных циклов под каждый тип объектов метаданных. Однако обойти эти ограничения и объединить перебор в компактный алгоритм возможно.

Способ 1. Динамический вызов через функцию Шаблон()

Основным штатным механизмом динамического вычисления выражений в 1С 7.7 выступает системная функция Шаблон(). Если поместить выражение в квадратные скобки внутри строки, платформа попытается вычислить его и вернуть строковое представление результата.

Посмотрим на пример формирования списка типов метаданных и динамического вычисления количества объектов каждого вида:


СписокТипов = СоздатьОбъект("СписокЗначений");
СписокТипов.ДобавитьЗначение("Константа");
СписокТипов.ДобавитьЗначение("Справочник");
СписокТипов.ДобавитьЗначение("Документ");
СписокТипов.ДобавитьЗначение("Перечисление");
СписокТипов.ДобавитьЗначение("Отчет");
СписокТипов.ДобавитьЗначение("Обработка");
СписокТипов.ДобавитьЗначение("ПланСчетов");
СписокТипов.ДобавитьЗначение("Регистр");
СписокТипов.ДобавитьЗначение("Журнал");

Для Счетчик = 1 По СписокТипов.РазмерСписка() Цикл
    ИмяТипа = СписокТипов.ПолучитьЗначение(Счетчик);
    
    // Вызов без параметров возвращает общее количество объектов данного типа
    КолвоСтр = Шаблон("[Метаданные." + ИмяТипа + "()]");
    КолвоОбъектов = Число(КолвоСтр);
    
    Сообщить("Тип метаданных: " + ИмяТипа + " — всего: " + КолвоОбъектов);
КонецЦикла;

Важный нюанс: Имена методов должны передаваться строго в единственном числе (Константа, а не Константы; Справочник, а не Справочники). При передаче имени во множественном числе платформа выдаст ошибку Поле агрегатного объекта не обнаружено.

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

При использовании функции Шаблон() возникает сложность: она всегда возвращает строковый тип данных. Если вызвать Шаблон("[Метаданные.Справочник(1)]"), мы получим строковое представление первого справочника, но не ссылку на сам контекст объекта метаданных, из-за чего обратиться к его свойствам (например, Идентификатор, Синоним, Комментарий) будет невозможно.

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


Функция глПрисвоить(Куда, Что) Экспорт
    Куда = Что;
    Возврат "";
КонецФункции

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


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

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

Способ 3. Прямой разбор файла структуры базы данных (1cv7.dd / 1cv7.dds)

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

В каталоге любой информационной базы 1С 7.7 находится файл описания структуры таблиц:

  1. 1cv7.dd — для файловых баз формата DBF;
  2. 1cv7.dds — для баз на платформе MS SQL Server.

Этот файл представляет собой обычный текстовый документ с четко структурированным описанием всех констант, справочников, документов, регистров и их реквизитов. С помощью базового объекта СоздатьОбъект("Текст") можно прочитать файл и извлечь названия объектов и физических полей в одном последовательном цикле.

Способ 4. Использование внешнего компонента MSScriptControl

Еще один вариант динамического обращения к объектам — задействовать стандартный системный COM-объект операционной системы Windows MSScriptControl.ScriptControl. Он позволяет интерпретировать код на VBScript или JScript с прямым доступом к переданному объекту метаданных 1С.

Разберем пример инициализации скриптового движка:


Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
Скрипт.Language = "VBScript";
Скрипт.AddObject("Метаданные", Метаданные);

// Получаем количество документов динамически через VBScript
КолвоДокументов = Скрипт.Eval("Метаданные.Документ()");
Сообщить("Всего документов: " + КолвоДокументов);

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

Рекомендации и выводы

  1. Для небольших задач внутри конфигурации без использования внешних библиотек лучше всего подходит связка функции Шаблон() и глобальной функции глПрисвоить().
  2. Помните, что динамический вызов через Шаблон() работает медленнее прямого обращения к методам, поэтому для критичных к производительности участков кода имеет смысл оставить явные циклы.
  3. Следите за корректностью названий методов: системные вызовы метаданных 1С 7.7 строго чувствительны к форме слова (только единственное число).
← На главную