Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/25: Рейтинг темы: голосов - 25, средняя оценка - 4.56
 Аватар для Air_force
1 / 1 / 0
Регистрация: 24.05.2017
Сообщений: 10

Наиболее быстрый способ работы с файлом Excel (около 20000 строк)

24.05.2017, 11:17. Показов 5223. Ответов 11

Студворк — интернет-сервис помощи студентам
Здравствуйте ребята, хотел спросить у вас совета. Есть программа по распечатке ценников по артикулу или штрихкоду товара. Какой обработкой лучше пользоваться для взаимодействия с файлом Excel, для увеличения скорости.
Сейчас использую вариант, приведенный ниже. Суть в том, что по артикулу вытаскивается наименование и цена из таблицы. Если ценников около десятка, то приходится ждать около 15-20 сек. И это при том. что я сократил таблицу, до 2500 строк. Столбца 4 - это штрихкод, артикул, цена и наименование (здесь приведен поиск по артикулу). Я хотел бы увеличить количество строк в идеале вообще до 127000, но чувствую тут никакая обработка наверно не поможет, ну хотя бы до 15000-20000. На компьютерах будет стоять Excel 2016. Если даже сложный вариант предложите, я согласен, освою лишь бы скорость обработки увеличить. Честно я начинающий в этой сфере,так что грубо не судите, ещё хотел спросить, может ли здесь помочь многопоточность?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
            excelapp = new Excel.Application();
            excelapp.Visible = false;
            excelapp.Workbooks.Open(@"C:\Users\Air\Desktop\Ready_base.xlsm");
            Excel.Workbook WB = excelapp.ActiveWorkbook;
            Excel.Worksheet WS = excelapp.ActiveSheet;
            int LastRow = WB.Sheets[1].Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
 
            // A это штрихкод, B это артикул
 
            
            string FindObj = String.Empty;
            string Obj = String.Empty;
            string Name = String.Empty;
 
            // нулевой элемент массива
            
            for (i = 0; i < j1; i++)
            {
                FindObj = STR_art_1[i];
 
                for (j=1; j<LastRow;j++)
                {
                    Name = "B" + j;
                    Excel.Range ObjE = WS.get_Range(Name, Type.Missing);
                    Obj = Convert.ToString(ObjE.Value2);
 
                    if (FindObj == Obj)
                    {
 
                        //получаю артикул
                        ObjE = WS.get_Range(Name, Type.Missing);
                        Shablon_1[k1, 0] = Convert.ToString(ObjE.Value2);
 
                        //получаю наименование
                        Name = "C" + j;
                        ObjE = WS.get_Range(Name, Type.Missing);
                        Shablon_1[k1, 1] = Convert.ToString(ObjE.Value2);
 
                        //получаю цену
                        Name = "D" + j;
                        ObjE = WS.get_Range(Name, Type.Missing);
                        Shablon_1[k1, 2] = Convert.ToString(ObjE.Value2);
 
                        k1++;
                        break;
                    }
                }
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.05.2017, 11:17
Ответы с готовыми решениями:

Ниболее быстрый способ работы с файлом Excel (более 100 000 строк) Java
Добрый вечер друзья! В С# есть такая команда, которая одним махом кидает весь лист в двумерный массив(неопределенного типа), можете...

Наиболее эффективный способ работы с книгой Excel
Достал отсюда код, для чтения таблицы в List&lt;List&lt;string&gt;&gt;: int row = 1; List&lt;List&lt;string&gt;&gt; maping =...

Наиболее быстрый способ записи в консоль
Какой наиболее быстрый способ отрисовки символов в консоли, если использовать исключительно WinAPI? Заранее благодарю за ответы

11
 Аватар для kesean
292 / 291 / 108
Регистрация: 04.09.2010
Сообщений: 638
24.05.2017, 11:28
Если данные в книге Excel в "нормальном" виде (т.е., таблица начинается в ячейке "А1", нет пустых или объединенных строк, и т.д.), то самый быстрый способ выгрузить данные, имхо, - OLEDB. Примеров в сети хватает. Но большие объемы данных хранить в Excel не комильфо. Для этого существуют СУБД.
0
 Аватар для Air_force
1 / 1 / 0
Регистрация: 24.05.2017
Сообщений: 10
24.05.2017, 11:54  [ТС]
Вообще именно так, нет пропусков и нет объединенных ячеек, спасибо, обязательно гляну. Просто я неплохо знаю VBA и мне относительно легко работать с Excel. При работе с файлами СУБД например Microsoft Access'а скорость выше?
0
999 / 358 / 135
Регистрация: 27.10.2006
Сообщений: 764
25.05.2017, 16:36
Лучший ответ Сообщение было отмечено Air_force как решение

Решение

Я не очень понял, вы записываете данные в Excel или хотите получить данные из Excel?
Если вам нужно получить данные из Excel, то лучше никогда не обращаться к ячейкам Excel в цикле, т.к. этот процесс очень долгий.
Вам нужно открыть Excel, взять все данные с листа в массив, а дальше уже циклами искать нужные данные в этом массиве. Этот подход намного быстрее, чем бегать в цикле по ячейкам Excel.

Последнюю строку, например, в столбце А вы можете найти так
int iLastRow = xlSht.Cells[xlSht.Rows.Count, "A"].End[Excel.XlDirection.xlUp].Row;

Взять данные в двумерный массив можно так
var arrData = (object[,])xlSht.Range["A1:Z" + iLastRow].Value;

если есть пустые ячейки на листе, то в массиве они будут как null, при проверке вам нужно это проверять
if (arrData[iRow, iCol] != null)

Таким образом вы намного ускорите работу программы
2
 Аватар для Air_force
1 / 1 / 0
Регистрация: 24.05.2017
Сообщений: 10
26.05.2017, 15:05  [ТС]
Оо Pavel55, вот это интересно, спасибо большое, обязательно попробую.

Добавлено через 2 часа 21 минуту
Pavel55 протестировал на поиске 10 ценников получилось примерно 1с против 30 с в 30 раз скорость выросла. Спасибо!!!
0
360 / 287 / 76
Регистрация: 21.06.2016
Сообщений: 1,115
27.05.2017, 16:48
А если еще и перетащить данные в сиквел, то за 1 сек сможете доставать из записей в миллионы строк ))
1
 Аватар для Air_force
1 / 1 / 0
Регистрация: 24.05.2017
Сообщений: 10
27.05.2017, 20:27  [ТС]
hoolygan, скорость итак на высоте, он за пару секунд осуществил поиск по 120000 строк. SQL мне ещё осваивать, но я рад, если скорости такие... Надо будет глянуть как перенести данные в БД из Excel'я.
0
0 / 0 / 0
Регистрация: 02.04.2018
Сообщений: 10
03.04.2018, 00:06
Добавлено через 1 минуту
Цитата Сообщение от hoolygan Посмотреть сообщение
А если еще и перетащить данные в сиквел, то за 1 сек сможете доставать из записей в миллионы строк ))
поясните, что за сиквел? спасибо

Добавлено через 2 минуты
Цитата Сообщение от Pavel55 Посмотреть сообщение
Я не очень понял, вы записываете данные в Excel или хотите получить данные из Excel?
Если вам нужно получить данные из Excel, то лучше никогда не обращаться к ячейкам Excel в цикле, т.к. этот процесс очень долгий.
Вам нужно открыть Excel, взять все данные с листа в массив, а дальше уже циклами искать нужные данные в этом массиве. Этот подход намного быстрее, чем бегать в цикле по ячейкам Excel.

Последнюю строку, например, в столбце А вы можете найти так
int iLastRow = xlSht.Cells[xlSht.Rows.Count, "A"].End[Excel.XlDirection.xlUp].Row;

Взять данные в двумерный массив можно так
var arrData = (object[,])xlSht.Range["A1:Z" + iLastRow].Value;

если есть пустые ячейки на листе, то в массиве они будут как null, при проверке вам нужно это проверять
if (arrData[iRow, iCol] != null)

Таким образом вы намного ускорите работу программы
можете небольшой пример привести? что бы лучше до меня дошло, спасибо)

Добавлено через 45 секунд
Цитата Сообщение от Air_force Посмотреть сообщение
Оо Pavel55, вот это интересно, спасибо большое, обязательно попробую.

Добавлено через 2 часа 21 минуту
Pavel55 протестировал на поиске 10 ценников получилось примерно 1с против 30 с в 30 раз скорость выросла. Спасибо!!!
можете поделиться кодом, что получилось? у меня та же проблема по считыванию из екселя. спасибо

Добавлено через 9 минут
Pavel55 Разве переменная arrData банально не будет ссылаться на все тот же Range? Откуда тут "копирование" и увеличение скорости?
0
Эксперт .NET
 Аватар для Usaga
14073 / 9290 / 1347
Регистрация: 21.01.2016
Сообщений: 34,877
03.04.2018, 05:53
Цитата Сообщение от pucher Посмотреть сообщение
поясните, что за сиквел? спасибо
Любая реляционная СУБД.
0
0 / 0 / 0
Регистрация: 02.04.2018
Сообщений: 10
03.04.2018, 08:53
Цитата Сообщение от Pavel55 Посмотреть сообщение
Я не очень понял, вы записываете данные в Excel или хотите получить данные из Excel?
Если вам нужно получить данные из Excel, то лучше никогда не обращаться к ячейкам Excel в цикле, т.к. этот процесс очень долгий.
Вам нужно открыть Excel, взять все данные с листа в массив, а дальше уже циклами искать нужные данные в этом массиве. Этот подход намного быстрее, чем бегать в цикле по ячейкам Excel.

Последнюю строку, например, в столбце А вы можете найти так
int iLastRow = xlSht.Cells[xlSht.Rows.Count, "A"].End[Excel.XlDirection.xlUp].Row;

Взять данные в двумерный массив можно так
var arrData = (object[,])xlSht.Range["A1:Z" + iLastRow].Value;

если есть пустые ячейки на листе, то в массиве они будут как null, при проверке вам нужно это проверять
if (arrData[iRow, iCol] != null)

Таким образом вы намного ускорите работу программы
1. Разве переменная arrData банально не будет ссылаться на все тот же Range? Откуда тут "копирование" и увеличение скорости?
2. Решил проверить пример, но возник вопрос. Есть
var arrData = excelworksheet.get_Range("A8", "P5029").Value;
В отладке видно, что в этой переменной храниться двумерный массив, все ок.
Как перебрать такой массив arrData ? Через for (int i = 0; i < arrData.; i++) не могу обратиться к размерности. Через foreach (var item in arrData) пишет не реализован GetEnumerator. Спасибо
0
 Аватар для Air_force
1 / 1 / 0
Регистрация: 24.05.2017
Сообщений: 10
03.04.2018, 09:17  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
 
 
            string[,] arrLast_b = new string[100000, 5];
             
            //Загрузка массива базы 
            excelapp.Workbooks.Open(@Directory.GetCurrentDirectory() +"\\Ready_base.xlsx");
            Excel.Workbook WB = excelapp.ActiveWorkbook;
            Excel.Worksheet WS = excelapp.ActiveSheet;
            //беру последнюю строку листа
            int LastRow = WB.Sheets[1].Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
            //переменная для поиска элемента(мне нужна была в программе)
            string FindObj = String.Empty;
            //массив "общего" типа, потом в строку конвертирую
            var arrReady_b = (object[,])WS.Range["A1:E" + LastRow].Value;
            //массив есть теперь эксель не нужен, с массивом можно работать
            WB.Close(false);
            excelapp.Quit();
            //excelapp = null;
            GC.Collect();
 
                for (int j1 = 1; j1 <= LastRow; j1++)
                {
                    //контроль пустых строк, заменяю их пробелами, чтобы потом С# не переживал, крича о ошибках
                    if (arrReady_b[j1, 2] == null)
                        arrReady_b[j1, 2] = " ";
                    if (arrReady_b[j1, 3] == null)
                        arrReady_b[j1, 3] = " ";
                    if (arrReady_b[j1, 4] == null)
                        arrReady_b[j1, 4] = " ";
                    arrReady_b[j1, 5] = "0";
                 }
 
                 //в строку преобразуешь и радуешься
                 arrLast_b[2, 1] = arrReady_b[2, 2].ToString();
Добавлено через 1 минуту
Сиквел - SQL ...

Добавлено через 2 минуты
Перебор вот:
последнюю строку беру
int LastRow = WB.Sheets[1].Cells.SpecialCells(Excel.XlCellType.xlC ellTypeLastCell).Row;
и вперед
for (int i = 1; i <= LastRow; i++)

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

По скорости - да он берёт диапазон, но для меня важно это было, потому что изначально я построчно брал (или даже пояйчейкам), а это атас полный, все через модуль чтения эксель. А так забрал диапазон и до свиданья и работаешь с массивом...

Добавлено через 9 минут
По ячейкам брал, видно из примера...
0
999 / 358 / 135
Регистрация: 27.10.2006
Сообщений: 764
04.04.2018, 10:29
pucher,

посмотрите пример тут Считать ячейку из excel

1. Разве переменная arrData банально не будет ссылаться на все тот же Range? Откуда тут "копирование" и увеличение скорости?

- нет, если вы взяли данные с листа в двумерный массив, то привязки между массивом и данными на листе нет.
C#
1
var arrData = (object[,])xlSht.Range["A1:Z" + iLastRow].Value;
2. Решил проверить пример, но возник вопрос. Есть var arrData = excelworksheet.get_Range("A8", "P5029").Value;
В отладке видно, что в этой переменной храниться двумерный массив, все ок.
Как перебрать такой массив arrData ? Через for (int i = 0; i < arrData.; i++) не могу обратиться к размерности. Через foreach (var item in arrData) пишет не реализован GetEnumerator. Спасибо

вот так можно узнать размерность массива и работать с ним в цикле

C#
1
2
3
4
5
6
7
8
9
10
11
int iTotalRows = arrData.GetUpperBound(0);
int iTotalColumns = arrData.GetUpperBound(1);
 
for (int iRow = 1; iRow <= iTotalRows; iRow++) //цикл по строкам
{                
        for (int iCol = 1; iCol <= iTotalColumns; iCol++) //цикл по столбцам
        {
            //что-то делаем с данными
            //arrResult[iRowInResultArray, iCol-1] = arrData[iRow, iCol].ToString(); //перекладываем данные с общего массива в чистый массив
        }            
}

Только надо проверять значение в массиве на null (если ячейка была пустая)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.04.2018, 10:29
Помогаю со студенческими работами здесь

Наиболее быстрый способ склеивания фрагментов файла
Имеется несколько фрагментов одного файла. Требуется собрать эти фрагменты в исходный файл. Размеры фрагментов могут быть разными, от...

Наиболее быстрый способ забрать данные из html
Мне нужно забрать данные с вебстранички. Там может содержаться просто одно слово, например &quot;ОК&quot;, в этом случае использую...

Наиболее быстрый способ сортировки файла в 1 Тб при ограниченном объёме оперативной памяти
Привет! Какой есть наиболее быстрый способ сортировки файла, содержащего int-ы (по одному int-у на каждой строчке), размером в 1...

Наиболее быстрый способ сравнения двух экземпляров структур на предмет одинаковости их полей
Есть структура, в которой есть несколько int-ов и char-ов, какой имеется наиболее быстрый способ в C/C++ для сравнения двух экземпляров...

Быстрый способ работы с recordset
Хочу поделится способом работы с recordset'ом, который работает примерно на 30% быстрее: Пример: Имеется Public rs As...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru