Имя: Пароль:
1C
1С v8
Запутался в рекурсии. Подскажите
0 1dvd
 
22.08.17
09:15
Помогите, люди добрые, кто чем может

Надобно сравнить два элемента справочника Конвертации: Конвертация1 и Конвертация2.
Справочник ПравилаКонвертацииОбъектов подчинен Конвертациям, многоуровневый
Справочник ПравилаКонвертацииСвойств подчинен справочнику ПравилаКонвертацииОбъектов, многоуровневый

Пытаюсь записать всё это дело в дерево значений(ТаблицаСравнений) с колонками Параметр, Значение1 и Значение2.

В рекурсивной функции Одним циклом перебираю подчиненные Конвертация1. Параллельно ищу такой же элемент в Конвертация2 и заношу в строку дерева.
Вторым циклом перебираю подчиненные Конвертация2 и если этот элемент ещё не внесен в дерево, то добавляю новой строкой.
1 1dvd
 
22.08.17
09:15
Вот код:

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

КонецПроцедуры

Процедура ПрочитатьСправочник(Узел, ИмяСправочника, Владелец1 = Неопределено, Владелец2 = Неопределено, Родитель1 = Неопределено, Родитель2 = Неопределено)
    
    Если ЗначениеЗаполнено(Владелец1) Тогда
        Если Не ЗначениеЗаполнено(Родитель1) Тогда
            Выборка = Справочники[ИмяСправочника].Выбрать(Справочники[ИмяСправочника].ПустаяСсылка(), Владелец1);
        Иначе
            Выборка = Справочники[ИмяСправочника].Выбрать(Родитель1, Владелец1);
        КонецЕсли;
        Менеджер2 = Справочники[ИмяСправочника];
        Пока Выборка.Следующий() Цикл
            ПодУзел = Узел.Строки.Добавить();
            ПодУзел.Параметр = Выборка.Ссылка;
            ПодУзел.Значение1 = Выборка.Ссылка;
            ПодУзел.Значение2 = НайтиЭлементСправочника2(Выборка.Ссылка, Владелец2, Родитель2);
            Если ИмяСправочника = "ПравилаКонвертацииОбъектов" Тогда
                ПрочитатьСправочник(ПодУзел, "ПравилаКонвертацииСвойств", ПодУзел.Значение1, ПодУзел.Значение2);
            КонецЕсли;
            ПрочитатьСправочник(ПодУзел, ИмяСправочника, Владелец1, Владелец2, ПодУзел.Значение1, ПодУзел.Значение2);
        КонецЦикла;
    КонецЕсли;
    
    Если ЗначениеЗаполнено(Владелец2) Тогда
        Если Не ЗначениеЗаполнено(Родитель2) Тогда
            Выборка = Справочники[ИмяСправочника].Выбрать(Справочники[ИмяСправочника].ПустаяСсылка(), Владелец2);
        Иначе
            Выборка = Справочники[ИмяСправочника].Выбрать(Родитель2, Владелец2);
        КонецЕсли;
        Пока Выборка.Следующий() Цикл
            Если Узел.Строки.Найти(Выборка.Ссылка, "Значение2") = Неопределено Тогда
                ПодУзел = Узел.Строки.Добавить();
                ПодУзел.Параметр = Выборка.Ссылка;
                ПодУзел.Значение1 = Справочники[ИмяСправочника].ПустаяСсылка();
                ПодУзел.Значение2 = Выборка.Ссылка;
                ПодУзел.Статус = 2;
                Если ИмяСправочника = "ПравилаКонвертацииОбъектов" Тогда
                    ПрочитатьСправочник(ПодУзел, "ПравилаКонвертацииСвойств", ПодУзел.Значение1, ПодУзел.Значение2);
                КонецЕсли;
                ПрочитатьСправочник(ПодУзел, ИмяСправочника, Неопределено, Владелец2, ПодУзел.Значение1, ПодУзел.Значение2);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры
2 1dvd
 
22.08.17
09:17
Проблема в том, что когда доходит до элемента ПКС, который есть в Конвертация2, но нет в Конвертация1, то зависает наглухо
3 h-sp
 
22.08.17
09:43
(0) там же есть типровое сравнение
4 rabbidX
 
22.08.17
09:58
НайтиЭлементСправочника2 - что за функция? Не в ней виснет? Что отладчик говорит?
5 1dvd
 
22.08.17
10:27
(3) не нравится оно, криво работает
6 1dvd
 
22.08.17
10:28
всем спасибо, разобрался.
Тут была ещё процедура по сравнению реквизитов. В ней косяк был. Я не стал её показывать, ибо был уверен что там всё ок
7 1dvd
 
22.08.17
10:36
(4) всё ровно там

Функция НайтиЭлементСправочника2(Значение1, Владелец2, Родитель2)
    
    Менеджер = Справочники[Значение1.Метаданные().Имя];
    
    Если Значение1.Метаданные().ОсновноеПредставление = Метаданные.СвойстваОбъектов.ОсновноеПредставлениеСправочника.ВВидеКода Тогда
        Если НЕ ЗначениеЗаполнено(Родитель2) Тогда
            Возврат Менеджер.НайтиПоКоду(Значение1.Код, Истина, Менеджер.ПустаяСсылка(), Владелец2);
        Иначе
            Возврат Менеджер.НайтиПоКоду(Значение1.Код, Истина, Родитель2, Владелец2);
        КонецЕсли;
    Иначе
        Если НЕ ЗначениеЗаполнено(Родитель2) Тогда
            Возврат Менеджер.НайтиПоНаименованию(Значение1.Наименование, Истина, Менеджер.ПустаяСсылка(), Владелец2);
        Иначе
            Возврат Менеджер.НайтиПоНаименованию(Значение1.Наименование, Истина, Родитель2, Владелец2);
        КонецЕсли;
    КонецЕсли;
    
КонецФункции
8 Лефмихалыч
 
22.08.17
10:38
Сериализуй оба в XML и сравни любым kdiff'ом
9 Лефмихалыч
 
22.08.17
10:39
+(8) а уже потом прицельно сравнивай то, что реально интересует. А то может и не понадобится это - все понятно будет и так
10 1dvd
 
22.08.17
10:39
(8) пробовал я эти kdiffы. для данной задачи не подходит