Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   error al guardar el listview en un archivo (https://www.clubdelphi.com/foros/showthread.php?t=90999)

danielmj 22-10-2016 14:51:28

error al guardar el listview en un archivo
 
Hola,
Siguiendo con la aplicacion de los numeros aleatorios, permutaciones etc.. me ha surgido un problema, resulta que para hacer 1.000.000 de combinaciones, ni si quiera para comparar estas con las permutaciones, ha tardado unas 8h con lo cual, cuando le exprima a tope, resultará que para entonces apofis habrá colisionado contra la tierra! solución, guardar el contenido del listview en un archivo y continuar en otro momento previa carga de estos datos. Informandome y buscando pr la web, encontre este codigo.. http://www.ajpdsoft.com/modules.php?...iewtopic&t=902

¿Cual es el problema? que en vez de guardar los datos reales del listview, guarda otra cosa, por que al cargar los datos aparecen numeros aleatorios del 0 al 9 ¿de donde saca esos numeros si el contenido era aleatorios del 1 al 49? ¿por que no guarda el contenido real?

Adjunto capturas

[datos cargados del archivo]
http://pasteall.org/pic/index.php?id=107982

[datos reales]
http://pasteall.org/pic/index.php?id=107983

Por otra parte, el archivo .dat (extensión que estoy usando para guardar la lista) contiene esto...
Cita:

d a t 2 3 3 2 1 6 1 3 3 4 4 1 2 3 1 4 4 3 2 1 4 2 3 6 2 2 2 2 1 3 1 4 2 4 4 6 8 2 3 1 2 3 2 4 1 2 2 2 3 6 1 4 1 3 4 4 9 3 1 3 1 2 4 2 4 1 2 4 1 3 2 4 8 3 1 3 1 4 3 4 9 2 1 2 3 2 3 2 3 3 4 2 4 1 2 1 4 1 1 1 4 2 4 2 1 2 2 2 2 4 1 2 2 3 2 3 3 2 2 1 1 5 3 3 1 2 4 8 1 7 4 3 4 1 2 2 4 1 3 3 2 1 4 6 4 9 4 3 1 1 3 1 3 1 4 4 2 2 4 2 1 1 5 2 3 1 3 5 4 6 1 2 2 1 1 1 1 3 4 1 2 4 3 2 3 3 2 2 2 1 4 1 3 2 2 2 6 3 4 1 3 3 1 4 1 2 2 5 8 3 4 1 4 1 1 1 2 2 3 7 1 1 1 1 4 2 3 4 1 1 4 2 2 2 1 2 1 8 3 1 3 4 3 1 2 3 6 3 3 2 4 7 2 2 2 1 4 1 6 3 4 3 8 1 4 3 3 1 3 3 2 4 2 7 2 3 3 1 1 2 1 3 4 3 3 1 2 4 4 3 2 2 1 1 3 1 3 1 1 2 1
Ni por asomo a los numeros del 1 al 49. Sinceramente ni idea de por que pasa eso ni de donde saca esos numeros del 1 al 9.
Alguna idea? Saludos

ecfisa 22-10-2016 17:21:17

Hola danielmj.

¿ Y no te sirve aquél código de este hilo ? : Problema al guardar lista en fichero

Saludos :)

danielmj 22-10-2016 17:52:36

hola ecfisa, mira que busque en el foro.. ese hilo fue de cuando hice la aplicacion que guarda todas mis contraseñas XD lamentablemente el codigo lo perdi y solo tengo el exe. Voy a mirar, si sirvio una vez, debe servir otra.
Gracias por la informacion. Saludos.

danielmj 22-10-2016 18:38:34

Hola ecfisa,

El código que me indicas y que fue por una aplicacion de ya hace tiempo, en su dia me daba error al cargar el archivo, siempre decía lo mismo "... no es un archivo correcto" esto me lo decía usando xe7 en delphi7 iba como la seda. Pues bién, ahora vuelvo a estar con xe7 y sigue diciendo lo mismo a la hora de cargar el archivo " bla bla bla no es un archivo correcto" lal solución que he encontrado a este error es anular la linea que dice:

Código Delphi [-]
{if signat <> form1.opendialog1.FileName+'.dat' then
  begin
    Stream.Free;
    raise Exception.Create(Format('%s no es el archivo correcto',[FileName]));
  end;}
Dentro del procedimiendo de cargar y asignar la extension al opendialog en tiempo de diseño. Pero sigo teniendo el mismo error que antes (el del post anterior), es decir, no guarda el contenido del listview tal como se muestra en pantalla, sino una cantidad igual de lineas con numeros aleatorios pero del 1 al 9. Pondría una captura pero al ser lo mismo de antes vuelvo a poner los enlaces anteriores.

[datos cargados del archivo]
http://pasteall.org/pic/index.php?id=107982

[datos reales]
http://pasteall.org/pic/index.php?id=107983

Realmente no sé por que hace esto. La unica opcion que se me ocurre es volcarlo todo a delphi 7... pero no me seduce mucho esa idea.
Saludos.

Edito: He probado a cambiar la extension de .dat a .txt, pero no sirve.

