Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Ordenar un TListView
Ir a página 1, 2  Siguiente
 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Ordenar un TListView Responder citando

Hola!

Tengo un TListView (con la propiedad ViewStyle ajustada "vsReport"). Me gustaría saber si alguien tiene un código que permita ordenar cualquiera de sus columnas,de manera tanto ascendente como descendente, cuando el usuario haga click sobre la columna. He visto algunos ejemplos en la ayuda del builder pero no me termino de aclarar.

Gracias.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Ya he encontrado la solución (la pongo por si a alguien le interesa). El problema es que si una de las columnas es numérica (por ejemplo: 1,2,3....90,91...) me lo ordena incorrectamente. Por ejemplo, pone: 91, 90, 9, 89, 88... ¿Alguien sabe como arreglar esto?. El código es el siguiente:

Variables globales:
Código:

int  LastSortedColumn;
bool    Ascending;


después:
Código:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    LastSortedColumn = -1;
    Ascending = true;
}


y finalmente
Código:

void __fastcall TForm1::ListView1ColumnClick(TObject *Sender,
      TListColumn *Column)
 {
    if (Column->Index == LastSortedColumn)
      Ascending =! Ascending;
    else
      LastSortedColumn = Column->Index;

    static_cast<TListView*>(Sender)->CustomSort(SortByColumn, Column->Index);
}


donde:
Código:
int  __stdcall SortByColumn(long Item1,long Item2, long Data)
{
    int w;
    if (Data == 0)
      w=AnsiCompareText(((TListItem *)Item1)->Caption, ((TListItem *)Item2)->Caption);
    else
      w=AnsiCompareText(((TListItem *)Item1)->SubItems->Strings[Data-1],((TListItem *)Item2)->SubItems->Strings[Data-1]);

    if (!Ascending)
      return -w;
}


Como os decía: las columnas numéricas las ordena incorrectamente ¿Alguna idea?
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola Marky:

Podrías usar por ejemplo la propiedad 'Tag' de cada columna, por no complicarlo mucho, para indicar el tipo de dato de esa columna. En este caso 0 para texto y 1 para números:
Código:
int  __stdcall SortByColumn(long Item1,long Item2, long Data)
{
    TListItem* item1 = reinterpret_cast<TListItem*>(Item1);
    TListItem* item2 = reinterpret_cast<TListItem*>(Item2);
    bool bCampoNumerico = item1->ListView->Column[Data]->Tag;
    int w;

    if (Data == 0)
    {
        w = !bCampoNumerico
            ? AnsiCompareText(item1->Caption, item2->Caption)
            : item1->Caption.ToIntDef(0) - item2->Caption.ToIntDef(0);
    }
    else
    {
        w = !bCampoNumerico
            ? AnsiCompareText(item1->SubItems->Strings[Data-1],
                item2->SubItems->Strings[Data-1])
            : item1->SubItems->Strings[Data-1].ToIntDef(0)
                - item2->SubItems->Strings[Data-1].ToIntDef(0);
    }

    return Ascending ? w : -w;
}

Saludos:
_Leo
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Gracias Leo por tu rapidísima respuesta! Funciona a la perfección.

No había pensado en la propiedad Tag, de hecho es la primera vez que la uso.

Te debo unas cañas y unas bravas Wink
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Pues no.... ahora hay un pequeño problemilla :__( Si modifico la propiedad "FullDrag" del TListView a "true" y cambio algunas columnas de posición se vuelve a plantear el mismo problema: no ordena correctamente.

¿Porque puede ser esto?
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

No había previsto ese caso:

Cambiamos la línea:

  bool bCampoNumerico = item1->ListView->Column[Data]->Tag;

Por:

  TListView* lv = static_cast<TListView*>(item1->ListView);
  TListColumn* lc = static_cast<TListColumn*>(lv->Columns->FindItemID(Data));
  bool bCampoNumerico = lc->Tag;
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Joder _Leo!!! Eres un auténtico fiera!!! Muchísimas gracias. Ahora si que todo funciona perfectamente :-)

P.D. Si algún día voy para Lanzarote puedes contar con unas cañas de mi cuenta
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola _Leo,
Intenté utilizar metodo que describen pero no logro compilar ni a palos.

Los dos errores son:
-Imposible de convertir 'int (__stdcall * (_closure )(long,long,long))(long,long,long)' en 'int (__stdcall *)(long,long,long)'

-E2342 Mala correspondencia de tipo en el paramètro 'SortProc' ('int (__stdcall *)(long,long,long)' querido, 'void' obtenido).

Intente castear SortByColumn pero tampoco:
Código:
ListView->CustomSort((PFNLVCOMPARE)SortByColumn, Column->Index);

Reproduzco el codigo completo para verificar que no hice ninguna metida de pata:
Código:
//---------------------------------------------------------------------------
int  __stdcall SortByColumn(long Item1, long Item2, long Data)
{
    int w;
    if (Data == 0)
        w = CompareText(((TListItem *)Item1)->Caption, ((TListItem *)Item2)->Caption);
    else
        w = CompareText(((TListItem *)Item1)->SubItems->Strings[Data-1],((TListItem *)Item2)->SubItems->Strings[Data-1]);

    if (Wnd_Doc->Ascending == false)
       return -w;

return w;
}

//---------------------------------------------------------------------------
void __fastcall TWnd_Doc::ListViewColumnClick(TObject *Sender, TListColumn *Column)
{
    if (Column->Index == LastSortedColumn)
      Ascending =! Ascending;
    else
      LastSortedColumn = Column->Index;

    static_cast<TListView*>(Sender)->CustomSort(SortByColumn, Column->Index);
    //ListView->CustomSort((PFNLVCOMPARE)SortByColumn, Column->Index);
}
Pereciera que tengo que pasarle los parametros de 'SortByColumn' pero en el ejemplo ustedes no lo hacen y tampoco en los ejemplos de Borland.
Alguna sugerencia?
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

No dije nada!!!
De puro bruto nomas, habia declarado la funcion "SortByColumn" y no era necesario.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: hola a todos. Responder citando

Hola a todos.

estoy aprendiendo a ocupar el componente TListView, y ya tengo lo necesario.

traigo de una bd datos y los pongo en esta lista en modo reporte.

pero me gustaria saber como al momento de incorporar contenido a la lista indicarle a la columna que adopte el largo maximo que se vaya insertando?---

porque siempre tengo que alinear a mano las columnas para poder ver los datos que se truncan visualmente para datos muy extensos.
muchisimas gracias.. si aprendo a como hacer eso, entonces ya estaria en condiciones de dar un uso como se debe al componente.

(otra cosa, en el ejemplo anterior,
static_cast<TListView*>(Sender)->CustomSort(SortByColumn, Column->Index);

me manda un error de que SortByColumn no está definido, y tengo la funcion en la clase, la pegué. y que en la funcion SortByColumn existen elementos que tampoco estan definidos.
) Smile... gracias por la futura ayuda.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

amigos disculpen la ignorancia
pero donde debo poner el codigo paar que funcione?
me imagino que ese tipo de oreden seria dandole clic a x columna no?
si tengo 7 columnas como haria lo mismo?
_________________
Todos somos ignorantes, lo que no todos ignoramos lo mismo...
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Buenas. Recupero este tema porque me está haciendo cosas "raras" este código. Estoy tratando de ordenar esta tabla:


Y si pulso, por ejemplo, la columna etiquetada Refª la primera vez me hace SIEMPRE esta ordenación:


Es decir: La primera vez que pulso me invierte el orden alfabético de la primera columna. La segunda vez ya me lo hace bien, pero no es solución. ¿Alguna idea?
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Hola, a mi el codigo descrito en esta página funciona correctamente. Aunque para mi gusto he modificado el evento ColumnClick para que siempre que pico en una columna diferente, el orden sea ascendente.
Código:
if (Column->Index == LastSortedColumn)
   Ascending =! Ascending;
else {
   Ascending = true;
   LastSortedColumn = Column->Index;
}

static_cast<TListView>(Sender)->CustomSort(SortByColumn, Column->Index);


Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Recupero, una vez más, este tema porque me ha surgido una duda básica.
_Leo escribió:
Código:
int  __stdcall SortByColumn(long Item1,long Item2, long Data) ...

Acepto collejas múltiples porque la pregunta que voy a hacer es de párvulos desde el punto de vista de C++: ¿Dónde o como defino esa función SortByColum? Sé que lo he hecho otras veces pero no encuentro el código por ningún lado.

Ahora lo tengo así:
Cita:
En .h
Código:
public:      // User declarations
     __fastcall TfBusSoc(TComponent* Owner);
     int  __stdcall SortByColumn(long Item1,long Item2, long Data);
     int LastSortedColumn;
     bool Ascending;

Cita:
En .cpp
Código:
int  __stdcall SortByColumn(long Item1,long Item2, long Data)
{...

Y me está dando estos errores:
    E2451 Undefined symbol 'Ascending'
    E2034 Cannot convert 'int (__stdcall * (_closure )(long,long,long))(long,long,long)' to 'int (__stdcall *)(long,long,long)'
    E2342 Type mismatch in parameter 'SortProc' (wanted 'int (__stdcall *)(long,long,long)', got 'void')

Sé que es una tontería, pero en este momento estoy bloqueado y no soy capaz de ver lo que hago mal. Embarassed
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Hola Angel,

Si lo estás creando como metodo de la clase formulario, has olvidado poner el nombre del fomulario en el cpp.

Código:
En .cpp
Código:
int  __stdcall TFomNN::SortByColumn(long Item1,long Item2, long Data)
{...


Saludos,
Juanma
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.