logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak posortować alfabetycznie w TStringGrid w Delphi?

VeXXoN 17 Sty 2010 21:28 1854 9
REKLAMA
  • #1 7551545
    VeXXoN
    Poziom 10  
    Posty: 60
    Ocena: 3
    Witam mam taki problem potrzebuje przerobić kod aby mi sortował w tabeli TstringGrid nazwy alfabetycznie sortowanie numeryczne działa ok ale niestety nie wiem jak zrobić aby działało alfabetycznie.

    Próbowałem wklepać tego gotowca:
    http://4programmers.net/Delphi/Gotowce/Alfabetyczne_sortowanie_b%C4%85belkowe

    Jednak wywala mi błąd praktycznie od początku do końca oczywiście stringlista zamieniłem z nazwa mojej.


    Tak wygląda kod programu możne ktoś mi napisać jak ma to poprawnie wyglądać jestem bardzo początkujący i nie wiem a na środę muszę oddać na zaliczenie. Interesują mnie kolumny Nazwa Gatunku i Zamieszkanie.

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Grids, jpeg, ExtCtrls, ImgList, ComCtrls, ToolWin,
      Menus, XPMan;
    
    type
    
    
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        OpenDialog1: TOpenDialog;
        SaveDialog1: TSaveDialog;
        ImageList1: TImageList;
        ToolBar1: TToolBar;
        ToolButton1: TToolButton;
        ToolButton2: TToolButton;
        ToolButton3: TToolButton;
        ToolButton4: TToolButton;
        ToolButton5: TToolButton;
        ToolButton6: TToolButton;
        ToolButton7: TToolButton;
        ToolButton8: TToolButton;
        PopupMenu1: TPopupMenu;
        SortujwgNazwyGatunku1: TMenuItem;
        SortujwgWieku1: TMenuItem;
        SortujwgWagi1: TMenuItem;
        SortujwgRozmiaru1: TMenuItem;
        SortujwgZamieszkania1: TMenuItem;
        ToolButton9: TToolButton;
        XPManifest1: TXPManifest;
        MainMenu1: TMainMenu;
        procedure FormCreate(Sender: TObject);
        procedure ToolButton2Click(Sender: TObject);
        procedure ToolButton1Click(Sender: TObject);
        procedure ToolButton3Click(Sender: TObject);
        procedure ToolButton5Click(Sender: TObject);
        procedure ToolButton4Click(Sender: TObject);
        procedure SortujwgNazwyGatunku1Click(Sender: TObject);
        procedure SortujwgRozmiaru1Click(Sender: TObject);
        procedure SortujwgWieku1Click(Sender: TObject);
        procedure SortujwgWagi1Click(Sender: TObject);
        procedure SortujwgZamieszkania1Click(Sender: TObject);
        private
        { Private declarations }
      public
        { Public declarations }
      end;
     dane=record
     Nazwa_Gatunku:string[20];
     Wiek:integer;
     Waga:integer;
     Rozmiar:integer;
     Zamieszkanie:string[30];
    
     end;
     rekordy=array of dane;
    
    var
      Form1: TForm1;
      zwierzeta:rekordy;
      plik:file of dane;
      plik1:file of integer;
      n:byte;
      otwarto:boolean;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    
    begin
    
    otwarto:=false;
    
    StringGrid1.colwidths[0]:=35;
    StringGrid1.colwidths[1]:=300;
    StringGrid1.colwidths[2]:=100;
    StringGrid1.colwidths[3]:=100;
    StringGrid1.colwidths[4]:=100;
    StringGrid1.colwidths[5]:=305;
    StringGrid1.Cells[0,0]:='L.P.';
    StringGrid1.Cells[1,0]:='Nazwa Gatunku';
    StringGrid1.Cells[2,0]:='Wiek';
    StringGrid1.Cells[3,0]:='Waga';
    StringGrid1.Cells[4,0]:='Rozmiar';
    StringGrid1.Cells[5,0]:='Zamieszkanie';
    
    
    end;
    
    
          procedure TForm1.ToolButton1Click(Sender: TObject);
    var
    i:integer;
    begin
    n:=Strtoint(inputbox('Dane','Określ liczbę gatunków:',''));
    setlength(zwierzeta,n);
      for i:=0 to n-1 do
        begin
        zwierzeta[i].Nazwa_Gatunku:=inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Nazwa_Gatunku ' ,' ' );
        zwierzeta[i].Wiek:=Strtoint(inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Wiek ' ,' ' ));
        zwierzeta[i].Waga:=Strtoint(inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Waga ' ,' ' ));
        zwierzeta[i].Rozmiar:=Strtoint(inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Rozmiar ' ,' ' ));
        zwierzeta[i].Zamieszkanie:=inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Zamieszkanie ' ,' ' );
    
        end;
        StringGrid1.RowCount:=n+1;
          for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
               end;
    end;
    
    
    
         procedure TForm1.ToolButton2Click(Sender: TObject);
    var
    i:integer;
    begin
     n:=Strtoint(inputbox('Dane','Okresl liczbę gatunków które chcesz dodac',''));
    setlength(zwierzeta,n);
      for i:=0 to n-1 do
        begin
        zwierzeta[i].Nazwa_Gatunku:=inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Nazwa_Gatunku ' ,' ' );
        zwierzeta[i].Wiek:=Strtoint(inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Wiek ' ,' ' ));
        zwierzeta[i].Waga:=Strtoint(inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Waga ' ,' ' ));
        zwierzeta[i].Rozmiar:=Strtoint(inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Rozmiar ' ,' ' ));
        zwierzeta[i].Zamieszkanie:=inputbox('dane '+inttostr(i+1)+' zwierzeta ' ,' Zamieszkanie ' ,' ' );
        end;
        StringGrid1.RowCount:=n+1;
          for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
    
          end;
       if savedialog1.execute then
    
       begin
         assignfile(plik,savedialog1.FileName);
         reset(plik);
         seek(plik,filesize(plik));
            for i:=0 to n-1 do
              write(plik,zwierzeta[i]);
              closefile(plik);
    
       end
       else showmessage('Nie dopisano do pliku');
        assignfile(plik,savedialog1.FileName);
         reset(plik);
         n:=filesize(plik);
      setlength(zwierzeta,n);
      stringgrid1.RowCount:=n+1;
    
        for i:=0 to n-1 do
          read(plik,zwierzeta[i]);
          closefile(plik);
    
        for i:=0 to n-1 do
          begin
                 StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
          end;
    
    
        end;
    
    
    
    
    
    
    
    procedure TForm1.ToolButton4Click(Sender: TObject);
    var
    i:integer;
    begin
      if savedialog1.Execute then
        begin
        assignfile(plik,savedialog1.FileName);
        rewrite(plik);
         for i:=0 to n-1 do
          write(plik,zwierzeta[i]);
         closefile(plik);
    
                     end
                     else
                     showmessage('Nie wskazano pliku');
    end;
    
    procedure TForm1.ToolButton3Click(Sender: TObject);
    var
    i:integer;
    
    begin
    if opendialog1.Execute then
      begin
      assignfile(plik,opendialog1.FileName);
      reset(plik);
      n:=filesize(plik);
      setlength(zwierzeta,n);
      stringgrid1.RowCount:=n+1;
    
        for i:=0 to n-1 do
          read(plik,zwierzeta[i]);
          closefile(plik);
    
        for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
    
          end;
    
      end;
    
    end;
      procedure TForm1.ToolButton5Click(Sender: TObject);
    begin
    close;
    end;
        
    procedure TForm1.SortujwgNazwyGatunku1Click(Sender: TObject);
    
    var
    i,j:integer;
    tmp:dane;
    
    begin
      for j:=0 to n-2 do
         for i:=0 to n-2 do
    if zwierzeta[i].Nazwa_Gatunku>zwierzeta[i+1].Nazwa_Gatunku then
     begin
       tmp:=zwierzeta[i];
       zwierzeta[i]:=zwierzeta[i+1];
       zwierzeta[i+1]:=tmp;
     end;
    
       for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
          end;
    
    
    end;
    
    
    
    procedure TForm1.SortujwgRozmiaru1Click(Sender: TObject);
    
    var
    i,j:integer;
    tmp:dane;
    
    begin
      for j:=0 to n-2 do
         for i:=0 to n-2 do
    if zwierzeta[i].Rozmiar>zwierzeta[i+1].Rozmiar then
     begin
       tmp:=zwierzeta[i];
       zwierzeta[i]:=zwierzeta[i+1];
       zwierzeta[i+1]:=tmp;
     end;
    
       for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
          end;
    
    
    
    end;
    
    
    
    procedure TForm1.SortujwgWieku1Click(Sender: TObject);
    
    var
    i,j:integer;
    tmp:dane;
    
    begin
      for j:=0 to n-2 do
         for i:=0 to n-2 do
    if zwierzeta[i].wiek>zwierzeta[i+1].wiek  then
     begin
       tmp:=zwierzeta[i];
       zwierzeta[i]:=zwierzeta[i+1];
       zwierzeta[i+1]:=tmp;
     end;
    
       for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
          end;
    
    
    
    end;
    
    procedure TForm1.SortujwgWagi1Click(Sender: TObject);
    
    var
    i,j:integer;
    tmp:dane;
    
    begin
      for j:=0 to n-2 do
         for i:=0 to n-2 do
    if zwierzeta[i].Waga>zwierzeta[i+1].Waga  then
     begin
       tmp:=zwierzeta[i];
       zwierzeta[i]:=zwierzeta[i+1];
       zwierzeta[i+1]:=tmp;
     end;
    
       for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
          end;
    
    
    
    end;
    
    
    procedure TForm1.SortujwgZamieszkania1Click(Sender: TObject);
    var
    i,j:integer;
    tmp:dane;
    
    begin
      for j:=0 to n-2 do
         for i:=0 to n-2 do
    if zwierzeta[i].Zamieszkanie>zwierzeta[i+1].Zamieszkanie then
     begin
       tmp:=zwierzeta[i];
       zwierzeta[i]:=zwierzeta[i+1];
       zwierzeta[i+1]:=tmp;
     end;
    
       for i:=0 to n-1 do
          begin
           StringGrid1.Cells[0,i+1]:=inttostr(i+1);
           StringGrid1.Cells[1,i+1]:=zwierzeta[i].Nazwa_Gatunku;
           StringGrid1.Cells[2,i+1]:=inttostr(zwierzeta[i].Wiek);
           StringGrid1.Cells[3,i+1]:=inttostr(zwierzeta[i].Waga);
           StringGrid1.Cells[4,i+1]:=inttostr(zwierzeta[i].Rozmiar);
           StringGrid1.Cells[5,i+1]:=zwierzeta[i].Zamieszkanie;
          end;
    
    
    end;
    end.
    
  • REKLAMA
  • #3 7551766
    VeXXoN
    Poziom 10  
    Posty: 60
    Ocena: 3
    Tam podalem kod ktory jest dobry i dziala ale nie odpowiednio sortuje. a z tym kodem z gotowca mam tak:
    licznik2:=zwierzeta.Count-2;

    Build
    [Error] Unit1.pas(375): Record, object or class type required
    [Error] Unit1.pas(381): Incompatible types: 'String' and 'dane'
    [Error] Unit1.pas(383): Incompatible types: 'String' and 'dane'
    [Error] Unit1.pas(385): Incompatible types: 'dane' and 'String'
    [Fatal Error] zwierz.dpr(5): Could not compile used unit 'Unit1.pas'

    Wersja 2:
    licznik2:=Zamieszkanie.Count-2;
    [Error] Unit1.pas(375): Undeclared identifier: 'Zamieszkanie'
    [Error] Unit1.pas(375): Missing operator or semicolon
    [Error] Unit1.pas(381): Incompatible types: 'String' and 'dane'
    [Error] Unit1.pas(383): Incompatible types: 'String' and 'dane'
    [Error] Unit1.pas(385): Incompatible types: 'dane' and 'String'
    [Fatal Error] zwierz.dpr(5): Could not compile used unit 'Unit1.pas'
  • REKLAMA
  • #5 7551867
    VeXXoN
    Poziom 10  
    Posty: 60
    Ocena: 3
    ogólnie to mam tak przerobionego gotowca ale.. wywala mi błąd po błędzie
    procedure TForm1.SortujwgZamieszkania1Click(Sender: TObject);
    
    var i,j,licznik2:integer;
    temp:string;
    Zamieszkanie:string;
    
    begin;
    licznik2:=Zamieszkanie.Count-2;
    //sortowanie metodą sortowania bąbelkowego
    for j:=0 to licznik2 do
      begin;
        for i:=0 to licznik2 do
          begin;
            if AnsiCompareText(zwierzeta[i],Zamieszkanie[i+1])>0 then
              begin
                temp:=zwierzeta[i];
                zwierzeta[i]:=zwierzeta[i+1];
                zwierzeta[i+1]:=temp;
              end;
          end;
      end;
    end;
    
  • #6 7551886
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    jeśli tablica zwierząt jest rekordem, to jak możesz to stringa ją przypisywać?
    Jak możesz porównywać stringa z literą ze stringa Zamieszkanie?
    Kompletny chaos :(
  • REKLAMA
  • #7 7551936
    VeXXoN
    Poziom 10  
    Posty: 60
    Ocena: 3
    Ops...wkleiłem to Zamieszkanie:string; przez pomyłkę to było tylko na probe czy coś zmieni normalnie tego w programie nie ma ... i tak nie działa... rekordem jest wygląda to tak jak na zdjęciu... mógłbyś mi napisać jak to ma mniej więcej wyglądać.

    Jak posortować alfabetycznie w TStringGrid w Delphi?
  • REKLAMA
  • #8 7551981
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    najpierw ustal co chcesz porównywać - jak domniemam - pole Nazwa_Gatunku rekordu tablicy zwierzęta.
    Do przenosin musisz użyć zmiennej pomocniczej o budowie identycznej jak rekord, czyli typu dane.

    oczywiście licznik (wartośc maksymalna dla pętli) powinien wskazywać na ilość elementów tablicy zwierzęta - funckja Length!
  • #9 7553110
    arnoldziq
    VIP Zasłużony dla elektroda
    Posty: 5376
    Pomógł: 789
    Ocena: 300
    A może prościej? Zamiast sortować każdą kolumnę w osobnej procedurze, użyć czegoś takiego :
    procedure SortStringGrid(var GenStrGrid: TStringGrid; ThatCol: Integer);
    const
      TheSeparator = '@';
    var
      CountItem, I, J, K, ThePosition: integer;
      MyList: TStringList;
      MyString, TempString: string;
    begin
      CountItem := GenStrGrid.RowCount;
      MyList        := TStringList.Create;
      MyList.Sorted := False;
      try
        begin
          for I := 1 to (CountItem - 1) do
            MyList.Add(GenStrGrid.Rows[I].Strings[ThatCol] + TheSeparator +
              GenStrGrid.Rows[I].Text);
          Mylist.Sort;
          for K := 1 to Mylist.Count do
          begin
            MyString := MyList.Strings[(K - 1)];
            ThePosition := Pos(TheSeparator, MyString);
            TempString  := '';
            TempString := Copy(MyString, (ThePosition + 1), Length(MyString));
            MyList.Strings[(K - 1)] := '';
            MyList.Strings[(K - 1)] := TempString;
          end;
          for J := 1 to (CountItem - 1) do
            GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)];
        end;
      finally
        MyList.Free;
      end;
    end;

    Możesz to wywołać tak :
    SortStringGrid(StringGrid1, numer_sortowanej_kolumny);
  • #10 7558113
    VeXXoN
    Poziom 10  
    Posty: 60
    Ocena: 3
    Rozwiązanie

    if zwierzeta[i].Zamieszkanie>zwierzeta[i+1].Zamieszkanie then
    
    
    na
    
    
    if AnsiCompareText(zwierzeta[i].Nazwa_Gatunku, zwierzeta[i+1].Nazwa_Gatunku) > 0 then
    


    Mozna zamknac.

Podsumowanie tematu

LABEL_AI_GENERATED
Użytkownik ma problem z sortowaniem danych alfabetycznie w komponencie TStringGrid w Delphi. Wskazuje, że sortowanie numeryczne działa poprawnie, ale nie potrafi zaimplementować sortowania alfabetycznego. Próbował użyć gotowego kodu, jednak napotkał liczne błędy kompilacji związane z typami danych i nieprawidłowym przypisaniem. Uczestnicy dyskusji sugerują użycie funkcji AnsiCompareStr do porównywania stringów oraz wskazują na konieczność użycia zmiennej pomocniczej o typie rekordu. Ostatecznie, rozwiązaniem jest zmiana warunku porównania w algorytmie sortowania, aby odnosił się do odpowiednich pól rekordu, co pozwala na poprawne sortowanie według kolumny "Nazwa_Gatunku".
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA