Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Ordenar ListBox (https://www.clubdelphi.com/foros/showthread.php?t=85701)

ZayDun 21-04-2014 12:29:07

Ordenar ListBox
 
Hola, en principio lo que quería realizar parecía algo sencillo pero o bien no lo es o me estoy liando mas de lo que debería, lo que quiero hacer es ordenar un listbox que contiene datos de este tipo


Código:

009 UsuarioA
005 UsuarioA
002 UsuarioC
002 UsuarioB
006 UsuarioC

quisiera ordenarlos para que se muestre así:

Código:

005 UsuarioA
009 UsuarioA
002 UsuarioB
002 UsuarioC
006 UsuarioC

Como veis se ordenan numericamente por usuarioA, usuarioB o usuarioC

he realizado varias pruebas, he ordenado mediante "sort", también he eliminado los primeros 3 números y he ordenado el listbox pero ya no sabía como volver a añadir los números.

¿Alguna idea? gracias compañeros.

ecfisa 21-04-2014 12:51:23

Hola ZayDun.

Podes hacer:
Código Delphi [-]
procedure SortByUserName(TS: TStrings);
  function CompareNom(TS: TStrings; const i1, i2: Integer): Integer;
  begin
    Result:= CompareText(Copy(TS[i1],4,MaxInt)+Copy(TS[i1],1,3),
                         Copy(TS[i2],4,MaxInt)+Copy(TS[i2],1,3));
  end;
var
  SL: TStringList;
begin
  SL:= TStringList.Create;
  try
    SL.Assign(TS);
    SL.CustomSort(@CompareNom);
    TS.Assign(SL);
  finally
    SL.Free;
  end;
end;

Uso:
Código Delphi [-]
  SortByUserName(ListBox1.Items);

Saludos :)

Edito: Agregué la concatenación de los números detras en la comparación para que ordene por nombre y a su vez por número.

ZayDun 21-04-2014 13:13:48

Cita:

Empezado por ecfisa (Mensaje 475363)
Hola ZayDun.

Código Delphi [-]
procedure SortByUserName(TS: TStrings);
  function CompareNom(TS: TStrings; const i1, i2: Integer): Integer;
  begin
    Result:= CompareText(Copy(TS[i1],4,MaxInt), Copy(TS[i2],4,MaxInt));
  end;
var
  SL: TStringList;
begin
  SL:= TStringList.Create;
  try
    SL.Assign(TS);
    SL.CustomSort(@CompareNom);
    TS.Assign(SL);
  finally
    SL.Free;
  end;
end;

Uso:
Código Delphi [-]
  SortByUserName(ListBox1.Items);

Saludos :)


Muchas gracias por tu ayuda ecfisa, me ordena perfectamente por usuario pero el numero principal no se ordena, queda así..

Código:

009 UsuarioA
005 UsuarioA
002 UsuarioB
006 UsuarioC
002 UsuarioC


ecfisa 21-04-2014 13:17:40

Hola ZayDun.

Revisa la corrección que hice al código anterior para solucionar ese detalle. (creo que publicamos mas o menos al mismo tiempo :))

Saludos :)

ZayDun 21-04-2014 13:53:28

Cita:

Empezado por ecfisa (Mensaje 475365)
Hola ZayDun.

Revisa la corrección que hice al código anterior para solucionar ese detalle. (creo que publicamos mas o menos al mismo tiempo :))

Saludos :)

Revise el nuevo código y sigue sucediendo lo mismo, da preferencia para ordenar al usuario que a los 3 primeros números, no se donde puede estar el problema.

Gracias de nuevo ecfisa

nlsgarcia 21-04-2014 20:56:35

ZayDun,

Cita:

Empezado por ZayDun
...lo que quiero hacer es ordenar un ListBox que contiene datos de este tipo (Código y Usuario)...

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

interface

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

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    ListBox2: TListBox;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure SortListBox(InputListBox, OutPutListBox: TStrings);

  function Sort(Input: TStrings; const i1, i2: Integer): Integer;
  begin
    Result:= CompareText(Copy(Input[i1],1,3) + Copy(Input[i1],4,MaxInt),
                         Copy(Input[i2],1,3) + Copy(Input[i2],4,MaxInt));
  end;

var
  SL : TStringList;

begin
   SL := TStringList.Create;
   try
      SL.Assign(InputListBox);
      SL.CustomSort(@Sort);
      OutPutListBox.Assign(SL);
   finally
      SL.Free;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   SortListBox(ListBox1.Items,ListBox2.Items);
end;

end.
El código anterior, ordena un TListBox que contiene dos campos (Código y Usuario) de menor a mayor por medio de un CustomSort, como se muestra en la siguiente imagen:



El código sugerido funciona correctamente según lo esperado en Delphi 7, Delphi 2010 y Delphi XE4 bajo Windows 7 Professional x32.

Espero sea útil :)

Nelson.

ecfisa 21-04-2014 20:59:06

Hola ZayDun.

No se que te puede estar pasando... ¿ Será la versión de Delphi ? he visto que hay muchas diferencias entre Delphi 7 y EX4.

Esta es la prueba con el código anterior que en Delphi 7 funciona sin problemas:
Código Delphi [-]
...
implementation

procedure SortByUserName(TS: TStrings);
  function CompareNom(TS: TStrings; const i1, i2: Integer): Integer;
  begin
    Result:= CompareText(Copy(TS[i1],4,MaxInt)+Copy(TS[i1],1,3),
                         Copy(TS[i2],4,MaxInt)+Copy(TS[i2],1,3));
  end;
var
  SL: TStringList;
begin
  SL:= TStringList.Create;
  try
    SL.Assign(TS);
    SL.CustomSort(@CompareNom);
    TS.Assign(SL);
  finally
    SL.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  Randomize;
  for i:= 1 to 22 do
    ListBox1.Items.Add(Format('%.3d Usuario%s',[i,Chr(65+Random(26))]));
  ListBox2.Items.Assign(ListBox1.Items);
  SortByUserName(ListBox2.Items);
end;

Resultado:


Saludos :)

ZayDun 22-04-2014 10:00:11

muchas gracias tanto a ecfisa como nlsgarcia por vuestra ayuda, al final viendo que daba problemas dependiendo de la versión de delphi he tenido que realizarlo utilizando un TListview y añadiendo los datos por columnas para organizarlo mejor.


La franja horaria es GMT +2. Ahora son las 08:05:13.

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