Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Guardar ListView como Texto Plano (https://www.clubdelphi.com/foros/showthread.php?t=87111)

danielmj 15-11-2014 11:01:38

Guardar ListView como Texto Plano
 
Hola,

Sigo con la lista de otro post anterior a este, solo que esta vez el problema es otro. Intento guardar el contenido de la lista en un archivo de texto plano, buscando información por internet, encontre este código, que imagino ya habreis visto antes:

Código Delphi [-]
procedure guardarListViewFichero (AListView: TListView; sFileName: string);
var
  idxItem, idxSub, IdxImage: Integer;
  F: TFileStream;
  pText: PChar;
  sText: string;
  W, ItemCount, SubCount: Word;
  MySignature: array [0..2] of Char;

begin
  // Inicio
  with rForm.Lista do
  if rForm.saveDialog1.Execute then
  begin
    ItemCount := 0;
    SubCount  := 0;
    //****
    MySignature := 'txt';
    //  ListViewFile
    F := TFileStream.Create(rForm.saveDialog1.FileName, fmCreate or fmOpenWrite);
    F.Write(MySignature, SizeOf(MySignature));

    if Items.Count = 0 then
      // List is empty
      ItemCount := 0
    else
      ItemCount := Items.Count;
      F.Write(ItemCount, SizeOf(ItemCount));

    if Items.Count > 0 then
    begin
      for idxItem := 1 to ItemCount do
      begin
        with Items[idxItem - 1] do
        begin
          // Guardamos los SubItems
          if SubItems.Count = 0 then
            SubCount := 0
          else
          begin
          SubCount := Subitems.Count;
          F.Write(SubCount, SizeOf(SubCount));
          // Guardamos el Index
          IdxImage := ImageIndex;
          F.Write(IdxImage, SizeOf(IdxImage));
          // Guardamos la Caption
          sText := Caption;
          w     := Length(sText);
          pText := StrAlloc(Length(sText) + 1);
          StrPLCopy(pText, sText, Length(sText));
          F.Write(w, SizeOf(w));
          F.Write(pText^, w);
          StrDispose(pText);
          end;
          if SubCount > 0 then
          begin
            for idxSub := 0 to SubItems.Count - 1 do
            begin
              // Guardamos los Items y SubItems
              sText := SubItems[idxSub];
              w     := Length(sText);
              pText := StrAlloc(Length(sText) + 1);
              StrPLCopy(pText, sText, Length(sText));
              F.Write(w, SizeOf(w));
              F.Write(pText^, w);
              StrDispose(pText);
            end;
          end;
        end;
      end;
    end;
    F.Free;
  end;

end;

En la opcion "crear informe" del popup menú tengo esto:
Código Delphi [-]
procedure TrForm.Crearinforme1Click(Sender: TObject);
begin
    guardarListViewFichero(Lista, SaveDialog1.FileName);
end;

Aparentemente todo va bien, quiero decir que no da error en tiempo de compilación, pero cuando intento crear el informe, me tira un error de "stack overflow" como si hubiera desbordamiento de pila, y la verdad, no sé donde está el error (me refiero en el código)

¿alguna idea? Gracias y un saludo.

nlsgarcia 15-11-2014 15:54:31

danielmj,

Cita:

Empezado por danielmj
...Guardar ListView como Texto Plano...

:rolleyes:

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ImgList;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// Crea un ListView
procedure TForm1.FormCreate(Sender: TObject);
var
   i : Integer;

begin

   // Crea 4 columnas en el ListView
   ListView1.ViewStyle := vsReport;
   for i := 0 to 3 do
   begin
      ListView1.Columns.Add;
      ListView1.Columns[i].Caption := 'Col-' + IntToStr(i);
      ListView1.Columns[i].Width := 150;
   end;

   // Adiciona las Filas al ListView
   for i := 0 to 9 do
      with ListView1.Items.Add do
      begin
         Caption := 'Caption Row-' + IntToStr(i);
         Subitems.Add('SubItem-0');
         Subitems.Add('SubItem-1');
         Subitems.Add('SubItem-2');
      end;

end;

// Salva el ListView en un Archivo TXT
procedure TForm1.Button1Click(Sender: TObject);
var
   i, j : Integer;
   F : TFileStream;
   Buffer : String;

begin

   SetCurrentDir(ExtractFilePath(Application.ExeName));

   F := TFileStream.Create('FileListView.txt', fmCreate);

   for i := 0 to ListView1.Items.Count - 1 do
   begin

      Buffer := Buffer + ListView1.Items.Item[i].Caption + ',';

      for j := 0 to ListView1.Items.Item[i].SubItems.Count - 1 do
         Buffer := Buffer + ListView1.Items.Item[i].SubItems.Strings[j] + ',';

      Delete(Buffer, Length(Buffer), 1);
      Buffer := Buffer + #13 + #10;
      F.Write(Buffer[1], Length(Buffer));
      Buffer := EmptyStr;

   end;

   F.Free;

end;

end.
El código anterior en Delphi 7 sobre Windows 7 Professional x32, crea un TListView y salva su contenido en un Archivo TXT, como se muestra en la siguiente imagen:



Espero sea útil :)

Nelson.

danielmj 15-11-2014 22:03:07

Hola nelson,

gracias por tu ayuda pero me surgen dos problemas, a saber:

1º Tu código me guarda el contenido de la lista así:


Es decir, no guarda todo el contenido, todas las columnas.

El código que me pusiste yo lo tengo de esta manera:
Código Delphi [-]
procedure TrForm.Button4Click(Sender: TObject);
var
  i,j: integer;
  fTxt: TextFile;
  F : TFileStream;
  Buffer : String;

begin
...
   SetCurrentDir(ExtractFilePath(Application.ExeName));

   F := TFileStream.Create('factura.txt', fmCreate);

   for i := 0 to Lista.Items.Count - 1 do
   begin

      Buffer := Buffer + Lista.Items.Item[i].Caption + ', ';

      for j := 0 to Lista.Items.Item[i].SubItems.Count - 1 do
         Buffer := Buffer + Lista.Items.Item[i].SubItems.Strings[j] + ', ';
         Delete(Buffer, Length(Buffer), 1);
         Buffer := Buffer + #13 + #10;
         F.Write(Buffer[1], Length(Buffer));
         Buffer := EmptyStr;
   end;

   F.Free;


end;
end;

2º Aunque consiga que me guarde todo el contenido de la lista, como realmente quiero que lo guarde sería de este modo:


No sé si es posible guardar así el contenido de una lista. Si no fuera posible ¿que otra alternativa me sugeris?

Por otra parte tengo también este código aunque lo tenía entre {}
Código Delphi [-]
procedure TrForm.Crearinforme1Click(Sender: TObject);
var
  i : Integer;

begin
  with TStringList.Create do
  try
    for i := 0 to Lista.Items.Count-1 do
      Add(Lista.Items[i].Caption +','+
          Lista.Items[i].SubItems.CommaText);
          SaveToFile((ExtractFilePath(Application.ExeName) + 'factura.txt'));
  finally
    Free
  end
end;

Me devuelve todo el contenido de la lista pero sigue sin incluirse de forma ordenada el caption de cada columna, me refiero al nombre de cada columna.

Un saludo y gracias.

ecfisa 16-11-2014 06:34:29

Hola danielmj.
Cita:

Empezado por danielmj (Mensaje 484874)
...como realmente quiero que lo guarde sería de este modo:

Para que se guarde con ese formato:
Código Delphi [-]
procedure SaveListView(LV: TListView; const aFileName: TFileName; const Title: string);
var
  r, c: Integer;
begin
  with TStringList.Create do
  try
    Add('['+Title+']');
    for r:= 0 to LV.Items.Count-1 do
    begin
      for c:= 1 to LV.Columns.Count-1 do
        Add(Format('%s: %s',[LV.Columns[c].Caption, LV.Items[r].SubItems[c-1]]));
      Add('');
    end;
    SaveToFile(aFileName);
  finally
    Free;
  end;
end;

Ejemplo de uso:
Código Delphi [-]
procedure TForm1.btnSaveClick(Sender: TObject);
begin
  SaveListView(ListView1, 'ListView.txt', 'DATOS CLIENTES');
end;

Datos de ejemplo:


Archivo resultante:


Saludos :)

nlsgarcia 16-11-2014 07:44:57

danielmj,

Cita:

Empezado por danielmj
...Tu código...no guarda todo el contenido, todas las columnas...Aunque consiga que me guarde todo el contenido de la lista, como realmente quiero que lo guarde sería de este modo...

:rolleyes:

Te comento:

1- El código del Msg #2 funciona según lo esperado, como se puede ver en la imagen anexa y su propósito es de servir de guía a tu requerimiento, las adaptaciones necesarias debes hacerlas en función de tu aplicación y su datos.

2- Efectivamente, puedes formatear la salida del archivo como mejor se adapte a tu requerimiento.

3- El código del Msg #4 se adapta al formato de salida que comentas en el Msg #3, solo debes hacer unos pequeños ajustes relacionados a la columna Caption (Dado que no la usas) y al Monto Total requerido.

Pregunto : ¿Este proyecto es de índole académica, comercial o personal? :confused:

Espero sea útil :)

Nelson.

danielmj 16-11-2014 11:05:53

Hola nelson buenos dias,

Ahora me pondre a mirar tu respuesta, gracias.

En cuanto a tu pregunta, en principio es personal con vistas a ser comercial para mi, quiero decir que aprovechando esta nueva moda de llevar pulseras de supervivencia, pensé en hacer una aplicacion que me permita su venta. La idea es subirla a la web que haga para tal fin, que la gente la descargue y pueda diseñar su propia pulsera en casa, eligiendo los elementos que la formaran (hebilla, tamaño, si llevara pedernal... etc). Sé que esta forma tiene mas contras que pros, también sé que todo esto podria hacerlo en la misma web, pero el hecho de hacerlo en delphi y de este modo, tiene su parte de reto ademas que no tengo ni idea de php ni nada de eso, y solo con html y CSS no conseguiria nada decente, así que de las dos opciones esta me pareció la mas factible. Ahora solo falta que el asunto tenga exito :rolleyes:

Por otra parte, llevaba bastante tiempo (meses) sin hacer nada de codigo, llevo un tiempo dandole caña a blender (programa 3d), y lo cierto es que de vez en cuando necesito un "chute" de delphi, empiezo a darle vueltas a la cabeza hasta que pasado unos dias me pongo frente a esta "maquina infernal" llamada pc y empiezo a diseñar formularios, escribir sintaxis etc... es una necesidad que tengo de tanto en tanto. En resumen, es un proyecto personal/comercial (espero).

Saludos.


La franja horaria es GMT +2. Ahora son las 02:45:54.

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