Информационный поток
Задания вакансии материалы разработки сообщения форума
Рубрики статей и материалов
Яндекс-директ

Иерархическая загрузка номенклатуры из Excel-файла

  • Добавить свою публикацию
  • для этого требуется регистрация

Глобальные переменные модуля:

 

Перем ExcelПоследняяСтрока;
Перем УстановкаЦен;
Перем ТипЦен;
Перем ВалютаТипаЦены;

 

Итак, обработка состоит из 3 процедур:

Первая процедура открывает окно для выбора файлика из которого будет идти загрузка.  Здесь всё предельно просто:

Процедура ФайлИмпортаНачалоВыбора(Элемент, СтандартнаяОбработка)    
	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Заголовок = НСтр("ru='Укажите имя Excel-файла");    
	Диалог.Фильтр = "(*.xls)|*.xls;*.xlsx";
    Если Диалог.Выбрать() Тогда 
       ФайлИмпорта = Диалог.ПолноеИмяФайла;
    Иначе
        Возврат;
    КонецЕсли;
КонецПроцедуры

  

После выбора файла, при нажатии на кнопку дергается эта процедура:

 

Процедура ПрочитатьИзФайла() Экспорт
	Дерево = Новый ДеревоЗначений;
    Дерево.Колонки.Добавить("ЭтоГруппа");
    Дерево.Колонки.Добавить("Наименование");
    Дерево.Колонки.Добавить("Ссылка");
    ВыбФайл = Новый Файл(ФайлИмпорта);
    Если НЕ ВыбФайл.Существует() Тогда
        Сообщить("Файл не существует!");
        Возврат;
    КонецЕсли;
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.WorkBooks.Open(ФайлИмпорта);
        Состояние("Обработка файла Microsoft Excel...");
        ExcelЛист = Excel.Sheets(1);
    Исключение
        Сообщить("Ошибка. Возможно неверно указан номер листа книги Excel.");
        Возврат;
    КонецПопытки;
    ТекСтр = 1;
    Работник    = СокрЛп(ExcelЛист.Cells(ТекСтр,2).Value);
    xlCellTypeLastCell = 11;
    ExcelПоследняяСтрока = ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Row;
    НоваяВетвь = Дерево.Строки.Добавить();
    НоваяВетвь.Наименование = СокрЛп(ExcelЛист.Cells(1,3).Value);
    НоваяВетвь.ЭтоГруппа = Истина;
    Ссылка = Справочники.Номенклатура.НайтиПоНаименованию(НоваяВетвь.Наименование, Истина);
    Если ЗначениеЗаполнено(Ссылка) Тогда
        НоваяВетвь.Ссылка = Ссылка;
    Иначе
        НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
        НоваяГруппа.Наименование = НоваяВетвь.Наименование;
        НоваяГруппа.Записать();
        НоваяВетвь.Ссылка = НоваяГруппа.Ссылка;
    КонецЕсли;
    ДобавитьВеткуВДерево(ExcelЛист, НоваяВетвь, 1, 2);
    Excel.WorkBooks.Close();
    Excel = 0;
КонецПроцедуры

 

Здесь напишу немного пояснений. Сперва создаем дерево. В дерево мы помещаем иерархию из файла. В дереве можно создать необходимые для дальнейшей работы поля. Далее производим чтение из файла и инициализируем первый элемент нашего дерева.

Третья процедура - это рекурсивный обход по дереву. При обходе создаются группы и элементы в справочнике


 Процедура ДобавитьВеткуВДерево(ExcelЛист, ТекущаяВетвь, ТекущийУровень, ТекСтр)
  
    Пока ТекСтр Цикл 
        ВетвьУдалили = Ложь;
        ПолученныйУровень = ExcelЛист.Rows(ТекСтр).OutlineLevel;
        Если ТекущийУровень < ПолученныйУровень Тогда
            // Попали в дочерний узел
            НоваяВетвь = ТекущаяВетвь.Строки.Добавить();
        ИначеЕсли ТекущийУровень > ПолученныйУровень Тогда
            // Закончили обход элементов старой группировки и перескочили на новую группировку
            НоваяВетвь = ТекущаяВетвь.Родитель.Родитель.Строки.Добавить();
        Иначе
            // Перебираем элементы текущей группировки
            НоваяВетвь = ТекущаяВетвь.Родитель.Строки.Добавить();
        КонецЕсли;
        // Если в 8 колонке этой строки ничего нет, то это группировка. Иначе - элемент
        Если СокрЛп(ExcelЛист.Cells(ТекСтр,8).Value) = "" Тогда
            НоваяВетвь.Наименование = СокрЛп(ExcelЛист.Cells(ТекСтр,3).Value);
            НоваяВетвь.ЭтоГруппа = Истина;
            // Группы ищем по наименованию. Если не нашли, то создаем
            НайденнаяГруппа = Справочники.Номенклатура.НайтиПоНаименованию(НоваяВетвь.Наименование, Истина);
            Если ЗначениеЗаполнено(НайденнаяГруппа) Тогда
                // Нашли. Такая группа уже есть в базе.
                // Проверим, совпадает ли родитель найденной группы с аналогичной группой из файла
                Если НоваяВетвь.Родитель <> Неопределено И НайденнаяГруппа.Родитель.Наименование <> НоваяВетвь.Родитель.Наименование Тогда
                    // Группы различаются. Нужно обновить группу элемента из базы
                    ОбъектНайденнойГруппы = НайденнаяГруппа.ПолучитьОбъект();
                    ОбъектНайденнойГруппы.Родитель = НоваяВетвь.Родитель.Ссылка;
                    Попытка
                        ОбъектНайденнойГруппы.Записать();
                    Исключение
                    КонецПопытки;
                КонецЕсли;
                НоваяВетвь.Ссылка = НайденнаяГруппа;
            Иначе
                // Такой группы нет в базе. Необходимо создать
                НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
                НоваяГруппа.Наименование = НоваяВетвь.Наименование;
                НоваяГруппа.Родитель = НоваяВетвь.Родитель.Ссылка;
                НоваяГруппа.Записать();
                НоваяВетвь.Ссылка = НоваяГруппа.Ссылка;
            КонецЕсли;
        Иначе
            // Номенклатуру ищем по артикулу
            НайденныйЭлемент = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", СокрЛп(ExcelЛист.Cells(ТекСтр,3).Value));
            Если ЗначениеЗаполнено(НайденныйЭлемент) Тогда
                // Нашли. Такой элемент уже есть в базе.
                // Проверим, совпадает ли группа имеющегося товара с группой аналогичного из файла
                Если НайденныйЭлемент.Родитель.Наименование <> НоваяВетвь.Родитель.Наименование Тогда
                    // Группы различаются. Нужно обновить группу элемента из базы
                    ОбъектНайденногоЭлемента = НайденныйЭлемент.ПолучитьОбъект();
                    ОбъектНайденногоЭлемента.Родитель = НоваяВетвь.Родитель.Ссылка;
                    ОбъектНайденногоЭлемента.Записать();
                КонецЕсли;
            Иначе
                // Такого элемента нет в базе. Необходимо создать
                НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
                НовыйЭлемент.Родитель = НоваяВетвь.Родитель.Ссылка;
                НовыйЭлемент.Наименование = СокрЛп(ExcelЛист.Cells(ТекСтр,4).Value);
                НовыйЭлемент.Артикул = СокрЛп(ExcelЛист.Cells(ТекСтр,3).Value);
                НовыйЭлемент.ВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товар", Истина);
                НовыйЭлемент.БазоваяЕдиницаИзмерения = Справочники.КлассификаторЕдиницИзмерения.НайтиПоНаименованию(СокрЛп(ExcelЛист.Cells(ТекСтр,8).Value));
                НовыйЭлемент.СтавкаНДС = Перечисления.СтавкиНДС.НДС0;
                НовыйЭлемент.Записать();
            КонецЕсли;
            // Элементы из дерева удаляем
            ТекущаяВетвь.Строки.Удалить(НоваяВетвь);
            ВетвьУдалили = Истина;
        КонецЕсли;
        ТекСтр = ТекСтр + 1;
        Если Не ВетвьУдалили Тогда
            ДобавитьВеткуВДерево(ExcelЛист, НоваяВетвь, ПолученныйУровень, ТекСтр);
        КонецЕсли;
    КонецЦикла;
 КонецПроцедуры

 

Здесь самое важное - это свойство OutlineLevel: "ExcelЛист.Rows(ТекСтр).OutlineLevel;". Оно содержит уровень группировки для текущей строки. По нему можно определить входит ли данная строка в какую-то группировку или нет, а так же уровень иерархии, то есть количество группировок.

Ветви дерева, которые соответствуют элементам справочника, будем из дерева удалять, чтобы оно не разросталось до жутких размеров.

 
0
Еще от автора
≡ к списку статей