Как загрузить иерархический справочник (группы и элементы) из Excel в 1С 7.7?

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

Рассмотрим задачу загрузки данных в 1С:Предприятие 7.7 из файла Excel, когда исходные данные имеют сложную структуру с вложенностью. Часто при переносе классификаторов (например, ОКОФ или номенклатуры) мы сталкиваемся с ситуацией, где иерархия зашифрована в самом коде элемента.

Разберем пример, где структура кодов выглядит следующим образом:

  1. 100 — Группа верхнего уровня.
  2. 110 — Подгруппа (входит в группу 100).
  3. 110.105.00 — Конечный элемент (входит в подгруппу 110).

Наша цель — написать обработку, которая корректно создаст дерево папок и поместит элементы в нужные родительские группы.

Стратегия решения задачи

Для платформы 1С 7.7 существует несколько подходов к загрузке иерархии. Наиболее надежный способ, который мы проанализируем, заключается в использовании предварительной загрузки данных в ТаблицаЗначений или построчной обработке с логическим вычислением родителя.

Основная сложность заключается в том, чтобы при создании элемента или подгруппы их «Родитель» (группа вышестоящего уровня) уже существовал в базе данных. Поэтому мы будем использовать алгоритм проверки существования родителя и его поиска по коду.

Алгоритм определения родителя

Исходя из структуры кодов, предложенной в задаче, мы можем выделить закономерности:

Реализация загрузки на встроенном языке 1С 7.7

Посмотрим на рабочий пример кода, который реализует эту логику. В данном случае данные сначала считываются из Excel, а затем проходят через каскад условий для определения типа создаваемого объекта (группа или элемент) и его места в иерархии.

Предположим, что мы перебираем строки файла Excel или Таблицы Значений, куда уже загрузили данные:


// Создаем объект справочника один раз перед циклом (рекомендуемый подход)
Спр = СоздатьОбъект("Справочник.ОсновныеСредства");
СпрПоиск = СоздатьОбъект("Справочник.ОсновныеСредства");

// Допустим, переменные Код и Название уже получены из ячейки Excel
// Анализируем длину кода
Если СтрДлина(Код) = 3 Тогда
    // Вычисляем предполагаемый код корневой группы (например, из 110 получаем 100)
    ПерваяЦифра = Лев(Код, 1);
    КодКорневойГруппы = ПерваяЦифра + "00";
    
    РазницаКодов = Число(Код) - Число(КодКорневойГруппы);
    
    // СЛУЧАЙ 1: Это группа первого уровня (100, 200)
    // Разница равна 0, и такой группы еще нет
    Если (РазницаКодов = 0) И (Спр.НайтиПоКоду(Код) = 0) Тогда    
        Спр.НоваяГруппа();
        Спр.Код = Код;
        Спр.Наименование = Название;
        Спр.Записать();
        
    // СЛУЧАЙ 2: Это подгруппа (110, 120)
    // Разница больше 0, такой группы нет
    ИначеЕсли (РазницаКодов > 0) И (Спр.НайтиПоКоду(Код) = 0) Тогда 
        // Ищем родителя (группу 100)
        Если СпрПоиск.НайтиПоКоду(КодКорневойГруппы) = 1 Тогда                        
            Спр.НоваяГруппа();
            Спр.Код = Код;
            Спр.Наименование = Название;  
            // Устанавливаем родителя
            Спр.Родитель = СпрПоиск.ТекущийЭлемент();
            Спр.Записать();
        Иначе 
            Сообщить("Родительская группа " + КодКорневойГруппы + " не найдена!");
        КонецЕсли;           
    КонецЕсли;
    
// СЛУЧАЙ 3: Это элемент (код длиннее 4 символов, например 110.105.00)
ИначеЕсли (СтрДлина(Код) > 4) И (Спр.НайтиПоКоду(Код) = 0) Тогда 
    // Вычисляем код родителя (первые 3 символа, т.е. 110)
    КодРодителя = Лев(Код, 3);   
    
    // Ищем родительскую подгруппу
    Если СпрПоиск.НайтиПоКоду(КодРодителя) = 1 Тогда                        
        Спр.Новый(); // Создаем элемент, а не группу
        Спр.Код = Код;
        Спр.Наименование = Название;  
        Спр.Родитель = СпрПоиск.ТекущийЭлемент();
        Спр.Записать();
    Иначе 
        Сообщить("Родитель для элемента " + Код + " не найден!");
    КонецЕсли; 
КонецЕсли;

Важные рекомендации по оптимизации

При написании подобных обработок в 1С 7.7 обратите внимание на следующие моменты:

  1. Работа с объектами OLE: Чтение из ячеек Excel (Cells) работает медленно. Если строк много, лучше сначала загрузить данные в объект ТаблицаЗначений или сохранить Excel как текстовый файл (CSV) и читать его через объект Текст.
  2. Создание объектов в цикле: В примере выше мы используем СоздатьОбъект. Старайтесь выносить создание объекта справочника за пределы цикла перебора строк. Многократное создание и уничтожение COM-объектов внутри цикла может приводить к утечкам памяти и замедлению работы.
  3. Порядок следования строк: Код будет работать корректно, только если строки в файле упорядочены (сначала группа 100, потом 110, потом элементы). Если файл не отсортирован, рекомендуется сначала загрузить его в ТаблицаЗначений, отсортировать её по колонке кода, и только потом создавать элементы справочника.
  4. Транзакции: Для ускорения записи и обеспечения целостности данных оберните цикл создания элементов в транзакцию:
    
    НачатьТранзакцию();
    // ... цикл загрузки ...
    ЗафиксироватьТранзакцию();
    

Таким образом, используя методы работы со строками (Лев, СтрДлина) и методы справочника (НайтиПоКоду, Родитель), можно восстановить любую иерархию при загрузке данных.

← На главную