Примеры использования MDClasses¶
В этом документе представлены примеры использования библиотеки MDClasses для работы с метаданными 1С.
Оглавление¶
- Базовые операции
- Работа с конфигурацией
- Работа с метаданными
- Работа с формами
- Работа с модулями
- Поиск и фильтрация объектов
- Практические сценарии
Базовые операции¶
Инициализация парсера и чтение конфигурации¶
// Сначала стандартные библиотеки Java
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
// Затем библиотеки сторонних разработчиков
import com.github._1c_syntax.bsl.mdclasses.MDClasses;
import com.github._1c_syntax.bsl.mdo.AccumulationRegister;
import com.github._1c_syntax.bsl.mdo.Catalog;
import com.github._1c_syntax.bsl.mdo.Configuration;
import com.github._1c_syntax.bsl.mdo.Document;
import com.github._1c_syntax.bsl.mdo.Form;
import com.github._1c_syntax.bsl.mdo.FormItem;
import com.github._1c_syntax.bsl.mdo.InformationRegister;
import com.github._1c_syntax.bsl.mdo.MD;
import com.github._1c_syntax.bsl.mdo.MdoReference;
import com.github._1c_syntax.bsl.mdo.Module;
import com.github._1c_syntax.bsl.mdo.ModuleType;
import com.github._1c_syntax.bsl.mdo.Right;
import com.github._1c_syntax.bsl.mdo.Role;
import com.github._1c_syntax.bsl.mdo.Subsystem;
// ... и другие объекты метаданных
// Путь к каталогу конфигурации
Path configurationPath = Paths.get("path/to/configuration");
// Чтение конфигурации
Configuration configuration = MDClasses.createConfiguration(configurationPath);
Получение основной информации о конфигурации¶
// Название конфигурации
String name = configuration.getName();
System.out.println("Имя конфигурации: " + name);
// Синоним конфигурации
String synonym = configuration.getSynonym();
System.out.println("Синоним конфигурации: " + synonym);
// Версия конфигурации
String version = configuration.getVersion();
System.out.println("Версия: " + version);
// Поставщик
String vendor = configuration.getVendor();
System.out.println("Поставщик: " + vendor);
Работа с конфигурацией¶
Обход подсистем¶
// Получение всех подсистем верхнего уровня
configuration.getSubsystems().forEach(subsystem -> {
System.out.println("Подсистема: " + subsystem.getName());
// Получение дочерних подсистем
subsystem.getSubsystems().forEach(childSubsystem -> {
System.out.println(" - Дочерняя подсистема: " + childSubsystem.getName());
});
});
Получение списка всех объектов конфигурации¶
// Получение всех объектов конфигурации
List<MD> allObjects = configuration.getAllMdo();
// Для работы со справочниками
List<Catalog> catalogs = configuration.getCatalogs();
// Для работы с документами
List<Document> documents = configuration.getDocuments();
// Вывод количества объектов по типам
Map<String, Long> objectCountByType = allObjects.stream()
.collect(Collectors.groupingBy(
obj -> obj.getClass().getSimpleName(),
Collectors.counting()
));
objectCountByType.forEach((type, count) -> {
System.out.println(type + ": " + count);
});
Работа с метаданными¶
Работа со справочниками¶
// Получение всех справочников
List<Catalog> catalogs = configuration.getCatalogs();
catalogs.forEach(catalog -> {
System.out.println("Справочник: " + catalog.getName());
// Получение реквизитов справочника
catalog.getAttributes().forEach(attribute -> {
System.out.println(" Реквизит: " + attribute.getName() +
", Тип: " + attribute.getType().getDescription());
});
// Получение табличных частей
catalog.getTabularSections().forEach(section -> {
System.out.println(" Табличная часть: " + section.getName());
// Получение реквизитов табличной части
section.getAttributes().forEach(attribute -> {
System.out.println(" Реквизит ТЧ: " + attribute.getName() +
", Тип: " + attribute.getType().getDescription());
});
});
});
Работа с документами¶
// Получение всех документов
List<Document> documents = configuration.getDocuments();
documents.forEach(document -> {
System.out.println("Документ: " + document.getName());
// Получение реквизитов документа
document.getAttributes().forEach(attribute -> {
System.out.println(" Реквизит: " + attribute.getName());
});
// Получение табличных частей
document.getTabularSections().forEach(section -> {
System.out.println(" Табличная часть: " + section.getName());
});
// Получение регистраторов движений
document.getRegisterRecords().forEach(registerRecord -> {
System.out.println(" Регистратор: " + registerRecord.getName());
});
});
Работа с регистрами¶
// Работа с регистрами накопления
configuration.getAccumulationRegisters().forEach(register -> {
System.out.println("Регистр накопления: " + register.getName());
System.out.println(" Вид регистра: " + register.getRegisterType());
// Получение измерений регистра
register.getDimensions().forEach(dimension -> {
System.out.println(" Измерение: " + dimension.getName());
});
// Получение ресурсов регистра
register.getResources().forEach(resource -> {
System.out.println(" Ресурс: " + resource.getName());
});
});
// Работа с регистрами сведений
configuration.getInformationRegisters().forEach(register -> {
System.out.println("Регистр сведений: " + register.getName());
System.out.println(" Периодичность: " + register.getPeriodicity());
// Получение измерений регистра
register.getDimensions().forEach(dimension -> {
System.out.println(" Измерение: " + dimension.getName());
});
});
Работа с формами¶
Получение и анализ форм¶
// Получение всех форм
List<Form> allForms = configuration.getAllForms();
System.out.println("Всего форм в конфигурации: " + allForms.size());
// Анализ конкретной формы
allForms.stream()
.filter(form -> "ФормаДокумента".equals(form.getName()))
.findFirst()
.ifPresent(form -> {
System.out.println("Анализ формы: " + form.getName());
if (form.getFormData() != null) {
// Получение элементов формы
FormItem rootItem = form.getFormData().getItems();
analyzeFormItem(rootItem, 0);
}
});
// Рекурсивный метод для анализа элементов формы
private static void analyzeFormItem(FormItem item, int level) {
if (item == null) return;
String indent = " ".repeat(level);
System.out.println(indent + "Элемент: " + item.getName() + ", Тип: " + item.getType());
// Обработка дочерних элементов
if (item.getChildItems() != null) {
item.getChildItems().forEach(child -> analyzeFormItem(child, level + 1));
}
}
Работа с модулями¶
Получение и анализ модулей¶
// Получение всех модулей
List<Module> allModules = configuration.getAllModules();
System.out.println("Всего модулей в конфигурации: " + allModules.size());
// Группировка модулей по типу
Map<ModuleType, List<Module>> modulesByType = allModules.stream()
.collect(Collectors.groupingBy(Module::getModuleType));
// Вывод количества модулей каждого типа
modulesByType.forEach((type, modules) -> {
System.out.println("Модули типа " + type.getName() + ": " + modules.size());
});
// Анализ содержимого конкретного модуля
allModules.stream()
.filter(module -> module.getModuleType() == ModuleType.ObjectModule)
.filter(module -> module.getOwner().getName().equals("ИмяОбъекта"))
.findFirst()
.ifPresent(module -> {
System.out.println("Содержимое модуля:");
String[] lines = module.getContent().split("\n");
for (int i = 0; i < Math.min(10, lines.length); i++) {
System.out.println((i+1) + ": " + lines[i]);
}
});
Поиск и фильтрация объектов¶
Поиск объекта по ссылке¶
// Создание ссылки на объект метаданных
MdoReference reference = MdoReference.create("Справочник.Товары");
// Поиск объекта по ссылке
Optional<MD> mdoOptional = configuration.findChild(reference);
mdoOptional.ifPresentOrElse(
mdo -> System.out.println("Найден объект: " + mdo.getName()),
() -> System.out.println("Объект не найден")
);
Фильтрация объектов по условию¶
// Найти все справочники с табличными частями
List<Catalog> catalogsWithTabularSections = configuration.getCatalogs().stream()
.filter(catalog -> !catalog.getTabularSections().isEmpty())
.collect(Collectors.toList());
System.out.println("Справочники с табличными частями:");
catalogsWithTabularSections.forEach(catalog -> {
System.out.println(catalog.getName() + " (" + catalog.getTabularSections().size() + " ТЧ)");
});
// Найти все объекты с определенным префиксом имени
String prefix = "ПрефиксИмени";
List<MD> objectsWithPrefix = configuration.getAllMdo().stream()
.filter(obj -> obj.getName().startsWith(prefix))
.collect(Collectors.toList());
System.out.println("Объекты с префиксом '" + prefix + "':");
objectsWithPrefix.forEach(obj -> {
System.out.println(obj.getClass().getSimpleName() + ": " + obj.getName());
});
Практические сценарии¶
Построение диаграммы зависимостей объектов¶
// Упрощенный пример построения графа зависимостей между объектами
Map<String, Set<String>> dependencies = new HashMap<>();
// Сбор зависимостей из типов реквизитов справочников
configuration.getCatalogs().forEach(catalog -> {
String catalogKey = "Catalog." + catalog.getName();
dependencies.putIfAbsent(catalogKey, new HashSet<>());
catalog.getAttributes().forEach(attribute -> {
if (attribute.getType() != null) {
String typeDescription = attribute.getType().getDescription();
// Проверяем, что тип ссылается на другой объект метаданных
if (typeDescription != null && typeDescription.contains("CatalogRef.")) {
String referencedObject = typeDescription.replace("CatalogRef.", "Catalog.");
dependencies.get(catalogKey).add(referencedObject);
}
}
});
});
// Вывод зависимостей
dependencies.forEach((object, refs) -> {
if (!refs.isEmpty()) {
System.out.println(object + " зависит от:");
refs.forEach(ref -> System.out.println(" - " + ref));
}
});
Анализ прав доступа¶
// Получение всех ролей
List<Role> roles = configuration.getRoles();
// Анализ прав доступа к объектам для каждой роли
roles.forEach(role -> {
System.out.println("Роль: " + role.getName());
if (role.getRights() != null) {
// Группировка прав по объектам
Map<String, List<Right>> rightsByObject = role.getRights().stream()
.collect(Collectors.groupingBy(Right::getName));
// ... existing code ...
}
});
Поиск неиспользуемых реквизитов¶
// Упрощенный пример поиска неиспользуемых реквизитов
// (в реальном сценарии нужен более сложный анализ кода модулей)
// Сбор всех реквизитов справочников
Map<String, Set<String>> catalogAttributes = new HashMap<>();
configuration.getCatalogs().forEach(catalog -> {
String catalogName = catalog.getName();
Set<String> attributes = new HashSet<>();
catalog.getAttributes().forEach(attr -> {
attributes.add(attr.getName());
});
catalogAttributes.put(catalogName, attributes);
});
// Простой анализ использования в модулях
catalogAttributes.forEach((catalogName, attributes) -> {
System.out.println("Проверка реквизитов справочника: " + catalogName);
attributes.forEach(attrName -> {
boolean found = false;
// Поиск использования реквизита в модулях
for (Module module : configuration.getAllModules()) {
if (module.getContent().contains(attrName)) {
found = true;
break;
}
}
if (!found) {
System.out.println(" Потенциально неиспользуемый реквизит: " + attrName);
}
});
});
Эти примеры демонстрируют базовые возможности библиотеки MDClasses. В реальных сценариях вы можете комбинировать и расширять их для решения конкретных задач по анализу и обработке метаданных 1С.