Newsgroup: it.comp.lang.delphi
Titolo: Ordinamento dati in TStringGrid

Ciao a tutti,
avrei la necessità di avere due tipi di ordinamenti su una TStringGrid
che viene popolata a run-time, ovvero:
1) Inserire i dati sempre in testa alla StringGrid, cioè inserire
nella prima riga i dati nuovi che vengono caricati e a seguire i dati
precedenti, quindi un ordinamento del tipo
dato 10
dato 9
dato 8
dato 7
dato 6
dato 5
dato 4
dato 3
dato 2
dato 1
Non conosco a priori il numero dei dati che verranno caricati.
2) Poter modificare l'ordinamento cliccando sui campi fixed.
Ho fatto qualche ricerca ma non ho trovato nulla in proposito, potete
darmi una mano?
Grazie mille


--- posted by geoForum on 
http://www.delphiedintorni.it

CMQ per inserire nel primo ordine
StringGrid1.Cols[X].Insert(pos,'ciao');


scusate se mi intrometto (da ignorante) ...
la necessità di "riordinare" la TStringGrid spostando i campi "fixed"
serve anche a me e dovrei arrivarci a breve nello sviluppo del mio
programma.
La cosa che ho notato "smanettando un po" è che se clicco su una row,
su una cella fixed, posso spostarla in basso e/o in alto ed
automaticamente le altre row si adeguano.
Questo è proprio quello di cui ho bisogno ... solo che non ho studiato
ancora il risultato "pratico" della cosa.
Credo sia solo uno spostamento "grafico" mentre i dati della Grid
restano sempre nella stessa posizione.
quindi sfruttando l'evento OnRowMoved leggere la "visuale" della
griglia (e/o utilizzare l'Array bidimensionale "mirror"), rimettere in
ordine i dati e riscrivere il tutto nella Grid.
secondo voi che strada sarebbe più "semplice" ?

Ho avuto modo di parlare con Andrea Laforgia una volta. Diciamo che è uno
che se ne intende, anche io medio basso.
Diciamo che delphii è molto vasto, quindi anche se abbiamo la testa sulla
cosa possiamo commettere errori rilevanti.
Andrea Laforgia mi ha spiegato che componenti come StringGrid devono
essere considerati prima di tutto come delle interfacce.
Se ho molti dati ad esempio andrebbero caricati in griglia solo quelli che
utilizzo sullo schermo. Quindi quando mi sposto carico gli altri.
Associare un array (magari packed se ho molte celle vuote), permette di
fare tutto
Se si pensa ad esempio ad un ordinamento, potrei ordinare l'array con un
ordinamento efficiente (es. una routine di tipo "ordinamento binario") e
poi riassocio tutto.
PS. Ho elaborato una routine molto bella per salvare i dati in griglia
(molto old pascal) ma efficiente. Se vi serve ve la posto.
Ciao.









Ciao.
--- posted by geoForum on 
http://www.delphiedintorni.it

Risposta a Scriptor:







Ciao.
--- posted by geoForum on 
http://www.delphiedintorni.it

a parte sistemarti il pulsante del mouse ... ;)
ho trovato anche io (ed al momento li ho messi da parte) routine per
salvare la griglia in un file.
Comunque è una cosa che mi serve dato che utilizzerò il file, oltre
che per riscrivere le modifiche apportate, come una sorta di
UserDefault, non entro nel merito di cosa faccia il mio programma per
non diventare noioso ... se volete posso anche farlo.
il dubbio che ho (ma forse faccio prima a fare le prove) è se dopo
aver spostato la ROW in basso e/o in alto questa resta sempre come
ROW[1,3], ma graficamente spostata, e/o cambi anche di "indicatori"
la ROW in oggetto contiene una decina di campi che non mi interessa
cambiare (o lo potrei fare con altri sistemi)
le 32 ROW corrispondono ad una serie di "indicatori" che sono
memorizzati sequenzialmente sotto forma di blocco di byte
spostando la singola ROW dovrei spostare gli "indicatori" e riscrivere
tutto il blocco di byte che contiene i 32 "indicatori"

Posto una routine per il QUICK SORT della StringGrid
Delphi QSort Source Code 
type 
  { callback routine types - make sure you declare them as FAR } 
  { expected result:  <0 if elem[e1] < elem[e2];   
                       0 if elem[e1] = elem[e2]; 
                      >0 if elem[e1] > elem[e2] } 
  TCompNdxFunc = function(e1, e2: word): integer; 
  TSwapNdxFunc = procedure(e1, e2: word); 
{ This is the main sorting routine. It is passed the number of elements 
and the 
  two callback routines. The first routine is the function that will 
perform 
  the comparison between two elements. The second routine is the 
procedure that 
  will swap two elements if necessary } 
procedure QSort(uNElem: word; FCmp: TCompNdxFunc; FSwap: TSwapNdxFunc); 
{ uNElem - number of elements to sort } 
  procedure qSortHelp(pivotP: word; nElem: word); 
  label 
    TailRecursion, 
    qBreak; 
  var 
    leftP, rightP, pivotEnd, pivotTemp, leftTemp: word; 
    lNum: word; 
    retval: integer; 
  begin 
    TailRecursion: 
      if (nElem <= 2) then 
        begin 
          if (nElem = 2) then 
            begin 
              rightP := pivotP +1; 
              if (Fcmp(pivotP, rightP) > 0) then Fswap(pivotP, rightP); 
            end; 
          exit; 
        end; 
      rightP := (nElem -1) + pivotP; 
      leftP :=  (nElem shr 1) + pivotP; 
      { sort pivot, left, and right elements for "median of 3" } 
      if (Fcmp(leftP, rightP) > 0) then Fswap(leftP, rightP); 
      if (Fcmp(leftP, pivotP) > 0) then Fswap(leftP, pivotP) 
      else if (Fcmp(pivotP, rightP) > 0) then Fswap(pivotP, rightP); 
      if (nElem = 3) then 
        begin 
          Fswap(pivotP, leftP); 
          exit; 
        end; 
      { now for the classic Horae algorithm } 
      pivotEnd := pivotP + 1; 
      leftP := pivotEnd; 
      repeat 
        retval := Fcmp(leftP, pivotP); 
        while (retval <= 0) do 
          begin 
            if (retval = 0) then 
              begin 
                Fswap(leftP, pivotEnd); 
                Inc(pivotEnd); 
              end; 
            if (leftP < rightP) then 
              Inc(leftP) 
            else 
              goto qBreak; 
            retval := Fcmp(leftP, pivotP); 
          end; {while} 
        while (leftP < rightP) do 
          begin 
            retval := Fcmp(pivotP, rightP); 
            if (retval < 0) then 
              Dec(rightP) 
            else 
              begin 
                FSwap(leftP, rightP); 
                if (retval <> 0) then 
                  begin 
                    Inc(leftP); 
                    Dec(rightP); 
                  end; 
                break; 
              end; 
          end; {while} 
      until (leftP >= rightP); 
    qBreak: 
      if (Fcmp(leftP, pivotP) <= 0) then Inc(leftP); 
      leftTemp := leftP -1; 
      pivotTemp := pivotP; 
      while ((pivotTemp < pivotEnd) and (leftTemp >= pivotEnd)) do 
        begin 
          Fswap(pivotTemp, leftTemp); 
          Inc(pivotTemp); 
          Dec(leftTemp); 
        end; {while} 
      lNum := (leftP - pivotEnd); 
      nElem := ((nElem + pivotP) -leftP); 
      if (nElem < lNum) then 
        begin 
          qSortHelp(leftP, nElem); 
          nElem := lNum; 
        end 
      else 
        begin 
          qSortHelp(pivotP, lNum); 
          pivotP := leftP; 
        end; 
      goto TailRecursion; 
    end; {qSortHelp } 
begin 
  if (uNElem < 2) then  exit; { nothing to sort } 
  qSortHelp(1, uNElem); 
end; { QSort } 
====================================================================== 
Delphi QSort Example 
{This is the user-defined function that will be used to compare the 
elements} 
function SortCompare(e1, e2: word): integer; far; 
begin 
  with MyForm.StringGrid1 do 
    begin 
      if (Cells[1, e1] < Cells[1, e2]) then 
        Result := -1 
      else if (Cells[1, e1] > Cells[1, e2]) then 
        Result := 1 
      else 
        Result := 0; 
    end; {with} 
end; 
{This is the user-defined function that will be used to swap 2 elements} 
procedure SortSwap(e1, e2: word); far; 
var 
  s: string[63];  { must be large enough to contain the longest string 
in the grid } 
  i: integer; 
begin 
  with MyForm.StringGrid1 do 
    for i := 0 to ColCount -1 do 
    begin 
      s := Cells[i, e1]; 
      Cells[i, e1] := Cells[i, e2]; 
      Cells[i, e2] := s; 
    end; {for} 
end; 
procedure TMyForm.Button1Click(Sender: TObject); 
begin 
  QSort(StringGrid1.RowCount-1, SortCompare, SortSwap); 
end;
