Имя: Пароль:
1C
1С v8
Загрузить данные из excel в регистр сведений
0 cheshuyka324
 
06.06.22
12:21
Не понимаю уже как нужно делать...
Когда-то делал такую загрузку в справочник, все работало. А как это переделать под регистр сведений, уже вообще не понимаю...
В общем, в регистре сведений есть измерение Материал и ресурс Цена. В excel-файле так же есть колонки Материал и Цена.

Вот код обработки:

&НаСервере
Процедура ВыбратьФайлНаСервере(ИмяФайла)
    //подключаемся к эксель
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.WorkBooks.Open(ИмяФайла);
    Исключение
        Сообщить("Ошибка при открытии файла с помощью Excel");
        Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    //Получаем количество строк и колонок.
    Excel.Sheets(1).Select();
    ФайлСтрок = Excel.Cells(1,1).SpecialCells(11).Row;
    ФайлКолонок = Excel.Cells(1,1).SpecialCells(11).Column;
    
    //считываем первую строку и генерируем колонки на форме с наименованиями из файла
    ТЗ = Новый ТаблицаЗначений;
    Сч = 1;
    Пока ЗначениеЗаполнено(Excel.Cells(1, Сч).Text) Цикл
        ИмяКолонки = Excel.Cells(1, Сч).Text;
        ИмяБезПробелов = СтрЗаменить(ИмяКолонки,",",""); // убираем из имени колонок пробелы
        ТЗ.Колонки.Добавить(ИмяБезПробелов,,ИмяКолонки);
        Сч = Сч + 1;
    КонецЦикла;
    
    //считываем тело файла эксель и построчно заносим данные в табличное поле
    Для НС = 2 по ФайлСтрок Цикл // НС указываем с какой строки начинать обработку
        НоваяСтрока = ТЗ.Добавить();
        Для НК = 1 по ФайлКолонок Цикл
            //заполняем строку значениями
            ТекущееЗначение = Excel.Cells(НС, НК).Text;
            ИмяКолонки = ТЗ.Колонки[НК-1].Имя;
            НоваяСтрока[ИмяКолонки] = ТекущееЗначение;        
        КонецЦикла;
    КонецЦикла;
    Excel.DisplayAlerts = 0;
    Excel.Quit();
    Excel.DisplayAlerts = 1;
    
    
    Для каждого Об из ТЗ Цикл    
        Менеджер = РегистрыСведений.ЦеныНаМатериалы.СоздатьМенеджерЗаписи();
        Менеджер.Период = ТекущаяДата();
        Менеджер.Материал = Справочники.Материалы.НайтиПоНаименованию("Материал");
        Менеджер.Цена = Об.Цена;
        Менеджер.Записать();
    КонецЦикла;

    
КонецПроцедуры

&НаКлиенте
Процедура ВыбратьФайл(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Если Диалог.Выбрать() Тогда
        ИмяФайла = Диалог.ПолноеИмяФайла;
        ВыбратьФайлНаСервере(ИмяФайла);
    КонецЕсли;

КонецПроцедуры


Какой итог: создается лишь одна строка, в которой в поле Период загружается текущая дата, поле Материал остается пустым, а в поле Цена загружается цена из последней строки файла excel.
А хотелось бы, конечно, чтобы все строчки загрузились... В чем моя ошибка?
1 Мультук
 
гуру
06.06.22
12:25
(0)

>>>В чем моя ошибка?

В том, что вместо того, чтобы использовать отладчик, ты используешь форум.


P.S.

Менеджер.Материал = Справочники.Материалы.НайтиПоНаименованию("Материал");

В этой строке ничего не смущает?
2 mikecool
 
06.06.22
12:32
вторая ошибка - не пользуешься уже написанными обработками
3 cheshuyka324
 
06.06.22
12:37
(1) еще как смущает) но уж так сложилось, что не пойму что именно
4 PuhUfa
 
06.06.22
12:39
(3) проговори вслух самому себе что делает эта строка
5 cheshuyka324
 
06.06.22
12:39
(2) ох благодарю, потрачу еще кучу времени на поиски подходящей...
6 hhhh
 
06.06.22
12:43
(5) ну, вы должны понятьг, де у вас в экселе названия материалов?
7 skafandr
 
06.06.22
13:09
(3) В справочнике Материалы нужно искать значение из ТЗ в колонке "Материалы"
8 Гений 1С
 
гуру
06.06.22
13:11
Используй обработку для загрузки в ТЗ, а уже оттуда в регистр.

