Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Delphi, Excel и грабли...


Автор: Vit 13.9.2005, 17:16
Давеча пришлось поработать с Excel. Хочу поделиться несколькими впечатлениями.

Подключался к Excel используя ADO и строку подключения:

ConnectionString=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\имя файла.XLS;Extended Properties="Excel 8.0";


Первые грабли такие:
Берём TADOQuery, подключаем connectionstring, выполняем запрос типа "Create Table...", если файл XLS не существует, то запрос благополучно создаёт указанный XLS файл со страницей, а вот если использовать TADOConnection для подключения - то подключится к несуществующему файлу и создать таким образом файл не получится...

Вторые грабли посложнее будут, угрохал 3 часа и начал было даже сомневаться в своей умственной полноценности... Код простейший: перегоняю из таблицы другой базы данных данные в excel выполняя примерно следующий алгоритм (это упрощённый псевдокод):


Код

MyExcelADOQuery.sql.text:='Insert into MyExcelSheet (Field1, field2, ...) Values (:param1, :Param2, ...)';
MySourceTable.first;
while not MySourceTable.eof do
  begin
    for i:=0 to MySourceTable.fields.count-1 do
       MyExcelADOQuery.parameters[i].value:=MySourceTable.fields[i].value;
    MyExcelADOQuery.execSQL;
    MySourceTable.next;
  end;


И в результате получаю достаточно странную сортировку в Excel. Надо сказать что в Excel я делал собственно отчёт и сортировка мне была важна... Плясал с бубном долго, выяснилось что запрос 'Insert into MyExcelSheet ...' вставляет новую запись ПЕРВОЙ строкой, а не последней, как это принято в базах данных! Итого пришлось код переписать:

Код

MyExcelADOQuery.sql.text:='Insert into MyExcelSheet (Field1, field2, ...) Values (:param1, :Param2, ...)';
MySourceTable.last;
while not MySourceTable.bof do
  begin
    for i:=0 to MySourceTable.fields.count-1 do
       MyExcelADOQuery.parameters[i].value:=MySourceTable.fields[i].value;
    MyExcelADOQuery.execSQL;
    MySourceTable.prior;
  end;


Третьи грабли: после выполнения хотя бы одного запроса на Excel, даже если вызывался ExecSQL и таблица не открыта - файл Excel остаётся заблокированным! Его нельзя открыть. Мне надо было полученный файл Excel после заполнения из программы открыть в Excel... Чтобы это сделать надо у ADOQuery обнулить ConnectionString:

Код

MyExcelADOQuery.ConnectionString='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\имя файла.XLS;Extended Properties="Excel 8.0"';
MyExcelADOQuery.sql.text:='Create table ...';
MyExcelADOQuery.ExecSQL;
MyExcelADOQuery.sql.text:='Что-то там мне необходимое';
MyExcelADOQuery.ExecSQL;
MyExcelADOQuery.ConnectionString=''; //! Вот оно, без этого полученный файл не откроешь!
ShellExecute(handle, '', 'MyFile.xls'....


Автор: bas 14.9.2005, 15:49
Цитата(Vit @ 13.9.2005, 14:16)
Первые грабли такие:
Берём TADOQuery, подключаем connectionstring, выполняем запрос типа "Create Table...", если файл XLS не существует, то запрос благополучно создаёт указанный XLS файл со страницей, а вот если использовать TADOConnection для подключения - то подключится к несуществующему файлу и создать таким образом файл не получится...

Проверил оба варианта (BCB5) - все нормально.
И всталяеться в конец как и должно быть.


Автор: SergeBS 14.9.2005, 16:45
Vit
А зачем такой заковыристый способ? ADO все-таки под сервера заточено (в основном).
Я через OLE все делал и вроде проблем нет. Тем более если из таблицы что-то шарашить - сразу в диапазон матрицу вписываешь. Вполне даже быстро получается.
Если поячеечно - гораздо медленней.

Насчет вставки первой строкой - вставляет туда, где selection. Т.е. все проблемы - что нужно прыгать в нужное место, а затем вставлять.

Да, а насчет connection string - KeepConnection = true(default)? И потому ADOconnection и блокирует доступ - это ж не сервер, а файл. В этом небось грабельки. Проверь.

Насколько шустро получаются все эти вставки у тебя через ADO?

Автор: bas 14.9.2005, 17:41
Цитата(SergeBS @ 14.9.2005, 13:45)
Насколько шустро получаются все эти вставки у тебя через ADO?

На порядок.

Автор: SergeBS 15.9.2005, 07:27
bas
Мне всякие порядки неинтересны. "Столько-то записей на таком-то проце за столько-то секунд" - это я пойму.

Автор: bas 15.9.2005, 10:25
AMD 2ГГц (ОЗУ 256) Win 98 Off.-2000
Одно поле символьное
65500 записей - 4мин 50 сек.
Данные выбирались циклом (см. сооб. Vit) из DBase + ADO.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)