Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Servers (https://www.clubdelphi.com/foros/forumdisplay.php?f=9)
-   -   Llevar desde Excel a una BD paradox (https://www.clubdelphi.com/foros/showthread.php?t=2696)

DarkSide 03-08-2003 05:05:50

Llevar desde Excel a una BD paradox
 
Necesito recuperar información desde una planilla Excel a una BD, en este caso Paradox. El problema es que son mas de 50.000 lineas, y en el traspaso se queda pegado en la 4.000 aprox., ademas que el proceso resulta demasiado lento, si bien se va a realizar una o dos veces al año, calculo que llevaria mas de media hora en completarse. Si alguien tiene alguna solución mas eficiente, por favor de enviarmela, o alguna dirección de internet que hable del tema.

A continuación les envio el codigo fuente. Esta en Delphi 5.0 y paradox 7.0. de antemnao muchas gracias:


uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, Db, DBTables, ComObj, ComCtrls;
...

public
Excel: Variant; // Objeto OLE.
...

procedure TfrmImporta.btnImportaClick(Sender: TObject);
var Hoja: OleVariant;
nFil: Integer;
xVal: String;
begin

// Crea objeto Excel.
try
Excel := CreateOleObject('Excel.Application');
except
showmessage('No se pudo crear el Objecto Excel.');
Exit;
end;

Excel.Workbooks.Open(Edit1.Text); // Abre libro Excel
Hoja := Excel.Worksheets.Item['Datos']; // Abre Hoja 'Datos'.
Hoja.Activate;

// Elimina datos anteriores
Table1.Open;
Table1.First;
while not Table1.Eof do begin
Table1.Delete;
end;

nFil:= 2;
repeat
Table1.Insert;
Table1.FieldByName('fecha').AsDateTime:= Excel.Cells[nFil,1].Value;
Table1.FieldByName('cuenta').AsString := Excel.Cells[nFil,4].Value;
Table1.FieldByName('debe').AsString := Excel.Cells[nFil,7].Value;
Table1.FieldByName('debe_d').AsString := Excel.Cells[nFil,9].Value;
Table1.FieldByName('haber').AsString := Excel.Cells[nFil,8].Value;
Table1.FieldByName('haber_d').AsString:= Excel.Cells[nFil,10].Value;
Table1.FieldByName('ccosto').AsString := Excel.Cells[nFil,12].Value;
Table1.FieldByName('cpadre').AsString := Excel.Cells[nFil,16].Value;
Table1.FieldByName('tcomp').AsString := Excel.Cells[nFil,11].Value;
Table1.FieldByName('comp').AsString := Excel.Cells[nFil,2].Value;
Table1.FieldByName('predio').AsString := Excel.Cells[nFil,6].Value;
Table1.FieldByName('tconc').AsString := Excel.Cells[nFil,14].Value;
Table1.FieldByName('conc').AsString := Excel.Cells[nFil,15].Value;
Table1.Post;
nFil:= nFil + 1;
xVal:= IntToStr(Excel.Cells[nFil,4].Value);
until (xVal = '0');

// Cierra archivo excel.
try
Excel.Quit;
except
ShowMessage('La aplicación Excel no se pudo finalizar automaticamente.');
Excel.Visible := True;
end;
end;

roman 03-08-2003 06:54:16

Quizá te sirva usar ADO. Jamás había utilizado estas componentes pero recordaba haber leído alguna vez acerca de acceder a Excel mediante ellas. Hice una pequeña búsqueda y me encontré este artículo en Delphi Magazine. Quizá no tengas acceso a él ya que muchos artículos son sólo para suscriptores pero si conoces ADO no tendrás problemas, si no, pregunta y te digo los pasos a seguir (que yo seguí como burro pues, repito, desconozco ADO).

El punto importante es que hice una prueba con una hija de Excel con 65534 filas (el máximo que permite Excel) y tres columnas. Además de no colgarse el traspaso duró no más de cuatro minutos.

Será cuestión de que experimentes a ver si te sirve.

// Saludos

roman 03-08-2003 06:57:36

Fe de erratas:

En el mensaje anterior donde dice "hija de Excel" debe decir "hoja de Excel". Yo mejor no me meto con las hijas del señor Excel, no quiero problemas ni con él n i con mi novia :D

DarkSide 03-08-2003 07:36:42

Gracias por contestar. Me parece increible que en solo cuatro minutos se haya traspasado 65.000 lineas, lamentablemente no he trabajado con ADO, asi que recurro a tu ayuda, solo necesito un empujon incial y despues me voy solito.

En cuanto a las 'hijas de Excel' no te preocupes que yo me encargo, ya que por ahora no tengo novia, ja.:D

roman 03-08-2003 08:10:04

Ok, ahí va.

1. Agrega las componentes ADO a la paleta de componentes

2. Agrega una componente TAdoConnection a tu formulario y pon su propiedad LoginPrompt en false.

3. Haz doble click en la componente para que se abra el editor de la propiedad ConnectionString y selecciona "Use connection string" y luego oprime el botón "Build" para que se abra la ventana de vínculo de datos.

4. En esa ventana, en la ficha "Proveedor" (Provider) selecciona Microsoft Jet 4.0 OLE DB y da click en siguiente.

5. En la ficha "Conexión" (Connection), en el cuadro "Usar nombre de origen de datos" (o algo así) escribe el nombre del archivo excel (te deja buscarlo con un botoncito)

6. En la ficha "Todas" (All) selecciona "Extended properties" y luego "Modificar valor" y escribes "Excel 8.0" (sin las comillas)

7. Oprime 'Ok' las veces necesarias para cerrar todas las ventanas.

Esta fue la parte "difícil", crear la cadena de conexión.

8. Ahora coloca una componente TAdoDataSet en el formulario y asigna el AdoConnectio a su propiedad "Connection"

9. Pon la propiedad CommandType del DataSet en cmdTableDirect y en la propiedad CommandText escoges la hoja que desees del archivo de Excel (si todo salió bien te aparece una lista con las hojas del libro) El nombre de la hoja aparece seguido de un signo $, es normal.

A partir de aquí ya todo es "coser y cantar". El AdoDataSet funciona similar a un Table (aunque de sólo lectura) y lo abres con su propiedad Active:=true o con el método Open (cuidado porque a mi me marcó un error cuando lo activé en tiempo de diseño y luego corrí la aplicación así que mejor lo dejé inactivo y lo abrí hasta la ejecución).

Para la transferencia simplemente usas un bucle:

Código:

while not AdoDataSet1.EoF do
begin
  Table1.Append;

  Table1.Fields[0].Value := AdoDataSet1.Fields[0].Value;
  Table1.Fields[1].Value := AdoDataSet1.Fields[1].Value;
  Table1.Fields[2].Value := AdoDataSet1.Fields[2].Value;
  ...
  AdoDataSet1.Next;
end;

o con FieldByName como lo hiciste tú. En lo anterior Table1 es la tabla Paradox ya creada con la estructura deseada.

Espero que te sirva. Parece complicado pero en realidad no lo es tanto, es sólo que es largo describir los pasos de forma escrita.

// Saludos

roman 03-08-2003 08:52:06

¡Ah qué caray!

El bucle tiene un error pero supongo que ya lo habrás notado: ¡le falta Table1.Append al principio!

// Saludos

DarkSide 03-08-2003 09:02:29

De nuevo muchas gracias, realize todos los pasos que me indicaste, y todo funciono a la perfecion. Si bien los pasos una vez descritos son bastante entendibles, ¿como pudiste llegar a ellos?. Mientras me contestabas, trate de una y otra forma de utilizar estos componentes, pero no se me ocurrio hacerlo de esa forma. Ya sé que muchas veces se cuenta el milagro pero no el santo, pero en realidad me interesa investigar mas a fondo los componentes ADO, si me pudieras dar algunas direcciones internet que haben del tema te lo agradeceria mucho.

Consulta: Existe alguna diferencia que sea importante al momento de decidir ocupar, entre las propiedades:

Table1.Fields[0].Value;
y
Table1.FieldByName('campo').AsString;

Reitero mis agradecimientos roman.

roman 03-08-2003 09:17:25

Cita:

Posteado originalmente por DarkSide
De nuevo muchas gracias, realize todos los pasos que me indicaste, y todo funciono a la perfecion. Si bien los pasos una vez descritos son bastante entendibles, ¿como pudiste llegar a ellos?. Mientras me contestabas, trate de una y otra forma de utilizar estos componentes, pero no se me ocurrio hacerlo de esa forma. Ya sé que muchas veces se cuenta el milagro pero no el santo, pero en realidad me interesa investigar mas a fondo los componentes ADO, si me pudieras dar algunas direcciones internet que haben del tema te lo agradeceria mucho.

Como te mencioné, seguí los pasos del artículo, no creas que se me ocurrieron a mi solito. Por cierto, la suscripción no es muy cara y es muy buena la revista y tienes acceso a un montón de artículos de todos los números pasados.

De cualquier forma debe haber muchos lugares en la Web en dónde consultar. Una búsqueda en Google me dió al menos este artículo del sitio de Borland. Aquí debes registrarte pero es gratuito.

Tanbién seguro que otras personas en estos foros podrán orientarte mejor que yo, una vez que despierten :)

Cita:

Posteado originalmente por DarkSide

Consulta: Existe alguna diferencia que sea importante al momento de decidir ocupar, entre las propiedades:

Table1.Fields[0].Value;
y
Table1.FieldByName('campo').AsString;

Dado que la primera forma accede a los campos mediante "variants" quizá sea más lento, prueba usando FieldByName().AsXXX a ver si se agiliza un poco.

// Saludos

DarkSide 03-08-2003 10:03:27

Muchas gracias por todo, ahora me voy a acostar porque es muy tarde y me dio mucho sueño :o .

Saludos.:)

