Справочники и Данные · 10 мин
Зацикливание уровней в 1С: причины, поиск и исправление
Зацикливание уровней в 1С: почему возникает ошибка циклической иерархии в справочниках, как найти и устранить зацикливание без потери данных.
Зацикливание уровней — это ошибка иерархии, при которой элемент справочника или плана видов характеристик прямо или через цепочку других элементов ссылается сам на себя как на родителя. Например, группа «Канцелярия» подчинена группе «Товары для офиса», а та, в свою очередь, снова подчинена «Канцелярии». Получается замкнутое кольцо, у которого нет корня.
Для платформы 1С такая структура недопустима: иерархия по определению должна быть деревом, где у каждого элемента есть путь вверх к корню. При обнаружении цикла 1С отказывается записывать элемент, выдаёт ошибку при обходе иерархии в запросах или «зависает» в процедурах, которые рекурсивно поднимаются по родителям без защиты от зацикливания.
Проблема встречается чаще всего в справочниках «Номенклатура», «Подразделения», «Статьи затрат», «Контрагенты» с иерархией групп, а также в планах счетов и планах видов характеристик с ручной настройкой родителей. Ниже разберём, как устроена ошибка, как её найти и безопасно исправить.
Что такое зацикливание уровней и как оно выглядит
В иерархическом справочнике каждый элемент имеет поле «Родитель» — ссылку на группу или элемент уровнем выше. Нормальная структура — это дерево: двигаясь от любого элемента по родителям вверх, вы обязательно придёте к элементу без родителя (корню). Зацикливание нарушает это правило: обход по родителям никогда не заканчивается, потому что цепочка замыкается в кольцо.
Простейший случай — самоссылка: элемент указан родителем самого себя. Такое платформа обычно блокирует ещё при записи. Сложнее с косвенными циклами из двух и более элементов: они могут возникнуть при обмене данными, групповой обработке или загрузке из внешних файлов, где проверки формы не срабатывают.
Внешне зацикливание проявляется по-разному: сообщение об ошибке «Зацикливание уровней» при записи элемента, бесконечное выполнение отчёта или процедуры, ошибки в запросах с итогами по иерархии, некорректное отображение дерева в форме списка.
Из-за чего возникает циклическая иерархия
Чаще всего цикл появляется при программной записи элементов. Обработки загрузки номенклатуры из Excel, обмены с сайтом или другой базой могут присваивать родителей «по коду» или «по наименованию» без проверки, не образует ли новая связь кольцо. Если во внешнем источнике иерархия описана с ошибкой, она переносится в 1С как есть.
Вторая типичная причина — ручное перетаскивание групп в дереве при большом количестве одноимённых групп. Пользователь переносит группу в папку, которая сама находится внутри переносимой группы, — и получает цикл из двух звеньев. В формах с включённой проверкой платформа это блокирует, но не во всех конфигурациях такая проверка есть.
Третья причина — обмены по правилам конвертации, где родитель ищется после записи элемента. Если поиск не удался и в качестве родителя подставился сам элемент или элемент из его поддерева, цикл записывается молча, особенно при отключённой проверке ссылочной целостности.
Как обнаружить зацикливание в базе
Самый надёжный способ — запрос с итогами по иерархии или конструкцией В ИЕРАРХИИ: при наличии цикла платформа выдаёт ошибку. Но это способ «после факта». Для профилактического поиска используют обход каждого элемента вверх по родителям с ограничением глубины: если за разумное число шагов (например, 100 итераций) корень не достигнут — элемент находится в цикле.
В типовых конфигурациях часть проблем выявляет штатная проверка «Тестирование и исправление» информационной базы, а также проверка ссылочной целостности. Однако специальной операции «поиск циклов иерархии» в стандартном тестировании может не быть — тогда помогает небольшая процедура в консоли кода.
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка, Родитель ИЗ Справочник.Номенклатура");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Тек = Выборка.Ссылка;
Для Шаг = 1 По 100 Цикл
Если Тек.Родитель.Пустая() Тогда Прервать; КонецЕсли;
Тек = Тек.Родитель;
Если Тек = Выборка.Ссылка Тогда
Сообщить("Цикл: " + Выборка.Ссылка);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;Ещё один признак — отчёты или обработки, которые раньше работали, начинают «зависать» именно на определённой ветке справочника. Если зависание воспроизводится при выборе конкретной группы, с высокой вероятностью цикл находится внутри неё.
Как исправить зацикливание вручную
Исправление сводится к разрыву кольца: одному из элементов цепочки нужно назначить родителя вне цикла или очистить родителя, подняв элемент на верхний уровень. Выбирайте для разрыва тот элемент, чьё положение в иерархии явно ошибочно, — обычно видно, какая группа оказалась «не на своём месте».
- 1Сделайте резервную копию базы или выгрузку DT перед любыми изменениями
- 2Определите все элементы, входящие в цикл, с помощью запроса или обхода
- 3Откройте элемент с ошибочным положением и смените родителя на корректную группу
- 4Если форма блокирует запись, измените родителя программно через консоль кода
- 5Повторно запустите проверку обходом иерархии — цикл должен исчезнуть
- 6Проверьте отчёты и обработки, которые раньше зависали на этой ветке
Если форма элемента не даёт записать изменения из-за той же ошибки проверки, разорвите цикл с другой стороны: измените родителя у соседнего элемента цепочки. В крайнем случае используйте программную запись с отключённой проверкой — но только точечно и сразу с корректным родителем.
Особенности при обменах и синхронизации
В распределённых базах и при обмене через универсальный формат цикл может «приехать» из другого узла. Если исправить его только в одной базе, при следующем обмене старая связь вернётся. Поэтому источник ошибки нужно искать в узле-источнике и исправлять там, а затем выполнять обмен повторно.
При обмене с сайтом или внешней учётной системой проверьте сам файл обмена: нередко в нём группа ссылается на несуществующий или перепутанный идентификатор, и загрузка подставляет родителя «как получилось». Исправление файла-источника надёжнее, чем чистка последствий в 1С.
Как выбрать действие
Профилактика: как не допустить циклов
Основная мера — проверка при записи. В собственных обработках и доработках перед установкой родителя проверяйте, не является ли новый родитель самим элементом или его потомком. Для этого достаточно пройти от нового родителя вверх по цепочке: если встретили проверяемый элемент — связь создаст цикл.
Для обменов полезно включать контроль после загрузки: пакетный обход иерархии с отчётом о найденных циклах позволяет отловить проблему до того, как она проявится в отчётах у пользователей. В правилах конвертации избегайте подстановки родителя «по умолчанию», если поиск не дал результата.
Проверка результата после исправления
После разрыва цикла убедитесь, что иерархия стала деревом: повторный обход всех элементов должен для каждого доходить до пустого родителя за конечное число шагов. Затем откройте отчёты, которые раньше зависали, и убедитесь, что они выполняются и показывают корректные итоги по группам.
Как проверить результат
Каждый элемент достигает корня за разумное число шагов
Есть элементы, для которых обход возвращается к исходной ссылке
Запрос выполняется без ошибок
Ошибка зацикливания или бесконечное выполнение
Ветка разворачивается, группы на ожидаемых местах
Дерево не разворачивается или группа отображается внутри самой себя
Дополнительно проверьте, что у исправленных элементов корректно заполняются поля, зависящие от родителя: в некоторых конфигурациях от группы наследуются ставки НДС, счета учёта, права доступа. Смена родителя могла изменить эти настройки.
Что важно запомнить
Зацикливание уровней — это замкнутое кольцо в цепочке родителей иерархического справочника. Находится обходом элементов вверх по родителям, исправляется разрывом цикла через смену родителя у одного из звеньев. Перед исправлением делайте копию базы, а при обменах устраняйте причину в источнике данных.
Частые вопросы
Может ли зацикливание возникнуть само, без действий пользователя?
Да, при обменах данными, фоновой загрузке из внешних систем или работе обработок, которые программно меняют родителей. Без программной записи или обмена цикл сам по себе не появляется.
Опасно ли зацикливание для данных в базе?
Сами данные цикл не портит, но блокирует запись элементов, ломает отчёты с иерархией и может вызывать зависание процедур обхода. Чем дольше цикл существует, тем больше операций успевает накопиться с ошибками.
Почему форма не даёт исправить родителя и выдаёт ту же ошибку?
Проверка при записи анализирует всю цепочку элемента, включая текущий цикл. Разорвите кольцо с другой стороны — измените родителя у соседнего элемента цепочки, после чего первый элемент запишется нормально.
Как найти цикл, если в справочнике десятки тысяч элементов?
Только программным обходом: запросом выбираются все элементы, для каждого выполняется подъём по родителям с ограничением числа шагов. Элементы, не достигшие корня, входят в цикл. Ручной перебор в дереве на таких объёмах непрактичен.
Помогает ли «Тестирование и исправление» базы?
Оно выявляет часть проблем ссылочной целостности, но специального механизма автоматического исправления циклов иерархии обычно нет. Используйте его как дополнительную проверку, а основной поиск и разрыв цикла выполняйте осознанно вручную или обработкой.
Нужно ли перепроводить документы после исправления иерархии?
Как правило, нет: смена родителя группы не изменяет ссылки в документах. Но если в конфигурации от группы наследуются учётные настройки, проверьте отчёты по затронутой ветке и при необходимости скорректируйте настройки элементов.