helpf.pro
Регистрация
 +1 
Распечатать

Обход метаданных (полезные функции)

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

Ниже приведен небольшой модуль, который решает задачу легко и удобно. Создана специальная функция РазвернутьСтрокуОбходаМетаданных, которая может по строке типа "Метаданные.Справочники.*.Реквизиты.*" построить массив строк с перечислением всех реквизитов всех справочников. При помощи этой и нескольких других функций в экспортных функциях модуля реализованы вполне прикладные задачи - получение всех реквизитов, всех макетов, всех форм конфигурации и построение таблицы всех составных типов.

Код 1C v 8.х
  // Автор: Alexander Speshilov
// Рекрсивная функция, которая разворачивает строку вида "Метаданные.Справочники.*[Имя].Реквизиты.*.Тип" 
// в массив строк, заменяя "*" или другой символ, задаваемый параметрами обходом всех элементов 
// коллекции. Допускает выполнение функций встроенного языка (не стоит отдавать ввод параметров 
// пользователям). При этом выражение, используемое для получения по умолчанию может быть задано в 
// квадратных скобках или параметром функции.
//
// Параметры
//  СтрокаОбхода  - Строка - Разворачиваемая строка
//  ЗаменяемоеЗначение  - Строка - заменяемое значение
//  ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
//   Массив строк
//
Функция РазвернутьСтрокуОбходаМетаданных(СтрокаОбхода, ЗаменяемоеЗначение = "*", ПредставлениеПоУмолчанию = "")
    
    Рез = Новый Массив;
    
    ЧастиСтрокиОбхода = РазобратьСтрокуОбхода(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
    Если ЧастиСтрокиОбхода = Неопределено тогда 
        Рез.Добавить(СтрокаОбхода); //фактически это ограничение рекурсии.
    Иначе
        ОбъектКоллекции = Вычислить(ЧастиСтрокиОбхода.СтрокаКоллекции);
        РазвернутаяКоллекция = РазвернутьКоллекциюВПредставления(ОбъектКоллекции, ЧастиСтрокиОбхода.СтрокаПредставление);
        Для каждого ЭлементРазвернутойКоллекции Из РазвернутаяКоллекция Цикл
            
            // рекурсивный вызов
            ТекущаяСтрокаОбхода = ЧастиСтрокиОбхода.СтрокаНачало + ЭлементРазвернутойКоллекции + ЧастиСтрокиОбхода.СтрокаКонец;
            МассивЭлемента = РазвернутьСтрокуОбходаМетаданных(ТекущаяСтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
            
            Для каждого ПримитивныйЭлементОбхода Из МассивЭлемента Цикл
                Рез.Добавить(ПримитивныйЭлементОбхода);
            КонецЦикла;
            
        КонецЦикла;
    КонецЕсли;
    
    Возврат Рез;
    
КонецФункции // РазвернутьСтрокуОбходаМетаданных()

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

// Разворачивает объект коллекции в массив представления элементов
//
// Параметры
//  Коллекция  - Произвольный - Коллекция, которую можно обойти через "Для каждого"
//  ПредставлениеЭлемента  - Строка - необяз., свойство элементов коллекции, которое 
//               используется для получения представления.
//
// Возвращаемое значение:
//   Массив   - Массив представлений коллекции
//
Функция РазвернутьКоллекциюВПредставления(Коллекция, Знач ПредставлениеЭлемента = "")
    
    //Проверка и подгонка параметров
    Если не ПустаяСтрока(ПредставлениеЭлемента) Тогда 
        Если Найти(ПредставлениеЭлемента, ";")>0 Тогда 
            ВызватьИсключение "Некорректное выражение представления";
        КонецЕсли;
        ПредставлениеЭлемента = "." + ПредставлениеЭлемента;
    КонецЕсли;
    
    Рез = Новый Массив;
    Для каждого ЭлементКоллекции Из Коллекция Цикл
        ТекПредставление = Строка(Вычислить("ЭлементКоллекции" + ПредставлениеЭлемента));
        Рез.Добавить(ТекПредставление);
    КонецЦикла; 
    Возврат Рез;
    
КонецФункции // РазвернутьКоллекцию()

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

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

// Возвращает все реквизиты конфигурации, которые сохраняются в ИБ
//
// Параметры - Нет
//
// Возвращаемое значение:
//   Массив объектов метаданных
//
Функция ПолучитьВсеХранимыеРеквизитыКонфигурации() Экспорт
    
    СтрокаВсехРеквизитов = 
    "
    |Метаданные.Константы.*
    |Метаданные.ПланыОбмена.*.Реквизиты.*
    |Метаданные.ПланыОбмена.*.ТабличныеЧасти.*.Реквизиты.*
    |Метаданные.Справочники.*.Реквизиты.*
    |Метаданные.Справочники.*.ТабличныеЧасти.*.Реквизиты.*
    |Метаданные.Документы.*.Реквизиты.*
    |Метаданные.Документы.*.ТабличныеЧасти.*.Реквизиты.*
    |Метаданные.Последовательности.*.Измерения.*
    |Метаданные.ПланыВидовХарактеристик.*.Реквизиты.*
    |Метаданные.ПланыВидовХарактеристик.*.ТабличныеЧасти.*.Реквизиты.*
    |Метаданные.ПланыСчетов.*.Реквизиты.*
    |Метаданные.ПланыСчетов.*.ПризнакиУчета.*
    |Метаданные.ПланыСчетов.*.ПризнакиУчетаСубконто.*
    |Метаданные.ПланыСчетов.*.ТабличныеЧасти.*.Реквизиты.*
    |Метаданные.ПланыВидовРасчета.*.Реквизиты.*
    |Метаданные.ПланыВидовРасчета.*.ТабличныеЧасти.*.Реквизиты.*
    |Метаданные.РегистрыСведений.*.Измерения.*
    |Метаданные.РегистрыСведений.*.Ресурсы.*
    |Метаданные.РегистрыСведений.*.Реквизиты.*
    |Метаданные.РегистрыНакопления.*.Измерения.*
    |Метаданные.РегистрыНакопления.*.Ресурсы.*
    |Метаданные.РегистрыНакопления.*.Реквизиты.*
    |Метаданные.РегистрыБухгалтерии.*.Измерения.*
    |Метаданные.РегистрыБухгалтерии.*.Ресурсы.*
    |Метаданные.РегистрыБухгалтерии.*.Реквизиты.*
    |Метаданные.РегистрыРасчета.*.Измерения.*
    |Метаданные.РегистрыРасчета.*.Ресурсы.*
    |Метаданные.РегистрыРасчета.*.Реквизиты.*
    |Метаданные.БизнесПроцессы.*.Реквизиты.*
    |Метаданные.БизнесПроцессы.*.ТабличныеЧасти.*.Реквизиты.*
    |Метаданные.Задачи.*.Реквизиты.*
    |Метаданные.Задачи.*.РеквизитыАдресации.*
    |Метаданные.Задачи.*.ТабличныеЧасти.*.Реквизиты.*
    |";
    ВсеХранимыеРеквизитыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
    Возврат ВсеХранимыеРеквизитыКонфигурации;
    
КонецФункции // ПолучитьВсеХранимыеРеквизитыКонфигурации()

// Возвращает все реквизиты конфигурации составного типа, которые сохраняются в ИБ
//
// Параметры - Нет
//
// Возвращаемое значение:
//   ТаблицаЗначений
//
Функция ПолучитьВсеХранимыеРеквизитыКонфигурацииСоставногоТипа() Экспорт
    
    ВсеХранимыеРеквизитыКонфигурации = ПолучитьВсеХранимыеРеквизитыКонфигурации();
    Рез = Новый ТаблицаЗначений;
    Рез.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
    Рез.Колонки.Добавить("Тип", Новый ОписаниеТипов("ОписаниеТипов"));
    Рез.Колонки.Добавить("КоличествоПростыхТипов", Новый ОписаниеТипов("Число"));
    
    Для каждого ТекРеквизит Из ВсеХранимыеРеквизитыКонфигурации Цикл
        
        Реквизит = Вычислить(ТекРеквизит);
        Тип = Реквизит.Тип;
        КоличествоПростыхТипов = Тип.Типы().Количество();
        Если КоличествоПростыхТипов<>1 Тогда 
    	    ТекСтрока = Рез.Добавить();
            ТекСтрока.Имя = ТекРеквизит;
            ТекСтрока.Тип = Тип;
            ТекСтрока.КоличествоПростыхТипов = КоличествоПростыхТипов;
        КонецЕсли;
    
    КонецЦикла; 
    
    Возврат Рез;
    
КонецФункции // ПолучитьВсеХранимыеРеквизитыКонфигурации()

// Возвращает все формы конфигурации
//
// Параметры - Нет
//
// Возвращаемое значение:
//   Массив объектов метаданных
//
Функция ПолучитьВсеФормыКонфигурации() Экспорт
    
    СтрокаВсехРеквизитов = 
    "
    |Метаданные.ПланыОбмена.*.Формы.*
    |Метаданные.КритерииОтбора.*.Формы.*
    |Метаданные.ОбщиеФормы.*
    |Метаданные.Справочники.*.Формы.*
    |Метаданные.Документы.*.Формы.*
    |Метаданные.ЖурналыДокументов.*.Формы.*
    |Метаданные.Перечисления.*.Формы.*
    |Метаданные.Отчеты.*.Формы.*
    |Метаданные.Обработки.*.Формы.*
    |Метаданные.ПланыВидовХарактеристик.*.Формы.*
    |Метаданные.ПланыСчетов.*.Формы.*
    |Метаданные.ПланыВидовРасчета.*.Формы.*
    |Метаданные.РегистрыСведений.*.Формы.*
    |Метаданные.РегистрыНакопления.*.Формы.*
    |Метаданные.РегистрыБухгалтерии.*.Формы.*
    |Метаданные.РегистрыРасчета.*.Формы.*
    |Метаданные.БизнесПроцессы.*.Формы.*
    |Метаданные.Задачи.*.Формы.*
    |";
    ВсеФормыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
    Возврат ВсеФормыКонфигурации;
    
КонецФункции // ПолучитьВсеФормыКонфигурации()

// Возвращает все макеты конфигурации
//
// Параметры - Нет
//
// Возвращаемое значение:
//   Массив объектов метаданных
//
Функция ПолучитьВсеМакетыКонфигурации() Экспорт
    
    СтрокаВсехРеквизитов = 
    "
    |Метаданные.ПланыОбмена.*.Макеты.*
    |Метаданные.ОбщиеМакеты.*
    |Метаданные.Справочники.*.Макеты.*
    |Метаданные.Документы.*.Макеты.*
    |Метаданные.ЖурналыДокументов.*.Макеты.*
    |Метаданные.Перечисления.*.Макеты.*
    |Метаданные.Отчеты.*.Макеты.*
    |Метаданные.Обработки.*.Макеты.*
    |Метаданные.ПланыВидовХарактеристик.*.Макеты.*
    |Метаданные.ПланыСчетов.*.Макеты.*
    |Метаданные.ПланыВидовРасчета.*.Макеты.*
    |Метаданные.РегистрыСведений.*.Макеты.*
    |Метаданные.РегистрыНакопления.*.Макеты.*
    |Метаданные.РегистрыБухгалтерии.*.Макеты.*
    |Метаданные.РегистрыРасчета.*.Макеты.*
    |Метаданные.БизнесПроцессы.*.Макеты.*
    |Метаданные.Задачи.*.Макеты.*
    |";
    ВсеМакетыКонфигурации = РазвернутьМассивСтрокОбходаМетаданных(ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов));
    Возврат ВсеМакетыКонфигурации;
    
КонецФункции // ПолучитьВсеМакетыКонфигурации()   
Разместил:   Версии: | 8.x | 8.2 УП |  Дата:   Прочитано: 48661
 +1 
Распечатать
Возможно, вас также заинтересует
Как заполнить табличную часть формы программно? 8
Нужно по кнопке Заполнить - сформировать данные для заполнения табличных частей и заполнить их. Форма имеет вид: Рядом с кнопкой Записать и закрыть добавлена кнопка Заполнить документ , код ее команды: // Код заполнения ТЧ НаСервере П
17 правил для составления оптимального ЗАПРОСа к данным базы 1С 53
Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос . Создается этот объект вызовом конструкции Новый Запрос . Запрос удобно использовать, когда требуется получ
1C и Google Maps 21
была поставлена задача отображения на географической карте медицинских учреждений. После обзора предлагаемых решений был выбран сервис google. Но так же подобного рода подход будет работать и с картами сервиса yandex. Во время решения задачи было реш
1C: Enterprise Development Tools 52
И вот случилось долгожданное: Вышел 1C: Enterprise Development Tools - это среда для разработки конфигурации в IDE Eclipse. С сайта 1С: « 1C:Enterprise Development Tools » – это инструмент нового поколения для разработчиков бизнес-приложений систем
1Cv8.1CD - Файл данных достиг максимального размера! 9
1С выдает предупреждение " Файл данных достиг максимального размера" . Подскажите из - за чего это и как можно решить ? Превышен размер файла, обычно это сообщение возникает, когда размер файла 1Cv8.1CD приближается к 10 гигабайтам или размер ка
Посмотреть все результаты поиска похожих
Вы не можете отправить комментарий анонимно, пожалуйста войдите или зарегистрируйтесь.
Загрузка... Дождитесь завершения!