DarkSide 05-08-2003 08:43:17

Hola, de nuevo. Resulta que probando con una planilla Excel,
tuve que validar si las celdas estaban vacias o no, a traves del
siguiente codigo dentro del bucle de asignación:

Código:

val cConc: String;
 ...
while not AdoDataSet1.Eof do begin
  if AdoDataSet1.Fields[14].Value = Null
      then cConc:= ''
      else cConc:= AdoDataSet1.Fields[14].Value;
  ...

  Table1.FieldByName('conc').AsString:= cConc;
  ...
end;

Pero resulta que sucedio algo extraño, habian celdas que tenian
información (valor numerico), y en la asignación aparecian con
valores nulos (Null), siendo que la celda anterior (misma columna)
se recuperaba el valor sin ningun problema, y en otra columna
simplemente no recuperaba su valor en todo el bucle.

Revise la planilla excel para ver si era el formato de la celda, pero
ambas tenian el mismo formato. Probe cambiando de Excel 2000
a Excel 97, pero no resulto. La unica diferencia que encontre es el
valor que contenian, la que me arrojaba el valor nulo tenia
5202006 y la anterior 1118084, pero como la recuperaba con la
sentencia:

Table1.FieldByName('cuenta').AsString:= AdoDataSet1.Fields[3].Value;

deberia devolverme un valor 'variants'. Desde ya agradesco su ayuda.

DarkSide 25-08-2003 05:58:09

Esta vez me respondo yo mismo.

Resulta que el programa estaba bien, el problema era la planilla excel, que tenia datos con distinta alineación (izq. y derecha) en una misma columna, y esto por alguna razón que desconozco traspasaba valores nulos. La solución fue copiar "solo los valores" de la hoja (pegado especial), pegarlos en una hoja nueva y dar el formato de "texto" a todas las celdas.

En fin, cuando se trabaja con Excel hay que tener en cuenta estos inconvenientes.

Por mi parte cierro este hilo, y muchas gracias por todo.

atirado 30-03-2004 03:58:04

:cool: :cool: Hola de nuevo! Hice nuevamente los pasos que le menciona Román a DarkSide y corregí algunos errores que tenía y logré por fin que el dbgrid se conectara a mi archivo de excel.
Sin embargo, no logro hacer que en el dbgrid me muestre la tabla. ¿Alguien sabrá por qué me marca un error al querer abrir la tabla que lo contiene?

Tengo los siguientes componentes en la forma:
1. Una ADOConnection llamado adcExcel cuya ConnectionString es la siguiente:

Código:

Provider=Microsoft.Jet.OLEDB.4.0;User ID=admin;
Data Source=C:\Documents and Settings\Administrador\Mis documentos\BD Pruebas XL-ADO\nomina.xls;
Mode=ReadWrite;Extended Properties=Excel 8.0;Jet OLEDB:System database="";
Jet OLEDB:Registry Path="";Jet OLEDB:Database Password="";
Jet OLEDB:Engine Type=35;Jet OLEDB:Database Locking
Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;
Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;
Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;
Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False

Manda llamar como provider a Microsoft.Jet.OLEDB.4.0 y el archivo es de Excel, llamado "nominas.xls"
2. Un ADODataSet llamado dsExcel que tiene las siguientes propiedades:
  • Connection => adcExcel.
  • Command type => cmdTableDirect
  • CommandText => Hoja1$ (donde está la tabla con los datos)
Este ADODataSet contiene todos los campos de la tabla de Excel, por ello comento que al parecer el enlace sí se logra.
3. Un DataSource llamado dsExcel cuyo DataSet es dsExcel.
4. Un ADOTable llamado tblExcel con las siguientes propiedades:
  • Connection => adcExcel
  • MasterSource => dscExcel
  • TableName => Hoja1$
Y al momento de tratar de abrir la tabla en tiempo de ejecución, me envía la excepción:

Código:
Project X.exe raised exception class EOleException with message 'Error de sintaxis en la cláusula FROM'. Process stopped. Use Step or Run to continue.

De antemano muchas gracias por su ayuda; realmente me ha servido mucho tener contacto con ustedes :cool:

roman 30-03-2004 06:28:34

atirado

Por favor edita tu mensaje para cortar la línea del "connection string" ya que ocasiona que el ancho total de tu mensaje y por tanto de todos los demás se haga extremadamente ancho y muy difícil de leer.

En cuanto a tu pregunta no sé a qué se deba. Quizá tenga que ver con la versión de Excel. ¿Qué versión utilizas?

// Saludos

atirado 30-03-2004 18:56:56

Hola, Román! Sorry a todos, creo que se me fueron las 4 con lo del código, jeje :D

Respecto al problema, les paso aquí cómo lo solucioné, por si alguien más tiene ese problema:

Mi problema fue, precisamente, haber puesto un ADOTable, pues al querer conectar el DBGrid a dicho componente, era donde me marcaba el dichoso código
Código:

Error de sintáxis en la cláusula FROM
pues no le podía agregar los campos que tomaba el DataSource del archivo de EXCEL.
La solución fue tan simple y sencilla como borrar el ADOTable y conectar el DBGrid directamente al DataSource.
Es decir, sólo me quedé con lo siguiente:
  1. Un TADOConection, enlazado al archivo de Excel por medio de Microsoft Jet OLEDB 4.0 con el valor "Excel 8.0" en Extended Properties de la pestaña "All".
  2. Un TADODataSet con los valores:
    • Connection: adcNomina (el nombre de mi TADOConnection)
    • Command Type: cmdTableDirect
    • Command Text: Nomina$ (Nombre de la HOJA -no del libro- donde están los datos)
  3. Un DataSource con los siguientes valores:
    • DataSet : dsNomina (nombre de mi TADODataSet)
Espero que si alguien tiene un problema parecido, lo pueda resolver :cool:
Un enorme saludo a tod@s :p

Alejandro

AntonioMM 23-05-2006 19:42:00

Me falta algo?
 
Estoy intentando pasar este codigo a un programa.
Todo va de maravilla, pero a la hora de conectar el TADODataSet, la propiedad commandText, me da el siguiente error :
NO SE PUDO ENCONTRAR EL ARCHIVO ISAM INSTALABLE

Alguien me puede asesorar..

Muchas Gracias

oracle 20-12-2006 00:46:38

Saludos amigos:

He seguido los pasos de Roman al pie de la letra y hasta el momento todo bien.

Utilizo un ADOConection, un ADODataSet, un DataSource y un DBGrid. Siguiendo los pasos y adicionando además el DBGrid logro que los datos se muestren en el DBGrid en tiempo de diseño, pero cuando ejecuto el programa, me salé el siguiente error:

Cita:

Projet Project.exe Raised exception class EOLeException with message "Error Catástrofico. Process Stoped used....."
He probado estos pasos tanto en C++ (Borland C++ 6) y en Delphi y en ambos me sale exactamente el mismo error....

En espera de alguna sugerencia....

Saludos

roman 24-12-2006 03:33:49

Pues el mensaje es bastante genérico como para poder decir algo sensato. Convendría que te fijases en qué línea de código te marca ese error.

// Saludos

Lepe 24-12-2006 08:51:00

Lo de Error catastrófico lo he vivido también. Busca Updates de delphi.

Di la versión que tienes de delphi y si tienes algún Update pack instalado.

Creo recordar que había problemas al tener instalado C++ y Delphi al mismo tiempo en las versiones 6, tenías que bajar un parche de Borland.

Saludos

roraclau 12-01-2007 11:47:01

"segui tus pasos Roman, pero estoy detenida en el punto 9"
 
Cita:

Empezado por roman
Ok, ahí va. Que conste en actas que quizá diga burradas pues como dije no conozco ADO. Lo bueno es que quienes sí lo conocen están dormidos así que no se reirán.

1. Agrega las componentes ADO a la paleta de componentes

2. Agrega una componente TAdoConnection a tu formulario y pon su propiedad LoginPrompt en false.

3. Haz doble click en la componente para que se abra el editor de la propiedad ConnectionString y selecciona "Use connection string" y luego oprime el botón "Build" para que se abra la ventana de vínculo de datos.

4. En esa ventana, en la ficha "Proveedor" (Provider) selecciona Microsoft Jet 4.0 OLE DB y da click en siguiente.

5. En la ficha "Conexión" (Connection), en el cuadro "Usar nombre de origen de datos" (o algo así) escribe el nombre del archivo excel (te deja buscarlo con un botoncito)

6. En la ficha "Todas" (All) selecciona "Extended properties" y luego "Modificar valor" y escribes "Excel 8.0" (sin las comillas)

7. Oprime 'Ok' las veces necesarias para cerrar todas las ventanas.

Esta fue la parte "difícil", crear la cadena de conexión.

8. Ahora coloca una componente TAdoDataSet en el formulario y asigna el AdoConnectio a su propiedad "Connection"

9. Pon la propiedad CommandType del DataSet en cmdTableDirect y en la propiedad CommandText escoges la hoja que desees del archivo de Excel (si todo salió bien te aparece una lista con las hojas del libro) El nombre de la hoja aparece seguido de un signo $, es normal.

A partir de aquí ya todo es "coser y cantar". El AdoDataSet funciona similar a un Table (aunque de sólo lectura) y lo abres con su propiedad Active:=true o con el método Open (cuidado porque a mi me marcó un error cuando lo activé en tiempo de diseño y luego corrí la aplicación así que mejor lo dejé inactivo y lo abrí hasta la ejecución).

Para la transferencia simplemente usas un bucle:

Código:

