Hola
Tuve que repensar esta pregunta porque cuando te iba a poner el enlace a un ejemplo me di cuenta de un pequeño detalle.
Vamos a resumir un poco.
Hay dos métodos favoritos para acceder a una hoja de Excel:
El primero viene a ser el que te proporcionan las componentes de la paleta Servers y el segundo es usando las componentes de la paleta ADO.
La razón por la que yo siempre recomiendo ADO en lugar de OLE es porque es mucho más rápido cuando se trata de una gran cantidad de registros.
El detalle es que siempre había usado ADO para leer datos de una hoja de Excel más que para escribir. Y en este segundo caso, el problema es que si el archivo no existe hay primero que crearlo y llenar la fila de encabezados para que la conexión con ADO sea posible.
Quizá con el mismo ADO pueda crearse el archivo pero en tal caso desconozco como.
Así que vamos a dividir el problema en dos partes
- Crear el archivo
- Vaciar los datos
Para crear el archivo usaremos OLE, aunque directamente, sin recurrir a las componentes de la paleta Server.
Código Delphi
[-]
const
xlWBATWorksheet = -4167;
var
Excel, WorkBook, WorkSheet: Variant;
begin
Excel := CreateOleObject('Excel.Application');
Excel.DisplayAlerts := false;
Workbook := Excel.Workbooks.Add(xlWBATWorksheet);
WorkSheet := WorkBook.WorkSheets[1];
WorkSheet.Name := 'nombre de la hoja';
WorkBook.SaveAs('c:\ruta al archivo\archivo.xls');
Excel.Quit;
end;
Para llenar las celdas lo hacemos mediante WorkSheet.Cells que es similar a StringGrid.Cells, es decir, un arreglo de dos dimensiones.
Pero hay que observar dos cosas respecto a los índices del arreglo:
- En StringGrid.Cells los índices comienzan en cero mientras que en WorkSheet.Cells comienzan en 1.
- En StringGrid.Cells el primer índice es de la columna y el segundo de la fila mientras que en WorkSheet.Cells es alrevés.
Así, por ejemplo, para llenar los títulos (nombres de 'campos') a partir de la primera fila del StringGrid haríamos:
Código Delphi
[-]
for J := 0 to StringGrid.ColCount - 1 do
WorkSheet.Cells[1, J + 1] := StringGrid.Cells[J, 0];
Una vez llenados los encabezados puedes cerrar el archivo y comenzar con ADO o bien seguir llenando celdas con WorkSheet usando un doble ciclo:
Código Delphi
[-]
for I := 1 to StringGrid1.RowCount - 1 do
for J := 0 to StringGrid1.ColCount - 1 do
WorkSheet.Cells[I + 1, J + 1] := StringGrid1.Cells[J, I];
Pero como mencioné antes, cuando se trata de muchos registros, la diferencia entre ADO y OLE puede ser enorme.
Para usar ADO necesitas una componente TAdoConnection y una componente TAdoTable.
Código Delphi
[-]
const
AdoConn = 'Provider=%s;Data Source=%s;Extended Properties=%s';
begin
AdoConnection.ConnectionString :=
Format(AdoConn, ['Microsoft.Jet.OLEDB.4.0', FileName, 'Excel 8.0']);
AdoTable.Connection := AdoConnection;
AdoTable.CursorLocation := clUseServer;
AdoTable.CursorType := ctOpenForwardOnly;
AdoTable.TableName := 'nombrehoja$';
AdoTable.Open;
AdoTable.Close;
end;
El llenado de las celdas se hace también con un doble ciclo:
Código Delphi
[-]
for I := 1 to StringGrid1.RowCount - 1 do
begin
AdoTable1.Append;
for J := 0 to StringGrid1.ColCount - 1 do
AdoTable1.Fields[J].Value := StringGrid1.Cells[J, I];
AdoTable1.Post;
end;
Prueba ambos métodos para el llenado de celdas y dependiendo de los resultados y la cantidad de filas escoge el más adecuado.
// Saludos