CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Sortowanie ListView skojarzonego z dodatkową tablicą

Sortowanie ListView skojarzonego z dodatkową tablicą

dział ogólny

Sortowanie ListView skojarzonego z dodatkową tablicą

Nowy postprzez woj117 » wtorek, 10 lipca 2012, 21:29

Witam,
mam następujący problem. Wypełniam obiekt ListView danymi pobieranymi z bazy danych. Oprócz tego co jest prowadzane do ListView, są do dodatkowej tablicy pobierane indeksy wczytywanych do ListView rekordów.
KOD cpp:     UKRYJ  
        iRows={ilość rekordów};
        wordL=new int[iRows+1];
        wordL[0]=iRows;

        for (int fd = 0; fd < iRows; fd++)
        {

                {baza danych}.setRow(fd);
                List = ListF->Items->Add();
                List->Caption={baza danych}.fieldValue("Pole 1");
                List->SubItems->Add({baza danych}.fieldValue("Pole 2"));
                wordL[fd+1]={baza danych}.fieldValue("idRec");
        }


Teraz zależy mi na tym aby podczas sortowania ListView elementy z tablicy indeksów wordL także odpowiednio zmieniły miejsce. Tzn, jeżeli trzeci element ListView zostanie zamieniony w wyniku sortowania z np. pierwszym to aby wordL[3] zamienił się miejscami z wordL[1].
Próbowałem to osiągnąć porzez dodanie paru linii kodu do procedury sortowania ListView, ale to niestety nie działa (użycie ...->Index+1 wiąże sie z tym że w elemencie wordL[0] przechowuję ilość elementów tablicy.

KOD cpp:     UKRYJ  
void __fastcall TFZestawyFiszek::ListMagazynCompare(TObject *Sender,
          TListItem *Item1, TListItem *Item2, int Data, int &Compare)
{
        int iTemp;
        if(((TListView *)Sender)->Tag == 0)
        {
                Compare = CompareText(Item1->Caption, Item2->Caption);

        }
        else
        {
                int c = ((TListView *)Sender)->Tag - 1;
                Compare = CompareText(Item1->SubItems->Strings[c], Item2->SubItems->Strings[c]);
        }

        if (Compare < 0 && Data == 1)
        {
                iTemp=wordL[Item1->Index+1];
                wordL[Item1->Index+1]=wordL[Item2->Index+1];
                wordL[Item2->Index+1]=iTemp;
        } else
        if (Compare>0 && Data == 0)
        {
                iTemp=wordL[Item2->Index+1];
                wordL[Item2->Index+1]=wordL[Item1->Index+1];
                wordL[Item1->Index+1]=iTemp;
        }

        if(Data == 1) Compare = -Compare;
}


Czy ktoś ma jakiś pomysł jak to poprawnie zaimplementować?
Avatar użytkownika
woj117
Bladawiec
Bladawiec
 
Posty: 4
Dołączył(a): wtorek, 10 lipca 2012, 20:55
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: brak kompilatora
Gadu Gadu: 0
    Windows 7Firefox

Re: Sortowanie ListView skojarzonego z dodatkową tablicą

Nowy postprzez Cyfrowy Baron » wtorek, 10 lipca 2012, 22:11

Takie sortowanie jest możliwe tylko poprzez porównanie rekordów, czyli do tej dodatkowej tablicy musisz wprowadzić to samo co do tablicy ListView, a potem po posortowaniu ListView posortować dodatkową tablicę w pętli sprawdzając jej zawartość i porównując z zawartością ListView.

Ewentualnie:
Jeżeli dodatkowa tablica zawiera tylko indeksy to ListView również musi te indeksy zawierać, wtedy przy sortowaniu ListView będziesz mógł poprzez porównanie zawartości ListView z dodatkowa tablicą poukładać w tej drugiej rekordy w tej samej kolejności co w ListView.

Jeżeli ListView zawiera jedno, a dodatkowa tablica drugie i obie tablice nie mają wspólnych wartości, to nie istnieje żaden punkt odniesienia, który pozwalałby połączyć te listy ze sobą. Jedyna możliwość to stworzenia trzeciej listy pośredniczącej, która będzie zawierała elementy wspólne obydwu tablic i pozwoli je posortować tak samo poprzez porównanie tych rekordów.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie ListView skojarzonego z dodatkową tablicą

Nowy postprzez woj117 » środa, 11 lipca 2012, 12:57

ok, ale czy aby na pewno zostałem dobrze zrozumiany: ja nie chcę sortować tablicy wordL, tylko pozamieniać miejscami elementy zgodnie z wynikiem sortowania ListView.
W jaki sposób Builder sortuje elementy? Co się dzieje po określeniu wartości Compare i zakończeniu procedury (w moim przypadku) ListMagazynCompare?

Pozdrawiam
Wojciech W
Avatar użytkownika
woj117
Bladawiec
Bladawiec
 
Posty: 4
Dołączył(a): wtorek, 10 lipca 2012, 20:55
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: brak kompilatora
Gadu Gadu: 0
    Windows XPChrome

Re: Sortowanie ListView skojarzonego z dodatkową tablicą

Nowy postprzez Cyfrowy Baron » środa, 11 lipca 2012, 13:03

Nie jest ważne co i jak sortujesz. Jeżeli masz dwie listy, z których każda zawiera inny zestaw rekordów i listynie są ze sobą w żaden sposób połączone, to poprzez brak między nimi jakiegokolwiek związku nie możesz ich posortować w ataki sposób, by sortowanie rekordów jednej listy dało taki sam wynik w drugiej. No bo jak te listy miałyby się między sobą wymienić informacje co i jak ma być posortowane.

Być może rzeczywiście źle Ciebie rozumiem. Pokaż więc przykład zawartości tych dwóch. Co zawiera jedna lista a co druga i jak każda z nich powinna wyglądać po posortowaniu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie ListView skojarzonego z dodatkową tablicą

Nowy postprzez woj117 » środa, 11 lipca 2012, 14:08

Oczywiście ListView i tablica wordL choć zawierają dane pochodzące z jednej tablicy bazy danych, nie są jednak za sobą połaczone, ale sortująć elementy ListView powinno być wiadomo jak zmieniają się miejscami sortowane wiersze, i np. jeśli wiersz 3 (w ListView) w wyniku sortowania zamienia się miejcami z wierszem 2 to na tej podstawie powinno być możliwa analogiczna zamiana w tablicy wordL. Stąd moje drugie pytanie jak na podstawie wartości Compare są sortowane wiersze w ListView?

Pozdrawiam
Wojtek W.
Avatar użytkownika
woj117
Bladawiec
Bladawiec
 
Posty: 4
Dołączył(a): wtorek, 10 lipca 2012, 20:55
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: brak kompilatora
Gadu Gadu: 0
    Windows XPChrome

Re: Sortowanie ListView skojarzonego z dodatkową tablicą

Nowy postprzez Cyfrowy Baron » środa, 11 lipca 2012, 16:14

woj117 napisał(a):jeśli wiersz 3 (w ListView) w wyniku sortowania zamienia się miejcami z wierszem 2 to na tej podstawie powinno być możliwa analogiczna zamiana w tablicy wordL.


Owszem, ale gdzie ta informacja o tym jak zmieniła się kolejność elementów na liście jest przechowywana, bo na pewno ListView podczas sortowania nie przechowuje takich informacji. Lista sortuje elementy według zadanego klucza i tylko przestawia je miejscami, ale nigdzie nie zachowuje informacji o tym jak pierwotnie były rozmieszone elementy ani jak się pozmieniały. Obiekt również nie wysyła nigdzie tych informacji w żadnym zdarzeniu, dlatego nie ma nic co mógłbyś przekazać z jednej listy do drugiej. Sortowanie odbywa się poprzez porównanie dwóch elementów i tak aż wszystkie elementy zostaną porównane.

Co do Compare to po prostu porównywane są dwa elementy. Przykłady sortowanie dynamicznego, czyli chyba jednego z najbardziej wydajnych znajdziesz tutaj: http://programowanie.cal.pl/cyfbar/listbox.html#listbox7. Zauważysz tam, że porównywane są tylko dwa elementy, i informacja o tym gdzie się pierwotnie znajdowały i jak zmieniły miejsce nigdzie nie jest przechowywana. Konieczność przechowywania takich informacji znacząco wydłużyłaby sam czas sortowania.

Jedyne co możesz zrobić, to przypisać elementom obydwu list numery, czyli każdy wiersz ma własny numer, który zmienia miejsce wraz z sortowaniem listy, wtedy wystarczy wiersz po wierszu z pierwszej listy sprawdzać jaki ten wiersz miał numer pierwotnie i jaki numer ma teraz. Potem w drugiej liście wystarczy te numery poustawiać w ten sam sposób. Tyle, że to wystarczy tylko na pierwsze sortowanie, potem numery już nie będą miały znaczenia, dlatego po zsynchronizowaniu obydwu list, należy znów tym wierszom w obydwu listach przypisać kolejne numery.

Zdarzenie OnCompare obiektu TListView dotyczy sortowania elementów tego obiektu, a konkretnie porównywania Item1 z Item2, czyli kolumn tej listy. Przydaje się tylko wtedy gdy elementy listy muszą być porównywane w czasie sortowania tej listy, ale dwa elementy z tego samego wiersza, lecz z sąsiednich kolumn. Na nic się nie przyda, gdyż przy pomocy tego zdarzenia nie da się nawet zsynchronizować dwóch listy typu TListView. To zdarzenie masz dość dobrze opisane w pliku pomocy.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sortowanie ListView skojarzonego z dodatkową tablicą

Nowy postprzez woj117 » czwartek, 12 lipca 2012, 12:14

A więc skorzystałem z nieoczekiwanie prostego, ale nie jestem pewny czy prawidłowego rozwiązania.
Dodałem tylko dwie kolumny do obiektu ListColumn, ale aż 2 elementy SubItem do obiektu ListItem. Wszystko się elegancko sortuje, a dodatkowe
elementy nie są wyświetlane w ListView:
KOD cpp:     UKRYJ  
TListColumn *ListCol;
ListCol = ListView1->Columns->Add();
    ListCol->Caption = "Pole 1";
ListCol = ListView1->Columns->Add();
    ListCol->Caption = "Pole 2";

TListItem *List;
List = ListF->Items->Add();
List->Caption={baza danych}.fieldValue("Pole 1");
List->SubItems->Add({baza danych}.fieldValue("Pole 2"));
List->SubItems->Add({baza danych}.fieldValue("idRec"));
 

Pozdrawiam
Wojciech W.
Avatar użytkownika
woj117
Bladawiec
Bladawiec
 
Posty: 4
Dołączył(a): wtorek, 10 lipca 2012, 20:55
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: brak systemu
Kompilator: brak kompilatora
Gadu Gadu: 0
    Windows XPChrome


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 46 gości

cron