ecfisa 22-10-2016 18:55:39

1 Archivos Adjunto(s)
Hola.

Por si te pudiera servir para hacer alguna prueba, te adjunto el código del ejemplo completo.

Saludos :)

danielmj 22-10-2016 19:16:23

Gracias, sigo mirando por internet y encontre este codigo... lo pongo por un detalle que marco en rojo.
Código Delphi [-]
procedure ListViewSaveToFile(ListView: TListView; const FileName: string);

  procedure AddTextToLine(var Line: string; const Text: string);
  begin
    Line := Line + Text + #9;
  end;

  procedure MoveCompletedLineToList(const Strings: TStringList; var Line: string);
  begin
    Strings.Add(System.Copy(Line, 1, Length(Line)-1));//remove trailing tab
    Line := '';
  end;

var
  Strings: TStringList;
  LatestLine: string;
  i, j: Integer;

begin
  LatestLine := '';

  Strings := TStringList.Create;
  try
    for i := 0 to ListView.Items.Count-1 do begin
      AddTextToLine(LatestLine, ListView.Items[i].Caption);
      for j := 0 to ListView.Items[i].SubItems.Count-1 do begin
        AddTextToLine(LatestLine, ListView.Items[i].SubItems[j]);
      end;
      MoveCompletedLineToList(Strings, LatestLine);
    end;
    Strings.SaveToFile(FileName, TEncoding.UTF8);
  finally
    Strings.Free;
  end;
end;
¿Puede ser que el contenido del lisview no se guarde correctamente por la codificacion?
Voy a probar tu archivo en un progrmaa a parte en xe7 a ver que hace.
Saludos.

danielmj 22-10-2016 19:35:28

Hola,

He probado tu codigo ecfisa, en xe7 en compilacion no da error pero cuando ejecuto el exe generado...https://youtu.be/WI0CkLp5zEs
Me estoy volviendo loco ya. Decir que (por si sirve de algo) uso windows 10 en una pc nueva, es decir da el mismo error que aquella vez hace tiempo cuando use el listview para guardar contraseñas (en otra app). No sé que puede ser, ¿algo interno de xe7?
Y para salir de dudas he abierto tu programa en delphi 7 y va perfecto, carga perfectamente toda la informacion en el listview, asi que está claro, es cosa de xe7. Voy a ver si actualizandolo se arregla.
Saludos.

ecfisa 22-10-2016 20:25:36

Hola.

Me quedé pensando... Aparentemente el problema se produce en la verificación de la firma, pero si en este caso no la necesitas podrías omitirla:
Código Delphi [-]
procedure TListView.SaveToFile(const FileName: TFileName);
var
  i, j, aux           : Integer;
  Stream              : TStream;
  str {, signat }     : string;
  ItemCount, SubCount : Word;
begin
begin
  // Crear archivo
  Stream := TFileStream.Create(FileName, fmCreate);

  { guardar firma
  signat := Name;
  aux    := Length(signat);
  Stream.Write(aux, SizeOf(aux));
  Stream.Write(PChar(signat)^, aux); }
...
end;

procedure TListView.LoadFromFile(const FileName: TFileName);
var
  Stream: TStream;
  i, j, aux: Integer;
  ItemCount, SubCount: Word;
  str{, signat}: string;
  it: TListItem;
begin
  // verificar existencia
  if not FileExists(FileName) then
    raise Exception.Create(Format('No se encuentra el archivo %s',[FileName]));
  // Abrir archivo
  Stream := TFileStream.Create(FileName, fmOpenRead);

  { leer firma
  Stream.Read(aux, SizeOf(aux));
  SetLength(signat, aux);
  Stream.Read(PChar(signat)^, aux);
   verificar firma
  if signat <> Name then
  begin
    Stream.Free;
    raise Exception.Create(Format('%s no es el archivo correcto',[FileName]));
  end;}
...
end;
Fijate, es sólo una prueba mas...

Saludos :)

danielmj 22-10-2016 22:06:23

Hola, gracias mañana cuando llegue a casa lo miro y te digo. Pero en realidad son dos problemas, lo de guardar y cargar ya lo tengo, lo conseguí antes de irme a trabajar, bueno más o menos, lo tengo encaminado, pero lo que ocurre es que cuando se guarda el contenido del listview, se hace mal, guarda números aleatorios del 1 al 9 cuando tendría que ser del 1 al 49 y además también mete símbolos chinos. Y eso si que no tengo idea de por qué pasa. Ya me estoy planteando rehacerlo todo con d7 que si funciona.
Otra cosa, antes de salir de casa baje e instale el xe8 bajado de la web de embarcadero, por 30 días, y hace lo mismo, en lugar de guardar el listado guarda lo que le da la gana y con símbolos chinos.
En fin, mañana será otro día.
Un saludo y gracias por tu ayuda y paciencia.

danielmj 23-10-2016 13:25:55

Buenos dias, al final he desistido de hacerlo en xe7 y lo he pasado todo a delphi 7, pero cuando pulso F9 me tira el error "duplicate resourde" supongo que será algun archivo o no, no lo sé. ¿alguna idea?

