Войти

Показать полную графическую версию : [решено] перекинуть данные из Excel в прогу на Delphi


Страниц : [1] 2

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

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

LilLoco
19-04-2011, 07:49
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 - столбец

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

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

uses ComObj

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

LilLoco
20-04-2011, 10:37
как прочитать оттуда ячейки и закинуть их в 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
что-то не хочет работать такая вот комбинация:

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
В коде у меня тоже подчеркивается красным, и та же ситуация Undeclarated identifier 'Value', но при этом все компилируется и работает отлично! Что делает строка

n := OpenFile();
?
И где инициирование переменной excel?
Тут (http://forum.oszone.net/post-1661456.html#post1661456) было все довольно конкретно описано!

Хоф
21-04-2011, 14:07
LilLoco,
вопрос в догонку так сказать для собственного просвещения.
любая_прога := CreateOleObject('название этой проги') »
Создает объектную переменную размером с саму программу? :o

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

anatoly_neo
21-04-2011, 14:09
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
вроде бы в sg1.cells[i , j] , i - это столбец, а j - это строка... »
Да, моя ошибка :) извиняюсь, сначала идет столбец, а потом строка! У меня же в примере, наоборот :sorry:

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

anatoly_neo
21-04-2011, 14:37
состряпал такой вот кодик:

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
так он заполняет табличку, но не с самой верхней строки, а со второй, подскажите куда рыть? »

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

LilLoco
21-04-2011, 15:08
если j у Вас это столбцы, то почему длина цикла такая же как и у i, до RowsCount?
но не с самой верхней строки, а со второй »
Из Excel берет со второй. или вставляет в StringGrid со второй?

anatoly_neo
21-04-2011, 15:25
Из Excel берет со второй. или вставляет в StringGrid со второй? »

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

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

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

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

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

LilLoco
21-04-2011, 16:21
обновляться и искать строки »
Обновляться должно автоматически или опять же по нажатии на кнопку вручную?

Тут уже Вам не обойтись тем циклом который Вы представили! Можно конечно сначала добавить все строки, потом циклом пройтись по 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
Обновляться должно автоматически или опять же по нажатии на кнопку вручную? »

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


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

LilLoco
21-04-2011, 20:42
перебрасываются все данные »
Пройдитесь циклом по StringGrid черновика, и перекиньте все данные в StringGrid чистовика!

хотелось бы чтобы автоматически все обновлялось, как раз в "крайние" моменты времени (12:00, 15:00, 18:00). »
Воспользуйтесь таймером, и на событие "тика" поставьте функция считывания из Excel в StringGrid!

anatoly_neo
22-04-2011, 09:51
LilLoco »
ОК. будем пробовать :)

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

Хоф
22-04-2011, 12:07
LilLoco,
ИМХО, создается просто ссылка на объект, так как сам excel во время работы запускается в фоновом режиме, »
скажите
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
Так, если я правильно понял, то,
Технология OLE позволяет работать с программами разработанными Только компанией Microsoft.
Соответственно, невозможно так работать с любой программой!




© OSzone.net 2001-2012