Как восстановить иерархию справочника номенклатуры в 1С 7.7 после неудачного программного переноса элементов

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Работа со справочниками в системе 1С:Предприятие 7.7 требует особой осторожности, особенно при написании программных обработок для массового изменения данных. Одной из критических проблем является нарушение логической целостности иерархии, когда элементы перестают отображаться в древовидном режиме, хотя присутствуют в базе. В этой статье мы разберем, почему возникают «зацикливания» в справочниках, как восстановить данные через прямое редактирование файлов и как предотвратить подобные ошибки в коде.

Анализируем причину сбоя: почему «исчезают» элементы

Рассмотрим типичную ситуацию: при программном переносе элементов из одной папки в другую процесс аварийно прерывается или зависает. После этого пользователи замечают странное поведение программы — в режиме просмотра «Дерево» элементы пропадают из своих групп, но при включении режима «Без групп» (одноуровневый список) они видны. Проанализируем, что происходит на техническом уровне.

В платформе 1С 7.7 за иерархию отвечает поле PARENTID в соответствующем DBF-файле справочника. Если в результате работы скрипта родителем папки становится она сама или одна из её дочерних подпапок, возникает циклическая ссылка. Платформа при попытке построить дерево уходит в бесконечную рекурсию или некорректно обрабатывает индекс, из-за чего визуальное отображение списка обрывается. Выясним, почему это происходит: в отличие от версии 8.x, объектная модель 7.7 при вызове метода Записать() не всегда выполняет автоматическую проверку на то, не является ли новый родитель подчиненным элементом по отношению к записываемому объекту.

Выявление проблемы в программном коде

Посмотрим на пример кода, который может привести к фатальной ошибке. Проанализируем алгоритм, который кажется рабочим, но содержит скрытую угрозу:


Процедура Выполнить()
    Спр1 = СоздатьОбъект("Справочник.ТМЦ");
    Список = СоздатьОбъект("СписокЗначений");
    Спр1.ИспользоватьРодителя(ПапкаОткуда);
    Спр1.ВыбратьЭлементы();
    Пока Спр1.ПолучитьЭлемент() = 1 Цикл
        Список.ДобавитьЗначение(Спр1.ТекущийЭлемент());
    КонецЦикла;
    Для к = 1 По Список.РазмерСписка() Цикл
        ТекЭл = Список.ПолучитьЗначение(к);
        Если Спр1.НайтиЭлемент(ТекЭл) = 1 Тогда
            Спр1.Родитель = ПапкаПриёмник;
            Спр1.Записать();
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Разберем, в чем здесь ошибка. Этот алгоритм работает корректно до тех пор, пока ПапкаПриёмник не окажется внутри ПапкаОткуда. Если пользователь случайно выберет в качестве приемника подчиненную папку, то при итерации цикла родителем вышестоящей папки станет её собственный «внук». В файле данных ID родителя станет равен ID самого элемента или возникнет более сложная петля. Это моментально «ломает» индексный файл .CDX и структуру отображения.

Шаг 1: Восстановление данных через редактирование DBF

Если Тестирование и Исправление (ТиИ) в Конфигураторе зависает на долгие часы, это верный признак циклической ссылки. Программа пытается обойти дерево и зацикливается. В этом случае нам поможет прямое редактирование таблиц базы данных. Внимание: всегда делайте резервную копию перед любыми манипуляциями с файлами!

  1. Выясним имя файла справочника. Это можно сделать, открыв файл 1CV7.DD (или .DDS) в текстовом редакторе и найдя там описание справочника ТМЦ. Файл будет называться примерно SC123.DBF.
  2. Используем любой DBF-редактор. Нам нужно найти записи, у которых поле PARENTID содержит некорректные данные.
  3. Особое внимание уделим записям, где значение в поле ID совпадает со значением в поле PARENTID. Это и есть прямая петля.
  4. Чтобы «вылечить» такой элемент, нужно вручную очистить поле PARENTID (заполнить его пробелами) — тогда элемент переместится в корень справочника, или прописать ID корректной родительской папки.
  5. Проверим также поле ISGROUP. Если папка помечена как элемент или наоборот, это также создаст проблемы в интерфейсе.

Шаг 2: Правильное перестроение индексов

Проанализируем ситуацию, когда стандартная переиндексация при запуске 1С не помогает. Это происходит потому, что 1С проверяет лишь целостность заголовка индексного файла. Если файл .CDX логически поврежден из-за прерванной записи, автоматическая проверка может его пропустить.

Рассмотрим правильный порядок действий для восстановления индексов:

  1. Завершим работу всех пользователей в базе.
  2. Зайдем в каталог базы данных и удалим вручную все файлы с расширением .CDX.
  3. Запустим 1С в монопольном режиме. Программа сообщит об отсутствии индексов и предложит их перестроить.
  4. После завершения этой процедуры индексы будут созданы «с чистого листа» на основе исправленных нами данных в DBF.

Шаг 3: Исправление программного алгоритма (Профилактика)

Чтобы в будущем избежать подобных проблем, наш код должен содержать защиту от «зацикливания». Рассмотрим, как дополнить процедуру переноса проверкой на вложенность. Нам нужно убедиться, что ПапкаПриёмник не является дочерним элементом по отношению к переносимому объекту ТекЭл.


Функция ПроверитьЦикл(Элемент, НовыйРодитель)
    ВремРодитель = НовыйРодитель;
    Пока ВремРодитель.Выбран() = 1 Цикл
        Если ВремРодитель.ТекущийЭлемент() = Элемент Тогда
            Возврат 1; // Обнаружена попытка переноса родителя в дочернюю папку
        КонецЕсли;
        ВремРодитель = ВремРодитель.Родитель;
    КонецЦикла;
    Возврат 0;
КонецФункции

// В основном цикле переноса используем:
Если ПроверитьЦикл(ТекЭл, ПапкаПриёмник) = 0 Тогда
    Спр1.Родитель = ПапкаПриёмник;
    Спр1.Записать();
Иначе
    Сообщить("Нельзя перенести папку в саму себя или в подчиненную папку!");
КонецЕсли;

Этот простой цикл поднимается от целевой папки вверх к корню справочника. Если на этом пути встречается наш перемещаемый элемент — значит, мы пытаемся совершить недопустимое действие, которое приведет к краху иерархии. Проанализировав этот метод, мы видим, что он гарантирует логическую целостность справочника даже при ошибках пользователя.

Дополнительные рекомендации по диагностике

Если после всех исправлений элементы все равно ведут себя странно, проанализируем еще два фактора. Во-первых, проверьте наличие локального кеша. В 1С 7.7 это могут быть временные файлы в папке пользователя. Попробуйте очистить каталог пользователя в папке базы данных. Во-вторых, убедитесь, что при переносе не нарушается логика «Группы и элементы». В 1С 7.7 существует ограничение: если в справочнике установлена настройка «Использовать группы», то у обычного элемента родителем может быть только группа. Если программно назначить родителем обычный элемент, структура справочника станет непредсказуемой.

Подведем итог: восстановление «сломанного» справочника в 1С 7.7 требует комплексного подхода — от низкоуровневой правки данных в DBF до модификации кода с использованием защитных проверок. Соблюдение этих правил позволит вам уверенно управлять данными и быстро ликвидировать последствия программных сбоев.

← На главную