Вход | Регистрация

1С:Предприятие ::

Метки:Обмен данными и УРБД

Загрузка прайса в Ехселе в справочник

Я
   Ерж
26.05.04 - 22:54
Помогите загрузить Прайс.xls с 5000 наименованиями в справочник Номенклатура. Что за процедура и в каком модуле её располагают. Я только 3 месяца изучаю 1С, пытаюсь написать конфигу "Оперативный учет" для аптеки. Если можно подробнее объясните начинающему
 
  Рекламное место пустует
   It is me
 
1 - 26.05.04 - 23:09
Перем Excel, ТекСтрока, Разделитель, СпрМетаданные, спРеквизиты, Столбцов, Дубль, Справочник;

// ===============================

Процедура ПриОткрытии()
    ДатаДок = НачМесяца(РабочаяДата())-1;      
    
    Для Инд = 1 По Метаданные.Справочник() Цикл    
        Если Метаданные.Справочник(Инд).Владелец.Выбран() = 0 Тогда
            спСправочники.ДобавитьЗначение(Метаданные.Справочник(Инд).Идентификатор,Метаданные.Справочник(Инд).Синоним);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

// ===========================

Функция ПроверкаЗаписьРеквизитов()
    Для Стлб = 3 По Столбцов Цикл
        Если ((Строка(Excel.Cells(1, Стлб).Value) = "Наименование") или (Строка(Excel.Cells(1, Стлб).Value) = "Код")) Тогда
           // зарезервированные

            Продолжить;
        ИначеЕсли (СпрМетаданные.Реквизит(Строка(Excel.Cells(1, Стлб).Value)).Выбран() = 0) Тогда
           // нет такого реквизита в справочнике

            глКомментарий("Справочник не может быть загружен! В файле присутствуют реквизиты, которых нет в данном справочнике. Колонка "+Стлб+".", 0,,"!");
            Возврат 0;
        КонецЕсли;
    КонецЦикла;
    
    спРеквизиты = СоздатьОбъект("СписокЗначений");
    Для Стлб = 3 По Столбцов Цикл
        спРеквизиты.ДобавитьЗначение(СокрЛП(Строка(Excel.Cells(1, Стлб).Value)));
    КонецЦикла;
    Возврат 1;
КонецФункции

// ===============================

Процедура ОпределитьРодителя()
    Справочник.ИспользоватьРодителя(0);
    КодС = Сокрлп(Excel.Cells(ТекСтрока, 2).Value);
    Если Дубль = 1 Тогда
        Возврат;
    КонецЕсли;

    Поз = СтрДлина(КодС);
    Пока Поз > 1 Цикл
        Если Сред(КодС, Поз, 1) = Разделитель Тогда
            КодРодителя = Лев(КодС, Поз-1);
            Род = СоздатьОбъект("Справочник."+Справочник.Вид());
            Если Род.НайтиПоРеквизиту("СтарыйПолныйКод", КодРодителя, 1) = 1 Тогда
                Попытка
                    Справочник.ИспользоватьРодителя(Род.ТекущийЭлемент());
                Исключение
                    глКомментарий("Родителем для записи должна быть запись, у которой установлен тип группа (Г)! Строка "+ТекСтрока,1,,"!");
                КонецПопытки;
            КонецЕсли;
            Возврат;
        КонецЕсли;
        Поз = Поз -1;   
    КонецЦикла; 
КонецПроцедуры

// ===========================

