Ładowanie danych z dataset do VirtualStringTree

0

Witam,

mam pytanie, w jaki sposób (nie pytam czy się da, bo wszystko się da) chcąc zamienić komponent typu DBGrid na VirtualStringTree obsłużyć ładowanie danych, mając zapytanie

select * from dupa_maryny

które zwraca przykładowo 30 000 rekordów?

Wiadomo, że grid ładuje tyle rekordów ile jest w stanie wyświetlić, a kolejne są wczytywane na OnScroll. Pytanie za milion punktów, jak ma się ta zasada do VirtualStringTree, aby odzwierciedlał dokładnie to samo zadanie uwzględniając jego virtualizację?

Czy ktoś ma z tym jakieś doświadczenie? Mam nadzieję, że pętla

while not dataset eof

po 30 000 rekordach nie jest jedynym rozwiązaniem.

dodanie znacznika <code class="sql"> i tagu Delphi - furious programming

2
  1. jeśli wyświetlasz userowi 30 000 rekordów to masz błąd na etapie projektowania.
  2. jeśli już bardzo chcesz wyświetlić mu te 30 000 rekordów od razu to to MUSI trwać (trwa nie samo dodawanie ich do VTV ale odczyt z bazy)
  3. jeśli chcesz wszystkie rekordy pokazać w VTV to musisz przejść przez wszystkie rekordy. Czy zrobisz to w pętli while not DataSet.EoF do czy przypiszesz VTV.RootNodeCount := Ilosc_rekordow i potem będziesz w OnInitNode przechodził do następnego rekordu to twoja decyzja.
  4. jeśli chcesz ładować po kawałku to sobie musisz sam zrealizować takie przepisywanie do VTV
0
  1. jeśli wyświetlasz userowi 30 000 rekordów to masz błąd na etapie projektowania.
  • Nie zgodzę się z Tobą, co jeśli masz bazę w chmurze i użytkownik wchodzi w selekcję danych w której wybiera sobie, że chce wyszukać zakres dokumentów od 2014-01-01 do 2014-12-31 żeby wydrukować zestawienie z wyszukanych danych i tak się składa, że nazbierało się tam sporo tyś. rekordów.
  1. jeśli chcesz ładować po kawałku to sobie musisz sam zrealizować takie przepisywanie do VTV
  • Własnie dlatego napisałem ten post, z myślą, że ktoś miał już podobne doświadczenie z tym i to jakoś oprogramował.

Czuję, że pozostaje mi póki co, lecieć po wszystkich rekordach, co raczej nie wchodzi w grę.

0
  1. jeśli to jest zestawienie to po co to ładować do VTV zamiast dać podgląd wydruku i/lub wydrukować?
  2. kiedyś się zastanawiałem nad podobnym dylematem (pisałem własną kontrolkę do automatycznego ładowania danych do VTV na podstawie pliku z definicją źródła danych, wyglądu i zachowania VTV, ale to opowieść na inny czas) i doszedłem do wniosku, że nie warto sobie głowy zawracać. Tylko, że ja mam zbiory po maksymalnie parę set rekordów (a to i tak wyjątki)
0
user322 napisał(a):

Witam,

mam pytanie, w jaki sposób (nie pytam czy się da, bo wszystko się da) chcąc zamienić komponent typu DBGrid na VirtualStringTree obsłużyć ładowanie danych, mając zapytanie select * from dupa_maryny, które zwraca przykładowo 30 000 rekordów?

Konkret - jaka baza danych i jakie komponenty do jej obsługi?
Przykładowo; FireDAC (i AnyDAC w wersji min. 6.x, o ile dobrze pamiętam) załatwia takie coś od ręki dla komponentu TFDTable.
Poczytaj o Live Data Window

Wiadomo, że grid ładuje tyle rekordów ile jest w stanie wyświetlić, a kolejne są wczytywane na OnScroll.

W OnScroll?
A możesz podać źródło tych rewelacji?

Pytanie za milion punktów, jak ma się ta zasada do VirtualStringTree, aby odzwierciedlał dokładnie to samo zadanie uwzględniając jego virtualizację?

Trzeba o zrealizować tak samo, czyli obsłużyć odpowiednie zdarzenia i napisać DataReader danych z bazy, ale w ten sposób aby wczytywał dane po kawałkach.

Czy ktoś ma z tym jakieś doświadczenie? Mam nadzieję, że pętla

while not dataset eof

po 30 000 rekordach nie jest jedynym rozwiązaniem.

Ktoś pewnie ma (Zauważ, że przy tej ilości danych to nie tylko czas ładowania jest wąskim gardłem, ale i dostępna pamięć - po prostu może się skończyć, ponieważ TDataSet trzyma wszystkie pobrane dane w pamięci.), ale nie chce mi się pisać gotowca od początku.
Zatem jak mi przygotujesz projekt (taki proof-of-concept) który:

  1. Posiada bazę danych, może być np. baza MSSQL, Firebird, SQLite z wypełnionymi danymi dla rzeczonej tabeli.
  2. Projekt w Delphi, który łączy się do tej bazy za pomocą "normalnych" (najlepiej to co jest na pokładzie, a więc IBX, dbGO, DBExpress, FireDAC) komponentów.
  3. Ładuje dane do wymaganej kontrolki.

To postaram się napisać prezentację rozwiązania Twojego problemu.

0

@wloochacz

W OnScroll?
A możesz podać źródło tych rewelacji?

Mając grida podłączonego do źródła TDatasource i robiąc zapytanie select * from dupa_maryny gdzie liczba rekordów wynosi 30 000, dataset poradzi sobie z tym zapytaniem w mniej niz sekundę i wyświetli tyle rekordów ile mieści się na gridzie. Natomiast, jeżeli przewiniesz suwakiem Grida do krawędzi dolnej, wówczas zaczytuje wszystkie dane aż do EOF. Jeżeli scrollujesz klikając na strzałki, dane doczytywane są na bieżąco.

Oczywiście zgadzam się, że ciężko będzie wyświetlić wszystkie 30 000 rekordów, bo na 99% skończy się to Out of memory, ale metoda "doczytywania" danych spełniłaby tutaj swoją rolę.
Tutaj akurat chodzi o silnik Firebird komponenty IBDataset.

Bazę i programik postaram się przygotować.

0
user322 napisał(a):

@wloochacz

W OnScroll?
A możesz podać źródło tych rewelacji?

Mając grida podłączonego do źródła TDatasource i robiąc zapytanie select * from dupa_maryny gdzie liczba rekordów wynosi 30 000, dataset poradzi sobie z tym zapytaniem w mniej niz sekundę i wyświetli tyle rekordów ile mieści się na gridzie. Natomiast, jeżeli przewiniesz suwakiem Grida do krawędzi dolnej, wówczas zaczytuje wszystkie dane aż do EOF. Jeżeli scrollujesz klikając na strzałki, dane doczytywane są na bieżąco.

Wiesz... ja wiem jak to działa i ładnie nam tu opisałeś swoje obserwacje, a chodzi o to, że działa o ciut inaczej - ale nieważne.

Oczywiście zgadzam się, że ciężko będzie wyświetlić wszystkie 30 000 rekordów, bo na 99% skończy się to Out of memory, ale metoda "doczytywania" danych spełniłaby tutaj swoją rolę.

Eeee... nie dopatrzyłem - 30K to jest pryszcz (aczkolwiek zależy co w tych danych jest i ile jest pól/typy danych/dane/itd.), myślałem, że chodzi o 300K albo o 3 mln rekordów...
30K to mi się do grida ładuje w ok. sekundę ;-)
Pamiętaj o tym, aby nie ładować BLOBów (zdjęcia, duże opisy, dane binarne itd.) do grida w tak dużym zestawie danych. poza tym to nie ma sensu (w standardowym TDBGrid) bo i tak takich danych nie wyświetlisz.

Tutaj akurat chodzi o silnik Firebird komponenty IBDataset.
Bazę i programik postaram się przygotować.

OK, czekam.
Ale pamiętaj, aby w programie przykładowym dane ładować do VirtualStringTree a nie do DBGrida!

0

aczkolwiek zależy co w tych danych jest i ile jest pól/typy danych/dane/itd.

Te dane to przeważnie stringi i integery.

30K to mi się do grida ładuje w ok. sekundę

Weź pod uwagę to, że grid ma obsłużone zdarzenia OnCellPain - wiersz wypełniany jest kolorem w zależności od danych w kolumnie np. STATUS = 'OPŁACONE' (zielony); STATUS = 'NIEOPŁACONE' (czerwony) itp. w gridzie malowanie strasznie zjada pamięć, to jest też m.in powód, dla którego chcę przejść na virtuala. Dodatkowo na uwzględnieniu trzeba mieć słabsze komputery, na których aplikacja będzie uruchamiana (a tak właśnie jest, bo program działa u różnych klientów, na różnych komputerach).

(w standardowym TDBGrid) bo i tak takich danych nie wyświetlisz.

Używam XDBGrid.

0
user322 napisał(a):

aczkolwiek zależy co w tych danych jest i ile jest pól/typy danych/dane/itd.

Te dane to przeważnie stringi i integery.

30K to mi się do grida ładuje w ok. sekundę

Weź pod uwagę to, że grid ma obsłużone zdarzenia OnCellPain - wiersz wypełniany jest kolorem w zależności od danych w kolumnie np. STATUS = 'OPŁACONE' (zielony); STATUS = 'NIEOPŁACONE' (czerwony)

No i co z tego? Wystaw sobie, że ja takie rzeczy robię z dynamicznym obliczaniem warunków dla wiersza przez co uzyskuje efekt analogiczny do Excelowego formatowania warunkowego.
Różnica taka, że user może sam sobie ustawić warunki i styl wyróżniania danych. I jakoś nie mam problemów wydajnościowych, a narzut w stosunku do zwykłego sprawdzenia warunku i zmiany kolory czcionki/tła jest znacznie większy.

itp. w gridzie malowanie strasznie zjada pamięć, to jest też m.in powód, dla którego chcę przejść na virtuala. Dodatkowo na uwzględnieniu trzeba mieć słabsze komputery, na których aplikacja będzie uruchamiana (a tak właśnie jest, bo program działa u różnych klientów, na różnych komputerach).

To bez znaczenia, a jak Ci "w gridzie malowanie strasznie zjada pamięć" to po prostu coś spartoliłeś i tyle - albo kontrolka partoli...
Malowane są tylko te wiersze, które są widoczne. po drugie - oczywiście przez operacjami typu otwieranie danych, odświeżanie, filtrowanie, wyszukiwanie (locate) włączasz DataSet.DisableControls?
Chodzi o taką konstrukcję:

  DataSet.DisableControls;
  try
    DataSet.CloseOpen;  
  finally
    DataSet.EnableControls;
  end;

Jeśli tego nie robisz, to czym prędzej zacznij.
Sprawdź wyniki i zamelduj o efektywności poprawek - ile będzie x szybciej? Tak na oko, to ze 4...

(w standardowym TDBGrid) bo i tak takich danych nie wyświetlisz.

Używam XDBGrid.

OK, ale ja go nie używam i instalować dema nie będę. Tak więc użyj zwykłego DBGrida, albo z DevExpress Quantum Grid, bo to mój podstawowy ;-)

0

DataSet.DisableControls;
try
DataSet.CloseOpen;
finally
DataSet.EnableControls;
end;

Oczywiście, że używam, różnica jest zauważalna, ale nie zmienia to faktu, że zjada pamięć im więcej rekordów wczytam i wyświetlę tym więcej zjada ale mniejsza o to.

OK, ale ja go nie używam i instalować dema nie będę. Tak więc użyj zwykłego DBGrida, albo z DevExpress Quantum Grid, bo to mój podstawowy
Grida nie użyję, miałem użyć VST i pętlę

while not

zgadza się?

0
user322 napisał(a):

DataSet.DisableControls;
try
DataSet.CloseOpen;
finally
DataSet.EnableControls;
end;

Oczywiście, że używam, różnica jest zauważalna, ale nie zmienia to faktu, że zjada pamięć im więcej rekordów wczytam i wyświetlę tym więcej zjada ale mniejsza o to.

Eeee... to niemożliwe, albo czegoś nie zwalniasz - albo kontrolka.

OK, ale ja go nie używam i instalować dema nie będę. Tak więc użyj zwykłego DBGrida, albo z DevExpress Quantum Grid, bo to mój podstawowy
Grida nie użyję, miałem użyć VST i pętlę

while not

zgadza się?

Zgadza się.

1 użytkowników online, w tym zalogowanych: 0, gości: 1