SMDBGrid gubi zaznaczone wiersze przy filtrowaniu

SMDBGrid gubi zaznaczone wiersze przy filtrowaniu
LO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

witam,

Pobieram dane z MySQL przy pomocy DBExpress. Wyświetlam dane w komponencie SMDBGrid (SimpleDataSet). Grid ustawiony jest w taki sposób aby user mógł zaznaczać wiele wierszy (dgMultiSelect i eoCheckBoxSelect) oraz dodatkowo filtrować kolumny w poszukiwaniu wierszy do zaznaczenia (eoShowFilterBar). Niestety gdy user filtruje grida z już zaznaczonymi wierszami, to zaznaczenie "nie wędruje" za wybranymi wcześniej wierszami tylko "stoi w miejscu". Efekt jest taki, że po przefiltrowaniu danych zaznaczone pozostają nowe wiersze z bieżącego widoku.

Czy macie może pomysł jak osiągnąć efekt filtrowania aby nie zgubić zaznaczonych rekordów?

WL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1084
0

Tak, mamy pomysł; tj. ja mam ;-)
Tylko nie wiem jak dokładnie działa SMDBGrid i nie chce mi się tego w ogóle tykać; z tego co opisujesz zgaduję, że ów grid trzyma indeks rekordu jako zaznaczenie - a to totalna lipa jest i będzie się tak zachowywać jak opisujesz.

LO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

czyli wiem ale nie powiem bo mi się nie chce... super :)

Odnośnie samego problemu, to wysłałem zapytanie do autora komponentu i poniżej jego odpowiedź:

Hello,

This is a bug for your database engine. This is not a bug in SMDBGrid.
In grid the selected rows is a list of bookmarks to real records in database. When filter changed your database engine returns the incorrect records for bookmarks.

This is a reason why I suggested to clear the selected rows when filter changed.

With best regards, Mike Shkolnik
E-mail: mshkolnik@scalabium.com

czyli z odpowiedzi wynika, że nie da się tego zrobić w taki sposób. tylko nie rozumiem czy nie da się tylko np. z bazą MySQL czy też z żadną.

woolfik
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1611
0

Miałem podobny problem z cxGrid i ADO:
Czy istnieje jakieś dodatkowe zabezpieczenie w ADO przed edycją danych z grida?
Rozwiązaniem było zapisane danych do TClientDataSet i potem operacja na danych w pamięci. Nie wiem jak działa ten SMDBGrid ale jeśli masz możliwość użycia np zeoslib do połączenia z bazą, a SMDBGrid dziedziczy po TDBGrid to nie powinno być problemów z rekodami z bazy - chodzi mi o ten wpis:

filter changed your database engine returns the incorrect records

WL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1084
0

@Lookze nie myślałem, że Mike Shkolnik będzie pisał takie bzdury... zakładki (bookmarks) nie mają nic a nic wspólnego z "database engine" i są w całości zarządzane przez TDataSet.
A więc nie jest to błąd w Twoim Database Engine, a problem polega na tym jak ów SMDBGrid korzysta z tych bookmarków.
A korzysta z nich źle, zapisują jako zaznaczenie wiersza w gridzie bookmark rekordu, który nie istnieje bo go odfiltrowałeś.
Możesz to zrobić ręcznie, ale będziesz musiał sam to zrobić przez:

  • Przed nałożeniem filtru zapamiętaj listę bookmarków, które są zaznaczeniem w gridzie - powinna być do tego odpowiednia metoda (SelectedRows czy jakoś tak)
  • Czyścisz zaznaczenie w gridzie
  • Nakładasz filtr na TDataSet
  • Sprawdzasz czy zapamiętane bookmarki są dalej ważne
  • Jeśli dany bookmark jest Valid, to zaznaczasz ten wiersz w gridzie z poziomu kodu
    i tyle.

@woolfik To nie jest podobny problem, to jest zupełnie inny problem i dotyczy zupełnie innej warstwy. I nie, wcale nie musiałeś przepisywać danych do TClientDataSet, a mogłeś rozwiązać ten problem inaczej i lepiej.
A tezy zawarte w tym wątku w ogóle są.... ciekawe ;-) Tam jest sporo racji, ale nie wszystko jest prawdą. Np,. to że "W przypadku wielojoinowych zapytań ADO sobie z tym nie radzi" to nieprawda. ADO nie radzi sobie z automatu, ale można to obsłużyć przez obsługę odpowiedniego zdarzenia.
No i oczywiście lepiej by było użyć czegoś innego niż ADO, a jeśli ADO to tego:
http://cc.embarcadero.com/item/15727

  • Rejestracja: dni
  • Ostatnio: dni
0

@wolfik: Czytałem wątek, do którego się tu odwołujesz. Niestety Twój opis jest dla mnie mało zrozumiały. Ale jeśli chcesz edytować dane z TADODataSet tak, aby odbywało sie to bez kontaktu (konfliktu?) z bazą (a tak można zrozumieć Twój opis) to jest to w miarę proste. Poniższy przykład piszę z palca - czyli mogą być błędy. Tak tylko dla zrozumienia

Kopiuj
procedure TForm1.GetDataForGrid(dataset: TADODataSet; Connection: TADOConnection; grid: TDBGrid);
begin
  dataset.LockType := ltBatchOptimistic;
  dataset.Connection := Connection;
  dataset.Active := true;
  dataset.Connection := nil;
  grid.datasource.dataset := dataset; // i tu już mamy w gridzie dane i jesteśmy odcięci od bazy 

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.