Results 1 to 11 of 11

Thread: hoe maak ik een adodataset/dbgrid editable?

  1. #1
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426

    hoe maak ik een adodataset/dbgrid editable?

    Hallo Allemaal,

    Bestaande applicatie in D7. Ik probeer een ADOdataset (+100000 recors) weergegeven in een dbgrid "editable" te maken om wachttijd bij het verversen na aanpassingen zo klein mogelijk te maken. dwz de updates/inserts worden als afzonderlijke sql statements naar het RDMS gestuurd en het relevante record in dataset wordt "handmatig" bijgewerkt.
    ik heb de volgende insteken geprobeerd:

    - clientdataset:

    werkt op zich (al is het editable maken van alle velden niet altijd een even vanzelfsprekend) maar de laadtijd is onaanvaardbaar lang.

    - dataset kopieeren naar een inMemory table (tvirtualdataset, tkbmmemtable):

    werkt goed wat betreft het editable maken van de velden maar het overnemen van de oorspronkelijke dataset ( in feite veld voor veld, record voor record) duurt relatief lang

    - De connection van de ADOdataset op nil te zetten en de velden expliciet op readonly=false te zetten:

    De dataset gedraagt zich dan grotendeels als een losse in memory dataset waarvan de meeste velden kunnen worden veranderd en waaraan ook records kunnen worden toegevoegd.
    Laadtijd is relatief kort , maar een deel van de velden blijft niet veranderbaar in de zin dat de velden wel zijn te veranderen maar dat de ingevulde waarden niet allenaal "persistent" zijn. Welke velden dat zijn is mede afhankelijk van de achterliggende query en het gebruikte RDMS

    de snelste optie tot nu toe

    - De ADOdataset openen, saven als XML bestand, het rowsetschema in het XML aanpassen en vervolgens de XML dataset weer laden (save/load via ADTG ipv XML is een stuk sneller maar ik weetniet hoe je de fieldsettings kan verandeen) in een ADTG bestand):

    Alles editable en de totale laadtijd is binnen aanvaardbare grenzen....maar zo'n tijdelijk tussenbestand vind ik erg onelegant.

    Al met al zou je denken dat het aanpassen van de veldeigenschappen toch ook op een minder omslachtige manier zou moeten kunnen worden gerealiseerd. Het aantal aanpasbare veld eigenschappen in een ADOdataset/ADOquery is alleen erg beperkt. Ik zie niet zo gauw hoe ik eventueel verborgen eigenschappen toegankelijk zou kunnen maken.
    De enige eigenschap die in het attributetype van het XML-veld hoeft te worden aangepast/toegevoegd om een veld editbale te maken is rs:maydefer='true' . Die eigenschap wordt meegegeven bij een export naar XML dus die zou ergens als property verstopt moeten zitten in de oorspronkelijke t(ADO)dataset. Of is dat wat kort door d bocht gedacht? iemand een idee?

  2. #2
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Honderduizend records weergeven in een DBGrid is vragen om vertraging.
    Heb je al gebruik gemaakt van Disablecontrols/Enablecontrols. Dan stop je tijdelijk de 'invoer' van de data naar de grid, omdat deze telekns na een record opnieuw wordt getekend.
    werkt goed wat betreft het editable maken van de velden maar het overnemen van de oorspronkelijke dataset ( in feite veld voor veld, record voor record) duurt relatief lang
    Dan heb je dat niet goed gedaan. Met Virtualtable.Assign(dataset) gaat dat heel snel. Maar ook hier heb je het probleem met de DBGrid.

    Waarom alle records tegelijk tonen?

  3. #3
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    ... ja ik weet dat dit soort datasets niet via een grid moet weergeven. Erger nog , het is niet alleen een erg "lange" dataset maar ook een erg "brede". Alle enable/disable opties zijn al gebruikt. Punt is dat het aanpassingen betreft aan een bestaande applicatie. De gebruikers zijn gewend aan een weergave in een grid. Ze zien dat zelfs als een noodzakelijkheid.

    De oorspronkelijke dataset zelf opent in ca. 15-20sec. tvirtualtable(assign) is daarna iets meer dan een minuut bezig met laden. Een kbmmemtable met een simpele field by field copy doet er niet zoveel langer over (vandaar het idee dat tvirtualTable ook iets dergelijks doet,verder niet echt naar gekeken). Mischien doe ik inderdaad wat fout.
    Save/load van XML bestand duurt samen ca. 10-15 seconden. Uiteindelijk een factor 3 sneller dan bij gebruik van een tVirtualtable. Het probleem zit oorspronkelijk vooral in het verversen van het grid na een recordaanpassing... dan moe(s)t de hele dataset weer worden ververst. 35 seconden laadtijd als tradeof voor een min of meer directe gridverversing daarna is aanvaardbaar... anderhalve minuut gaat een beetje wringen.

    Bijkomend voordeel van werken via een ADOdataset is dat bestaande procedures voor filteren/sorteren in het grid etc niet hoeven te worden aangepast.

    Als de write restricties van de (ado)dataset velden zouden kunnen worden aangepast is het hele kopieeren via virtual table of bestand niet meer nodig. Gezien de flexibiliteit in de door de verschillende RDMSen doorgegeven restrictiesets (zelfde query maar verschillende restricties voor Oracle, SQLserver, Jetengine en Mysql) zou je enige manipuleerbaarheid verwachten maar tot nu toe heb ik de ingang daarvoor nog niet gevonden.

  4. #4
    Quote Originally Posted by jkuiper View Post
    Honderduizend records weergeven in een DBGrid is vragen om vertraging.
    euh..niet echt. Een dbgrid met een database met 9.000.000 records is sneller geladen dan ik met mijn ogen kan knipperen. Echter waar die ado verbinding echt mee verbonden is en hoe snel die provider is dat maakt wel weer uit.

    Verder snap ik het verhaal niet helemaal. Een dbgrid is toch gewoon editable? Wat is exact het probleem? Hebben we het soms over een multi-user systeem waar ook alle wijzigingen gemaakt door andere direct zichtbaar moeten zijn voor alle andere gebruikers?

  5. #5
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    Tussen zichtbaar en geladen zit verschil. Als de dataset op AsyncFetchNonBlocking staat worden de eerste records meteen weergegeven zodra ze "binnen" zijn. Ondertussen gaat echter op de achtergrond het laden van de dataset door. Dat kan afhankelijk van de grootte dataset en het RDMS nog even duren. Dat merk je als je bv. direct na het openen van de dataset naar het laaste record wil.

    In een dbgrid zijn alleen dié velden editable die door de dataset op editable zijn gezet (of wellicht eerder anders om zijn die velden niet editable die door de dataset op niet editable zijn gezet). Een dataset die gemaakt is via een join query geeft in de meeste gevallen een gridweergave waarin de velden not updatable zijn.

    Het probleem is dat je veranderingen in een non-editable dataset alleen kan weergeven als je de hele dataset opnieuw laadt. Een langere laadtijd alleen bij het opstarten is niet erg maar als je na elke aanpassing/verandering van de gevens telkens 10 seconden moet wachten voordat de veranderingen zichtbaar zijn in het grid dan gaat dat gauw irriteren.
    Als je alleen dat deel van de dataset zou kunnen aanpassen dat werkelijk veranderd is (of is toegevoegd) dan scheelt dat een slok op een borrel

  6. #6
    Dit is niet op te lossen door in je grid maar een x aantal records te laden en telkens met een next page/previous page de gebruiker door de data heen te laten gaan? Op die manier kun je de sql resultset beperken en ook opnieuw laden indien gewenst.

  7. #7
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    ...kan standaard als je met een clientdataset een pageset gebruikt. Als je het laatste record van de ingestelde hoeveelheid records bereikt wordt de volgende set geladen. Dat laden gaat echter sequentieel.. als je een van de laatste records in je dataset hebt gewijzigd hebt moeten alle voorgaande records eerst worden afgelopen voor de verandering getoond kan worden.... toch?..of kan je opdracht geven de weergave bij een specifiek record te beginnen?

  8. #8
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    Veel geprobeerd maar niets is echt universeel genoeg om verschillende RDMSen met een enkele oplossing te bedienen... of te langzaam, of wel editable maar geen inserts mogelijk... de oplossing die eigenlijk het beste werkt is:

    - schrijf het query resultaat weg als tabel : adoconnection.execute('SELECT * INTO Temptabel from (querytekst));
    - open de Temptabel via een adodataset;
    - zet de adodataset.connection:=nil
    - adoconnection.execute('drop table temptabel');

    de tabel is nu helemaal editable, en er kan gewoon in ge-insert worden

  9. #9
    In het geval van die clientdataset. Heb je daarin al eens geprobeerd om eerst de dataset te openen, en pas daarna (in code) deze te koppelen aan een datasource? Ik kan me voorstellen dat er misschien stiekem toch wat update-berichten heen en weer gaan tijdens het laden van de data.
    1+1=b

  10. #10
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    Het komt een heel eind maar uiteindelijk blijven er een paar velden readonly
    1 grote query (union van drie subqueries met ieder 5-10 joins)
    2 uitvoeren, connection op nil, dataprovider & clientdataset aanmaken, verbinden en activeren
    3 datasource maken en koppelen aan de clientdataset
    4 velden aflopen en readonly op false zetten
    5 dataset koppelen aan het grid

    Onder de jet-engine (Access) zijn in editmode alle velden editable behalve een veld waar via de query veldwaarden zijn samengevoegd dwz. de waarde in het veld is editable maar bij een post volgt een melding 'trying to edit a readonly field'
    In InsertMode zij álle velden editable en postable ( op een disconnected set)

    Onder SQLserver gebeurt hetzelfde alleen zijn er ook een paar andere velden readonly.. ook hier is in IsertMode wel alles editable

    de clientdataset is een in memory set en het moet toch mogelijk moet zijn om een veld onafhankelijk van de oorspronkelijke dataset te editen. Ik kom er alleen niet achter welke parameters daar verder een rol bij kunnen spelen..

    overigens blijft het verbazingwekkend in hoeveel gevallen bij de genoemde query in "connected" mode de clientdataset de achterliggenede data op een juiste manier interpreteert en update

  11. #11
    Als je in je ClientDataSet de velden persistent maakt kun je daar zelf de readonly property zetten. Je kunt vervolgens alles wijzigen en opslaan. In de datasetprovider kun je de wijzigingen dan weer opvangen en zelf de queries schrijven om diverse tabellen te updaten.
    Marcel

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •