Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] перекинуть данные из Excel в прогу на Delphi (http://forum.oszone.net/showthread.php?t=205088)

anatoly_neo 18-04-2011 16:56 1661056

перекинуть данные из Excel в прогу на Delphi
 
Вложений: 2
Привет всем.
Помогите решить задачку. Есть файл эксель, содержит в себе данные в трёх столбцах (пример приложен) и примерно 25 строчках, на одном листе. Надо из него подгрузить эти данные в программу на Delphi в модуль StringGrid.
На скрине зафиксировал то чего уже удалось добиться в графическом виде, с кодом пока значительно сложнее, посему и прошу вашей помощи. Хотелось бы чтобы поподробнее объяснили, что к чему, зачем и почему.
Спасибо.

PS: хотелось бы сразу добавить небольшое усложнение задачи, сделать так чтобы программа в зависимости от времени суток выводила только нужные строки. То есть, в первом столбце таблицы Excel у нас будет время (в формате HH:MM), вот надо чтобы прога выводила например строки с временем с 9:00 до 15:00 именно в это время суток, следующую часть строк (с 15:00 до 21:00) она уже выводила именно с 15 до 21 часа.

LilLoco 19-04-2011 07:49 1661456

anatoly_neo, Здравствуйте! Вытащить данные из Excel можно следующим образом :

Код:

excel : Variant; // Объявляем переменную
...............
excel := CreateOleObject('Excel.Application');
excel.Workbooks.Open("excelfile.xls"); //Открываем файл excel
RowsCount := excel.ActiveSheet.UsedRange.Rows.Count; //Получаем количество использованных строк*
for i := 0 to RowsCount
begin
// выполняем операции со строками**
end
excel.ActiveWorkbook.Close;//закрываем файл excel
excel.Application.Quit;//"закрываем" excel приложение

* - Строки могут быть пустыми, но если они отформатированы, то будут считаться использованными, по вашему примеру их будет 18!

** - Обращаться к ячейкам так :
Код:

excel.Cells[i,j].Value
где i - строка, j - столбец

Цитата:

Цитата anatoly_neo
хотелось бы сразу добавить небольшое усложнение задачи »

Сначала тащите из excel ячейку с датой, выполняйте все операции необходимые для проверки, проверяйте, и если true выводите!

P.S.
не забыть добавить

Код:

uses ComObj

anatoly_neo 20-04-2011 10:16 1662188

как открыть файлик вроде разобрался, но вот как прочитать оттуда ячейки и закинуть их в StringGrid так и не могу пока понять, подмогните плиз :)

LilLoco 20-04-2011 10:37 1662209

Цитата:

Цитата anatoly_neo
как прочитать оттуда ячейки и закинуть их в StringGrid »

Циклом пройтись по документу!
Например по представленному вами файлу Excel :
Код:

for i := 2 to 4 do
begin
sg.cells[i - 1, 0] := excel.cells[i, 1].Value; // время
sg.cells[i - 1, 1] := excel.cells[i, 2].Value; // фио
sg.cells[i - 1, 2] := excel.cells[i, 3].Value; // номер

где sg - StringGrid

если количество строк неизвестно заранее то
Код:

RowsCount := excel.ActiveSheet.UsedRange.Rows.Count;

anatoly_neo 21-04-2011 11:32 1662978

что-то не хочет работать такая вот комбинация:

procedure TForm1.Button1Click(Sender: TObject);
var excel : variant;
i, j, n: integer;
begin
n := OpenFile();
//Caption := ExtractFileName(Form1.OpenDialog1.FileName);
for i := 1 to 3 do
begin
sg1.cells[i - 1, 0] := excel.cells[i, 1].Value; // время
sg1.cells[i - 1, 1] := excel.cells[i, 2].Value; // фио
sg1.cells[i - 1, 2] := excel.cells[i, 3].Value; // номер
end;
end;


жалуется на "Undeclarated identifier 'Value' "....

LilLoco 21-04-2011 12:58 1663058

В коде у меня тоже подчеркивается красным, и та же ситуация Undeclarated identifier 'Value', но при этом все компилируется и работает отлично! Что делает строка
Код:

n := OpenFile();
?
И где инициирование переменной excel?
Тут было все довольно конкретно описано!