while not AdoDataSet1.EoF do
begin
  Table1.Append;
 
  Table1.Fields[0].Value := AdoDataSet1.Fields[0].Value;
  Table1.Fields[1].Value := AdoDataSet1.Fields[1].Value;
  Table1.Fields[2].Value := AdoDataSet1.Fields[2].Value;
  ...
  AdoDataSet1.Next;
end;

o con FieldByName como lo hiciste tú. En lo anterior Table1 es la tabla Paradox ya creada con la estructura deseada.

Espero que te sirva. Parece complicado pero en realidad no lo es tanto, es sólo que es largo describir los pasos de forma escrita.

// Saludos

Hola soy Clau,
Alguien podría ayudarme dandome un ejemplo de como se abre una ADO en tiempo de ejecución, ya que me no he podido ver la aplicación funcionando y pretendo continuar pasando la info a paradox.

Por su apoyo, muchas Gracias.

p.d. Gracias a Bicho por sus sugerencias.

Bicho 12-01-2007 12:51:48

Hola Clau,

ahora he revisado los pasos de Roman, he visto que me había equivocado en el paso 6, pero ya lo he corregido y me funciona perfectamente.
Me has comentado por privado que tenias problemas en el punto 9.
¿Puedes indicarnos que problema exactamente te sucede?
¿Aparece algún mensaje de error?
Y eso de que no has podido ver la aplicación funcionando, ¿a que te refieres?
Cuantos más datos des, más posibilidades habrá de que entre todos encontremos una solucion.

Saludos

oracle 12-01-2007 15:43:49

Cita:

... por Lepe
Lo de Error catastrófico lo he vivido también. Busca Updates de delphi.

Di la versión que tienes de delphi y si tienes algún Update pack instalado.

Creo recordar que había problemas al tener instalado C++ y Delphi al mismo tiempo en las versiones 6, tenías que bajar un parche de Borland.

Excelente Lepe. Yo tenia instalado el Borland C++ Builder 6 y el Delphi 7. Lo he probado en otra PC con solo el C++ y funciona perfectamente. Muchas gracias y disculpen la demora pero es que estaba de vacaciones muy lejos...ah y muchas felicidades en este nuevo año a todos...

Saludos

roraclau 12-01-2007 17:45:23

como activar un componente ADODataSet en tiempo de ejecución.
 
Bicho Hola,

Perdón que hasta ahorita te conteste dormi un poco de las 5 a estas horas, ahora te digo:

¿Puedes indicarnos que problema exactamente te sucede?
si, según creo es porque tenia el Componente ADODataSet en su propiedad active en True, pero ya lo deje en false y de todas maneras sigo con el error :confused:
Hice los pasos hasta el 9 y aquí puse un componente DbGrid para ver la info del archivo excel ligandolo con un componente DataSurce, corrir el proyecto y bolas el error:rolleyes: aunque el en modo de diseño si puedo ver la info


¿Aparece algún mensaje de error?

si, el error que me marca es:
El motor de base de datos Microsoft Jet no puede abrir el archivo”. Está abierto en modo exclusivo por otro usuario o bien necesita permiso para ver sus datos.

Y eso de que no has podido ver la aplicación funcionando, ¿a que te refieres?
Cuantos más datos des, más posibilidades habrá de que entre todos encontremos una solucion.


Bueno, por el error no he podido ver el proyecto en tiempo de ejecución, como te comento solo en diseño me funciona. Me gustaría verlo en ejecución para poder continuar ahora con el traspaso de datos a tablita de paradox, tal como lo explica Roman.:)

muchisimas gracias por tu apoyo Bicho. Saludos
Ojalá sea buena esta explicación para que me puedan ayudar.

p.d. según yo intente activar así: puse un Botón para que en su evento OnClick activara el componente ADODataSet lo hice así:

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
TADODataSet.True;
end;


pero tambien me marco error: Undeclared identifier: True
este es mi problema no se como va la instrucción.:o

roraclau 12-01-2007 18:05:31

Bicho
 
Hola ya te conteste, pero no supe como, no se manejar bien las respuestas enseguidita de lo que me contestan, y quien sabe a donde se fue lo que te conteste, porque no los veo.
Me podrás ayudar. Gracias.

Bicho 12-01-2007 18:25:14

Cita:

Empezado por Clau
Hola ya te conteste, pero no supe como, no se manejar bien las respuestas enseguidita de lo que me contestan, y quien sabe a donde se fue lo que te conteste, porque no los veo.

:confused: No se a que te refieres, pero bueno.

Cita:

Empezado por Clau
si, según creo es porque tenia el Componente ADODataSet en su propiedad active en True, pero ya lo deje en false y de todas maneras sigo con el error
Hice los pasos hasta el 9 y aquí puse un componente DbGrid para ver la info del archivo excel ligandolo con un componente DataSurce, corrir el proyecto y bolas el error aunque el en modo de diseño si puedo ver la info

Es lo que comenta Roman, que da muchos problemas si lo tienes activado en tiempo de diseño y no de ejecución. Procura tenerlo desactivado o desconectado y conectarlo al ejecutar la aplicación, en los eventos OnCreate o OnActivate o un Click de botón sino no necesitas la conexión desde el inicio de la ejecución de la aplicación.
Yo lo he estado probando, como te comenté. Y no he visto la manera en diseño de conectar el DBGrid a un AdoDataSet. Es decir, tenía que hacerlo "a mano", recorrer el DataSet y asignar los datos a un StringGrid.

Cita:

Empezado por Clau
si, el error que me marca es:
El motor de base de datos Microsoft Jet no puede abrir el archivo”. Está abierto en modo exclusivo por otro usuario o bien necesita permiso para ver sus datos.

Quizá sea por lo de tener activado en tiempo de diseño.

Cita:

Empezado por Clau
p.d. según yo intente activar así: puse un Botón para que en su evento OnClick activara el componente ADODataSet lo hice así:

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
TADODataSet.True;
end;


pero tambien me marco error: Undeclared identifier: True
este es mi problema no se como va la instrucción.

La forma correcta es así:

Código Delphi [-]
 ADODataSet1.Active := True; //ADODataSet1, es el name que aparece en eobjeto que has arrastrado en el formulario, mientras que TADODataSet es el nombre de la clase a la que pertenece ese objeto.
//Active es la propiedad que tiene el dataset para conectarse. y el ":=" es para realizar una asignación
  
//Seguramente tambien deberías hacer antes conectar el ADOConnection de la misma forma.
  AdoConnection1.Connected := True; //En este caso la propiedad para activar o conectar el AdoConnection es Connected

Espero te sirva para avanzar. Ya nos comentas que tal.

En cuanto a tu experiencia en los foros, cuando escribas un hilo tienes una barra arriba que te permite encerrar el texto y formatearlo para hacerlo más legible. Échales un vistazo te ayudarán mucho. Son etiquetas muy sencillas.
Tienes [quote] para envolver citas, para escribir lo que ha dicho alguien.
Y etiquetas [delphi] y [code] para encerrar el código que escribas.

Saludos y suerte.

oracle 12-01-2007 18:49:17

Bueno primero: Clau quizas no ves las respuestas nuevas porque hay mas de una pagina en la vista que tienes del foro y tienes que mirar en las otras para ver los nuevo mensajes u ordenarlos en otro orden.

Por lo otro, creo que la forma de conectar el DBgrid al AdoDataSet es a traves de un DataSource, al menos asi es como lo hago yo. O sea la propiedad "DataSource" de nuestro DBGrid debe tener el DataSource del que les hablo, y a su ves este DataSource, en su propiedad "DataSet" debe tener el ADODataSet y asi ya estan conectados. Lo de la coneccion en tiempo de diseño o en tiempo de ejecucion es a discricion de uds, igual funciona...

Y por el otro error, ademas de lo que comenta Bicho asegurate de tener la coneccion que estableciste con el Excel, (pasos 6-7 u 8) en la ventana donde te pide el modo de lectura tener marcado read solamente, a mi eso me dio ese error...

Saludos

egostar 02-02-2007 01:23:35

Retomando el tema
 
Hola compañeros

Estoy con el tema de abrir una hoja de excel con ADO, seguí las indicaciones que se mostraron en este tema y funciona perfectamente.

Resulta que este procedimiento se hace en tiempo de diseño y funciona muy bien, ahora el punto es que necesito hacerlo en tiempo de ejecución y abrir cualquier archivo excel y cualquier hoja dentro del archivo.

En este momento he logrado abrir un archivo excel cualquiera desde un OpenDialog, pero según las instrucciones proporcionadas en tiempo de diseño al momento que se indica al ADODataSet.CommandType = cmdTableDirect, automaticamente muestra en la propiedad CommandText las hojas que están dentro de ese archivo.

Mi pregunta es la siguiente:

Como puedo obtener en un ComboBox o un ListBox los nombres de las hojas que están dentro del archivo.

Aqui pego lo que ya he hecho, aún me faltan algunas validaciones que ya agregaré posteriormente.

Código Delphi [-]
 
unit ULeeSalientes;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, DB, ADODB, Grids, DBGrids, ExtCtrls;
 
