TClientDataSet Access V. nie można pobrać danych

0

Witam,

Jako że ClientDataSet jest głównie używany w Delphi ten dział jest bardziej właściwy do zadania mojego pytania.

Chciałem użyć TClientDataSet ale na samym początku pojawił się problem. Jak tylko dochodzi do wyświetlania w dbgridzie wierszy to sypie Accessem.

  1. Na formie mam ADOConnection, ADOQuery (prosty select * from table), datasource i grida. Wyświetla ładnie rekordy.
  2. Dodałem DataSetProvider, ClientDataSet oraz dodatkowego grida i datasource.
  3. Ustawiam Active w ClientDataSet na true i ładnie powinno pobrać wiersze poprzez providera z ADOQuery i wyświetlić w drugim gridzie. W międzyczasie powinienem nawet zobaczyć że ADOQuery stał się aktywny i w pierwszym gridzie powinny być też widoczne wiersze. I tak się dzieje, pierwszy grid wyświetla wiersze a jak dochodzi do wyświetlenia wierszy w drugim to Access V. i koniec.

Ktoś wie o co chodzi? Zero kodu, podpięte po prostu kontrolki. ClientDataSet ma pobrane wiersze ale nie można ich czytać:

Zdarzenia:

1. ClientDataSet BeforeOpen
2. Query BeforeOpen
3. Query AfterOpen
4. Provider GetData -> RecordCount = 6 czyli sa wiersze pobrane
5. ClientDataSet AfterOpen

Jak przychodzi wyświetlić w dbgridzie Access. Jak odepnę datasource do którego grid jest podpięty to jest ok ale jak wówczas dodałem kod by pobrać cokolwiek to Access:

int count = ClientDataSet->RecordCount; // 6 wierszy
ClientDataSet->First();
AnsiString text = ClientDataSet->FieldByName("name")->AsString; //Access V.

Czy ktoś wie o co chodzi albo ma jakiś przykładowy kod?

PS IDE Borland C++ Builder 6.0 / Delphi

0

nie wiem czy dobrze zrozumiałem, masz dwa ClientDatasety ale jedno ADOQuery ?
Jeśli oba datasety pobierają dane z tego samego query, to w tym masz przyczynę wyjątku.


EDT. To chyba zły trop, zrobiłem prosty test pod Delphi i działa

0

Nie, standardowo ADOQuery -> TDataSetProvider -> TClientDataSet -> TDataSource -> TDBGrid

Dane są pobrane, jak sprawdzam ilość wierszy w ClientDataSet to pokazuje 6, ale jak próbuję pobrać cokolwiek to bumm. <- to mogłem sprawdzić dopiero jak odpiąłem TDataSource tak że grid nie był użyty.
Jak były połączone wszystkie komponenty sypie się na próbie pobrania i wyświetlenia wierszy w gridzie. Zero kodu w tym przypadku.

Analogicznie testowałem ADOQuery -> TDataSource -> TDBGrid i wszystko ok.

Przetestowałem teraz nie w run time ale design time.

  1. Connection połączył się z bazą
  2. ADOQuery ustawione na Active ładnie
  3. DataSetProvider ustawiony na ADOQuery
  4. ClientDataSet ustawione na Active ładnie
  5. I tu ciekawe - jak tylko DataSource ustawie na ClientDataSet to bum, mój borland wyparował hahaha włączyłem znów, te same kroki i to samo, borland pada i znika :)
0

Sprawdz czy field jest dostępny: pseudokod

if ClientDataSet.Fields.FindField('nazwa') <> nil then ...

Bo może rekordy masz, ale kto wie jaki bałagan w strukturze tego dataseta.
Poza tym, pobieżnie patrząc to nie widze sensu do tego celu stosowac Clientdataseta, uzyj kolejnego ADOQuery.

0

Z tego co rozumiem to po połączeniu z innym źródłem danych jak ADOQuery czy ADOTable ClientDataSet pobiera strukturę i nie trzeba ręcznie tworzyć pól ani wywoływać metody CreateDataSet.

PS 1: Provider -> GetData pokazuje RecordCount 6 ale FindField nie znajduje żadnego pola

PS 2: Tu się bawię tylko testowo więc przykład trywialny ale zależy mi na użyciu ClientDataSet-a ze względu na kilka dobrodziejstw które daje, edycja wierszy lokalnie i jednorazowy zapis po ApplyChanges albo anulowanie zmian, itd

PS 3: Czy da się z ClientDataSet pobrać na starcie wiersze z tabeli a dalej otrzymywać tylko zmiany w tabeli (insert/update/delete) jako eventy? Bez odświeżania i pobierania całego dataseta cyklicznie z użyciem jakiegoś timera i odświeżania widocznych list? Pobieram dane, ktoś robi updata i automatycznie i natychmiastowo event jest wysłany do providera i dataseta. User zobaczy tylko zmianę jednego wiersza na liście a nie przeładowaną całą listę. Czy muszę to ręcznie robić?

PS 4: Po dodaniu do ClientDataSet pól (przez edytora, dodaj wszystkie), Provider -> GetData znajdujepole (FindField) ale próba pobrania wartości daje A.V.

PS 5: Czy ma to może jakiś związek z midas.dll?

0
yabolik napisał(a):

PS 2: Tu się bawię tylko testowo więc przykład trywialny ale zależy mi na użyciu ClientDataSet-a ze względu na kilka dobrodziejstw które daje, edycja wierszy lokalnie i jednorazowy zapis po ApplyChanges albo anulowanie zmian, itd

Od dokumentacji zacznij, a dokładnie poczytaj sobie o CachedUdpates dla "normalnych" DataSetów, a dla ADO o Batch Updates.
Wszystko o czym piszesz jest dostępne od razu, bez potrzeby angażowania pośrednika w stylu CDS.

W ADO z kursorem po stronie klienta masz również filtrowanie i sortowanie po stronie klienta - identycznie jak w CDS.
A tak w ogóle, to jeśli możesz, to zamiast ADO wybierz coś innego - FireDAC, UniDAC, itp.
Tam jest lepiej, szybciej, nowocześniej i w ogóle...

A co do problemu; działa Ci to z innymi komponentami niż ADO?
Jeżeli tak, to pokaż jak masz ustawione to ADOQuery - nie masz czasem tam CursorType = ctOpenForwardOnly?
Ale to i tak powinien być wyjątek, a nie wylot w kosmos :/

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