AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi RecordCount synchronisieren zwischen ibQuery und ibtable
Thema durchsuchen
Ansicht
Themen-Optionen

RecordCount synchronisieren zwischen ibQuery und ibtable

Ein Thema von Darkchild · begonnen am 28. Nov 2006 · letzter Beitrag vom 29. Nov 2006
Antwort Antwort
Darkchild

Registriert seit: 13. Okt 2006
Ort: NRW
169 Beiträge
 
Delphi 2006 Enterprise
 
#1

RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 28. Nov 2006, 14:43
Datenbank: Firebird • Version: 1.5 • Zugriff über: Interbase
Hallöle,

ich habe da mal wieder ein Problem, wie so oft, leider .

folgendes:
Ich habe eine Maske mit einem cxdbgrid, die Daten welche ich dort Anzeige werden mir von meiner IBQuery (ibqueryzeiterfassungansicht) geliefert.
Jetzt ist es über das cxdbGrid möglich verschiedene Filter auf die Datensätze anzuwenden und eine dementsprechende Auswahl an verschiedenen Datensätzen Anzeigen zu lassen.
Jetzt möchte ich einen Count auf diese Datensätze Anwenden um zu wissen wieviele Datensetzte vor dem Filter oder auch danach jetzt noch zu sehen sind.
Denn mit diesem Ergebniss ist es geplant dann später einen weiteren durlauf durch die Datensätze zu machen und in einem Feld in der IBTable einen Wert zu schreiben (wäre das Feld gesperrt welches dann denn Wert 1 bekommen würde).
Jetzt sollen aber diese die Werte in die Table geschrieben werden und nicht in die Query, das bedeutet ich muss beide miteinander synchronisieren und genau das will mir nicht gelingen.

Nur auf der Table einen Count durchzuführen geht ohne Probs, habe ich wie folgt gemacht:
Delphi-Quellcode:
procedure Tfrmzeiterfassunguebersicht.cxbtndatensperrenClick(Sender: TObject);
var
counterrecord:integer;
begin
DataModuleMain.datasourcezeiterfassung.DataSet.First;
    while not DataModuleMain.ibtablezeiterfassung.Eof do
      begin
      counterrecord := DataModuleMain.ibtablezeiterfassung.RecordCount;
      DataModuleMain.ibtablezeiterfassung.Next;
      end;
ShowMessage(inttostr(counterrecord));
end;
Der obengezeigte Quellcode Funktioniert auch, nur das er immer alle Datensätze aus der Table nimmt und natürlich nicht die gefilterten wie im cxdbGrid zu sehen welche aus der Query kommen.

Habe dann Probiert die ganze Geschichte zu synchronisieren und zwar so:
Delphi-Quellcode:
DataModuleMain.dsqueryzeiterfassungsansicht.DataSet.First;
    while not DataModuleMain.ibqueryzeiterfassungansicht.Eof do
      begin
      DataModuleMain.ibqueryzeiterfassungansicht.Locate('zeiterfassung_id', DataModuleMain.ibtablezeiterfassungZEITERFASSUNG_ID.value,[]);
      counterrecord := DataModuleMain.ibtablezeiterfassung.RecordCount;
      DataModuleMain.ibqueryzeiterfassungansicht.LocateNext('zeiterfassung_id', DataModuleMain.ibtablezeiterfassungZEITERFASSUNG_ID.value,[]);
      DataModuleMain.ibtablezeiterfassung.Next;
      end;
ShowMessage(inttostr(counterrecord));
Habe dann mal das eine Locat und dann das andere auskommentiert aber das ergebniss war stets das selbe und zwar wenn ich im Debugger mit dem gesetzten haltepunkt die sache durchlaufe und immer brav F8 drücke läuft er durch und zählt(weiss zwar nicht ob er das dann so macht wie ich möchte , aber er zählt erstmal) ist der Haltepunkt weg und die Anwendung läuft normal und ich Starte die Geschichte, dann hängt sich die Anwendung gnadenlos weg und ich muss schauen das ich diese per TaskManager beende oder irgendwie anders daraus komme.

Hat jemand schonmal ähnliches versucht und weiss wie es geht oder hat einen Tipp oder, oder oder.... ?
Denn ich habe im Moment leider keine Idee was ich dort anders machen muss.

Über ein wenig Hilfe würde ich mich wie immer sehr freuen.

Gruss
Darkchild
Ich bin der Geist der stets verneint und das mit recht, denn alles was entsteht ist wert das es zugrunde geht, drum besser wär das nichts entstünde, so ist denn alles was ihr Sünde, Zerstörung, kurz das Böse nennt, mein eigendliches Element.
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.351 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 28. Nov 2006, 15:26
Hi Darkchild,

oh oh - dein Code...

Also erst mal folgendes.
In deinem ersten Codeschnipsel läßt du dir in einer Schleife immer wieder den selben Wert geben.

Warum den Wert 10000 mal holen, nur weil 10000 Records da sind. Das tut es auch:
Delphi-Quellcode:
procedure Tfrmzeiterfassunguebersicht.cxbtndatensperrenClick(Sender: TObject);
begin
  ShowMessage(inttostr(cDataModuleMain.ibtablezeiterfassung.RecordCount));
end;
Jetzt zur TcxGrid.
Diese kennt 2 Modi, und die sind sehr wichtig!
GridMode := True und GridMode := False.
Ohne GridMode (Standard) lädt die Grid alle Records aus der DB in einen eigenen Speicher und filtert, sortiert, gruppiert etc. mit den eigenen Daten.
In diesem Mode ist Alles einfach und Alles möglich. (Gruppierung, Summierung etc.)
Der Nachteil ist, dass der Server mächtig zu tun bekommt, denn er muss alle Records liefern. Und das DataSet (Query) ist nicht synchron mit den Daten der Grid.
Bei grösseren Datenmengen sollte man also im GrideMode arbeiten. Hier muss man zum Sortieren und Filtern etwas Hand anlegen. Dazu kann man erst mal die GrideMode - DEMO studieren.
Hier ist die Datenmenge der Grid mit der Query immer synchron. Nachteil: Gruppieren und Gruppensummen sind nicht mehr möglich.

Du musst also erst mal die entscheidende Frage klären, GridMode oder nicht.

IMHO sollte der DataController der Grid den Recordcount für die Daten der Grid liefern.
Na ja, ist ein schwieriges Thema, aber die Hürde sollte man erst mal nehmen.

Cu, Frank
Frank Reim
  Mit Zitat antworten Zitat
Darkchild

Registriert seit: 13. Okt 2006
Ort: NRW
169 Beiträge
 
Delphi 2006 Enterprise
 
#3

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 28. Nov 2006, 15:43
@dataspider

Hm,

ok das mit dem counter ist klar kann also auch aus den 2 Zeilen 1 machen, soweit so gut und danke zunächst einmal für diesen Tipp, aber jetzt habe ich noch mal ne Frage ob ich das alles richtig verstanden habe mit der Query, der Table und dem Grid.

Im Augenblick ist es so das in dem betreffenden cxGrid die Guppierung usw. über das Drag & Drop der Colums laufen, sowie verschiedene Footer die mir bestimmte Ergebnisse summieren und Anzeigen.

Kurz mal abschweifen:
Das Zählen der Datensätze und das zuweisen des Wertes für gesperrt und das damit verbundene sperren funktioniert bei mir und es sind vieleicht mit allem 30 Zeilen Quellcode. Klappt aber im Augenblick nur wenn ich direkt auf die Table zugreife und auch nur mit allen Datensätzen oder mit keinem, daher hier auch meine Frage im Thread.

So weiter geht's:
Wenn ich Dich jetzt gerade richtig verstanden habe kann ich mich jetzt entscheiden ob Gruppierung über Colums, Footer und Summenbildung oder das Sperren von im Grid ausgewählten Datensätzen, aber beides zusammen geht nicht ?

Habe ich das richtig verstanden ?

Das wäre nämlich ziemlich ungünstig für die Gesamtfunktionalität der Anwendung.

Gruss
Darkchild
Ich bin der Geist der stets verneint und das mit recht, denn alles was entsteht ist wert das es zugrunde geht, drum besser wär das nichts entstünde, so ist denn alles was ihr Sünde, Zerstörung, kurz das Böse nennt, mein eigendliches Element.
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.351 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 28. Nov 2006, 17:12
Hi,

ich weiss nicht, ob ich dein Problem richtig verstanden habe.
Ich denke, du willst die Datenmenge durchlaufen, die in der Grid angezeigt wird.
Da du nicht im Gridmode arbeitest, musst du mit dem DataBinding.DataController arbeiten.
Da gibt es den Recordindex, über den du die Id mit GetRecordId(RecordIndex) ermitteln kannst, sofern du ein KeyField mit deinem PK definiert hast.

Aber wie gesagt, ich verstehe das Problem noch nicht ganz.

Cu, Frank
Frank Reim
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 28. Nov 2006, 18:43
Hallo,