http://pasteall.org/pic/index.php?id=108058
saludos.

danielmj 23-10-2016 14:29:28

Hola, el contenido de la carpeta donde guardo todo el proyecto es este:
http://pasteall.org/pic/index.php?id=108059
Lo digo por si vosotros veis algún archivo que esté duplicado. Por otra parte, mirando en la web di con este post de otro foro.. http://delphiaccess.com/foros/index....hi/#entry84813 donde se dice que lo han solucionado pero yo no sé que archivo tengo duplicado, con esto de pasar de xe7 a delphi7...
Gracias.

danielmj 23-10-2016 16:08:11

Hola, ya lo he solucionado ufff... el problema es que en una de las unidades usadas, en ListViewExt hacía referencia a otra de las muchas pruebas que ya llevo del dichoso programa.
Un saludo.

danielmj 24-10-2016 10:52:53

Buenos dias,

La aplicacion ya funciona con sus mas y sus menos, pero si una vez cargado el archivo con el contenido de la lista intengo continuar con el proceso me dice:
"Access violation at address 00000000. Read of address 00000000" Pero si agrego un boton de prueba y dentro escribro:

Código Delphi [-]
...
lista.items.add.subitems.add('prueba');
...

Se agrega un nuevo item al final de la lista y no da error. ¿alguna sugerencia?
El codigo que genera numeros es este:

Código Delphi [-]
unit uTAlea;
 {Radikal, Q3 para Trucomania.}

 interface

 uses Windows,SysUtils, Math;

 type
   {Array de booleanos de longitud variable}
   TArrayBool = array[0..0] of boolean;
   PArrayBool = ^TArrayBool;

   {Clase para manejar numeros aleatorios}
   TAlea = class
     Maximo             : integer;            //Valor maximo de los numeros obtenidos
     Lista              : PArrayBool;
     FaltanDeSacar      : integer;
     constructor        Create(Rango:integer);
     destructor         Destroy; override;
     procedure          Reset;                //Resetea la lista de numeros
     function           PillaNumero:integer;  //Devuelve un numero aletorio sin repeticion
   end;



 implementation


 constructor TAlea.Create(Rango:integer);
 begin
 {
   Si los números a extraer no pueden ser repetidos
   hemos de crear un array para almacenar cual ha salido y cual no
   Como el array ha de ser variable, usamos el GetMem y
   los punteros para que sirva tambien para versiones
   anteriores a Delphi 4, que no incorporan los arrays
   de longitud variable...
 }
   inherited Create;
   Maximo:=Rango;
   FaltanDeSacar:=Rango;
   {Reservamos memoria para el array de longitud variable}
   GetMem(Lista, 1+Maximo * SizeOf(Boolean));
   ZeroMemory(Lista,1+Maximo * SizeOf(Boolean));
 end;

 destructor TAlea.Destroy;
 begin
   if Assigned(Lista) then FreeMem(Lista, 1+Maximo * SizeOf(Boolean));
   inherited Destroy;
 end;

 function TAlea.PillaNumero:integer;
 var
   Numero: integer;
 begin
   if FaltanDeSacar=0 then raise exception.create( 'Error. No se pude sacar otro numero sin repetir'+#13+#10+
                                                   'Error. No more numbers are available');

   {Buscamos un número que no haya salido ya}
   repeat
    Numero:=RandomRange(1,49)
   until NOT Lista^[Numero];
   {Lo apuntamos en la lista de numeros ya usados}
   Lista^[Numero]:=TRUE;
   {Decrementamos la cantidad de numeros que faltan por salir}
   Dec(FaltanDeSacar);
   Result:=Numero;
 end;

 procedure TAlea.Reset;
 begin
   ZeroMemory(Lista,1+Maximo * SizeOf(Boolean));
   FaltanDeSacar:=Maximo;
 end;

 end.

Y la llamada a la funcion esta:

Código Delphi [-]
...
case comb.ItemIndex of
    0: begin
         timer1.Enabled:= true;
         barra.MinValue:= 0;
         barra.Maxvalue:= 50000;  //50.000
         {Sacamos 6 numero sin repetir}
         for i:= 0 to 49999 do
          begin
            label4.Caption:= IntToStr((i)+1);
            Ristra:=TAlea.Create(49);
            with lista.Items.Add do
            begin
              subitems.Add(IntToStr(ristra.PillaNumero));
              subitems.Add(IntToStr(ristra.PillaNumero));
              subitems.Add(IntToStr(ristra.PillaNumero));
              subitems.Add(IntToStr(ristra.PillaNumero));
              subitems.Add(IntToStr(ristra.PillaNumero));
              subitems.Add(IntToStr(ristra.PillaNumero));
              Ristra.Free;
            end;
              barra.Progress:= i;
              label20.Caption:= FormatFloat('0.00',((i*100)/50000))+'%';
          end;
      end;
...

¿Por que no pueden agregarse items al final del listado previamente cargado desde fichero?
Gracias y un saludo.


La franja horaria es GMT +2. Ahora son las 03:22:37.

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