Хоф 21-04-2011 14:07 1663101

LilLoco,
вопрос в догонку так сказать для собственного просвещения.
Цитата:

Цитата LilLoco
любая_прога := CreateOleObject('название этой проги') »

Создает объектную переменную размером с саму программу? :o

и если создает то внутри кого VBA или Delphi (в применительно к условиям anatoly neo )

anatoly_neo 21-04-2011 14:09 1663104

n := OpenFile(); - это у меня была функция сделана для открытия файла...
переделал как вы писали выше, вроде и правда заработало.

получилось как то вот так:

Код:

procedure TForm1.Button1Click(Sender: TObject);
var excel : variant;
i, j, RowsCount: integer;

begin
Form1.OpenDialog1.Execute();
excel := CreateOleObject('excel.application');
excel.workbooks.open[Form1.OpenDialog1.FileName];
RowsCount := excel.ActiveSheet.UsedRange.Rows.Count;
excel.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam).Activate;

  for i := 1 to RowsCount do
    begin
      sg1.cells[i - 1, 0] := excel.cells[2, i].Value; // время
      sg1.cells[i - 1, 1] := excel.cells[3, i].Value; // фио
      sg1.cells[i - 1, 2] := excel.cells[4, i].Value; // номер
    end;
  excel.activeworkbook.close;
  excel.application.quit;
end;

осталось только допилить код чтобы он все данные без явного указания ячеек расставлял (я про такие строки sg1.cells[i - 1, 0] := excel.cells[2, i].Value; ) ...
будем думать и химичить, если не дойдёт как наверно ещё обращусь :)


PS: только одного не понял, вроде бы в sg1.cells[i , j] , i - это столбец, а j - это строка... но по вашему примеру он мне строки в столбцы выводил, а так как написано у меня, он выводит строки в строчку, как мне и хотелось... в чём же загадка?

LilLoco 21-04-2011 14:35 1663132

Цитата:

Цитата anatoly_neo
вроде бы в sg1.cells[i , j] , i - это столбец, а j - это строка... »

Да, моя ошибка :) извиняюсь, сначала идет столбец, а потом строка! У меня же в примере, наоборот :sorry:

Цитата:

Цитата Хоф
Создает объектную переменную размером с саму программу? »

Вы знаете, я затрудняюсь ответить на этот вопрос, так как не сильно разбирался когда нужно было это реализовать!
ИМХО, создается просто ссылка на объект, так как сам excel во время работы запускается в фоновом режиме, это можно отследить в процессах, а по окончании работы с документом из программы Delphi, он выгружается из памяти! Не думаю, что в программе под эту переменную выделяется много памяти!

anatoly_neo 21-04-2011 14:37 1663134

состряпал такой вот кодик:
Код:

for i := 1 to RowsCount do
    begin
      for j := 1 to RowsCount do
        begin
          sg1.cells[i - 1, j - 1] := excel.cells[j, i].Value;

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

anatoly_neo 21-04-2011 15:06 1663152

Цитата:

Цитата anatoly_neo
так он заполняет табличку, но не с самой верхней строки, а со второй, подскажите куда рыть? »

кажется сам понял, первая ячейка не доступна для изменения :)

LilLoco 21-04-2011 15:08 1663153

если j у Вас это столбцы, то почему длина цикла такая же как и у i, до RowsCount?
Цитата:

Цитата anatoly_neo
но не с самой верхней строки, а со второй »

Из Excel берет со второй. или вставляет в StringGrid со второй?

anatoly_neo 21-04-2011 15:25 1663165

Цитата:

Цитата LilLoco
Из Excel берет со второй. или вставляет в StringGrid со второй? »

В StringGrid вставляет со второй

Цитата:

Цитата LilLoco
если j у Вас это столбцы, то почему длина цикла такая же как и у i, до RowsCount? »

тормоз, поправлю:)

anatoly_neo 21-04-2011 16:03 1663198

Осталось наверно самое сложное, заставить эту прогу выводить строки соответственно времени, то есть, строки со временем 9:00 до 12:00 показывать в это время, остальные где то хранить (или в 12:00 обновляться и искать строки с 12:00 до 15:00) и выводить их в нужное время.

как бы вот с этой задачей разобраться?

