PDA

Ver la Versión Completa : Caso curioso exportando a excel desde una rejilla.


marcoszorrilla
01-03-2009, 15:36:16
Afortunadamente lo acabo de resolver, pero os cuento lo que me ha estado pasando.

Con este código exporto facturas de una rejilla a excel, sin problemas.

procedure TfrConFacturas.spExcelClick(Sender: TObject);
var
excel:Variant;
fila,columna:Integer;
nCols:Integer;
Data : TDataSet;
MyDataSet:TDataSet;
i:Integer;
begin
try
excel:=CreateOleObject('Excel.Application');
except
ShowMessage('Excel no se pudo iniciar.');
exit;
end;
excel.Visible:=true;

Data:=DbgFacturas.DataSource.DataSet;
Data.First;
fila:=1;
columna:=0;
excel.Workbooks.Add;
nCols:= DbgFacturas.Columns.Count;
//Poner los títulos
for Columna:=0 to nCols - 1 do
begin
Excel.Cells[fila,columna + 1].Value:=DbgFacturas.Columns[Columna].Title.Caption;
end;

Fila:=Fila + 1;

//Desengachar controles para agilizar


try
while not(Data.eof) do
begin

for columna := 0 to DbgFacturas.Columns.Count-1 do
begin
if columna = 0 then
begin
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsString;
end;

if columna = 1 then
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsDateTime;

if (columna > 3) and (columna < 8) then
begin
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsFloat;
excel.Cells[fila,columna + 1].Style:= 'Comma';
end
else
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsString;
end;

Data.Next;
fila:= fila + 1;
end;
//Ajustar columnas
for columna:=1 to ncols do
begin
Excel.Columns[Columna].EntireColumn.AutoFit;
end;

Except
ShowMessage('Atención, se produjo un error en la transmisión.');
end;

end;

Ocurre que la primera columna es el número de las facturas y tiene el siguiente formato:
04-1800
El 04 indica el año y el resto del número es el número de la factura.

Pues sucede que me funcionaba correctamente hasta que observe que ciertas facturas en vez de el número aparecía una fecha con un formato personalizado.

Después de muchas vueltas me dí cuenta que esto sucedía a partir de la factura 2000

es decir 04-2000 y no con la 04-1999

Llegué a la conclusión de que las anteriores funcionaban por los efectos de ser menores de 2000 y a partir de este número excel interpretaba el formato como fecha.

Probé añadiéndole a la factura según se la pasaba a excel una 'F' por delante pues nada seguía igual.

Al final se me ocurrio entrar a Excel crear una macro de formato, entrar luego en dicha macro y ver que utilizaba para asegurarse el formato de texto y gracias a esto lo resolví, pongo la solución por si a alguien le ocurriera lo mismo.



procedure TfrConFacturas.spExcelClick(Sender: TObject);
var
excel:Variant;
fila,columna:Integer;
nCols:Integer;
Data : TDataSet;
MyDataSet:TDataSet;
i:Integer;
begin
try
excel:=CreateOleObject('Excel.Application');
except
ShowMessage('Excel no se pudo iniciar.');
exit;
end;
excel.Visible:=true;

Data:=DbgFacturas.DataSource.DataSet;
Data.First;
fila:=1;
columna:=0;
excel.Workbooks.Add;
nCols:= DbgFacturas.Columns.Count;
//Poner los títulos
for Columna:=0 to nCols - 1 do
begin
Excel.Cells[fila,columna + 1].Value:=DbgFacturas.Columns[Columna].Title.Caption;
end;

Fila:=Fila + 1;

//Desengachar controles para agilizar


try
while not(Data.eof) do
begin

for columna := 0 to DbgFacturas.Columns.Count-1 do
begin
if columna = 0 then
begin
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsString;
excel.Cells[fila,columna + 1].NumberFormat:='@';
end;

if columna = 1 then
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsDateTime;

if (columna > 3) and (columna < 8) then
begin
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsFloat;
excel.Cells[fila,columna + 1].Style:= 'Comma';
end
else
Excel.Cells[fila,columna + 1].Value:=Data.FieldByName(DbgFacturas.Columns[Columna].FieldName).AsString;
end;

Data.Next;
fila:= fila + 1;
end;
//Ajustar columnas
for columna:=1 to ncols do
begin
Excel.Columns[Columna].EntireColumn.AutoFit;
end;

Except
ShowMessage('Atención, se produjo un error en la transmisión.');
end;


end;


Un Saludo.

fjcg02
01-03-2009, 21:57:12
Si no recuerdo mal, si pones el carácter comilla simple ' al comienzo del campo, lo toma como texto, independientemente del formato de la celda.

Por otro lado, y aunque no venga muy a cuento.... has podido exportar a excel 2007 ? Estoy pillado y no encuentro solución.

Saludos

marcoszorrilla
01-03-2009, 21:59:39
Ya probé el apóstrofo y tampoco funcionó, relativo al tema de Excel 2007, no he tenido aún la oportunidad de hacer la prueba.

Un Saludo.

fjcg02
02-03-2009, 09:41:21
Gracias por la respuesta. Me sorprende que el apóstrofo no funcione.
A ver si alguien abre este melón del office 2007 que me tiene mareado.

