Пишу такой код:
xAppl := CreateOleObject('Excel.Application');
xAppl.WorkBooks.Open('C:Loratable.xls');
lastRow := xAppl.ActiveCell.Row;
и в последней строке lastRow всегда равно единице. Как сделать, чтобы было известно всё кол — во строк?
Здравствуйте, Lizka, Вы писали:
L>Пишу такой код:
L> xAppl := CreateOleObject(‘Excel.Application’);
L> xAppl.WorkBooks.Open(‘C:Loratable.xls’);
L> lastRow := xAppl.ActiveCell.Row;
L>и в последней строке lastRow всегда равно единице. Как сделать, чтобы было известно всё кол — во стро
есть такая вещь:
worksheets(1).UsedRange.Rows.Count
посмотри хелп, могу подсказать только то что если у тебя заняты первые десять строк то вернет 10, а если идут первые две строки пустые а потом 10 занятых то один хрен вернёт 10, ибо возвращает количество занятых строк.
Как я понял у тебя будет таблица, следовательноо тебя это волновать не должно, но решил на всякий случай сказать, а то мало ди что.
Здравствуйте, RIPer, Вы писали:
RIP>Здравствуйте, Lizka, Вы писали:
L>>Пишу такой код:
L>> xAppl := CreateOleObject(‘Excel.Application’);
L>> xAppl.WorkBooks.Open(‘C:Loratable.xls’);
L>> lastRow := xAppl.ActiveCell.Row;
L>>и в последней строке lastRow всегда равно единице. Как сделать, чтобы было известно всё кол — во стро
Да, и по моему это вопрос не по дельфи а по VBA, если мой ответ тебе не пригодился то советую поменять тему, т.к. некоторые могут и не смотреть.
Здравствуйте, Lizka, Вы писали:
L>RIPer, СПАСИБО ОГРОМНОЕ!!!
Я рад что помог, но можно было и оценочку поставить
← →
АлеКо
(2003-04-08 07:09)
[0]
Просто надо определить число строк на листе Excel.
Пытаюсь использовать функцию
Sheet:=WorkBook.WorkSheets[1];
Rows:=Sheet.Cells.SpecialCells(xlLastCell).Rows.Count;
и нихрена не выходит.
Поможите чем можите.
← →
Hooch
(2003-04-08 07:20)
[1]
вообще число строк или используемых ?
← →
АлеКо
(2003-04-08 07:32)
[2]
Число строк в которых есть данные чтобы организовать цикл по ним и обрабатывать определенное количество а не все 65000 строк на листе
← →
Hooch
(2003-04-08 08:30)
[3]
ExcelApp : TExcelApplication;
// used range
ExcelApp.ActiveSheet.UsedRange.Row;
ExcelApp.ActiveSheet.UsedRange.Column;
← →
Спрашивающий
(2003-04-08 08:31)
[4]
Это все зависит от способа размещения данных
1.Если данные идут последовательно и нет пустых строк
кто мешает сделать элементарную проверку
на наличие данных в ячейке и прервать цикл.
2.Если есть пустые строки за которыми идут данные ,
например данные стоят в ячейке А1 и затем в А65536 то сдесь
без полного перебора не обойтись.
Уточните способ размещения данных.
← →
АлеКо
(2003-04-08 08:34)
[5]
Данные с пробелами. Вот пример который я привел выделяет не пустые ячейки (xlLastCell) он к сожелениб работает только в VBA.
← →
Hooch
(2003-04-08 09:14)
[6]
UsedRange побарабану пробелы, работает как часы
> Вот пример который я привел выделяет не пустые ячейки (xlLastCell)
> он к сожелениб работает только в VBA.
да должно работать
Вначале рассмотрим вариант чтения данных использованием которого грешат те, кто только начинает свое знакомство с Excel в Delphi — чтение данных из каждой ячейки по отдельности. Тестовая процедура с таким вариантом чтения может выглядеть следующим образом:
procedure TForm16.SlowVariant; var Rows, Cols, i,j: integer; WorkSheet: OLEVariant; d: TDateTime; begin //открываем книгу ExcelApp.Workbooks.Open(edFile.Text); //получаем активный лист WorkSheet:=ExcelApp.ActiveWorkbook.ActiveSheet; //определяем количество строк и столбцов таблицы Rows:=WorkSheet.UsedRange.Rows.Count; Cols:=WorkSheet.UsedRange.Columns.Count; StringGrid1.RowCount:=Rows; StringGrid1.ColCount:=Cols; //засекаем время начала чтения d:=Now; //выводим данные в таблицу for I := 0 to Rows-1 do for j := 0 to Cols-1 do StringGrid1.Cells[J,I]:=WorkSheet.UsedRange.Cells[I+1,J+1].Value; Label2.Caption:='Время чтения всего листа: '+FormatDateTime('hh:mm:ss:zzz', Now()-d); end;
Счётчик будет в итоге содержать время чтения и вывода в StringGrid данных.
Для теста этого варианта был создан лист Excel, содержащий 143 строки и 142 столбца с данными, т.е. 20306 ячеек с данными.
На время чтения ушло 12 секунд.
12 секунд на чтение…а если будет 1000 строк и 1000 столбцов? Так можно и не дождаться окончания операции.
Если внимательно посмотреть на процедуру, представленную выше, то можно видеть, что в цикле мы каждый раз при каждой итерации вначале получаем диапазон, занятый данными, затем в этом диапазоне получаем определенную ячейку и только потом считываем значение в ячейке. На самом деле столько лишних операций для чтения данных с листа не требуется. Тем более, когда данные располагаются непрерывным массивом. Более выгодным в этом случае вариантом чтения будет чтение данных сразу из всего диапазона в массив.
На деле реализация этого варианты работы окажется даже проще, чем представленного выше. Смотрите сами. Вот вариант чтения данных целым диапазоном:
procedure TForm16.RangeRead; var Rows, Cols, i,j: integer; WorkSheet: OLEVariant; FData: OLEVariant; d: TDateTime; begin //открываем книгу ExcelApp.Workbooks.Open(edFile.Text); //получаем активный лист WorkSheet:=ExcelApp.ActiveWorkbook.ActiveSheet; //определяем количество строк и столбцов таблицы Rows:=WorkSheet.UsedRange.Rows.Count; Cols:=WorkSheet.UsedRange.Columns.Count; //считываем данные всего диапазона FData:=WorkSheet.UsedRange.Value; StringGrid1.RowCount:=Rows; StringGrid1.ColCount:=Cols; //засекаем время начала чтения d:=Now; //выводим данные в таблицу for I := 0 to Rows-1 do for j := 0 to Cols-1 do StringGrid1.Cells[J,I]:=FData[I+1,J+1]; Label2.Caption:='Время чтения всего листа: '+FormatDateTime('hh:mm:ss:zzz', Now()-d); end;
Здесь мы ввели всего одну переменную FData типа Variant. В эту переменную мы прочитали за 1 операцию весь диапазон, занятый данными. После того как диапазон прочитан FData будет содержать матрицу, каждый элемент которой будет типом данных, определенным в Excel.
Время выполнения операции 0.022 секунды!
Как видите, прирост скорости оказался колоссальным, учитывая даже то, что в счётчик попало время обновления StringGrid’а.
Вот и всё, Удачи!
I use cxGrid and I want import a excel file to cxgrid. I wrote this code a function.
But, its wrong, because cxGrid dont know RowCount and ColCount.
I would like know, what can I use, what is similar?
Help me!
Thank you!
function Xls_To_cxGrid(AGrid: TcxGrid; AXLSFile: string): Boolean;
const
xlCellTypeLastCell = $0000000B;
var
XLApp, Sheet: OLEVariant;
RangeMatrix: Variant;
x, y, k, r: Integer;
begin
Result := False;
XLApp := CreateOleObject('Excel.Application');
try
XLApp.Visible := False;
XLApp.Workbooks.Open(AXLSFile);
Sheet := XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1];
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
x := XLApp.ActiveCell.Row;
y := XLApp.ActiveCell.Column;
AGrid.RowCount := x;
AGrid.ColCount := y;
RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;
k := 1;
repeat
for r := 1 to y do
AGrid.Cells[(r - 1), (k - 1)] := RangeMatrix[K, R];
Inc(k, 1);
AGrid.RowCount := k + 1;
until k > x;
RangeMatrix := Unassigned;
finally
if not VarIsEmpty(XLApp) then
begin
XLApp.Quit;
XLAPP := Unassigned;
Sheet := Unassigned;
Result := True;
end;
end;
end;