Autor Beitrag
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 21.08.11 10:59 
Moin!

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
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. :nixweiss:

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. :idea: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: 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

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
:
  ID := dm.ds_Auftrag.DataSet.FieldByName('ID').AsString;  //ID ist eine lokale Variable der OnKeyUP-Prozedur
  dm.ds_Auftrag.DataSet.Active := FALSE; //ds_Auftrag ist das Detail-DataSet
  dm.ds_Auftrag.DataSet.Active := TRUE;
  dm.GeheZuDatensatz(TDBDataSet(dm.ds_Auftrag.DataSet),'ID',ID); // alle Datensatzbezogenen Objekte befinden sin in 
                 // dem Datenbankmodul dm
                   // GeheZuDatensatz ist ein Prozedur in dm
:


ich denke es so:

ausblenden 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;  // aktuell : TDatetime, lokal in KeyUp
// in der DataSet.Datasource-Eigenschaft steht das Dataset der Mastertabelle
  if aktuell <> AuftragsStand then 
  begin
    AuftragsStand := aktuell; // AuftragsStand = Property im Formular
    ID := dm.ds_Auftrag.DataSet.FieldByName('ID').AsString;  //ID ist eine lokale Variable der OnKeyUP-Prozedur
    dm.ds_Auftrag.DataSet.Active := FALSE; //ds_Auftrag ist das Detail-DataSet
    dm.ds_Auftrag.DataSet.Active := TRUE;
    dm.GeheZuDatensatz(TDBDataSet(dm.ds_Auftrag.DataSet),'ID',ID); // alle Datensatzbezogenen Objekte befinden sin in 
                 // dem Datenbankmodul dm
                   // GeheZuDatensatz ist ein Prozedur in dm
  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.