Эта внешняя обработка выполняет проверку иерархической структуры справочников на предмет "зацикливания",
то есть ситуаций, когда родитель группы ссылается на саму себя или на одну из подчиненных групп нижнего уровня.
Результат работы - печатная форма таблицы, с колонками в виде "Код", "Наименование", "Внутреннее представление"
зацикленных групп, а также их родителей :) и колонки для составления схемы подчиненности зацикленных групп.
В печатную форму выводятся только группы, участвующие в замкнутых циклах подчиненности, например:
A=>A ; A=>B=>A ; A=>B=>C=>A. (A=>B означает, что B является родителем A ). Правильные "ветки" подчиненности,
подсоединенные к циклам, например, "ветка" "D" : D=>A=>B=>A из выборки исключаются.
Чтобы исправить замкнутую подчиненность, достаточно разорвать цепочку групп в одном месте - у одной из групп
очистить реквизит "Родитель". Программа анализирует и рекомендует для этих целей использовать: а) группы, которые
раньше других созданы (соответсвенно, должны иметь по логике более высокий уровень); б) группы, наиболее
удаленные от элементов (справедливо для справочников, где элементы всегда расположены последними по иерархии).
Цепочки замкнутых групп в отчете разделены пустыми строками. Для очистки родителя одной из групп цепочки нужно нажать
клавишу Enter / кликнуть мышкой на ячейке в строке с исправляемой группой, в колонке "Очистить!!!" .
В прикрепленных файлах - архив с внешним отчетом и архив пример информационной базы с зацикленным справочником
для демонстрации работы отчета.
Конечно, наилучший способ предотвращения такой ситуации, - это ее профилактика. Совсем несложно добавить
небольшую проверку в программный код, отвечающий за смену родителя группы:
// УстРодитель - устанавливаемый родитель для группы справочника
// Спр - переменная, для записи объекта справочника
ПопыткаЗаписиЦиклическойСсылки = 0;
ПопыткаЗаписиПринадлежностиКЦиклу = 0;
ПровРодитель = УстРодитель;
СЗ = СоздатьОбъект("СписокЗначений");
Пока ПустоеЗначение(ПровРодитель) = 0 Цикл
Если ПровРодитель = Спр.ТекущийЭлемент() Тогда
ПопыткаЗаписиЦиклическойСсылки = 1;
Прервать;
КонецЕсли;
Если СЗ.НайтиЗначение(ПровРодитель) > 0 Тогда
ПопыткаЗаписиПринадлежностиКЦиклу = 1;
Прервать;
КонецЕсли;
СЗ.ДобавитьЗначение(ПровРодитель);
ПровРодитель = ПровРодитель.Родитель;
КонецЦикла;
Если (ПопыткаЗаписиЦиклическойСсылки = 0) И
(ПопыткаЗаписиПринадлежностиКЦиклу = 0) Тогда
СпрРодитель = УстРодитель;
Спр.Записать();
КонецЕсли;
Перед самым опубликованием, еще раз (с меньшим поисковым фильтром) решил поискать здесь же, подобное:
Возможно, если бы я предварительно их изучил, этой публикации могло бы не быть,
а так... она есть, и она может быть кому-то полезна.
Желаю Вашим базам здоровья! :-)