Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Ayuda otra vez!!

Disculpen pero despues de lograr leer los datos de un txt me encuentro con el problema q el txt tiene mas de 3000000 de lineas !!!! o sea cada vez que cargo en un dbgrid el sistemita se me cuelga.
Queria saber si alguien sabe alguna componente para cargar tantas lineas y mostrarlas en una grilla.
lo que tengo es un RxMemoryData donde cargo las lineas que levanto del txt.
tengo un Datasouce conectado con un dbgrid el cual muestra lo que cargue en el RxMemoryData.
Gracias!!!
Responder Con Cita
  #2  
Antiguo 06-07-2011
Avatar de oscarac
[oscarac] oscarac is offline
Miembro Premium
 
Registrado: sep 2006
Ubicación: Lima - Perú
Posts: 2.010
Poder: 20
oscarac Va por buen camino
has probado usar ClientDataset ?
__________________
Dulce Regalo que Satanas manda para mi.....
Responder Con Cita
  #3  
Antiguo 06-07-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.057
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Por favor, recuerda poner títulos descriptivos a tus preguntas, "ayuda otra vez!!" no es ningún título descriptivo. No olvides leer nuestra guía de estilo. Gracias.

Cita:
Empezado por pelikno Ver Mensaje
Disculpen pero despues de lograr leer los datos de un txt me encuentro con el problema q el txt tiene mas de 3000000 de lineas !!!! o sea cada vez que cargo en un dbgrid el sistemita se me cuelga.
Queria saber si alguien sabe alguna componente para cargar tantas lineas y mostrarlas en una grilla.
lo que tengo es un RxMemoryData donde cargo las lineas que levanto del txt.
tengo un Datasouce conectado con un dbgrid el cual muestra lo que cargue en el RxMemoryData.
Gracias!!!
El problema que tienes será por la memoria, 3.000.000 de registros son muchos registros para meterlo en memoria, ¿necesitas todos esos registros en memoria?.
Yo uso rxmemorydata y kbmmemtable con muchos registros, pero nunca se me ocurriría cargar en memoria tantos registros. Bueno, mentira, sí lo hago en algunas ocasiones, pero con muy, muy, muy pocos campos.
No es lo mismo tres millones de registros con una tabla de un campo... que 3 millones de registros con una tabla de 20 campos.
Responder Con Cita
  #4  
Antiguo 06-07-2011
wal_laplata wal_laplata is offline
Registrado
NULL
 
Registrado: jul 2011
Posts: 2
Poder: 0
wal_laplata Va por buen camino
Hola Casimiro, soy compañero de Pelikno y te agradezco la respuesta. El tema es que son mas de 5 millones de registros (lista de proveedores de la AFIP en todo el pais) y cada registro contiene 6 campos (cuit como principal y mas extenso, y el resto de los campos son estados de 2 o 1 caracter cada uno)

ejemplo :

cuit ganancia iva sociedad monotributo empleador
20201215749 NI NI NI N N

el tema que acortamos el archivo a 1000000 y tambien se re cuelga.

la idea es levantar los datos que estan en un texto plano y pasarlo a SQL, para poder de esa forma, realizar la actualizacion de los estados de los proveedores que posee el sistema con los de la AFIP. Aclaro que el sistema trabaja con base de datos SQL, por eso queremos unificar todo.
Porque un proveedor puede cambiar su situacion frente a la AFIP, pasar de monotributista a responsable inscripto, por ejemplo

Última edición por wal_laplata fecha: 06-07-2011 a las 20:47:42.
Responder Con Cita
  #5  
Antiguo 06-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Por favor, recuerda poner títulos descriptivos a tus preguntas, "ayuda otra vez!!" no es ningún título descriptivo. No olvides leer nuestra guía de estilo. Gracias.



El problema que tienes será por la memoria, 3.000.000 de registros son muchos registros para meterlo en memoria, ¿necesitas todos esos registros en memoria?.
Yo uso rxmemorydata y kbmmemtable con muchos registros, pero nunca se me ocurriría cargar en memoria tantos registros. Bueno, mentira, sí lo hago en algunas ocasiones, pero con muy, muy, muy pocos campos.
No es lo mismo tres millones de registros con una tabla de un campo... que 3 millones de registros con una tabla de 20 campos.
Si Solamente tiene 5 campos el tema q es la informacion que tengo que usar para mantener la base sqlserver que tengo nada mas que en mi base tengo muchisimos menos, es una tabla de proveedores y la tengo que actualizar con ese archivo.txt de 85 Mb !!!! el tema es que me mandan todos los proveedores en el txt yo solo tengo que actualizar diariamente los que tenga en mi base.
Responder Con Cita
  #6  