LilLoco 21-04-2011 16:21 1663221

Цитата:

Цитата anatoly_neo
обновляться и искать строки »

Обновляться должно автоматически или опять же по нажатии на кнопку вручную?

Тут уже Вам не обойтись тем циклом который Вы представили! Можно конечно сначала добавить все строки, потом циклом пройтись по StringGrid и удалить те, которые не соответствуют времени!
Либо же, проверять это перед заполнением! И добавлять уже, только те которые нужны!
Например можно так :

Код:

time : string;
hour : int;
for i := первая строка to последняя строка do
begin
Time = excel.Cells[столбец времени, i].Value;
hour = ИзвлечьВремяИзСтроки(Time);
if тут выполняется проверка времени
begin
и если выполняется выводим в stringgrid
end;
end;

ИзвлечьВремяИзСтроки(Time) - функция которая из строки времени получает часы!

Ну вот как нибудь так можно это реализовать!

anatoly_neo 21-04-2011 16:44 1663243

Цитата:

Цитата LilLoco
Обновляться должно автоматически или опять же по нажатии на кнопку вручную? »

хотелось бы чтобы автоматически все обновлялось, как раз в "крайние" моменты времени (12:00, 15:00, 18:00).


PS: еще маленький вопросик, а уже заполненную StringGrid в одной форме, можно как то передать на другую форму (либо саму табличку, либо данные из неё), которая в итоге будет результирующей? объясню для чего это, первая форма это как бы черновик, в котором мы заполняем и проверяем все данные, а вторая форма как чистовик, на которую по нажатию кнопки "поехали" (в первой форме) перебрасываются все данные и выводятся на экран.

LilLoco 21-04-2011 20:42 1663416

Цитата:

Цитата anatoly_neo
перебрасываются все данные »

Пройдитесь циклом по StringGrid черновика, и перекиньте все данные в StringGrid чистовика!

Цитата:

Цитата anatoly_neo
хотелось бы чтобы автоматически все обновлялось, как раз в "крайние" моменты времени (12:00, 15:00, 18:00). »

Воспользуйтесь таймером, и на событие "тика" поставьте функция считывания из Excel в StringGrid!

anatoly_neo 22-04-2011 09:51 1663693

Цитата:

Цитата LilLoco
LilLoco »

ОК. будем пробовать :)

PS: Огромное спасибо за помощь :)

Хоф 22-04-2011 12:07 1663814

LilLoco,
Цитата:

Цитата LilLoco
ИМХО, создается просто ссылка на объект, так как сам excel во время работы запускается в фоновом режиме, »

скажите
Цитата:

Цитата LilLoco
excel := CreateOleObject('Excel.Application') »

я могу с помощью этого текста (заменив Exel на любую другую нужную мне программу) запустить допустим из того же VBA в Exel в фоновом режиме Adobe Reader, или Corel Draw, или OpenOffice Calc, чтоб считать данные из ячеек в Calc или из "рисованных" таблиц в Adobe reader или Corel Draw и перенести их в Exel ?
И где про это - состыковка двух разных программ из под VBA в Exel для переброса данных - можно прочитать по подробнее?

LilLoco 22-04-2011 13:42 1663891

Так, если я правильно понял, то,
Технология OLE позволяет работать с программами разработанными Только компанией Microsoft.
Соответственно, невозможно так работать с любой программой!

Хоф 22-04-2011 14:14 1663906

Я нашел в ru.Wikipedia.org - по теме OLE. Насколько я понял это было создано Microsoft для связывания различных данных из различных программ (в тч Adobe Flash Player) в программы семейства Microsoft. Далее ссылка идет на MSDN (Через Гогль Хром все быстро переводится на русский) В общих чертах понятно. Нужно теперь нарыть русскоязычную литературу в энтом направлении.

Iska 22-04-2011 18:48 1664005

Цитата:

Цитата LilLoco
Так, если я правильно понял, то, Технология OLE позволяет работать с программами разработанными Только компанией Microsoft. »

Вы неправильно поняли.
Цитата:

Цитата LilLoco
Соответственно, невозможно так работать с любой программой! »

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


Цитата:

Цитата Хоф
Я нашел в ru.Wikipedia.org - по теме OLE. »

Смотреть лучше в английский версии: OLE Automation - Wikipedia, the free encyclopedia — и ссылок куда больше, и качество их лучше.

anatoly_neo 25-04-2011 16:05 1665483

что-то я не понимаю слегка, сделал такой цикл:
Код:

  for i := 1 to 10 do
  for j := 1 to 3 do
        begin
          sg3.cells[i - 1, j - 1] := Form4.SG1.Cells[i ,j ];

и что-то не пашет

вот еще бы хотелось понять, на что заменить в данной строке (for i := 1 to 10 do) цифру 10, чтобы таки цикл был до конца СтрингГрида (SG1)? ну и соответственно во второй строке цифру 3 (хотя ее можно не менять.)
и что то мне кажется я не то пишут вот тут - sg3.cells[i - 1, j - 1] := Form4.SG1.Cells[i ,j ]; - помогите плиз понять в чём загвоздка?

LilLoco 25-04-2011 18:17 1665551

Цитата:

Цитата anatoly_neo
и что-то не пашет »

Что именно?
может быть нужно :
Код:

for i := 1 to 10 do
begin
for j := 1 to 3 do
begin
//что то делаем
end;
end;

Цитата:

Цитата anatoly_neo
на что заменить в данной строке (for i := 1 to 10 do) цифру 10 »

Код:

Form4.SG1.RowCount // Количество строк в StringGrid
Цитата:

Цитата anatoly_neo
ну и соответственно во второй строке цифру 3 »

Использовать количество столбцов!
Цитата:

Цитата anatoly_neo
что то мне кажется я не то пишут вот тут »

Поподробнее можно?)

anatoly_neo 26-04-2011 09:17 1665811

Цитата:

Цитата LilLoco
LilLoco »

вот что у меня получилось в итоге:
Код:

begin
  for i := 1 to Form4.SG1.RowCount do
  begin
  for j := 1 to 3 do
        begin
          sg3.cells[i - 1, j - 1] := Form4.SG1.Cells[i ,j ];
        end;
end;
end;

но переброса данных из черновика в чистовик не произошло :(

Цитата:

Цитата LilLoco
Цитата anatoly_neo:
что то мне кажется я не то пишут вот тут »
Поподробнее можно?) »

вот мне и кажется, что где-то я ошибаюсь в том что пишу, поэтому и переброс не происходит, ткните плиз мордочкой где не так?

LilLoco 26-04-2011 09:31 1665816

Сколько строк у Вас изначально в чистовике и черновике?
Цитата:

Цитата anatoly_neo
не произошло »

А хоть что нибудь происходит? тяжело судить о проблеме, исходя из Ваших "показаний"! Может быть какая нить ошибка, может еще что нибудь) Поясните)

anatoly_neo 26-04-2011 09:38 1665818

Цитата:

Цитата LilLoco
Сколько строк у Вас изначально в чистовике и черновике? »

в черновике 25 строк, в чистовике 10 (по задумке, там будут отображаться только те записи, которые подходят по времени), посему и количество строк меньше

Цитата:

Цитата LilLoco
А хоть что нибудь происходит? »

происходит, открывается программа (вторая форма, типа чистовик), но таблица в ней пустая.

anatoly_neo 26-04-2011 09:57 1665828

Вложений: 2
прикрепил два скрина для наглядности что как и куда планируется сделать, может чем то поможет :))

LilLoco 26-04-2011 10:11 1665832

Вложений: 1
Держите, набросал, посмотрите и отредактируйте как Вас нужно! Вроде все работает!)

Скоро в интернете появится вся база номеров автомобилей и их владельцев :D :D :D

anatoly_neo 26-04-2011 10:50 1665843

Цитата:

Цитата LilLoco
Скоро в интернете появится вся база номеров автомобилей и их владельцев :D :D :D »


не правда, это всего лишь презентация записи на обслуживание. :)

пытаюсь разобраться с вашим примером, спасибо


PS: подшаманил под себя то что Вы привели в примере, и... заработало :)))))))))

anatoly_neo 26-04-2011 16:29 1665982

фух, слава богу не надо по времени вывод данных делать. за сим считаю проблему решённой. огромное спасибо LilLoco. :)))


Время: 21:16.

Время: 21:16.
© OSzone.net 2001-