Delphi-Quellcode:
DataModuleMain.dsqueryzeiterfassungsansicht.DataSet.First;
    while not DataModuleMain.ibqueryzeiterfassungansicht.Eof do
      begin
      DataModuleMain.ibqueryzeiterfassungansicht.Locate('zeiterfassung_id', DataModuleMain.ibtablezeiterfassungZEITERFASSUNG_ID.value,[]);
      counterrecord := DataModuleMain.ibtablezeiterfassung.RecordCount;
      DataModuleMain.ibqueryzeiterfassungansicht.LocateNext('zeiterfassung_id', DataModuleMain.ibtablezeiterfassungZEITERFASSUNG_ID.value,[]);
      DataModuleMain.ibtablezeiterfassung.Next;
      end;
ShowMessage(inttostr(counterrecord));
Finster

Also du fängst mit einem DataSource(ds).DataSet.First an,
dann ein while no Query.EOF
und zum Schluss ein IBTable.Next.

Du produzierst hier ne Menge DB-Code, denke ich mal.
Zum zählen nimmt man immer noch Select Count(*)
Ich würde mir mal das ganze im SQL-Monitor ansehen.

Wenn die Daten nach zeiterfassung_id sortiert sind,
und du die noch nachfolgenden Daten haben willst,
wäre das also ein select count(*) from table where zeiterfassung_id>eineID

Das "DataModuleMain.dsqueryzeiterfassungsansicht.DataS et.First;"
ist auch nicht so gut, falls das ds wirklich ein DataSource ist,
was an einer Komponente hängt.
DisableControls fehlt dann, sonst wird die Komponente gezwungen,
durch deinen Code jedesmal ihre Anzeige zu aktualisieren.

Wenn es geht, ersetze die TIBTable komplett,
die ist nur aus "Kompatibilität" da und etwas lahm.


So, Feierabend !


Heiko
Heiko
  Mit Zitat antworten Zitat
Darkchild

Registriert seit: 13. Okt 2006
Ort: NRW
169 Beiträge
 
Delphi 2006 Enterprise
 
#6

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 29. Nov 2006, 07:57
@Dataspider

Morgen,

versuche nochmal mein Problem genau zu erklären, obwohl das leider garnicht so einfach ist.

Also, ich habe eine (alle namen nur als Beispiel) TForm_Zeiterfassung, in dieser TFormZeiterfassung liegt ein CXDBGrid (Grid von DevExpress), welches an einer IBQueryZeiterfassungsansicht gekoppelt ist. Das Grid befindet sich an einer Query damit ich halt alle Daten die in dieser Maske zu sehen seien sollen Angezeigt bekomme, da diese aus verschiedenen Tabellen kommen.

So, jetzt ist es ja über das cxdbGrid möglich über die Colums zu Filtern, z.B. einen einzelnen Namen Anzeigen lassen oder den Custom Filter benutzen und sich einen Bestimmten Zeitraum von allen dort eingetragenen Mitarbeitern anzeigen zu lassen usw. .
Jetzt bezieht sich dieser Filter ja nun auf die ans Grid angeschlossene IBQuery, wenn jetzt diese Datensätze gefiltert wurden möchte ich einen wert in ein Feld schreiben (in das Feld gesperrt soll dann nach drücken des Buttons eine 1 eingetragen werden)in die soeben gefilterten Datensätze, nur das der Wert nicht in die Query soll sondern in die zugehörige TTable_Zeiterfassung die noch etwas andere Felder besitzt, aber unteranderem auch das Feld Zeiterfassungs_ID, sowie auch das Feld Gesperrt usw.

Die Ansicht der Query aktuallisiert sich ja nur aus den dort eingetragenen TTablen nur soll der Wert gesperrt = 1 nur in die Datensätze in der Table_Zeiterfassung geschrieben werden, welche in der cxdbGrid - Anischt mit der dort Angeschlossenen IBQuery zu sehen sind nach dem Filtern.

Bei mir ist es im Augenblick so das die Datensätze gesperrt werden, aber leider immer alle und nicht nur die die im Grid über die Query mit den Filtern und Groupierungen des cxdbGrid ausgewählt wurden.

Muss dann ja irgendwie so gemacht werden das die Datensätze die im Grid angezeigt werden gelesen werden, dann jeder einzelne mit den Datensätzen aus der IBTable_Zeiterfassung verglichen wird, wurde eine Übereinstimmung gefunden, dann trage in der Table in den gefundenen Datensatz in das Feld gesperrt den Wert = 1 ein. Stimmen die beiden vergleichsdatensätze nich überein dann nehme den nächsten bis zu einer weiteren übereinstimmung und dann trage wieder in den Datensatz der in der Table steht(nicht in der Query) den Wert = 1 in das Feld gesperrt ein.

Hoffe das ist einigermassen verständlich geschrieben, ist noch früh, da klappt das mit dem formulieren noch nicht so gut, erstmal eine Cola trinken, eine Rauchen und dabei in ruhe wach werden .

Gruss
Darkchild
Ich bin der Geist der stets verneint und das mit recht, denn alles was entsteht ist wert das es zugrunde geht, drum besser wär das nichts entstünde, so ist denn alles was ihr Sünde, Zerstörung, kurz das Böse nennt, mein eigendliches Element.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#7

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 29. Nov 2006, 08:23
Also das Problem ist ein Allgemeines, und in der Architektur von Client-Server-Anwendungen begründet.

Blöderweise hilft Dir diese Erkenntnis nicht.

Du kannst versuchen, deine View (also das, was Du im Grid siehst), über einzelne TIBTable und Master-Detail-Verknüpfungen nachzubauen. Wenn Du dann an einer Tabelle etwas änderst, werden diese Änderungen auch in der zusammengeklickten 'View' sichtbar. Blöderweise hebelt man dadurch die Vorteile eines SQL-Servers aus, nämlich das extrem schnelle Suchen und Bereitstellen von Daten.

Wir haben einen anderen Ansatz verfolgt: Unsere Daten sind in einem TdxMemData, Du kannst aber auch ein TcxCustomDataSource ableiten. Wenn wir jetzt Änderungen an einer der diesen Daten zugrundeliegenden Tabellen posten, ändern wir diese Daten imn TdxMemData (oder TcxCustomDataSource) eben 'von Hand'. Das ist natürlich ziemlich bescheuert, aber anders bekommen wir das nicht hin.

Wir ziehen also die Daten vom Server und wissen ganz genau, wann welcher Record verändert werden muss. Eben weil wir in der Update-Logik die komplette View nachgebaut haben.

Wir haben zudem ein Messaging-System (TCP), sodaß die Änderungen von anderen Workstations auch auf allen Clients unmittelbar sichtbar werden, ohne das Jemand auf die Refresh-Taste haut.

Wie Du siehst, sind das aber alles Frickellösungen, eine allumfassende Lösung zu diesem Problem gibt es imho nicht. Denn der Traum, nämlich das die Query (also die View) glaskugelartig genau die Datensätze neu lädt, die sich verändert haben, ist so nicht realisierbar.

Für einen konkreten, speziellen Fall ist das aber sicherlich möglich.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.351 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 29. Nov 2006, 08:59
Hallo Darkchild,

mal sehen, ob ich helfen kann.
Mit der folgenden Methode durchläufst du die gefilterten Records der Grid und ermittelst die ID:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
Var
  i : Integer;
  ID: Integer;
begin
  with cxGridView.DataController do
  begin
    for i := 0 to FilteredRecordCount - 1 do
    begin
      // ID ermitteln anhand des Index
      ID := GetRecordId(FilteredRecordIndex[i]);
      // Jetzt am Besten eine SP zum Setzen von gesperrt auf Feld mit dieser ID
    end;
    // und jetzt ein Refresh auf die Table
    // das Refresh ist ausreichend, wenn die Table mit der Query eine gemeinsame Transaction benutzt.
    // Sonst wäre ein CommitRetaining der SP und der Table notwendig.
  end;
end;
Voraussetzung ist, dass du das Feld mit der eindeutigen ID in der Grid einträgst:
cxGridView.DataController.KeyFieldNames := 'zeiterfassung_id'; das geht auch im OI.
Ich denke, wenn du die zeiterfassung_id hast, kommst du weiter.

Wenn ich in der Grid eine Abfrage mit mehreren Tabellen habe und benötige Änderungen, erzeuge ich auf der DB einen Updateable View. Da kannst du über Trigger steuern, wie in welchen Tabelle Werte eingetragen werden.

Cu, Frank
Frank Reim
  Mit Zitat antworten Zitat
Darkchild

Registriert seit: 13. Okt 2006
Ort: NRW
169 Beiträge
 
Delphi 2006 Enterprise
 
#9

Re: RecordCount synchronisieren zwischen ibQuery und ibtable

  Alt 29. Nov 2006, 09:19
@alzaimer & Dataspider

Zunächstmal "Danke für eure Hilfe"
Scheint aber als wäre das Problem größer als von mir zunächst eingeschätzt, aber nun gut jetzt ist es da un muss dummerweise von mir bewältigt werden.

Werde mal sehen wie weit ich mit den ansätzten die Ihr mir gegeben habt komme.
Aber ein paar Sachen davon sollten mir aufjedenfall ein Stück weiterhelfen um der Lösung wieder ein Schritt näher zu kommen.

Also nochmal THX an euch zwei.

Gruss
Darkchild
Ich bin der Geist der stets verneint und das mit recht, denn alles was entsteht ist wert das es zugrunde geht, drum besser wär das nichts entstünde, so ist denn alles was ihr Sünde, Zerstörung, kurz das Böse nennt, mein eigendliches Element.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz