Autor |
Beitrag |
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Fr 19.08.11 11:03
Hallo Leute, auch wenn ich mich jetzt als totaler Laie in Datenbankfragen oute. Ich habe ein Problem. In der von mir benutzten Anwendung greifen oft mehrere User auf die gleiche Tabelle/Abfrage einer ACCESS-Datenbank zu. Da möchte ich, dass die einzelnen User darüber informiert werden, dass sich die aktuelle Ansicht geändert hat (z.B. neue Einträge, Einträge wurden gelöscht oder geändert). Außer dass ich die aktuelle Abfrage/Tabelle neu lade fällt mir dazu echt wenig ein. Welche Eigenschaft/Methode/Ereignis ist dafür geeignet? Ich habe schon "UpdatesPending" versucht, negativ, betrifft wohl nur den Nutzer selber und nicht die Eingaben irgendeinenes anderen Nutzers.
Für Hilfen wäre ich dankbar. Wenn ich die Information über die Änderung der aktuellen Abfrage (im vorliegenden Fall eine TQuery) hätte, könnte ich entsprechende Aktualisierungsroutinen schreiben. Bitte teilt mir Eure Ideen mit.
//Edit:
Bisher habe ich das so geregelt, dass ich bei der KeyUp-Methode des TDBGrids die mit dem TDBGrid verknüpfte Tabelle/Query aktualisiere. So wird nur dann die Tabelle/Query aktualisiert, wenn ich die Taste loslasse. Was bei einigen Abfragen oft etwas dauert, denn es sind mehrere Abfragekriterien gleichzeitig gewählt. Daher kann ich beim Scrollen diese Aktualisierung nicht vornehmen, denn dann hakt der Cursor. Die Datenbank liegt auf einem NAS-Laufwerk im Netz.
Aber diese Lösung erscheint mir ehrlich gesagt zwar machbar, führt auch zum gewollten Ergebnis, ist aber nicht sinnvoll. Da ich ja auch aktualisiere, wenn gar nichts passiert.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Fr 19.08.11 14:31
Mal abgesehen, dass ich sowas für wenig sinnvoll halte, solltest du die Prüfung im Hintergrund mit einer weiteren Abfrage machen. Eventuell über einen Timer gesteuert. Die Daten im Grid werden dann nur aktualisiert, wenn deine Hintergund-Prüfung einen Unterscheide feststellt.
Aber überlege erst, ob das wirklich sinnvoll ist. Vielleicht genügt schon ein Button unter dem Grid, der dem Anwender die Möglichkeit lässt, bei Bedarf zu aktualisieren.
|
|
Tranx 
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Sa 20.08.11 18:08
Jasocul: Das mit dem sinnvoll oder nicht, ist doch eigentlich klar.
Wenn jemand eine Abfrage gestartet hat, in der z.b. ein Feld auf einen gewissen Wert abgefragt wird, z.B.: "in Arbeit" und jemand anderes ändert den Status eines Datensatzes in "erledigt". Dann darf bei dem ersten dieser Datensatz nicht mehr erscheinen, weil er dem Kriterium nicht mehr entspricht. Das ist doch eindeutig, oder? Zumal dann, wenn der andere in dem Datensatz dann was ändern will, er die Meldung bekommt: "Dieser Datensatz kann nicht geändert werden ,da ein anderer Benutzer ...". Und das nur, weil er einen ja nicht mehr existenten Datensatz ändern will. Aber da ja keine weitere Reaktion kommt, bleibe ich bei der an sich sehr überflüssigen Weise, es zu regeln: Mit der KeyUp-Methode. Die funktioniert!
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Sa 20.08.11 19:05
Und wie oft kommt das vor? Aber das musst du ja wissen.
Ich habe dir ja zwei Alternativen aufgeschrieben. Du musst also nicht bei deiner Variante bleiben.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 21.08.11 10:59
Moin!
Tranx hat folgendes geschrieben : | Wenn jemand eine Abfrage gestartet hat, in der z.b. ein Feld auf einen gewissen Wert abgefragt wird, z.B.: "in Arbeit" und jemand anderes ändert den Status eines Datensatzes in "erledigt". Dann darf bei dem ersten dieser Datensatz nicht mehr erscheinen, weil er dem Kriterium nicht mehr entspricht. |
Wenn das so kritisch ist, dann kannst du das nicht der DB überlassen, noch dazu wenn es kein RDBMS ist.
Wenn du nicht pollen willst, dann bleibt ja nur aktive Signalisierung über: Sind alle Clients in einem Netz? Mach einen UDP-Broadcast, der anzeigt: Ansicht aktualisieren.  Clients nicht alle in einem Netz? Dann bleibt nur Registrierung bei einer Server-Instanz und die macht dann entweder UDP-Unicasts oder halte eine TCP-Verbindung zu jedem Client offen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Tranx 
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mo 22.08.11 07:18
Eine Frage hätte ich da. Es ist ja unsinnig, jedes Mal die Tabelle/Abfrage neu zu laden, nur um den Inhalt auf Stand zu halten (bei Mehr-User-Nutzung). Wie gesagt, das, was hich implementiert habe, klappt problemlos. Ist eben etwas überkandidelt.
Daher habe ich eine Idee: Wie wäre es, ein Feld "STAND" in der Mastertabelle hinzuzufügen, die den Stand des aktuellen Master-Datensatzes registriert. Bei jeder Änderung eines der mit dem Masterdatensatz verbundenen Detail-Datensätze (1-n-Verknüpfung) würde dann automatisch das Feld "Stand" des Master-Datensatzes aktualisiert. Wenn nun ein anderer User in der gleichen Detail-Abfrage ist, fragt die OnKeyUp-Prozedur das Masterfeld "Stand" ab. Ist es unterschiedlich zu einer Property "Auftragsstand" des Formulars, so wird der Datensatz bei KeyUp aktualisiert, sonst nicht. Das hätte obendrein noch den positiven Effekt, dass ich den aktuellen Stand der einzelnen Masterdatensätze dokumentiert hätte.
Ich denke mir das so:
Bisher habe ich es so implementiert
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| : ID := dm.ds_Auftrag.DataSet.FieldByName('ID').AsString; dm.ds_Auftrag.DataSet.Active := FALSE; dm.ds_Auftrag.DataSet.Active := TRUE; dm.GeheZuDatensatz(TDBDataSet(dm.ds_Auftrag.DataSet),'ID',ID); : |
ich denke es so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| (in KeyUp) : aktuell := dm.ds_Auftrag.DataSet.DataSource.Dataset.FieldByName('STAND').AsDateTime; if aktuell <> AuftragsStand then begin AuftragsStand := aktuell; ID := dm.ds_Auftrag.DataSet.FieldByName('ID').AsString; dm.ds_Auftrag.DataSet.Active := FALSE; dm.ds_Auftrag.DataSet.Active := TRUE; dm.GeheZuDatensatz(TDBDataSet(dm.ds_Auftrag.DataSet),'ID',ID); end; :
und in der AfterPost-Prozedur der Detail-Tabelle: Im Modul DM
procedure Tdm.q_AuftragAfterPost(DataSet: TDataSet); begin DataSet.DataSource.Dataset.Edit; DataSet.DataSource.Dataset.FieldByName('Stand').AsDateTime := now; DataSet.DataSource.Dataset.Post; end; |
Was meint Ihr dazu?
Für Anregungen bin ich offen.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
|