type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    OpenDialog1: TOpenDialog;
    Panel1: TPanel;
    Panel2: TPanel;
    BitBtn1: TBitBtn;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ADOConnection1BeforeConnect(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  Archivo: String;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.ADOConnection1BeforeConnect(Sender: TObject);
begin
   ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;'+
                                      'Data Source='+Archivo+
                                      ';Extended Properties=Excel 8.0;'+
                                      'Persist Security Info=False';
end;
 
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  If OpenDialog1.Execute then begin
     Archivo := OpenDialog1.FileName;
     ADODataSet1.CommandText  := 'Dic 06$'; //Aqui estoy asignando el nombre de la hoja
     ADOConnection1.Connected := True;
     AdoDataSet1.Open;
  end;
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  AdoDataSet1.Close;
  ADOConnection1.Connected := False;
end;
 
end.

Gracias anticipadas.

egostar 02-02-2007 03:29:30

Problema Resuelto
 
Pues actualizando la duda que tenia, ya encontré la manera de obtener el nombre de las hojas.

Código Delphi [-]
 
ADOConnection1.GetTablesNames(ComboBox1.Items,False);

Resulta que el archivo excel lo debía haber considerado como una base de datos y las hojas como las tablas que contiene.

Pues nada, creo que con esto ya quedó resuelto mi problema.

Aqui pego el código completo espero que sirva para alguien mas.

Código Delphi [-]
 
unit ULeeSalientes;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, DB, ADODB, Grids, DBGrids, ExtCtrls;
 
type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    OpenDialog1: TOpenDialog;
    Panel1: TPanel;
    BitBtn1: TBitBtn;
    ComboBox1: TComboBox;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ADOConnection1BeforeConnect(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  Archivo,Hoja: String;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.ADOConnection1BeforeConnect(Sender: TObject);
begin
   ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;'+
                                      'Data Source='+Archivo+
                                      ';Extended Properties=Excel 8.0;'+
                                      'Persist Security Info=False';
end;
 
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  If OpenDialog1.Execute then begin
     Archivo := OpenDialog1.FileName;
     ADOConnection1.Connected := True;
     ADOConnection1.GetTableNames(ComboBox1.Items,False);
  end;
end;
 
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  ADODataSet1.CommandText  := ComboBox1.Text;
  AdoDataSet1.Open;
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  AdoDataSet1.Close;
  ADOConnection1.Connected := False;
end;
 
end.

Saludos.

Dalmine 06-02-2007 02:37:41

que tal una pregunta se puede seguir agregando datos al archivo excel abierto y guardar los cambios


saludos

ozegarra 05-02-2008 23:49:14

Buenas estuve chekeando este hilo para saber como pasar una tabla excel a firebird.
He seguido todos los pasos pero no me graba los datos en mi tabla firebird, quiza me falta algo (soy nuevo en esto asi que perdonen mi ingenuidad). Les paso las lineas de codigo que tengo.

Código Delphi [-]
AdoDataSet1.Active :=True;
  while not AdoDataSet1.Eof do
  begin
    Table_Importado.Active := True;
    Table_Importado.Append;
    Table_Importado.Fields[0].Value := AdoDataSet1.Fields[0].Value;
    Table_Importado.Fields[1].Value := AdoDataSet1.Fields[1].Value;
    Table_Importado.Fields[2].Value := AdoDataSet1.Fields[2].Value;
    Table_Importado.Active := False;
    AdoDataSet1.Next;
  end;

esto no me marca ningun error, entra al bucle y recorreo todo el excel pero no me graba nada, que es lo que me falta?.

Gracias de antemano por su ayuda.

keyboy 06-02-2008 06:00:28

Prueba así:

Código Delphi [-]
AdoDataSet1.Active :=True;
Table_Importado.Active := True;

while not AdoDataSet1.Eof do
begin
  Table_Importado.Append;

  Table_Importado.Fields[0].Value := AdoDataSet1.Fields[0].Value;
  Table_Importado.Fields[1].Value := AdoDataSet1.Fields[1].Value;
  Table_Importado.Fields[2].Value := AdoDataSet1.Fields[2].Value;

  AdoDataSet1.Next;
end;

Table_Importado.Active := False;

No es necesario activar el AdoDataset en cada vuelta. Y al desactivarlo, no le das tiempo a que se guarden los datos.

Bye

DarkSide 06-02-2008 16:24:05

Como te dijo keyboy, no es necesario activar y desactivar la tabla en cada ciclo de ingreso, lo que si debes hacer es agregar el metodo "post", para forzar que grabe los datos, asi te deberia funcionar.

Código Delphi [-]
  Table_Importado.Active := True;
  AdoDataSet1.Active :=True;

  while not AdoDataSet1.Eof do
  begin
    Table_Importado.Append;
    Table_Importado.Fields[0].Value := AdoDataSet1.Fields[0].Value;
    Table_Importado.Fields[1].Value := AdoDataSet1.Fields[1].Value;
    Table_Importado.Fields[2].Value := AdoDataSet1.Fields[2].Value;

    Table_Importado.Post;
    
    AdoDataSet1.Next;
  end;
  
  Table_Importado.Active := False;
  AdoDataSet1.Active :=False;

Saludos.

keyboy 06-02-2008 16:35:19

Yo ttiendo a poner ese post que indicas, pero en realidad es innecesario. Un dataset hace un post automático cada vez que nos movemos de registro, de manera que en cada vuelta se guarda el registro de la vuelta anterior.

Bye

ozegarra 06-02-2008 16:38:23

Gracias por las respuestas, cambie un poco la logica para poder ejecutar un procedimiento almacenado que haga la insercion ya que no era tan simple como grabar una tabla directa. Ya pude realizar la tarea que requeria que era grabar dos tablas con ese excel.

De todas maneras probaré lo mencionado para cuando lo requiera, cada dia se aprende mas asi que muchas gracias por el apoyo y lo anotare en el libro...

Saludos
Oscar

faustofabian 05-03-2008 21:57:21

Paleta Servers
 
hola genta me interesaria saber si alguien tiene conocimiento de la paleta SERVER en realidad me interesa manejar formatos en exel desde delphi5 como ser, combinar seldas, darle un formato de fuente especial, recuadros, manejo de colores. todo lo que es formatos en exel desde delphi. Gracias, a la espera de alguna respuesta.

ledesmarc 15-07-2008 15:33:59

Excel
 
Roman gracias por la info, pero tengo un problema cuando quiero importar desde el excel (usando Ado) lo hace bien cuando se trata de una columna que sean todos del mismo tipo para mi caso(son todos numeros) el tema es que cuando en la columna hay mesclados numeros y letras en una misma celda, la importacion se corta (osea importa hasta esa celda)y la verdad me he cansado de buscar pero no encuentro el porque.
Te agredecere cualquier sugerencia
Saludos.
Marcos

ingabraham 17-06-2011 16:40:36

tengo problemas con hojas de excel .xlsx
Código Delphi [-]
error .  la tabla externa no tiene el formato esperado

kapcomx 23-06-2011 20:00:36

veo ke ya solucionaste el problema, nada mas te recomendaria cambiar el paradox por otra base de datos con el numero de registros que mencionas, yo utilizaba paradox con tablas de medianas a grandes y era una autentica pesadilla, ahora con mysql 5.0 todo es felicidad....

Saludos...

LuisAlf:: 28-08-2011 22:34:06

Cita:

Empezado por ledesmarc (Mensaje 300564)
Roman gracias por la info, pero tengo un problema cuando quiero importar desde el excel (usando Ado) lo hace bien cuando se trata de una columna que sean todos del mismo tipo para mi caso(son todos numeros) el tema es que cuando en la columna hay mesclados numeros y letras en una misma celda, la importacion se corta (osea importa hasta esa celda)y la verdad me he cansado de buscar pero no encuentro el porque.
Te agredecere cualquier sugerencia
Saludos.
Marcos

Hola!

Estuve siguiendo el hilo para hacer la conexión...

Pero tuve un inconveniente, en mi archivo de excel tengo celdas que inician con una letra y otros donde son puros números, al hacer la importación el DBGrid solo me muestra los valores que inician con letra y los que solo son números se los saltea dejando la celda vacia...

La verdad no se porque pasa esto, ni como solucionar el problema...

Si alguien me puede ayudar se lo agradecería...

LuisAlf:: 03-09-2011 20:00:13

Pudiste solucionar este problema de alguna forma? :(

juanlaplata 08-09-2011 14:58:23

Importar Excel:
Código Delphi [-]
procedure TForm80.ExcelClick(Sender: TObject);
var
 Excel, Sheet: OLEVariant;
 CantRow, CantCol, i, j : Integer;
 RangoMatriz: Variant;
 FileName :string ;
begin

      OpenDialog.Title := 'Excel a Importar ...';
      OpenDialog.DefaultExt := 'xls';
      OpenDialog.InitialDir := ExtractFilePath(Application.ExeName);
      OpenDialog.FileName := '';
      OpenDialog.Filter:='Archivos Excel (*.xls)|*.xls';
      OpenDialog.FilterIndex:=1;
      if(OpenDialog.Execute)then
           begin
           if(OpenDialog.FileName <> '')then
              begin  

              FileName := OpenDialog.FileName;
              Excel := CreateOleObject('Excel.Application');
              Excel.Workbooks.Open(FileName);

              Sheet := Excel.Workbooks[ExtractFileName(FileName)].WorkSheets[1];
              Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;

              CantRow := Excel.ActiveCell.Row;
              CantCol := Excel.ActiveCell.Column;

              RangoMatriz := Excel.Range['A1', Excel.Cells.Item[CantRow,CantCol]].Value;

              for i:=1 to CantRow do
                 begin
                      for j:=1 to CantCol do
                       begin

                            Table1.Append;
                            Table1Campo.AsString := trim(RangoMatriz[i,j]);
                            Table1.Post;

                       end; // for j
                 end;//for i
              Excel.quit;
              end;
           end;
end;

Este Codigo, no es de mi autoria, deberia colocar la fuente, que la verdad, no la tengo en este momento.
Lo que hace es recorrer todas las celdas del Excel y cargar en una tabla.
La idea es ver como se hace y q cada uno lo reprograme a gusto y necesidad.
Saludos.


La franja horaria es GMT +2. Ahora son las 21:46:49.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi