Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Volcar dos listview en uno (https://www.clubdelphi.com/foros/showthread.php?t=87118)

danielmj 16-11-2014 20:24:24

Volcar dos listview en uno
 
Hola, ya he abierto varios hilos sobre el control listview, y no sé si hago bien, pero es que son temas diferentes aunque sea sobre el mismo control. Y ahora vengo con otra duda, en fin si estoy haciendo mal decidmelo.

En cuanto a la duda, el proyecto usa dos listview, pero he pensado que para guardarlo como csv, es mejor tener todas los datos (de las dos listas) en una sola, y esa sería la que guardaría.

Y la duda es esta:
Código Delphi [-]
...
for i:= 0 to 19 do //----> 19 es la suma de columnas de los dos listview
    for j:= 0 to rForm.lista.Items.Count -1 do //------> recorro el listview1
      for l:= 0 to rForm.plista.Items.Count -1 do //---> recorro el listview2
      begin
        addLista.Columns.Add; //--------> addLista es un tercer control listview que creo en tiempo de ejecucion sin estar "fisicamente" sobre el formulario.
        addLista.Columns[i].Caption:= rForm.lista.Items.Item[j].Caption +
                                      rForm.plista.Items.Item[l].Caption ; //-------> en un listView "3" (addlista), meto las columnas de las otras dos listas (es correcta esta sintaxis?)
      end;
  for i:= 0 to rForm.lista.Items.Count -1 do //-------> vuelvo a recorrer el listView1
      for j:= 0 to rForm.lista.Items.Count -1 do //-----> vuelvo a recorrer el listview1 guardando en otra variable
    with addLista.items.Add do
      begin
        subItems.Add(rForm.lista.Items.Item[i].SubItems.Strings[j]) //-----------> intento guardar en addlista (listView3) el contenido del listview1
      end;
...

1º Es posible hacer lo que pretendo? esto es volcar dos listview en uno guardando sus columnas y todos sus items.
2º Aunque al compilar no me da error, no puedo acceder a los elementos en tiempo de ejecucion ¿donde está el error? ¿en que parte en concreto del código se produce el error?

Espero podais seguir ayudandome. Gracias y un saludo.

ecfisa 17-11-2014 07:10:56

Hola danielmj.

¿ Cuál es el formato con que deseas concatenar los ListView orígen ? ¿ Podes poner un esquema de ejemplo ?

Saludos :)

danielmj 17-11-2014 10:18:57

Buenos dias, no entiendo muy bien tu pregunta ecfisa cuando te refieres al formato. En todo caso, si te refieres al aspecto de la lista, lo más parecido (para que te hagas una idea) sería la tabla de una base de datos, donde cada columna del listview serían los campos de dicha tabla, por ejemplo:

Código:

{campos del listview1}
- Ref
- Nombre
- Apellidos
- Dirección
- Localidad
- Provincia
- C.P
- Tlf

{campos del listview2}
- Hebilla
- Tipo
- Color
- Aparejo
- Brújula
- Anilla
- Mosquetón
- Precio unidad
- Cantidad
- Precio total

{Finalmente se unirían los dos listview (1 y 2) en un tercero listview3, tal que así...}
- Ref
- Nombre
- Apellidos
- Dirección
- Localidad
- Provincia
- C.P
- Tlf
- Hebilla
- Tipo
- Color
- Aparejo
- Brújula
- Anilla
- Mosquetón
- Precio unidad
- Cantidad
- Precio total

sería este listview3, el que se guardaría (con todos sus datos, items y subitems) en un archivo csv.

Espero haberme explicado mejor. Sino, pues dimelo e intentaré explirme de nuevo (estoy preparando un examen en casa y no puedo detenerme mucho en esto ahora mismo, por eso si no me supe explicar dimelo).
Gracias y saludos.

ecfisa 17-11-2014 20:27:28

Hola danielmj.

Código Delphi [-]
procedure JoinListViews(LV1, LV2, LV3: TListView);
var
  c,r: Integer;
  li: TListItem;
begin
  for r:= 0 to 1 do
  begin
    LV3.Columns.Add;
    LV3.Column[r].Width:= 60;
  end;
  LV3.Column[0].Caption:= 'CONCEPTO';
  LV3.Column[1].Caption:= 'VALOR';

  for r:= 0 to LV1.Items.Count-1 do
  begin
    for c:= 0 to LV1.Columns.Count-2 do
    begin
      li:= LV3.Items.Add;
      li.Caption:= LV1.Column[c+1].Caption;
      li.SubItems.Add(LV1.Items[r].SubItems[c]);
    end;
  end;

  for r:= 0 to LV2.Items.Count-1 do
  begin
    for c:= 0 to LV2.Columns.Count-2 do
    begin
      li:= LV3.Items.Add;
      li.Caption:= LV2.Column[c+1].Caption;
      li.SubItems.Add(LV2.Items[r].SubItems[c]);
    end;
  end;
end;

Uso:
Código Delphi [-]
procedure TForm1.btnJoinClick(Sender: TObject);
begin
  JoinListViews(ListView1, ListView2, ListView3);
end;
En el ejemplo, los dos ListViews se concatenan uno debajo del otro en un tercero, de acuerdo al formato que mostraste en el mensaje anterior:


Saludos :)

danielmj 17-11-2014 20:55:15

Hola ecfisa, gracias por tu ayuda. Por mi parte llevo ya un buen rato (algunas horas) dandole vueltas a esto y no hay forma, voy a poner el código que tenía yo o mejor dicho, con el que pretendía hacer lo que tu has hecho.

Esta empeñado en hacerlo asi, por que conseguía volcar el contenido de una lista en otra y me decía a mi mismo "¿ostia, por que puedo volcar una lista y la otra no?"

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  i,j,k: integer;

begin
  for i:= 0 to lista1.Columns.Count -1 do
    begin
      lista3.Columns.Add;
      lista3.Columns.Add.Caption:= lista1.Columns.Items[i].Caption;
    end;

  for k:= 0 to lista2.Items.Count -1 do
    for j:= i to lista2.Columns.Count -1 do
      begin
        lista3.Columns.Add;
        lista3.Columns.Items[j].Caption:= lista2.Columns.Items[k].Caption;
      end;
end;

Y este su resultado...


Ese código es de un ejemplo nuevo que he iniciado solo para intentar lo de las listas, pero una vez conseguido usarlo con el proyecto de marras. Sé que mi codigo no llega a ningun sitio :rolleyes: pero insisto, si podía volcar una lista por que no podía volcar la otra? en fin... Ahora me pongo y miro lo tuyo, luego comento.

Gracias otra vez y saludos.

danielmj 17-11-2014 23:29:57

Hola de nuevo,

he estado mirando tu codigo ecfisa, y siendo honesto, no termino de pillar el hilo, la verdad me cuesta entender como funcionan los listview, tendré que dedicarle mas tiempo. De todos modos, creo que no me explique bien en cuanto al formato con el que quiero que salga, te lo puse en forma de listado cuando en realidad sería algo así:

Código:

[REF|NOMBRE|APELLIDOS|...PRECIO UNIDAD|CANTIDAD|SUBTOTAL|TOTAL
123 |LUIS  |MARTINEZ |...  2,34€  |  1  |  2,35€ | 2,35€

He intentado hacerlo yo, pero como te digo mas arriba me cuesta pillar el funcionamiento de este control listview. Mañana si tengo un hueco miraré algunos libros a ver si me aclaro algo.
Por otra parte, estoy pensando en usar una base de datos, por que todo sería mas sencillo y lo manejo mejor, aunque eso me deja cierto regusto a derrota por no haberlo podido hacer con listview. Así que en este punto no sé muy bien si abandonar la idea de las listas y usar las bases de datos o seguir insistiendo.

En fin, un saludo y gracias.

danielmj 18-11-2014 20:58:12

Vuelta a la carga,

Sigo insistiendo con los listview y siguen sin salirme, he modificado un poco tu codigo para usarlo en un ejemplo nuevo ecfisa, ¿podriais indicarme sobre los comentarios en el código donde cometo el error?

Código Delphi [-]
procedure JoinListViews(LV1, LV2, LV3: TListView);
var
  i,j: Integer;
  li: TListItem;
begin
  for j:= 0 to 6 do
  begin
    LV3.Columns.Add;
    LV3.Column[j].Width:= 60;
  end;
  LV3.Column[1].Caption:= 'REF';
  LV3.Column[2].Caption:= 'NOMBRE';
  LV3.Column[3].Caption:= 'APELLIDOS';
  LV3.Column[4].Caption:= 'LOCALIDAD';
  LV3.Column[5].Caption:= 'PROVINCIA';
  LV3.Column[6].Caption:= 'TLF';



  for j:= 0 to LV1.Items.Count-1 do  //cuenta los elementos de la lista NO las columnas ¿correcto?
  begin
    for i:= 0 to LV1.Columns.Count-2 do  //cuenta las columnas ¿correcto?
    begin
      li:= LV3.Items.Add;
      li.SubItems.Add(LV1.Items.Item[j].Caption);  //ESTA LINEA ES LA REFERENCIA EN LA LISTA1
      li.SubItems.Add(lv1.Items.Item[i].SubItems.Strings[j]); // CON ESTA LINEA INTENTO AGREGAR EL CONTENIDO DE-
      //LA FILA 1, COLUMNA 2 DE LISTVIEW1 en la misma posicion pero del listview3 ¿POR QUE NO ESTÁ BIEN? ¿DONDE COMETO EL ERROR?
    end;
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  JoinListViews(ListView1, ListView2, ListView3);
end;

Ya no es tanto por el proyecto en si, sino por comprender como funciona este maldito control.
Un saludo.

nlsgarcia 18-11-2014 22:19:12

danielmj,

Cita:

Empezado por danielmj
...la verdad me cuesta entender como funcionan los ListView...ya no es tanto por el proyecto en si, sino por comprender como funciona...

:rolleyes:

Revisa esta información:
Espero sea útil :)

Nelson.

ecfisa 19-11-2014 01:52:52

Hola Daniel.
Cita:

Empezado por danielmj (Mensaje 485032)
...
Ya no es tanto por el proyecto en si, sino por comprender como funciona este maldito control.
Un saludo.

Perdón por demorar en responder :o, pero estos días ando medio complicado...

Código Delphi [-]
 for j:= 0 to LV1.Items.Count-1 do  //cuenta los elementos de la lista NO las columnas ¿correcto?
  begin
    for i:= 0 to LV1.Columns.Count-2 do  //cuenta las columnas ¿correcto?
Es correcto.

Cita:

... Así que en este punto no sé muy bien si abandonar la idea de las listas y usar las bases de datos o seguir insistiendo.
Si preguntas mi opinión, usaría base de datos sin dudarlo.

Cita:

aunque eso me deja cierto regusto a derrota por no haberlo podido hacer con listview.
Intentaremos que eso no suceda :)

Los problemas que encuentras pueden deberse a si consideras el item como un elemento más o no. Para el ejemplo almaceno los elementos en los subitems descartando los ítems:
Código:

[-]-+
    |
    + Valor 1
    |
    + Valor 2
    |
    + ...
    |
    + Valor N

Según entendí, no buscabas encolumnarlos uno debajo del otro sino aparejarlos, entonces podrías hacer:
(Espero que el código comentado te clarifique las acciones)
Código Delphi [-]
procedure JoinListViews(LV1,LV2,LV3: TListView);
var
  c,r: Integer;
  li: TListItem;
begin
  // Crear las columnas necesarias en LV3 para contener LV1 y LV2 
  for r:= 0 to LV1.Columns.Count + LV2.Columns.Count - 2 do
  begin
    LV3.Columns.Add;
    if r = 0 then
      LV3.Column[r].Width:= 0 // No utilizo la columna 0
    else
      LV3.Column[r].Width:= 100;
  end;
  // Copiar los títulos
  for r:= 0 to LV1.Columns.Count-1 do
    LV3.Column[r].Caption:= LV1.Column[r].Caption;
  for r:= 1 to LV2.Columns.Count-1 do
    LV3.Column[-1+LV1.Columns.Count+r].Caption:= LV2.Column[r].Caption;

  // Agregar los items
  for r:= 0 to LV1.Items.Count+LV2.Items.Count-4 do
  begin
    // Crear una fila
    li:= LV3.Items.Add;
    // Copiar los items de LV1 como subitems
    for c:= 0 to LV1.Columns.Count-2 do
      li.SubItems.Add(LV1.Items[r].SubItems[c]);
    // Copiar los items de LV2 como subitems
    for c:= 0 to LV2.Columns.Count-2 do
      li.SubItems.Add(LV2.Items[r].SubItems[c]);
  end;
end;

procedure TForm1.btnJoinClick(Sender: TObject);
begin
  JoinListViews(ListView1, ListView2, ListView3);
end;

Con este resultado, que creo, es el que buscas:



Saludos :)

danielmj 20-11-2014 22:48:13

hola ecfisa,

estoy ahora mismo con tu codigo, he copiado y pegado directamente, y no funciona ( y no entiendo por qué si has puesto una captura del programa funcionando), solo me copia los titulos de las columnas pero no el contenido de estas.
Estoy usando lazarus para el "ejercicio" (por si sirve de algo que lo comente).

Dicho lo anterior, y leyendo tu codigo tengo algunas dudas, a saber:

Código Delphi [-]
for r:= 1 to LV2.Columns.Count-1 do
    LV3.Column[-1+LV1.Columns.Count+r].Caption:= LV2.Column[r].Caption;

¿por que ese "-1"? ¿es por la columna 0?

Código Delphi [-]
// Agregar los items
  for r:= 0 to LV1.Items.Count+LV2.Items.Count-4 do

¿por que "count -4? he probado a cambiarlo por -2, -1... y es cierto que da error, pero ¿ese -4 es para no contar las dos columnas 0 de cada una de las listas (1 y 2)?



Como puedes ver, solo copia la cabecera de las columnas pero no su contenido y he copiado y pegado tu codigo como dije antes.

En fin, sigo con esto, por cierto he mirado algunos manuales/libros (delphi al limite, la biblia de delphi, la cara oculta... de ian marteens, etc pero no consigo aclararme)

Por cierto, buscando informacion en la web encontré esto (por si le sirve a alguien): http://delphi.about.com/od/tlistview/


Un saludo y gracias.

danielmj 20-11-2014 22:49:50

Hola nlsgarcia,

Gracias por los enlaces, ya los habia mirado, pero no explica un caso como el mio, de meter el concatenar dos listas (columnas y sus subitems)

un saludo.

nlsgarcia 20-11-2014 23:14:02

danielmj,

Cita:

Empezado por danielmj
...los enlaces, ya los había mirado, pero no explica un caso como el mio, de meter el concatenar dos listas...

:rolleyes:

La idea de los enlaces sugeridos en el Msg #8, es brindar la base conceptual del uso del componente TListView y que esta sea aplicada a cualquier caso particular, lo anterior es análogo a toda la teoría asociada a Delphi y por extensión a cualquier lenguaje de programación :)

Nelson.

ecfisa 21-11-2014 00:22:22

1 Archivos Adjunto(s)
Hola Daniel.
Cita:

Empezado por danielmj (Mensaje 485183)
hola ecfisa,
estoy ahora mismo con tu codigo, he copiado y pegado directamente, y no funciona ( y no entiendo por qué si has puesto una captura del programa funcionando), solo me copia los titulos de las columnas pero no el contenido de estas.
...

Sinceramente yo tampoco lo entiendo. Pero te adjunto los fuentes del código funcionando en Lazarus, a ver si te sirve de guía.



(No soy experto en Lazarus, si llega a faltar algún archivo por favor avisame)

Saludos :)

danielmj 21-11-2014 10:29:08

hola ecfisa,

Sigo con esto y no me funciona, copio y pego tal cual está tu codigo y hace un volcado extraño, desordenado e incompleto. Este es el enlace para que lo veas por ti mismo: http://terawiki.clubdelphi.com/Delph...oad=ecfisa.zip .

No sé si debo subir este tipo de archivos al FTP, así que disculpad si no está para eso y si es necesario pues que algun admnistrador lo borre. Intenté ponerlo a pie del mensaje pero no sé como se hace.

En fin, cuando lo abras veras que solo carga la primera fila de cada una de las listas.


danielmj 21-11-2014 13:30:59

Buenas,

Ya tengo solucionado esto (creo), lo que pasaba es que en la linea:

Código Delphi [-]
for r:= 0 to LV1.Items.Count+LV2.Items.Count-4 do

El "-4" solo me sirve segun el numero de filas que tengan las listas, pero si tiene mas de 3 por ejemplo, da error, en el sentido de no agregar correctamente los datos. Lo que he hecho escambiar la linea por esto otro:
Código Delphi [-]
cant:= lv1.Items.Count +1; // CALCULA EL NUMERO DE FILAS DE LA LISTA Y LE SUMA "1" EJEMPLO: 4 FILAS + 1 = 5 FILAS   
// Agregar los items 
for r:= 0 to LV1.Items.Count+LV2.Items.Count -cant do
Bueno, ya todo esto esta corriendo bien, ahora tengo que sonseguir escribir todo el codigo por mi mismo, sin pedir ayuda constantemente :)

Gracias por la ayuda y un saludo.


La franja horaria es GMT +2. Ahora son las 19:31:02.

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