Функция ЗагрузитьТаблицуЗначенийИзФайла(ИмяФайла, Параметры = Неопределено) Экспорт
    //2021-01-19
    ТД = Новый ТабличныйДокумент();
    ТД.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Текст);
    ПараметрСтрокаШапки = 1;
    ОбязательныеПоля = Новый Массив();
    Если Параметры <> Неопределено Тогда
        Если Параметры.Свойство("СтрокаШапки") Тогда
            ПараметрСтрокаШапки = Параметры.СтрокаШапки;
        КонецЕсли;
        Если Параметры.Свойство("ОбязательныеПоля") Тогда
            ПараметрОбязательныеПоля = Параметры.ОбязательныеПоля;
        Иначе
            ПараметрОбязательныеПоля = Новый Массив();
        КонецЕсли;
    КонецЕсли;
    МассивКолонок = Новый Массив();
    МассивОбязательныхКолонок = Новый Массив();
    ТЗ = Новый ТаблицаЗначений();
    Для ИндКол = 1 ПО ТД.ШиринаТаблицы Цикл
        Текст = Сокрлп(ТД.Область(ПараметрСтрокаШапки, ИндКол).Текст);
        Если Текст = "" Тогда
            Продолжить;
        КонецЕсли;
        МассивКолонок.Добавить(ИндКол);
        ИмяКолонки = ОставитьДопустимыеДляКлючаСтруктурыСимволы(Текст, "_");
        ТЗ.Колонки.Добавить(ИмяКолонки);
        Для Каждого Эл ИЗ ПараметрОбязательныеПоля Цикл
            Если Эл = ИмяКолонки Тогда
                МассивОбязательныхКолонок.Добавить(ИндКол);
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    Для ИндСтр = ПараметрСтрокаШапки + 1 По ТД.ВысотаТаблицы Цикл
        
        ЕстьЗаполненные = ложь;
        
        Для Каждого ИндКол ИЗ МассивОбязательныхКолонок Цикл
            Текст = Сокрлп(ТД.Область(ИндСтр, ИндКол).Текст);
            Если Текст <> "" Тогда
                ЕстьЗаполненные = истина;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        
        Если НЕ ЕстьЗаполненные Тогда //Пропускаем строку
            Продолжить;
        КонецЕсли;
        
        НСтр = ТЗ.Добавить();
        Для СчКолонки = 0 По МассивКолонок.Количество() -1 Цикл
            ИндКол = МассивКолонок[СчКолонки];
            Текст = Сокрлп(ТД.Область(ИндСтр, ИндКол).Текст);
            НСтр[СчКолонки] = Текст;
        КонецЦикла;
    КонецЦикла;
    
    Возврат ТЗ;
    
КонецФункции


Функция ОставитьДопустимыеДляКлючаСтруктурыСимволы(Ключ, ЗаменятьНедопустимыеНа = "")
    ДопустимаяСтрока = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_";
    Рез = "";
    Для Инд = 1 По СтрДлина(Ключ) Цикл
        Симв = Сред(Ключ, Инд, 1);
        Если Найти(ДопустимаяСтрока, ВРег(Симв)) = 0 Тогда
            Рез = Рез + ЗаменятьНедопустимыеНа;
        Иначе
            Рез = Рез + Симв;
        КонецЕсли;
    КонецЦикла;
    Возврат Рез;
КонецФункции



&НаКлиенте
Процедура Загрузить(Команда)
    Ф = Новый Файл(ФайлЗагрузки);
    ДД = Новый ДвоичныеДанные(ФайлЗагрузки);

&НаСервере
Функция ЗагрузитьНаСервере(ДД, Расширение, Ссылка)        
    Результат = Новый Структура(
    "ОК, Ошибки" , ложь, "");
    ИмяФайла = ПолучитьИмяВременногоФайла(Расширение);
    ДД.Записать(ИмяФайла);

    ПараметрыТЗ = Новый Структура();
    ОбязательныеПоля = Новый Массив(); ОбязательныеПоля.Добавить("Номенклатура");
    ПараметрыТЗ.Вставить("ОбязательныеПоля", ОбязательныеПоля);
    ТЗ = ЗагрузитьТаблицуЗначенийИзФайла(ИмяФайла, ПараметрыТЗ);
9 kostik79
 
06.06.22
13:29
(8) А зачем вообще нужна ТЗ, если в ТД уже всё есть? Из ТД сразу в регистр.
10 kostik79
 
06.06.22
13:44
(1) Ну тут чтобы заработало, надо сначала запустить обработку вот с таким кодом:

Выборка = Справочники.Материалы.Выбрать();
Пока Выборка.Следующий() Цикл
    ТекМатериал = Выборка.Ссылка.ПолучитьОбъект();
    ТекМатериал.Наименование = "Материал";
    ТекМатериал.Записать();
КонецЦикла;

P.S.

Шутка, ТС, смотри так не делай!!!
11 kostik79
 
06.06.22
13:44
(0) Ты в справочнике "Материалы" ищешь материал с наименованием "Материал".
Менеджер.Материал = Справочники.Материалы.НайтиПоНаименованию("Материал");
Подставляй туда переменную со значением наименования материала из эксэля
Менеджер.Материал = Справочники.Материалы.НайтиПоНаименованию(НаименованияМатериалаИзЭксэля);