Загрузка таблицы Excel до 10 000 строк в 1С 8.2 Управляемые формы
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Я один раз для считывания матрицы 3000 строк х 200 столбцов банальным копи-пастом воспользовался.
Получилось довольно шустро. Может и вам пригодится...
На управляемой форме разместил реквизит типа 'ТабличныйДокумент', обозвал его 'ТаблицаДанных'.
Ну и по кнопочке на клиенте выполняю код:
Происходит вставка данных из буфера обмена Windows, а дальше из табличного документа считывайте их куда нужно...
Получилось довольно шустро. Может и вам пригодится...
На управляемой форме разместил реквизит типа 'ТабличныйДокумент', обозвал его 'ТаблицаДанных'.
Ну и по кнопочке на клиенте выполняю код:
Excel = Новый COMОбъект("Excel.Application");
Книга = Excel.WorkBooks.Open("ИмяФайла");
Range = Excel.Sheets(1).Range(("A1:GR3000"));
Range.Select();
Range.Copy();
ЭтаФорма.ТекущийЭлемент = Элементы.ТаблицаДанных;
WSHShell = Новый COMОбъект("WScript.Shell");
WSHShell.SendKeys("^v"); // имитация нажатия клавиш ctrl+v
Происходит вставка данных из буфера обмена Windows, а дальше из табличного документа считывайте их куда нужно...
(3) zamichnik, странно. я такое тоже пробовал. однако результат был противоположным - считывание с табличного документа происходило медленне, чем считывание из экселя.
причём - разница была видна невооружённым взглядом.
потом уже нарыл в инете, что 1с с табличным документом работает медленннее, чем с экселем.
если переубедите - буду рад.
причём - разница была видна невооружённым взглядом.
потом уже нарыл в инете, что 1с с табличным документом работает медленннее, чем с экселем.
если переубедите - буду рад.
тоже мудохался. в итоге счас гружу через:
скорости не прибавилось, правда. но зато, удобнее работать - не нужно вычислять ячейку типа R..C..
Excel = Новый COMОбъект("Excel.Application");
WB = Excel.Workbooks.Open(ИмяФайла);
WS = WB.Worksheets(1);
Excel.range("A1").value=текущаядата(); // это чтоб с первой ячейки был массив
arr = WS.UsedRange.Value;
WB.Close(0);
Excel.quit();
Excel = Неопределено;
...
МассивКолонок = arr.Выгрузить();
ОбщееКоличествоКолонок = arr.GetUpperBound(0);
ОбщееКоличествоСтрок = arr.GetUpperBound(1);
Для Инд = 1 По ОбщееКоличествоСтрок Цикл
НовСтр = товары.Добавить();
КонецЦикла;
Показатьскорости не прибавилось, правда. но зато, удобнее работать - не нужно вычислять ячейку типа R..C..
(1) Farkhod82, че-то не заметил в обсуждении, какая же часть обработки занимает больше всего времени. И сколько колонок в екселе, и куда все это складируется.
Через Оле перебор пусть даже 10000 строк Екселя не занимает четыре часа.
Короче, где замер производительности-то? :)
Через Оле перебор пусть даже 10000 строк Екселя не занимает четыре часа.
Короче, где замер производительности-то? :)
(1) Farkhod82, а я при загрузке больших таблиц из EXCEL (11 000 тыс примерно) копирую изначально таблицу в буфер, затем создаю текстовый документ и загоняю данные из буфера туда. Там конечно уже не таблица, а обычный текст в котором колонки разнесены по специальному символу. Дальше читаю строчку, по символу ее режу и уже получаю конкретные колонки.
Работает быстро. Код примерно такой:
Код "нарезан" из обработки.
МАС[0] - первая колонка EXCEL и т.д..
КОнечно, не совсем универсальный способ, так как если где то в ячейке есть "Символ(9)" то вся схема летит :) но в моем случае подходит. Ускорение было в разы.
ЗЫ. Блин, по сути дела продублировал 3 пост. Виноват :( Правда операторы немного другие - но суть та же
Работает быстро. Код примерно такой:
оЭксел = новый COMОбъект("Excel.Application");
оКнига = оЭксел.WorkBooks.Open(ИмяФайла);
оЛист = оКнига.Worksheets(1);
оЛист.Cells.Copy();
ОбъектКопирования = Новый COMОбъект("htmlfile");
Текст = новый ТекстовыйДокумент;
Текст.УстановитьТекст(ОбъектКопирования.ParentWindow.ClipboardData.Getdata("Text"));
для Индикатор=ПерваяСтрока по МаксСтрок цикл
рез = Текст.ПолучитьСтроку(Индикатор);
Мас = Общие.СтрокуВМассив(рез,Символ(9),истина); // уже массив колонок
Мас.Добавить(""); // для пустых колонок
КонецЦикла
ПоказатьКод "нарезан" из обработки.
МАС[0] - первая колонка EXCEL и т.д..
КОнечно, не совсем универсальный способ, так как если где то в ячейке есть "Символ(9)" то вся схема летит :) но в моем случае подходит. Ускорение было в разы.
ЗЫ. Блин, по сути дела продублировал 3 пост. Виноват :( Правда операторы немного другие - но суть та же
У себя использую так:
Взято с мисты, ссылку не помню.
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source = "+ПутьКФайлуОтчета;
СтрокаПодключения = СтрокаПодключения + "; Extended Properties = "+"""Excel 12.0"+";HDR=NO;IMEX=1"";";
// Подключаемся
Об_Конект = Новый COMОбъект("ADODB.Connection");
Попытка
Об_Конект.Open(СтрокаПодключения);
Исключение
Сообщить ("Невозможно подключится к Microsoft Excel Driver!!! Возможно файл ["+ПутьКФайлуОтчета+"] открыт другим пользователем.");
Возврат;
КонецПопытки;
СтрЗапроса = "
|SELECT *
|FROM [A" + Формат(2,"ЧГ=0") + ":CZ" + Формат(99999,"ЧГ=0") + "]
|"; //данный запрос выбирает все заполненные ячейки листа, однако можно наложить условия отбора. синтаксис SQL
Попытка
RecordSet = Об_Конект.Execute(СтрЗапроса);
Исключение
Сообщить("Не удалось выполнить запрос к файлу Excel "+ ОписаниеОшибки(),СтатусСообщения.Важное);
Возврат;
КонецПопытки;
Пока НЕ RecordSet.EOF() Цикл
ШтрихКод = RecordSet.Fields(3).value;
Количество = RecordSet.Fields(5).value;
ЦенаКомитента = RecordSet.Fields(6).value;
СуммаНДСКомитента = RecordSet.Fields(8).value;
СуммаКомитента = RecordSet.Fields(7).value;
ЦенаПродажи = RecordSet.Fields(9).value;
СуммаНДСПродажи = RecordSet.Fields(11).value;
СуммаПродажи = RecordSet.Fields(10).value;
ЗагрузитьСтрокуОтчета(ОтчетКомиссионера,ШтрихКод,Количество, ЦенаКомитента,СуммаНДСКомитента,СуммаКомитента,ЦенаПродажи,СуммаНДСПродажи,СуммаПродажи);
RecordSet.MoveNext();
КонецЦикла;
ПоказатьВзято с мисты, ссылку не помню.
Всем спасибо, буду пробовать варианты в ответах 2 и 3, на 10 тыс. строках. Кто быстрее.
Объясню почему 3-4 часа, колонок у таблицы около 20, и много нюансов по втягу, такие как найти номенклатура по коду, если не нашли, создать новую. То же самое с контрагентом, Партнером и т.д.
Объясню почему 3-4 часа, колонок у таблицы около 20, и много нюансов по втягу, такие как найти номенклатура по коду, если не нашли, создать новую. То же самое с контрагентом, Партнером и т.д.
Хоть и старый пост но может кому будет интересно, самый быстрый на сегодня способ который смог реализовать....
&НаСервере
Процедура ЗаполнитьТаблицу(МассивДанных,КоличествоСтрок)
Объект.ТаблицаЗагрузки.Очистить();
НашаТаблица=Объект.ТаблицаЗагрузки.Выгрузить();
Для инд=1 по КоличествоСтрок Цикл
НашаТаблица.Добавить();
КонецЦикла;
инд=0;
Для каждого СтрокаМассива из МассивДанных Цикл
Если инд=0 Тогда
НашаТаблица.ЗагрузитьКолонку(СтрокаМассива,"ТорговаяТочка");
ИначеЕсли инд=1 Тогда
НашаТаблица.ЗагрузитьКолонку(СтрокаМассива,"Номенклатура");
ИначеЕсли инд=2 Тогда
НашаТаблица.ЗагрузитьКолонку(СтрокаМассива,"КодТМЦ");
ИначеЕсли инд=3 Тогда
НашаТаблица.ЗагрузитьКолонку(СтрокаМассива,"План");
КонецЕсли;
инд=инд+1;
КонецЦикла;
Если НашаТаблица.Количество()>0 Тогда
НашаТаблица.Удалить(НашаТаблица[0]);
КонецЕсли;
Объект.ТаблицаЗагрузки.Загрузить(НашаТаблица.Скопировать());
Для каждого СтрокаТаблицы из Объект.ТаблицаЗагрузки Цикл
СтрокаТаблицы.ТМЦ=Справочники.Номенклатура.НайтиПоКоду(Прав("000000"+СтрЗаменить(СтрокаТаблицы.КодТМЦ,Символ(160),""),6));
СтрокаТаблицы.ТоварнаяГруппа=СтрокаТаблицы.ТМЦ.ПоследняяТоварнаяГруппа;
СтрокаТаблицы.Магазин=Справочники.ПР_ТорговыеТочки.НайтиПоНаименованию(СокрЛП(СтрокаТаблицы.ТорговаяТочка));
СтрокаТаблицы.КлассификацияD=?(СтрокаТаблицы.ТМЦ.Классификация=Справочники.Ном_КлассификацияНоменклатуры.Классификация_D,Истина,Ложь);
Если СтрокаТаблицы.ТМЦ=Справочники.Номенклатура.ПустаяСсылка() Тогда
Сообщить("Не найдена номенклатура по коду: "+СтрокаТаблицы.КодТМЦ+" наименование "+СтрокаТаблицы.Номенклатура);
КонецЕсли;
Если СтрокаТаблицы.Магазин=Справочники.ПР_ТорговыеТочки.ПустаяСсылка() Тогда
Сообщить("Не найдена торговая точка по наименованию: "+СтрокаТаблицы.ТорговаяТочка);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузитьИзЭкселя(Команда)
Попытка
Excel = Новый COMОбъект("Excel.Application");
ФайлХЛС=Excel.Application.Workbooks.Open(ПутьКФайлу);
Состояние("Обработка файла Microsoft Excel...");
ExcelЛист = Excel.Sheets(1);
Исключение
Сообщить("Ошибка. Возможно неверно указан номер листа книги Excel.");
Возврат;
КонецПопытки;
КонечнаяСтрокаДанных=ФайлХЛС.ActiveSheet.UsedRange.Rows.Count;
КоличествоКолонокДанных=ФайлХЛС.ActiveSheet.UsedRange.Columns.Count;
Состояние("Загрузка в память данных Excel...");
ExcelЛист=ФайлХЛС.ActiveSheet;
Область = Excel.Range(ExcelЛист.Cells(1,1), ExcelЛист.Cells(КонечнаяСтрокаДанных,КоличествоКолонокДанных));
МассивДанныхEXEL = Область.Value.Выгрузить();
Excel.WorkBooks.Close();
ЗаполнитьТаблицу(МассивДанныхEXEL,КонечнаяСтрокаДанных);
Excel.Quit();
КонецПроцедуры
Показать
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот