|
Peter Sippel
Guest
|
I'm obviously not able to reply to this thread: http://www.add-in-express.com/forum/read.php?FID=1&TID=10214
so I create another one her.
I had some performance issues by using Values property of Excelrange, so I used the item property instead. Both return a system.OleVariant value. Unfortunately the item property doesn't seem to set the VarType of the value and I can't tell e.g. if it's a date field and format it properly for some purposes.
In my opinion both variables should provide a proper vartype. |
|
Posted 23 Jan, 2012 05:29:13
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 18825
Joined: 2006-05-11
|
Hello Peter,
Our topics are closed in 30 days since the last response.
You use ExcelRange.Item[RowIndex: OleVariant; ColumnIndex: OleVariant] to access an individual cell (not its value) within the range of cells.
Note that ExcelRange.Value returns a 2D array for a range of cells. This works definitely faster than walking through individual cells of the range.
Andrei Smolin
Add-in Express Team Leader |
|
Posted 23 Jan, 2012 10:17:35
|
|
Top
|
|
Peter Sippel
Guest
|
Hi Andrei,
thanks for your reply. What I'm doing is
...
var
aws: ExcelWorksheet;
er: ExcelRange;
col,row: integer;
val: string;
begin
...
aws:= Self.ExcelApp.ActiveSheet as ExcelWorksheet;
er := ExcelRange(aws.Range['A1',EmptyParam].CurrentRegion);
...
for row := 1 to er.Rows.Count do
begin
for col := 1 to er.columns.Count do
begin
val := ValueToString(er.Item[row,col]); // <-- Fast, but no VarType
val := ValueToString(er.Value[row,col]); // <-- Vartype but very slow
end;
end;
...
Regards
Peter |
|
Posted 24 Jan, 2012 03:19:56
|
|
Top
|
|
Peter Sippel
Guest
|
just made some measurements:
val := ValueToString(er.Item[row,col]); // 41 ms
val := ValueToString(er.Value[row,col]); // 14906 ms |
|
Posted 24 Jan, 2012 03:51:48
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 18825
Joined: 2006-05-11
|
Pieter,
Try this:
var
aws: ExcelWorksheet;
er: ExcelRange;
col,row, sum: integer;
arrV: OleVariant;
begin
aws := Self.ExcelApp.ActiveSheet as ExcelWorksheet;
er := ExcelRange(aws.Range['A1',EmptyParam].CurrentRegion);
sum := 0;
arrV := er.Value2;
for row := 1 to er.Rows.Count do
for col := 1 to er.Columns.Count do
sum := sum + arrV[row, col];
ShowMessage('Sum is ' + FloatToStr(sum));
end;
How does it work for you? Is this what you are looking for?
Andrei Smolin
Add-in Express Team Leader |
|
Posted 24 Jan, 2012 06:07:18
|
|
Top
|
|
Peter Sippel
Guest
|
Hi Andrei,
Value2 is not giving the real type. But doing exactly this with Value instead, it's lightning fast (even 6 ms).
I don't understand the differnece though.... |
|
Posted 24 Jan, 2012 08:53:54
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 18825
Joined: 2006-05-11
|
Excel saves time if it uses its inner structures to supply you with data. Creating/releasing numerous COM objects in a loop produces too much overhead.
Andrei Smolin
Add-in Express Team Leader |
|
Posted 24 Jan, 2012 09:09:19
|
|
Top
|
|
Peter Sippel
Guest
|
Ah, so er.Value[row,col] creates a COM Object ? I assumed "er" was a COM Object and Value a property (array). |
|
Posted 24 Jan, 2012 10:14:19
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 18825
Joined: 2006-05-11
|
Hello,
er.Value[row,col] - this will not compile. A correct way is er.Item[row,col].Value; and this creates a COM object.
Andrei Smolin
Add-in Express Team Leader |
|
Posted 26 Jan, 2012 08:35:52
|
|
Top
|
|