Saludos

Caro
02-03-2009, 16:38:38
Holitas, a mi me ha pasado algo parecido hace dos semanas, en mi caso tenía que exportar un código XXX.XXXXXX donde las X son números, al exportarlo me lo tomaba como un número decimal cambiando el punto por la coma . También lo he solucionado con lo que comenta Marcos dandole formato ya que necesitaba que se exporte como texto. Lo unico diferente que tiene lo mío es "EntireColumn", para darle el formato a toda la columna.


ExcelSheet.Range['A1','A1'].EntireColumn.NumberFormat:='@';


Nota.- Yo tampoco he probado con Excel 2007

Saluditos

roman
02-03-2009, 17:22:38
Acabo de probar la exportación a Excel 2007 y no he tenido ningún problema.

// Saludos

fjcg02
02-03-2009, 17:50:40
Acabo de probar la exportación a Excel 2007 y no he tenido ningún problema.

// Saludos
roman, lo has hecho con delphi 7 ? o es otra versión ?
Por favor, confirmanoslo.

Gracias y un saludo

roman
02-03-2009, 18:09:17
Usé Delphi 7, y éste es el ejemplo:


var
Excel: OleVariant;
Libro: OleVariant;
Hoja: OleVariant;

begin
Excel := ComObj.CreateOleObject('Excel.Application');

Libro := Excel.Workbooks.Add();
Hoja := Libro.WorkSheets[1];

Hoja.Cells[1, 1] := 'id';
Hoja.Cells[1, 2] := 'nombre';

Hoja.Cells[2, 1] := '1';
Hoja.Cells[2, 2] := 'hugo';

Hoja.Cells[3, 1] := '2';
Hoja.Cells[3, 2] := 'paco';

Hoja.Cells[4, 1] := '3';
Hoja.Cells[4, 2] := 'luis';

Excel.Visible := true;
end;


Claro que aquí no tengo un dataset, pero esto ya sería los de menos ¿no?

// Saludos

fjcg02
04-03-2009, 13:40:09
FUNCIONA !!
Gracias por la aportación, he probado y me funciona. Hay unos cuantos hilos preguntando lo mismo, y parece que hay una pequeña diferencia.

El código que yo tengo y no funciona tiene unas pequeñas diferencias:
- Las variables son VARIANT en lugar de OLEVARIANT
- Cuando creo el objeto pongo Excel:= CreateObject('Excel.application')
- Lo demás es exactamente igual,...
- pero el resultado no es el mismo.

El código de roman funciona estupendamente tras probarlo.

Gracias y un saludo
:p

roman
04-03-2009, 17:32:31
Pues acabo de probar nuevamente usando Variant en lugar de OleVariant y sigue funcionando :p. Lo que no he podido probar es lo de CreateObject pues no sé a qué función te refieres. ¿En qué unidad está?

// Saludos

fjcg02
04-03-2009, 18:07:08
Creo que me equivoqué por hacer ezcrito de memoria.
Realmente quería decir CreateOleObject('Excel.Application'); y no CreateObject('Excel.Application');
Mañana la noche te responderé y copiaré el código exacto. Hoy no puedo , JUEGA EL ATHLETIC la semifinal de copa contra el Sevilla.

Saludos

roman
04-03-2009, 18:18:35
Pero entonces la única diferencia está sólo en el prefijo ComObj, pero eso sólo indica la unidad, no debería afectar, a menos que estés usando un CreateOleObject de otra unidad, aunque desconozco cuál podría ser.

JUEGA EL ATHLETIC

Quizá la primera vez que probaste la exportación a Excel 2007 también jugaba el Athletic :p :D

// Saludos

fjcg02
04-03-2009, 22:02:22
Bueno, como el athletic ha ganado, os pongo el código que no me funcionaba en un principio. Funcionaba para excel 2000 y 2003 pero no para excel 2007.

procedure ....
Excel: variant; Libro: variant; Hoja: variant; // Hoja de cálculo
begin
with SaveDialog1 do
begin
FileName :=DirectoryListBox1.Directory+'\'+trim(QPresupuestosSERIE.AsString)+'-'+trim(QPresupuestosNUMERO.AsString)+'.xls';
Filter:= 'Ficheros Excel|*.XLS;Todos los Ficheros|*.*';
DefaultExt := 'XLS';
Title := 'Exportando a Excel';
if execute then
begin
try
fichero:= SAveDialog1.FileName;
try
QLineasPres.Filtered:= False;
contRow:= 2; SheetsCont:= 0;
Excel := CreateOleObject( 'Excel.Application');
try
Excel.visible := False;
// Creamos un nuevo libro de trabajo
Excel.SheetsInNewWorkbook := 1;
xlt:= parametro('PRES_HOJAXLT');
if xlt<> '' then Libro := Excel.WorkBooks.Add();
Hoja := Libro.WorkSheets.Add;
Hoja := Libro.WorkSheets[1];
etc...

Pues eso, la diferencia está en el tipo de variable, que en este caso era variant y en el caso de roman olevariant.

Si hay algún gurú que pueda encontrar una respuesta, pues que nos la cuente si no es molestia.

Saludos

http://www.elcorreodigital.com/vizcaya/

Aupa Athletic !!