Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.12.04;
Скачать: [xml.tar.bz2];

Вниз

импорт данных из Excel   Найти похожие ветки 

 
ArhArhangel ©   (2005-11-08 14:56) [0]

Здравствуйте уважаемые мастера!

Надо реализовать импорт большого количества(несколько тысяч строк) данных из 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;


 
umbra ©   (2005-11-08 15:05) [1]

а что это за Values[i,j]?


 
ArhArhangel ©   (2005-11-08 15:15) [2]


try
 IRange := fTableExcelInfo.ExcelBook[idBook].ISheet.UsedRange[0]; //UsedRange листа. Это прямоугольная область, заключенная между ўлевой верхней непустойч и ўправой нижней непустойч ячейками.
 Values := IRange.Value;  //Свойство Value интерфейса Range в состоянии вернуть вариантный массив.
finally
 IRange := nil;
end;


 
Антоныч ©   (2005-11-08 15:17) [3]

Я делал поиск последней строки с данными в 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:58) [4]

этот вариант реализаци работает с такой же скоростью..
я делал то же самое, но не через VarArrayCreate, а через Values: OLEVariant;


 
ArhArhangel ©   (2005-11-08 16:02) [5]

Интересно, а как выполняет импорт MS SQL сервер? Там же ведь тоже реализовано через COM.
Там все данные импортируются влёт. ( Только вот не обрабатываются :-) )
Значит есть какие-то хитрости..


 
Digitman ©   (2005-11-08 16:04) [6]


> ArhArhangel ©   (08.11.05 15:58) [4]


"тормоза" у тебя (Excel не рассматриваем) в :

- неоптимальной работе с запросами : вместо использования парам.запроса ты всякий раз при каждой итерации вновь строишь практически один и тот же текст запроса ;

- обновлении виз.контролов (см. Statusbar) при каждой итерации


 
ArhArhangel ©   (2005-11-08 19:49) [7]


> "тормоза" у тебя (Excel не рассматриваем) в :
>
> - неоптимальной работе с запросами : вместо использования
> парам.запроса ты всякий раз при каждой итерации вновь строишь
> практически один и тот же текст запроса ;


А как ещё можно написать, чтобы не строить всякий раз при каждой итерации  практически один и тот же текст запроса?


> - обновлении виз.контролов (см. Statusbar) при каждой итерации

я поставил, только чтобы было видно работу программы.
Это только на этапе разработки.


 
umbra ©   (2005-11-08 20:55) [8]

чтобы ускорить работу программы надо как можно быстрее избавиться от экселя.
например - сохранить файл в другом формате и работать с этим новым файлом.
К тому же для определения непрерывного блока данных лучше использовать не UsedRange, а CurrentRegion


 
isasa ©   (2005-11-08 21:01) [9]

Возможно ли как-нибудь по-другому искать конец документа?

Как вариант - именованный диапазон в документе Excel.


 
Digitman ©   (2005-11-09 09:12) [10]


> как ещё можно написать, чтобы не строить всякий раз при
> каждой итерации  практически один и тот же текст запроса?
>


использовать запрос с параметрами


 
ArhArhangel ©   (2005-11-10 10:08) [11]

я проверял даже без использования запроса..
Медленность возникает не из за него, а из за считывания ячеек.
Может есть другие методы импорта из Excel.
Мне сказали, что к Excel можно и через АДО подключится (Provider=Jet-Extended Properties=Excel 8.x)

но как это сделать, я так и не понял..
при создании *.UDL я такого провайдера не нашёл..


 
alex_***   (2005-11-10 10:18) [12]

какое считывание ячеек? сказали же - определяешь Range и копируешь его в Variant. Никакого считывания ячеек


 
Digitman ©   (2005-11-10 10:26) [13]


> реализована через позднее связывание.


ну а что ж ты хотел ?

позднее связывание само по себе уступает в производительности раннему - всякий раз при обращении к методу интерфейса происходит разрешение имени метода в его Id, в отличии от раннего, где Id"ы методов интерфейса контроллеру автоматизации известны заранее


 
alex_***   (2005-11-10 10:29) [14]

а что на это заморачиваться, если обращаемся к outproc серверу



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.12.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.038 c
2-1131939950
stef
2005-11-14 06:45
2005.12.04
Шестнадцатиричные числа


5-1114086146
undefined
2005-04-21 16:22
2005.12.04
Просмотр в Инсп. Объектов и доступ к событиям вложеных классов


2-1131861741
PlotnMax
2005-11-13 09:02
2005.12.04
Поиск файлов


5-1114186238
Galiaf
2005-04-22 20:10
2005.12.04
Как установить компонент?


2-1132149143
.dn+
2005-11-16 16:52
2005.12.04
TImage, рисовать





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский