Показать полную графическую версию : [решено] перекинуть данные из Excel в прогу на Delphi
anatoly_neo
18-04-2011, 16:56
Привет всем.
Помогите решить задачку. Есть файл эксель, содержит в себе данные в трёх столбцах (пример приложен) и примерно 25 строчках, на одном листе. Надо из него подгрузить эти данные в программу на Delphi в модуль StringGrid.
На скрине зафиксировал то чего уже удалось добиться в графическом виде, с кодом пока значительно сложнее, посему и прошу вашей помощи. Хотелось бы чтобы поподробнее объяснили, что к чему, зачем и почему.
Спасибо.
PS: хотелось бы сразу добавить небольшое усложнение задачи, сделать так чтобы программа в зависимости от времени суток выводила только нужные строки. То есть, в первом столбце таблицы Excel у нас будет время (в формате HH:MM), вот надо чтобы прога выводила например строки с временем с 9:00 до 15:00 именно в это время суток, следующую часть строк (с 15:00 до 21:00) она уже выводила именно с 15 до 21 часа.
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 так и не могу пока понять, подмогните плиз :)
как прочитать оттуда ячейки и закинуть их в 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' "....
В коде у меня тоже подчеркивается красным, и та же ситуация Undeclarated identifier 'Value', но при этом все компилируется и работает отлично! Что делает строка
n := OpenFile();
?
И где инициирование переменной excel?
Тут (http://forum.oszone.net/post-1661456.html#post1661456) было все довольно конкретно описано!
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 - это строка... но по вашему примеру он мне строки в столбцы выводил, а так как написано у меня, он выводит строки в строчку, как мне и хотелось... в чём же загадка?
вроде бы в 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
так он заполняет табличку, но не с самой верхней строки, а со второй, подскажите куда рыть? »
кажется сам понял, первая ячейка не доступна для изменения :)
если 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) и выводить их в нужное время.
как бы вот с этой задачей разобраться?
обновляться и искать строки »
Обновляться должно автоматически или опять же по нажатии на кнопку вручную?
Тут уже Вам не обойтись тем циклом который Вы представили! Можно конечно сначала добавить все строки, потом циклом пройтись по 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 в одной форме, можно как то передать на другую форму (либо саму табличку, либо данные из неё), которая в итоге будет результирующей? объясню для чего это, первая форма это как бы черновик, в котором мы заполняем и проверяем все данные, а вторая форма как чистовик, на которую по нажатию кнопки "поехали" (в первой форме) перебрасываются все данные и выводятся на экран.
перебрасываются все данные »
Пройдитесь циклом по StringGrid черновика, и перекиньте все данные в StringGrid чистовика!
хотелось бы чтобы автоматически все обновлялось, как раз в "крайние" моменты времени (12:00, 15:00, 18:00). »
Воспользуйтесь таймером, и на событие "тика" поставьте функция считывания из Excel в StringGrid!
anatoly_neo
22-04-2011, 09:51
LilLoco »
ОК. будем пробовать :)
PS: Огромное спасибо за помощь :)
LilLoco,
ИМХО, создается просто ссылка на объект, так как сам excel во время работы запускается в фоновом режиме, »
скажите
excel := CreateOleObject('Excel.Application') »
я могу с помощью этого текста (заменив Exel на любую другую нужную мне программу) запустить допустим из того же VBA в Exel в фоновом режиме Adobe Reader, или Corel Draw, или OpenOffice Calc, чтоб считать данные из ячеек в Calc или из "рисованных" таблиц в Adobe reader или Corel Draw и перенести их в Exel ?
И где про это - состыковка двух разных программ из под VBA в Exel для переброса данных - можно прочитать по подробнее?
Так, если я правильно понял, то,
Технология OLE позволяет работать с программами разработанными Только компанией Microsoft.
Соответственно, невозможно так работать с любой программой!
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.