Функция Обработать(ВидЗаписи)
    Справочник.ИспользоватьДату(ДатаДок);
    ОпределитьРодителя(); 
    Если Дубль = 1 Тогда  
        КодС = Строка(Excel.Cells(ТекСтрока, 2).Value);
        Справочник.НайтиПоРеквизиту("СтарыйПолныйКод", КодС, 1);
    ИначеЕсли ВидЗаписи = "Элемент" Тогда
        Справочник.Новый();          
    Иначе
        Справочник.НоваяГруппа();          
    КонецЕсли;
    
    Справочник.СтарыйПолныйКод = Строка(Excel.Cells(ТекСтрока, 2).Value);

    Для Инд = 1 По спРеквизиты.РазмерСписка() Цикл
        Если Сокрлп(Excel.Cells(ТекСтрока, (Инд+2)).Value) = "" Тогда
           // в ячейке ничего нет

            Продолжить;
        КонецЕсли;
        Реквизит = спРеквизиты.ПолучитьЗначение(Инд); 
        Если Строка(Excel.Cells(1, (Инд+2)).Value) = "Наименование" Тогда
           // заполним наименование

            Справочник.УстановитьАтрибут(Реквизит,Строка(Excel.Cells(ТекСтрока, Инд+2).Value));
        ИначеЕсли Строка(Excel.Cells(1, (Инд+2)).Value) = "Код" Тогда
           // заполним код

            Если (СпрМетаданные.Автонумерация = 0) и (Сокрлп(Excel.Cells(ТекСтрока, (Инд+2)).Value) = "") Тогда
                глКомментарий("В строке "+ТекСтрока+" не указан код элемента справочника!", 0,,"!");
                Возврат 0;
            Иначе
                Если СпрМетаданные.ТипКода    = "Текстовый" Тогда
                    Справочник.Код = Строка(Excel.Cells(ТекСтрока, (Инд+2)).Value);
                ИначеЕсли СпрМетаданные.ТипКода    = "Числовой" Тогда                         
                    Справочник.Код = Число(Excel.Cells(ТекСтрока, (Инд+2)).Value);
                КонецЕсли;
            КонецЕсли;
        Иначе
           // произвольный реквизит

            Если (СпрМетаданные.Реквизит(Реквизит).Использование = "ДляЭлемента") и (ВидЗаписи = "Группа") 
            или (СпрМетаданные.Реквизит(Реквизит).Использование = "ДляГруппы") и (ВидЗаписи = "Элемент") Тогда
                Продолжить;
            КонецЕсли;
            
           // проверим тип реквизита

            Если СпрМетаданные.Реквизит(Реквизит).Тип = "Строка" Тогда
                Справочник.УстановитьАтрибут(Реквизит,Строка(Excel.Cells(ТекСтрока, Инд+2).Value));
            ИначеЕсли СпрМетаданные.Реквизит(Реквизит).Тип = "Число" Тогда
                Справочник.УстановитьАтрибут(Реквизит,Число(Excel.Cells(ТекСтрока, Инд+2).Value));    
            ИначеЕсли СпрМетаданные.Реквизит(Реквизит).Тип = "Дата" Тогда
                Справочник.УстановитьАтрибут(Реквизит,Дата(Excel.Cells(ТекСтрока, Инд+2).Value));    
            ИначеЕсли СпрМетаданные.Реквизит(Реквизит).Тип = "Счет" Тогда
                Сч = СчетПоКоду(Сокрлп(Excel.Cells(ТекСтрока, Инд+2).Value));
                Если Сч.Выбран() =1 Тогда
                    Справочник.УстановитьАтрибут(Реквизит, Сч);
                Иначе
                    глКомментарий("В строке "+ТекСтрока+" колонке "+(Инд+2)+" указан счет, которого нет в конфигурации",1,,"!");
                КонецЕсли;
            ИначеЕсли СпрМетаданные.Реквизит(Реквизит).Тип = "Перечисление" Тогда
               //Если Метаданные.Перечисление(СпрМетаданные.Реквизит(Реквизит).Вид).Выбран() <> 0 Тогда

               //    // есть такое

                    Пере = Перечисление.ПолучитьАтрибут(СпрМетаданные.Реквизит(Реквизит).Вид);
                    Значение = Пере.ЗначениеПоИдентификатору(СокрЛП(Строка(Excel.Cells(ТекСтрока, (Инд+2)).Value)));
                    Если ПустоеЗначение(Значение) = 1 Тогда
                        глКомментарий("В строке "+ ТекСтрока + " колонке "+(Инд+2)+" указано значение перечисления, которого нет в конфигурации",1,,"!");
                    Иначе
                        Справочник.УстановитьАтрибут(Реквизит,Значение);
                    КонецЕсли;
               //Иначе

               //    глКомментарий("В строке "+ ТекСтрока + " колонке "+(Инд+2)+" указано перечисление, которого нет в конфигурации",1,,"!");

               //КонецЕсли;

            ИначеЕсли СпрМетаданные.Реквизит(Реквизит).Тип = "Справочник" Тогда
                ВидСправочника = СпрМетаданные.Реквизит(Реквизит).Вид;
                Если ВидСправочника <> "" Тогда
                   //ПрефиксСп = СпрМетаданные.Реквизит(Строка(Excel.Cells(1, (Инд+2)).Value)).Вид;

                    Сп = СоздатьОбъект("Справочник."+ВидСправочника);
                    КодСп = Число(Excel.Cells(ТекСтрока, (Инд+2)).Value);
                    Если Метаданные.Справочник(ВидСправочника).ТипКода = "Текстовый" Тогда
                        КодСп = Строка(Excel.Cells(ТекСтрока, (Инд+2)).Value);
                    КонецЕсли;
                    Если Сп.НайтиПоКоду(КодСп) <> 0 Тогда
                        Справочник.УстановитьАтрибут(Реквизит, Сп.ТекущийЭлемент());
                    Иначе
                        глКомментарий("В строке "+ ТекСтрока+" колонке "+(Инд+2)+" ссылка на несуществующий элемент.", 1,,"!");
                    КонецЕсли;
                Иначе
                   // должен быть указан и вид справочника, и код элемента через разделитель

                    Темпл =  Строка(Excel.Cells(ТекСтрока, (Инд+2)).Value);
                    ВидСправочника = Лев(Темпл, (Найти(Темпл,Разделитель)-1));
                    Если Метаданные.Справочник(ВидСправочника).Выбран() <> 0 Тогда
                        Сп = СоздатьОбъект("Справочник."+ВидСправочника);                              
                        КодСп =  Число(Прав(Темпл, (СтрДлина(Темпл)-Найти(Темпл,Разделитель))));
                        Если Метаданные.Справочник(ВидСправочника).ТипКода = "Текстовый" Тогда
                            КодСп = Строка(Прав(Темпл, (СтрДлина(Темпл)-Найти(Темпл,Разделитель))));
                        КонецЕсли;
                        Если Сп.НайтиПоКоду(КодСп) <> 0 Тогда
                            Справочник.УстановитьАтрибут(Реквизит, Сп.ТекущийЭлемент());
                        Иначе
                            глКомментарий("В строке "+ ТекСтрока+" колонке "+(Инд+2)+" ссылка на несуществующий элемент.", 1,,"!");
                        КонецЕсли;
                    Иначе
                        глКомментарий("В строке "+ ТекСтрока+" колонке "+(Инд+2)+" указан справочник, которого нет в конфигурации.", 1,,"!");
                    КонецЕсли;
                КонецЕсли;
            ИначеЕсли СпрМетаданные.Реквизит(Реквизит).Тип = "Документ" Тогда
                ВидДокумента = СпрМетаданные.Реквизит(Строка(Excel.Cells(1, (Инд+2)).Value)).Вид;
                Если ВидДокумента <> "" Тогда
                   // документ определенного вида

                    ПрефиксДо = СпрМетаданные.Реквизит(Строка(Excel.Cells(1, (Инд+2)).Value)).Вид;
                    Док = СоздатьОбъект("Документ."+ПрефиксДо);
                    Темпл =  Строка(Excel.Cells(ТекСтрока, (Инд+2)).Value);
                    ДатаДо = Лев(Темпл, (Найти(Темпл,Разделитель)-1));
                    НомерДо = Прав(Темпл, (СтрДлина(Темпл)-Найти(Темпл,Разделитель)));
                    Если Док.НайтиПоНомеру(НомерДо, ДатаДо,) <> 0 Тогда
                        Справочник.УстановитьАтрибут(Реквизит, Док.ТекущийДокумент());
                    Иначе
                        глКомментарий("В строке "+ ТекСтрока+" колонке "+(Инд+2)+" ссылка на несуществующий документ.", 1,,"!");
                    КонецЕсли;
                Иначе
                   // документ неопределенного виды, должен быть указан и вид 

                    Темпл =  Строка(Excel.Cells(ТекСтрока, (Инд+2)).Value);
                    ПрефиксДо = Лев(Темпл, (Найти(Темпл,Разделитель)-1));
                    Темпл = Сред(Темпл, (Найти(Темпл,Разделитель)+1));
                    ДатаДо =  Дата(Лев(Темпл, (Найти(Темпл,Разделитель)-1)));   
                    НомерДо = Прав(Темпл,(СтрДлина(Темпл)-Найти(Темпл,Разделитель)));
                    Если Метаданные.Документ(ПрефиксДо).Выбран() <> 0 Тогда
                       // есть такой вид документа

                        До = СоздатьОбъект("Документ."+ПрефиксДо);
                        Если До.НайтиПоНомеру(НомерДо, ДатаДо,) <> 0 Тогда
                            Справочник.УстановитьАтрибут(Реквизит, До.ТекущийДокумент());
                        Иначе
                            глКомментарий("В строке "+ ТекСтрока+" колонке "+(Инд+2)+" ссылка на несуществующий документ.", 1,,"!");
                        КонецЕсли;
                    Иначе
                        глКомментарий("В строке "+ ТекСтрока+" колонке "+(Инд+2)+" некорректно заполнено значение.", 1,,"!");
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
            
        КонецЕсли;
    КонецЦикла;
    Попытка
        Справочник.Записать();
   Исключение
       глКомментарий("Строка "+ ТекСтрока+" не может быть корректно записана.
        |Проверьте ее заполнение. Колонка "+(Инд+2), 1,"!");
    КонецПопытки;
    Возврат 1;
КонецФункции

// ===============================

Функция ОбработатьСтроку()
   // обработка

    Состояние("Обрабатывается строка " + ТекСтрока);

    ТипПоля = Excel.Cells(ТекСтрока, 1).Value;
    СтарыйКод = Строка(Excel.Cells(ТекСтрока, 2).Value);

    Уровней = СтрЧислоВхождений(СтарыйКод, Разделитель);
    Если ((Уровней + 1) > СпрМетаданные.КоличествоУровней) Тогда
       глКомментарий("Количество уровней в заполняемом справочнике меньше,
       |чем указано в "+ТекСтрока + " строке загружаемого файла.
        |Увеличьте количество уровней в заполняемом справочнике.", 0,,"!");
        Возврат 0;
    КонецЕсли;
    
    Спр = СоздатьОбъект("Справочник."+спСправочники.ПолучитьЗначение(спСправочники.ТекущаяСтрока()));
    Дубль = Спр.НайтиПоРеквизиту("СтарыйПолныйКод", СтарыйКод, 1);
    Если (Дубль = 1) и (Обновлять = 0) Тогда
       // есть такой элемент, но обновлять не нужно

        Возврат 1;
    Иначе
        Если ВРЕГ(Лев(Строка(ТипПоля), 1)) = "Г" Тогда
            Возврат Обработать("Группа");
        ИначеЕсли ВРЕГ(Лев(Строка(ТипПоля), 1)) = "Э" Тогда
            Возврат Обработать("Элемент");
        КонецЕсли;
    КонецЕсли;
    Возврат 1;
КонецФункции

// ===============================

Процедура Выполнить()
    Если спСправочники.ТекущаяСтрока() = 0 Тогда
        Предупреждение("Выберите справочник!");
        Возврат;
    КонецЕсли;
    
    СпрМетаданные = Метаданные.Справочник(спСправочники.ПолучитьЗначение(спСправочники.ТекущаяСтрока()));
    Справочник = СоздатьОбъект("Справочник."+спСправочники.ПолучитьЗначение(спСправочники.ТекущаяСтрока()));
    
    Попытка
        Excel = СоздатьОбъект("Excel.Application");
    Исключение
        глКомментарий("Похоже, Excel на компьютере не установлен. Необходимо выполнить установку/переустановку Excel.",0,,"!");
        Возврат;
    КонецПопытки;
    
    Excel.Workbooks.Open(Сокрлп(ИмяФайла));
    Книга = Excel.ActiveWorkbook;
    
    Строк = Excel.Cells.CurrentRegion.Rows.Count;
    Столбцов = Excel.Cells.CurrentRegion.Columns.Count;
    
   // проверим наличие зарезервированных колонок

    Если (Строка(Excel.Cells(1, 1).Value) <> "ТипПоля") 
    или (Строка(Excel.Cells(1, 2).Value) <> "СтарыйПолныйКод") Тогда
        глКомментарий("Неверный формат файла! 1-я и 2-я колонки - зарезервированы.", 0,,"!");
        Возврат;
    КонецЕсли;
   // проверим наличие реквизита СтарыйПолныйКод

    Если СпрМетаданные.Реквизит("СтарыйПолныйКод").Выбран() = 0 Тогда
        глКомментарий("Справочник не может быть загружен! У данного справочника должен присутствовать реквизит СтарыйПолныйКод.", 0,,"!");
        Возврат;
    КонецЕсли;
   // проверим наличие "Сортировки" по этому реквизиту
   Если СпрМетаданные.Реквизит("СтарыйПолныйКод").Сортировка = 0 Тогда
       глКомментарий("Справочник не может быть загружен! У данного справочника у реквизита СтарыйПолныйКод должна быть отмечена 'Сортировка'.
        |(Конфигуратор - конфигурация - свойства реквизита СтарыйПолныйКод - закладка 'Дополнительные').", 0,,"!");
        Возврат;
    КонецЕсли;

    Если ПроверкаЗаписьРеквизитов() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    НачатьТранзакцию();
    Для ТекСтрока = 1 По Строк Цикл
        Если ОбработатьСтроку()= 0 Тогда
            ОтменитьТранзакцию();
            Возврат;
        КонецЕсли;
    КонецЦикла;
    ЗафиксироватьТранзакцию();
    
    Предупреждение("Справочник загружен!");        
    
    Excel.Workbooks.Close();
    Excel = 0;
    ОткрытьФорму("Справочник."+спСправочники.ПолучитьЗначение(спСправочники.ТекущаяСтрока()));
КонецПроцедуры

// ===============================

Процедура ВыбратьФайл()
    сФайл = "";
    сКатал = "";
    Если ФС.ВыбратьФайл(0,сФайл,сКатал,"Выберите файл импорта","Таблицы Excel (*.xls)|*.xls") = 1 Тогда
        ИмяФайла = сКатал+сФайл;
    КонецЕсли;
КонецПроцедуры

Разделитель = ":";

//Первая строка в Эксель должна содержать наименования реквизитов справочника. Располагать процедуру можешь где захочешь, данный пример взят из встроенной обработки типовой конфигурации, работать прямо так не будет, нужны реквизиты формы, которые (вместе с обработкой) могу выслать только на мыло или поищи на 1c.hippo.ru
   afk
2 - 26.05.04 - 23:24
Еще можно посмотреть в Торговле обработку ИмпортСправочников.


Список тем форума
  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует