![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
импорт данных из Excel [D7, WinXP]
ArhArhangel © (2005-11-08 14:56:00)Здравствуйте уважаемые мастера!
Надо реализовать импорт большого количества(несколько тысяч строк) данных из Excel в MS SQL.
Я написал программу на Delphi, которая через com считывает данные из *.xls и вносит их в MS SQL. Но программа работает медленно. (реализована через позднее связывание).
А именно: медленно работает считывание данных из Excel.
Пока ячейки не пустые, считываем данные и генерируем sql запрос.
Как только попадаются несколько подряд пустых ячеек, цикл прерывается и sql запрос отправляется на сервер.
Вопрос заключается в следующем:
Возможно ли как-нибудь по-другому искать конец документа?
Или по-другому делать импорт данных?
P.S. В документе xls всего одна таблица.
//Формирование SQL запроса
if DM.QuerySQL.Fields.FieldByNumber(1).AsInteger=0 then //Если нет записей в таблице, то выполняем добавление строк
begin
while string(Values[i,j])<>'' do //считываем поля, пока не всретим пустую ячейку
begin
sql.Add('Insert into xlsTempTab'+IntToStr(idBook)+'(id,['+Field+']) values ('+IntToStr(id)+','''+string(Values[i,j])+''')' );
inc(i);//проходим по строкам
inc(id);
FormImport.StatusBar1.Panels[1].Text:='ячейка: '+IntToStr(id);
FormImport.StatusBar1.Repaint;
end;
end
else //В противном случае, выполняем обновление строк
begin
while (string(Values[i,j])<>'') do //считываем поля, пока не всретим пустую ячейку
begin
sql.Add('Update xlsTempTab'+IntToStr(idBook)+' Set '+ '['+Field+']='''+string(Values[i,j])+''' ');
sql.Add('where id=id');// последняя строка запроса
inc(i);//проходим по строкам
inc(id);
FormImport.StatusBar1.Panels[1].Text:='ячейка: '+IntToStr(id);
FormImport.StatusBar1.Repaint;
end;
alex_*** (2005-11-10 10:29:00) [1]а что на это заморачиваться, если обращаемся к outproc серверу
Digitman (2005-11-10 10:26:00) [2]
> реализована через позднеесвязывание.
ну а что ж ты хотел ?
позднее связывание само по себе уступает в производительности раннему - всякий раз при обращении к методу интерфейса происходит разрешение имени метода в его Id, в отличии от раннего, где Id'ы методов интерфейса контроллеру автоматизации известны заранее
alex_*** (2005-11-10 10:18:00) [3]какое считывание ячеек? сказали же - определяешь Range и копируешь его в Variant. Никакого считывания ячеек
ArhArhangel (2005-11-10 10:08:00) [4]я проверял даже без использования запроса..
Медленность возникает не из за него, а из за считывания ячеек.
Может есть другие методы импорта из Excel.
Мне сказали, что к Excel можно и через АДО подключится (Provider=Jet-Extended Properties=Excel 8.x)
но как это сделать, я так и не понял..
при создании *.UDL я такого провайдера не нашёл..
Digitman (2005-11-09 09:12:00) [5]
> как ещё можно написать, чтобы не строить всякий раз при
> каждой итерации практически один и тот же текст запроса?
>
использовать запрос с параметрами
isasa (2005-11-08 21:01:00) [6]Возможно ли как-нибудь по-другому искать конец документа?
Как вариант - именованный диапазон в документе Excel.
umbra (2005-11-08 20:55:00) [7]чтобы ускорить работу программы надо как можно быстрее избавиться от экселя.
например - сохранить файл в другом формате и работать с этим новым файлом.
К тому же для определения непрерывного блока данных лучше использовать неUsedRange, аCurrentRegion
ArhArhangel (2005-11-08 19:49:00) [8]
> "тормоза" у тебя (Excel не рассматриваем) в :
>
> - неоптимальной работе с запросами : вместо использования
> парам.запроса ты всякий раз при каждой итерации вновь строишь
> практически один и тот же текст запроса ;
А как ещё можно написать, чтобы не строить всякий раз при каждой итерации практически один и тот же текст запроса?
> - обновлении виз.контролов (см. Statusbar) при каждой итерации
я поставил, только чтобы было видно работу программы.
Это только на этапе разработки.
Digitman (2005-11-08 16:04:00) [9]
> ArhArhangel © (08.11.05 15:58) [4]
"тормоза" у тебя (Excel не рассматриваем) в :
- неоптимальной работе с запросами : вместо использования парам.запроса ты всякий раз при каждой итерации вновь строишь практически один и тот же текст запроса ;
- обновлении виз.контролов (см. Statusbar) при каждой итерации
ArhArhangel (2005-11-08 16:02:00) [10]Интересно, а как выполняет импорт MS SQL сервер? Там же ведь тоже реализовано через COM.
Там все данные импортируются влёт. ( Только вот не обрабатываются :-) )
Значит есть какие-то хитрости..
ArhArhangel (2005-11-08 15:58:00) [11]этот вариант реализаци работает с такой же скоростью..
я делал то же самое, но не через VarArrayCreate, а через Values: OLEVariant;
Антоныч (2005-11-08 15:17:00) [12]Я делал поиск последней строки с данными в Excel так (работает при условии, что данные записаны без пропусков):
var
XLApp, WorkBk, WorkSheet: Variant;
nach, kon, cur: integer;
s: string;
begin
XLApp := CreateOLEObject('Excel.Application');
WorkBk := XLApp.WorkBooks.Open(filename);
WorkSheet := WorkBk.Sheets.Item[1];
nach:=1; kon:=65536;
repeat
cur:=(nach+kon) div 2;
s:=WorkSheet.Cells[cur,6];
if s='' then kon:=cur else nach:=cur;
until (kon-nach)<=1;
s:=WorkSheet.Cells[nach,6];
if s='' then dec(nach);
ShowMessage(IntToStr(nach));
WorkBk.Close;
А быстрый экспорт/импорт данных осуществляется через VarArrayCreate:
var
XLApp, WorkBk, WorkSheet: Variant;
begin
XLApp := CreateOLEObject('Excel.Application');
WorkBk := XLApp.WorkBooks.Open(fname);
WorkSheet := WorkBk.Sheets.Item[1];
Buf:=VarArrayCreate([1,1732,1,35], VarVariant);
Buf:=WorkSheet.Range['B2','AJ1733'].Value;
WorkBk.Close;
и работаешь с Buf как обычным двумерным массивом
ArhArhangel (2005-11-08 15:15:00) [13]
try
IRange := fTableExcelInfo.ExcelBook[idBook].ISheet.UsedRange[0]; //UsedRange листа. Это прямоугольная область, заключенная между ўлевой верхней непустойч и ўправой нижней непустойч ячейками.
Values := IRange.Value; //Свойство Value интерфейса Range в состоянии вернуть вариантный массив.
finally
IRange := nil;
end;
umbra (2005-11-08 15:05:00) [14]а что это за
Values[i,j]?