Il problema è che si sta chiamando l'oggetto di Excel per ogni cella; questa è un'operazione lenta nel migliore dei casi, quindi fare questo per un gran numero di celle richiederà molto tempo. Ho avuto un caso di questo non molto tempo fa: 4000 righe con 9 colonne sono voluti circa 44 secondi per il trasferimento in Excel.
La mia soluzione attuale prevede la creazione di un file CSV e quindi l'importazione di CSV in Excel.
const
fn = 'c:\windows\temp\csv.csv';
var
csv: tstringlist;
row, col: integer;
s: string;
begin
csv:= tstringlist.create;
for row:= 1 to stringgrid1.rowcount do
begin
s:= '';
for col:= 0 to stringgrid1.ColCount-1 do
s:= s + stringgrid1.Cells[col, row-1] + ',';
csv.add (s)
end;
csv.savetofile (fn);
csv.free;
objExcel := TExcelApplication.Create(nil);
objExcel.workbooks.open (fn);
deletefile (fn);
end;
Un altro modo viene da Mike Shkolnik che sto citando come è:
var
xls, wb, Range: OLEVariant;
arrData: Variant;
begin
{create variant array where we'll copy our data}
arrData := VarArrayCreate([1, yourStringGrid.RowCount, 1, yourStringGrid.ColCount], varVariant);
{fill array}
for i := 1 to yourStringGrid.RowCount do
for j := 1 to yourStringGrid.ColCount do
arrData[i, j] := yourStringGrid.Cells[j-1, i-1];
{initialize an instance of Excel}
xls := CreateOLEObject('Excel.Application');
{create workbook}
wb := xls.Workbooks.Add;
{retrieve a range where data must be placed}
Range := wb.WorkSheets[1].Range[wb.WorkSheets[1].Cells[1, 1],
wb.WorkSheets[1].Cells[yourStringGrid.RowCount, yourStringGrid.ColCount]];
{copy data from allocated variant array}
Range.Value := arrData;
{show Excel with our data}
xls.Visible := True;
end;
io suggerisco di provare entrambi i metodi e vedere che è più veloce per i vostri scopi.
fonte
2013-05-20 03:19:07
grazie per la rapida risposta, ragazzi. Penso che il metodo array sia il migliore per la mia situazione in questo momento perché non userò il file .csv. come contrassegno questa domanda come "Risolto"? – dapidmini