Antiguo 06-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Cita:
Empezado por oscarac Ver Mensaje
has probado usar ClientDataset ?

No que diferencia tiene?? no la he usado.
Responder Con Cita
  #7  
Antiguo 06-07-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.057
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
De todas formas si no pones el código fuente que lo veamos, no nos dice si sale algún error ni cual es, etc...
Responder Con Cita
  #8  
Antiguo 06-07-2011
wal_laplata wal_laplata is offline
Registrado
NULL
 
Registrado: jul 2011
Posts: 2
Poder: 0
wal_laplata Va por buen camino
Código Delphi [-]
begin
  AssignFile(myFile, 'C:\Temp\SELE-SAL-CONSTA.tmp');
  i:=0;
  FileMode := fmOpenRead;
  Reset(myFile);
  Memory.Active:=true;
  while not Eof(myFile) do
  begin
    text:='';
    while length(text) < 21 do
    begin
      Read(myFile, letter) ;   // Read and display one letter at a time
      text:=text + letter ;
    end;
    Read(myFile, letter);
    Memory.Append;
    Memorycuil.Value :=copy(text,1,2)+'-'+copy(text,3,8)+'-'+copy(text,11,1);
    Memoryganancias.Value:=copy(text,12,2);
    Memoryiva.Value:=copy(text,14,2);
    Memorymonotibuto.Value:= copy(text,16,2);
    MemoryintegranteSo.Value:= copy(text,18,1);
    Memoryempleador.Value:=copy(text,19,1);
    MemoryactividadMono.Value:=copy(text,20,2);
    Memory.Post;
    i:=i+1;
    Label1.Caption:=inttostr(i);
  end;
end;

Última edición por ecfisa fecha: 06-07-2011 a las 21:37:43. Razón: ETIQUETAS [DELPHI] [/DELPHI]
Responder Con Cita
  #9  
Antiguo 06-07-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola wal_laplata.

Por favor cuando pongas código Delphi encerralo entre las etiquetas [delphi] codigo [/delphi] para una mejor legibilidad.

Una pregunta: ¿ Cual es la longitud exácta que ocupa cada registro en el formato texto ?
Es decir en referencia a lo dicho más arriba:
Cita:
20201215749 NI NI NI N N
¿ Los últimos campos tienen longitud fija de dos caracteres, de uno ... ? ¿ Tienen algún separador ?



Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #10  
Antiguo 07-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Este es el Formato

Cita:
Empezado por ecfisa Ver Mensaje
Hola wal_laplata.

Por favor cuando pongas código Delphi encerralo entre las etiquetas [delphi] codigo [/delphi] para una mejor legibilidad.

Una pregunta: ¿ Cual es la longitud exácta que ocupa cada registro en el formato texto ?
Es decir en referencia a lo dicho más arriba:

¿ Los últimos campos tienen longitud fija de dos caracteres, de uno ... ? ¿ Tienen algún separador ?



Saludos.
Responder Con Cita
  #11  
Antiguo 07-07-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.057
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Entonces cuento 21 caracteres más cr+lf = 23 por línea.
Si son 5 millones de registros hacen: 115.000.000 bytes= 109 MB.
No es que sea algo muy abrumador, aunque me pregunto por qué lo cargas en memoria, ¿por qué no usas una tabla para ello?.
Responder Con Cita
  #12  
Antiguo 07-07-2011
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Otra cosa que podrías hacer es ir leyendo los datos en bloques, o sea, lees primero unas 1,000 líneas (o 10,000) y las procesas, luego lees otro bloque de n líneas y lo procesas y así hasta finalizar...


Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #13  
Antiguo 07-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Entonces cuento 21 caracteres más cr+lf = 23 por línea.
Si son 5 millones de registros hacen: 115.000.000 bytes= 109 MB.
No es que sea algo muy abrumador, aunque me pregunto por qué lo cargas en memoria, ¿por qué no usas una tabla para ello?.
El Archivo es de 85 mgb, por lo de la memoria vos decis que lo cargue en un ttable?
Responder Con Cita
  #14  
Antiguo 07-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);

var
  Fichero: File of byte;
  Buffer: array[0..21] of Char; // 22 bytes + 1
  Leidos: Integer;
  Str: string;
  b:byte;
  i:integer;
begin
i:=0;
  AssignFile(Fichero,'C:\Temp\SELE-SAL-CONSTA.tmp');
  Filemode:= fmOpenRead;
   Memory.Active:=true;
  {$I-}
    Reset(Fichero);// Reset(Fichero,1);
  {$I+}
  Timer1.Enabled:= true;
  if IOResult = 0 then
  begin

    while not  eof(Fichero) do
    begin
      FillChar(Buffer,Sizeof(Buffer),0);
      BlockRead(Fichero,Buffer,Sizeof(Buffer)-1,Leidos);
      read(fichero,b);
      if Leidos > 0 then
      begin
        Str:= String(PChar(@Buffer));
         i:=i+1;
         Label1.Caption:=inttostr(i);
        CargarGrilla(Str);
      end;
    end;
    Timer1.Enabled:=false;
    CloseFile(Fichero);
  end else
    ShowMessage('No puedo abrir el archivo');
end;

este es el codigo, el tema que tego que actualizar mi base con este txt, como me recomiendan que la cargue o donde, my base es sqlserver.
Gracias!!
Responder Con Cita
  #15  
Antiguo 07-07-2011
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Hola...

¿Es necesario que cargues la información en un grid?


Saludos...
__________________
Lee la Guía de Estilo antes que cualquier cosa. - Twitter
Responder Con Cita
  #16  
Antiguo 07-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Cita:
Empezado por maeyanes Ver Mensaje
Hola...

¿Es necesario que cargues la información en un grid?


Saludos...
No no solamente la ponia para ver como armaba el contenido ... y supongo que eso es lo que me tilda todo el sistema.
Responder Con Cita
  #17  
Antiguo 07-07-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola pelikno.

En el código que adjuntas (#14), para recorrer 100000 registros realiza 100000 ciclos de lectura, que es muchisimo mejor que el primer código que leia caracter a caracter(#8), ya que en ese caso eran 100000 x 22 lecturas. Pero creo que se puede optimizar mucho más el código de lectura en bloque.

No tengo acceso a los datos y puede que tengas que cambiar la cantidad de caracteres por registro o algún detalle que se me escape por no tener el archivo origen o el formato requerido.
Código Delphi [-]
...
const
  NCHAR = 22;
  LEER_X = 20000 ;
  TOT_BUFFER = LEER_X * NCHAR;

procedure TForm1.btnACDSClick(Sender: TObject);
var
  F: file of Char;
  Buf: array[1..TOT_BUFFER] of Char;
  c, rl: Integer;
  T1,T2: TTime;
  Ciclos: Integer;
begin
  AssignFile(F, 'C:\Archivo.txt');
  try
    Reset(file(F), 1);
    ClientDataSet.CreateDataSet;
    ClientDataSet.Open;
    ClientDataSet.DisableControls;
    T1:= Time;
    Ciclos:= 1;
    repeat
      BlockRead(file(F), Buf, SizeOf(Buf), rl);
      c:= 0;
      while c < TOT_BUFFER do
      begin
        if c mod 100 = 0 Then 
          ClientDataSet.MergeChangeLog;
        ClientDataSet.Append;
        ClientDataSetCuit.AsString:= Buf[c+1]+Buf[c+2]+Buf[c+3]+
            Buf[c+4]+Buf[c+5]+Buf[c+6]+Buf[c+7]+Buf[c+8]+Buf[c+9]+
            Buf[c+10]+Buf[c+11];
        ClientDataSetD1.AsString:= Buf[c+12]+Buf[c+13];
        ClientDataSetD2.AsString:= Buf[c+14]+Buf[c+15];
        ClientDataSetD3.AsString:= Buf[c+16]+Buf[c+17];
        ClientDataSetD4.AsString:= Buf[c+18];
        ClientDataSetD5.AsString:= Buf[c+19];
        Inc(c, NCHAR);
        ClientDataSet.Post;
      end;
      Inc(Ciclos);
    until rl = 0;
    CloseFile(F);
    T2:= Time;
    Caption:= FormatDateTime('hh:mm:ss:dd',T2-T1)+'  realizando '+IntToStr(Ciclos)+' ciclos.';
    ClientDataSet.EnableControls;
  except
    ShowMessage('Archivo inexistente');
  end;
end;
En este caso, con 100000 registros sólo realiza 7 ciclos en 00:00:05:30 (en mi equipo).

Como no tengo ni conozco el RxMemoryData, usé un TClientDataSet para la prueba. Lo único que tenés que hacer es crear los campos persistentes en él respetando los nombres y el código debería funcionarte.
Cualquier dificultad te adjunto el ejemplo con el generador de datos.

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 07-07-2011 a las 22:46:54.
Responder Con Cita
  #18  
Antiguo 08-07-2011
pelikno pelikno is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 95
Poder: 14
pelikno Va por buen camino
Cita:
Empezado por ecfisa Ver Mensaje
Hola pelikno.

En el código que adjuntas (#14), para recorrer 100000 registros realiza 100000 ciclos de lectura, que es muchisimo mejor que el primer código que leia caracter a caracter(#8), ya que en ese caso eran 100000 x 22 lecturas. Pero creo que se puede optimizar mucho más el código de lectura en bloque.

No tengo acceso a los datos y puede que tengas que cambiar la cantidad de caracteres por registro o algún detalle que se me escape por no tener el archivo origen o el formato requerido.
Código Delphi [-]... const NCHAR = 22; LEER_X = 20000 ; TOT_BUFFER = LEER_X * NCHAR; procedure TForm1.btnACDSClick(Sender: TObject); var F: file of Char; Buf: array[1..TOT_BUFFER] of Char; c, rl: Integer; T1,T2: TTime; Ciclos: Integer; begin AssignFile(F, 'C:\Archivo.txt'); try Reset(file(F), 1); ClientDataSet.CreateDataSet; ClientDataSet.Open; ClientDataSet.DisableControls; T1:= Time; Ciclos:= 1; repeat BlockRead(file(F), Buf, SizeOf(Buf), rl); c:= 0; while c < TOT_BUFFER do begin if c mod 100 = 0 Then ClientDataSet.MergeChangeLog; ClientDataSet.Append; ClientDataSetCuit.AsString:= Buf[c+1]+Buf[c+2]+Buf[c+3]+ Buf[c+4]+Buf[c+5]+Buf[c+6]+Buf[c+7]+Buf[c+8]+Buf[c+9]+ Buf[c+10]+Buf[c+11]; ClientDataSetD1.AsString:= Buf[c+12]+Buf[c+13]; ClientDataSetD2.AsString:= Buf[c+14]+Buf[c+15]; ClientDataSetD3.AsString:= Buf[c+16]+Buf[c+17]; ClientDataSetD4.AsString:= Buf[c+18]; ClientDataSetD5.AsString:= Buf[c+19]; Inc(c, NCHAR); ClientDataSet.Post; end; Inc(Ciclos); until rl = 0; CloseFile(F); T2:= Time; Caption:= FormatDateTime('hh:mm:ss:dd',T2-T1)+' realizando '+IntToStr(Ciclos)+' ciclos.'; ClientDataSet.EnableControls; except ShowMessage('Archivo inexistente'); end; end;

En este caso, con 100000 registros sólo realiza 7 ciclos en 00:00:05:30 (en mi equipo).

Como no tengo ni conozco el RxMemoryData, usé un TClientDataSet para la prueba. Lo único que tenés que hacer es crear los campos persistentes en él respetando los nombres y el código debería funcionarte.
Cualquier dificultad te adjunto el ejemplo con el generador de datos.

Saludos.
Muchas Graciasecfisa por tomarte el tiempo de hacer el codigo mañana lo pruebo y veo que pasa.
SALUDOS!!!
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
ayuda copiar datos de una tabla a otra Rofocale Varios 1 18-05-2011 03:39:40
Ayuda insertar cadena en otra ? Coco_jac Varios 4 14-12-2005 21:37:46
necesito ayuda para pasar registros a otra tabla ddd_ddd Conexión con bases de datos 2 09-09-2005 20:33:41
ayuda para enlazar con otra tabla Debian Conexión con bases de datos 1 24-03-2005 16:48:28
Como puedo tabajar de otra forma un DBGrid, Ayuda urgente danytorres Varios 7 18-07-2003 21:24:02


La franja horaria es GMT +2. Ahora son las 07:22:04.


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
Copyright 1996-2007 Club Delphi