Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Leer y ordenar fichero en delphi (https://www.clubdelphi.com/foros/showthread.php?t=60859)

izubal 16-10-2008 08:19:13

Leer y ordenar fichero en delphi
 
Hola,

Llevo un par de semanas programando en Delphi y necesito ayuda.
Tengo que leer un fichero plano. Tengo que ordenar todas las líneas en base a dos campos y cada línea contiene varios campos que están separados por el simbolo |.
Se leer las líneas y también encontrar este símbolo con la función pos, pero no tengo ni idea de como ordenarlos.

¿Alguien me podrí dar una pista?

Gracias, Un saludo

Lepe 16-10-2008 08:44:02

Código:

campo1 | campo2 | campo3 | campo4
¿por qué campos tienes que ordenar?
¿campo1 y campo 2?
o ¿puedes necesitar ordenar por campo2 y campo3 sin tener en cuenta el campo1?.
- ¿el usuario debe poder elegir los campos de ordenación?

Cada ordenación necesitará de algo distinto.

Saludos

izubal 16-10-2008 08:47:48

leer y ordenar ficheros planos en delphi
 
Hola,

en total cada línea cuenta de 12 campos
campo1 | campo2 | campo3 | campo4 | ...
y tengo que ordenar las líneas en base al campo2 y campo8
El usuario no tiene que seleccionar por qué campo ordenar, sino que tiene que ser en ascendente.

gracias

Neftali [Germán.Estévez] 16-10-2008 08:53:31

La forma más sencilla que se me ocurre es utilizar un TStringList que ya posee métodos de ordenación.

Monta una Clave (string) utilizando los dos campos que necesitas para ordenar, manteniendo en todos los casos la misma longitud y conviertiendolos a String si no lo son. Luego esa clave se la pasas a un StringList y le mandas que ordene. Ya tendrás las claves ordenadas.

A ver si me explico; Suponiendo que los campos fueran Nombre y Cantidad, por poner uno de cada tipo:

Carlos--234--...
Felipe--123--...
Ana-23--...
Juan--3456--...
Andres--4--...


Se trataría de montar la cadena de esta forma:
(Nombre rellenando hasta 15 y Cantidad también); En este caso he rellenado con 0, pero puedes usar otro caracter.

000000000Carlos000000000000234
000000000Felipe000000000000123
000000000000Ana000000000000023
00000000000Juan000000000003456
000000000Andres000000000000004


De esta forma ahora ya puedes pasar estas cadenas y te ordenará correctamente. El pointer (TObject) puedes utilizarlo para apuntar a la posición de la lista inicial.

No se si me expliqué más o menos claramente.


izubal 16-10-2008 08:58:56

leer y ordenar ficheros planos en delphi
 
Si, creo que ya te he entendido.

1. Montó la cadena.
2. Pasarlas al StringList
3. Usar el método de ordenación que tiene el StringList

pero y al StringList le tendría que decir por qué campo ordenar no? hay ya no lo tengo... vamos que no he entendido muy bien.
Si me puedes aclarar este último punto....

gracias
un saludo

izubal 16-10-2008 09:08:16

Voy a intentarlo.
estoy mirando como funciona el objeto StringList y si no lo consigo ya vuelvo a escribir.

Gracias por todo.
Un saludo

izubal 16-10-2008 09:55:47

Hola,

Tengo una duda.
Cargo en el TStringList todas las líneas del fichero.
pero el método sort no tiene como pasarle los parámetros.

sl := TStringList.Create;
try
Reset(ftIN);
Rewrite(ftOUT);
while (not EOF(ftIN)) and (Error<> 1) do
begin
Readln(ftIN, S);
sl.Add(S);
...

pero como le digo que quiero ordenarlo en base al campo2 y 8??
con el método xprocs.strTokenToStrings(S,'|',s2); puedo cargar en otro TStringList (s2) todos los campos que tiene pero no se como seguir.

un saludo.

Neftali [Germán.Estévez] 16-10-2008 11:18:34

Por pasos:
(1) Carga el fichero en un TStringList (llamaremos el original). Hay un método que lo hace, esa es otra de las ventajas del TStrigList.

Código Delphi [-]
  TS.loadFromFile('nombrefichero')

(2) Monta un segundo TStringList con las cadenas; Ese segundo es el que utilizaremos para ordenar. Tendrás las cadenas y el apuntador e la posición en la lista original.

Código Delphi [-]
var
  i:Integer;
  pi:PInteger;
begin
...
TS2 := TStringList.Create();
...
for i := 0 to (TS.Count - 1) do begin
  Str := 'Cadena con los campos 2 y 8'  // CURRO PARA TÍ
  // tendrás en Str concatenados el campo2 y el campo8

  // Añadirlo a la segunda lista
  pi := Pointer(i);
  // Añadimos a la segunda lista el String y la posicion en la original (usamos el puntero para colocar la posicion)
  TS2.AddObject(Str, TObject(pi));
end;

// Cuando salgas del FOR, en TS2 tendrás tantas cadenas como en TS
// pero sólo con los campos2 y 8

Ahora tu segunda lista tiene las cadenas 2 y 8 y la posicion en la lista original; Al ordenar, ordenará por las cadenas y segirás teniendo cada cadena con un entero que te dirá la posición en la lista original.

(3) Ordenar.

Código Delphi [-]
  TS2.Sort();

Si originalmente la lista estaba así (TS):
Lunes
Martes
Miercoles
Jueves
Viernes
Sábado
Domingo

La segunda lista estará así (TS2) despues de ordenar; Lo segundo es el apuntador:
Domingo (7)
Jueves(4)
Lunes(1)
Martes(2)
Miercoles(3)
Sábado(6)
Viernes(5)

Por lo tanto puedes reordenar la lista original en una tervera (TS3) utilizando algo así:

Código Delphi [-]
    for i := 0 to (TS2.Count - 1) do begin
      // cadena en la segunda lista
      Str := TS2[i];
      // posicion en la lista original
      j := Integer(TS2.Objects[i]);
      // añadirlo a la ternera lista
      TS3.Add(TS.[j]);
    end;

Espero que quede más claro.

Lepe 16-10-2008 11:25:59

Edito: Neftali sigue siendo el más rápido del Oeste.... :D.

(No sé si borrar el mensaje o dejarlo, lo dejo de momento, si te lías más, olvídame :D :D, prácticamente digo lo mismo que Neftali)

Vamos por partes:
- Para cargar el fichero, puedes usar un stringlist llamado fichero y usar fichero.LoadFromfile('ruta completa.txt');

Ahora por cada elemento de ese string, tienes que recorrerlo y ponerlo en formato:
000000000Carlos000000000000234

Suponiendo que "Carlos" es el campo1 y "234" es el campo8

Estos strings con formato especial, vamos a cargarlo en otro stringlist llamado Aordenar, de forma que lo añadimos así:
Código Delphi [-]
fichero := TStringlist.create;
Aordenar := TStringlist.create;
for i:= 0 to fichero.count-1 do
begin 
   strConCeros := pues eso, la cadena con los ceros, usa el xprocs o lo que sea para armar la cadena
   aordenar.AddObject(strConCeros, pointer(i));
end;
aordenar.sort;

Un ejemplito, Supongamos que aordenar (después de llamar a Sort) tiene esto
Código:

string                Object[i]
00000Antonio          3
00000Carlos          1

Eso significa que fichero[3] tendrá a "Antonio" y es el primer nombre en orden alfabético que existe en el fichero.

También significa que en segundo lugar de la lista ordenada, está "Carlos" el cual se encuentra en fichero[1]

Quizás sea un lío, te aconsejo probar con algo así
Código Delphi [-]
var str:string;
begin
for i:= 0 to Aordenar.count-1 do
begin
   str := Aordenar[i] + ' está en el índice '+  IntTostr(integer(Aordenar.objects[i])) + ' de fichero';
  ShowMessage(str);
end;

Dicho de otra forma Aordenar.objects[i] guarda la linea en que se encuentra ese individuo en el archivo.

Saludos

izubal 16-10-2008 11:28:18

leer y ordenar ficheros planos en delphi
 
OK.
Con las explicaciones que me habeís dado espero conseguirlo esta tarde.
Ya os comentaré que tal me ha ido.

muchas gracias a los dos.
un saludo

Neftali [Germán.Estévez] 16-10-2008 11:45:11

Cita:

Empezado por Lepe (Mensaje 320472)
...prácticamente digo lo mismo que Neftali

Bueno, eso debe ser que no vamos tan mal encaminados, pistolero! :):)

izubal 16-10-2008 15:59:25

leer y ordenar ficheros planos en delphi
 
Hola,

lo he conseguido!!
ahora lo veo sencillo, pero no me salía!!!

Muchas muchas gracias.

un saludo

izubal 16-10-2008 16:57:14

leer y ordenar ficheros planos en delphi
 
Hola,

lo he conseguido!!
ahora lo veo sencillo, pero no me salía!!!

Muchas muchas gracias.

un saludo


La franja horaria es GMT +2. Ahora son las 10:41:35.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi