База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как найти циклические ссылки в справочнике Номенклатуры в БП3? › Ответ в теме: Как найти циклические ссылки в справочнике Номенклатуры в БП3?
В типовой конфигурации «Бухгалтерия предприятия 3» справочник Номенклатура не содержит реквизитов-ссылок на самого себя, которые могли бы образовывать циклические ссылки напрямую. Однако, если в вашей конфигурации есть доработки или расширения, где в справочнике Номенклатура добавлены реквизиты-ссылки на элементы этого же справочника (например, для группировки, комплектов или составных изделий), то циклические ссылки могут появиться.
Чтобы найти циклические ссылки в справочнике Номенклатура, если они есть, можно использовать следующий алгоритм на 1С:
1. Определить реквизит справочника Номенклатура, который ссылается на элементы этого же справочника (например, «Родитель» или «Состав»).
2. Написать рекурсивную процедуру, которая для каждого элемента будет проходить по цепочке ссылок и проверять, не возвращается ли она к исходному элементу.
Пример кода на 1С для поиска циклов по реквизиту «Родитель» (если он есть):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
Процедура НайтиЦиклыВНоменклатуре() Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка КАК Элемент, | Номенклатура.Родитель КАК Родитель |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Родитель <> NULL"; Результат = Запрос.Выполнить().Выгрузить(); // Создаем словарь для быстрого поиска родителя Родители = Новый Соответствие; Для Каждого Строка Из Результат Цикл Родители.Вставить(Строка.Элемент, Строка.Родитель); КонецЦикла; Циклы = Новый Массив; Для Каждого Элемент Из Родители.Ключи() Цикл Посещенные = Новый Массив; Текущий = Элемент; Пока Текущий <> Неопределено Цикл Если Посещенные.Найти(Текущий) <> Неопределено Тогда // Цикл найден Циклы.Добавить(Текущий); Прервать; КонецЕсли; Посещенные.Добавить(Текущий); Если Родители.СодержитКлюч(Текущий) Тогда Текущий = Родители.Получить(Текущий); Иначе Текущий = Неопределено; КонецЕсли; КонецЦикла; КонецЦикла; Если Циклы.Количество() = 0 Тогда Сообщить("Циклических ссылок не найдено."); Иначе Сообщить("Найдены циклические ссылки в элементах:"); Для Каждого Элемент Из Циклы Цикл Сообщить(Элемент); КонецЦикла; КонецЕсли; КонецПроцедуры |
Объяснение:
— Запрос выбирает все элементы с заполненным реквизитом «Родитель».
— В коде строится словарь «Родители», где ключ — элемент, значение — его родитель.
— Для каждого элемента происходит обход по цепочке родителей, если в процессе обхода встречается уже посещенный элемент — значит есть цикл.
Если в вашей конфигурации нет реквизита «Родитель» или другого реквизита-ссылки на самого себя, то циклических ссылок в справочнике Номенклатура не может быть.
Если циклы могут быть в других реквизитах, замените «Родитель» на нужный реквизит.
—
Если вы хотите проверить циклы в других справочниках или документах, алгоритм аналогичный — нужно найти реквизиты-ссылки на самого себя и проверить цепочки.
Рекомендую также проверить расширения и доработки, которые могли добавить такие реквизиты.
—
https://helpf.pro/faq/view/1074.html — пример перебора всех типов ссылок в конфигурации.
Если нужна помощь с конкретным реквизитом — уточните его название.