AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?
Thema durchsuchen
Ansicht
Themen-Optionen

ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

Ein Thema von FragenderHerbert · begonnen am 28. Jun 2014 · letzter Beitrag vom 2. Jul 2014
Antwort Antwort
FragenderHerbert

Registriert seit: 4. Dez 2013
47 Beiträge
 
#1

ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 28. Jun 2014, 11:59
Datenbank: Dbase • Version: 4 • Zugriff über: TClientDataSet
Hallo,

ich stehe vor demProblem, das ich eine CD-, Video und PC-Datenträgerverwaltung bauen will, die folgendes leistet:

ich gebe in einer Masterdatei mit den Feldern

MEDIAID, zB. CD0001 oder DVD0002

MEDIAKIND und evtl noch zB. music, video oder software

FILENAME zb. MusikCDs.dbf oder Videos.dbf oder SoftwBackups.dbf

eine Datenmenge vor, die mit den Detaildatenbanken wie MusikCds.dbf, ... verknüpft ist und mir bei Auswahl einer MEDIAID den Inhalt des jeweiligen Datentägers anzeigt. Später will ich mit dem Programm auch gezielt nach einemTitel suchen können und die Bezeichnung des Speichermediums als Ergebnis der Abfrage haben.

Die Motivation hierzu ergibt sich aus dem Umstand das ich oft schon SOftwarebibliotheken, heruntergeladene Quelltexte, ... nach langer Zeit mal wieder benutzen will und dann nicht mehr weiß, auf welchem Medium und in welchem Ordner auf diesem Medium ich denn nun das Zeug gespeichert habe.

Mein derzeitiger Ansatz:

Delphi-Quellcode:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ADODB, DB, ExtCtrls, DBCtrls, Grids, DBGrids, dbf, Provider,
  DBClient;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Login1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    DBGrid1: TDBGrid; //Masterdaten anzeigen
    DBNavigator1: TDBNavigator;
    Dbf1: TDbf; //Zugriff auf Masterdaten
    DataSource1: TDataSource; //Datenquelle Masterdaten
    DataSource2: TDataSource; //Datenquelle Detaildaten, zB. MusikCds
    Dbf2: TDbf; //Zugriff auf Detaildaten
    Dbf3: TDbf; //Vorläufiger Zugriff auf Detaildaten einer weiteren Tabelle (***)
    DataSource3: TDataSource; //Datenquelle dieser Detaildaten
    DBNavigator2: TDBNavigator;
    DBGrid2: TDBGrid; //Detaildaten anzeigen
    ClientDataSet1: TClientDataSet; //Weil Master/Detail mit TDBF nicht funktioniert
    DataSetProvider1: TDataSetProvider; //mit Dbf2, meiner ersten Detailtabelle verbunden
    DataSource4: TDataSource; //Die Datnquelle hierzu zum Anzeigen in DBGrid3
    DBNavigator3: TDBNavigator;
    DBGrid3: TDBGrid; //Hier ist es
    procedure Exit1Click(Sender: TObject);
    procedure DataSource1DataChange(Sender: TObject; Field: TField);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
var RefField, ResField: WideString;
begin
  RefField := TDataSource(Sender).DataSet.Fields.FieldByName('MEDIAID').AsString;
  //dbf2.Locate(RefField, Field.CurValue, [loCaseInsensitive]); //Hier wird Exception geworfen
end;

procedure TForm1.Exit1Click(Sender: TObject);
begin
  Application.Terminate();
end;

end.
Mein Problem ist jetzt, das, wenn ich zB. CD0001 anwähle, dann ist die Anzeige korrekt, wenn ich aber dann CD0002 anwähle, ist die Anzeige zunächst auch korrekt, wenn ich dann aber zurück auf CD0001 gehe, wird mir die zugehörige Detaildatenmenge 2 Mal angezeigt. Wenn ich dann auf den dritten Masterdatensatz gehe und danach zurück, erscheint die datenmenge 3 Mal. Ich will sie natürlich in jedem Fall nur einmal sehen.

EDataBaseError: Operation bei geschlossener Datenmenge nicht ausführbar.

Wenn ich jedoch alles im Objektinsprktor einstelle, auch DataSet.Active = true, dann ist doch die Datenmenge geöffnet?

Warum kann ich das dann nicht voraussetzen, wenn ich jetzt Quelltext schreibe, um in meinm Fall auf Änderungen in einer Datenmenge, hier Satznummer in den Masterdaten, zu reagieren?

Was muss ich dazu noch einstellen?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 28. Jun 2014, 12:24
Du solltest erstmal bedenken, daß der Parameter "Field" nicht immer ein Feld enthalten muß und auch mal nil sein kann.
  • erstmal sagt dir die Exception-Message, welche du uns vorenthälst, ganz bestimmt was von "Zugriffsverletzung bei Adresse $000000xx" und schon weiß man, daß da irgendwo ein NIL im Spiel ist
  • und wenn man den Debugger verwenden würde, dann würde man auch sehen, daß dieses Property bestimmt NIL sein wird

Aber warum verwendest du nicht die Master-Detail-Funktionen des ClientDataSets, und lässt das automatisch synchronisieren?
  • IndexFieldNames
  • MasterFields
  • MasterSource

Oder man verwendet zum Ausrichten DataSet.OnAfterScroll.


Sicher, daß du Locate richtig verwendest, oder täuscht das nur und du hast eine etwas "eigenartige" Tabellenstruktur? (welche natprlich auch geheim ist)
  • ID als Feldname



PS: Statt Application.Terminate; kommt man mit {Self}.Close; oder Application.MainForm.Close; besser, denn damit verbaut man sich die Nutzung von TForm.OnCloseQuery nicht.
Das (erfolgreiche) Schließen der Hauptform beendet die Application, aber so kann man prüfen, ob wirklich geschlossen werden darf. z.B. wenn noch nicht gepseichert wurde.
$2B or not $2B

Geändert von himitsu (28. Jun 2014 um 13:40 Uhr)
  Mit Zitat antworten Zitat
FragenderHerbert

Registriert seit: 4. Dez 2013
47 Beiträge
 
#3

AW: ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 28. Jun 2014, 13:56
Du solltest erstmal bedenken, daß der Parameter "Field" nicht immer ein Feld enthalten muß und auch mal nil sein kann.
Ok, das könnte die Ursache meiner Exception sein. Ich habe stillschweigend vorausgesetzt, das der Event-Handler zwingend einen Feldinhalt übergibt und deshalb dort nicht gesucht.

  • erstmal sagt dir die Exception-Message, welche du uns vorenthälst, ganz bestimmt was von "Zugriffsverletzung bei Adresse $000000xx" und schon weiß man, daß da irgendwo ein NIL im Spiel ist
  • und wenn man den Debugger verwenden würde, dann würde man auch sehen, daß dieses Property bestimmt NIL sein wird
Und genau da ist das Problem! Wo ist irgendwo, wo ja der Nil Zeiger sein müsste?
Noch mal: Ich habe gar nicht mit irgendeinem NIL Zeiger gerechnet, da ich eine EDataBaseError Exception erhalten habe. Kann ja sein, das mein Konzept im Grundsatz schon falsch ist. Aber wie kann ich es dann besser machen. Eine Client-Server Architektur will ich absichtlich nicht, da ich mich noch nicht mal mit den elementarsten Grundlagen auskenne und auch die Delphi-Treff Tut-s hier nicht viel her geben.

Eine andere für mich hoch interessante Frage ist für mich im Gesamtzusammenhang: Wo finde ich ein einsteigerfreundliches Lehrbuch zu SQL Syntax. Möglichst MSSQL, da ich mich an CS Arcitekturen noch nicht heran traue und meine Medienverwaltung ausschließlich auf einem meiner lokalen Computer laufen soll, möglichst portabel auf einem USB Stick. Die Medienverwaltung soll deshalb keine vorinstallierten Datenbankserver voraussetzen. Leider kriege ich bei ADO den Verbindungsstring nicht "gebacken", ich erhalte dann Fehlermeldung, das die Tabelle nicht vorhanden ist. Ich habe da als Treiber den:

- OLE DB Simple Provider sowie den
- OLE DB Provider für Microsoft Directory Services

getestet.

Bei beiden kommt die Fehlermeldung "Tabelle nicht vorhanden"

Bei letzterem muss ich u.a. Datenquelle und Speicherort separat angeben.

Datenquelle -> meine Datenbankdatei
Speicherort -> mein Datenbankverzeichnis

Die Adresse 127.0.0.1 wird als Speicherort nicht akzeptiert. Daher habe ich "http://localhost" gar nicht erst probiert.

Ich will eine lokale Datenbank haben, da die für meine Zwecke komplett ausreicht und ich mir deshalb die Einarbeitung in CS Architekturen noch sparen möchte. Weil ich aber eine portable Anwendung will, scheidet BDE sofort aus. Bei Interbase bräuchte ich eine portable Version des Servers. Das hätte aber dann wohl zur Folge, das ich um die Erlernung der CS Architektur nicht herum käme.

Debuggen kann ich erst effektiv, wenn ich weiß, wo ich den Fehler suchen muss. Wenn ich den Fehlerort nicht eingrenzen kann, bin ich mit dem Test anderer DB Kompos genau so schnell oder gar schneller am Ziel.

Zitat:
Aber warum verwendest du nicht die Master-Detail-Funktionen des ClientDataSets, und lässt das automatisch synchronisieren?
  • IndexFieldNames
  • MasterFields
  • MasterSource
Doch, das habe ich schon erledigt. Alles im Objektinspector. Per Quelltext mache ich das zur Übung später, wenn ich das per OI geschafft habe.

Zitat:
Sicher, daß du Locate richtig verwendest, oder täuscht das nur und du hast eine etwas "eigenartige" Tabellenstruktur? (welche natprlich auch geheim ist)
  • ID als Feldname
Nein, bin ich nicht. Habe soeben das hier dazu gefunden:
http://www.delphipages.com/forum/showthread.php?t=41929

Da gibt es u.a. diesen Beitrag im Forum:

Zitat:
Change the comma to a semicolon in the Field string.
Example:

Locate('FIELD1;FIELD2;FIELD3',VarArrayOf([Value1,Value2,Value3]),[]);

Happy New Year
Christian
Allerdings brauche ich das variabel, das heißt -> Value1 muss der aktuelle Wert aus der Mastertabelle sein (CD0001,CD0002,DVD0001,USB-Stick0003,...)

Wenn aber der Parameter Field im Eventhandler der DataSource auch NIL sein kann?
Habe inzwischen den Quellcode schon in einen try except Block eingeschlossen. Aber mein EDatabaseError wird vor dem eingentlichen Start schon geworfen. Ich will aber, das in diesem Fall eben nix passiert. Wie aber stelle ich das an. Sorry, aber ich bin in Sachen Datenbank ein totales Greenhorn.

Bei dieser Gelegenheit frag ich gleich mal, wo gibt es denn wirklich einsteigerfreundliche Literatur zu Datenbanken? Ich habe außerdem Xampp auf meinem System installiert. Der beherrscht auch MySQL. Aber wo gibt es einsteigerfreundliche Tuts dazu?
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#4

AW: ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 29. Jun 2014, 11:50
Im OnDataChange bezeichnet der Field-Parameter das Feld, welches verändert wurde. Wenn Field=nil, dann findet ein Wechsel des aktuellen Datensatzes statt.

Bezüglich der Master-Detail-Beziehung setzt Du in der Detail-Datenmenge die 'MasterSource'-Eigenschaft auf das Dateset des Master-Datasets. Anschließend setzt Du die Master-Fields Eigenschaft entsprechend.

Das sollte das Problem lösen.

Es kann allerdings schneller sein, wenn Du einmalig alle Detaildaten lädst und dann die Detaildaten über die Filter-Eigenschaft beim Record-Wechsel (OnDataChange mit Field=nil ) neu setzt.
  Mit Zitat antworten Zitat
Benutzerbild von blawen
blawen

Registriert seit: 1. Dez 2003
Ort: Luterbach (CH)
679 Beiträge
 
Delphi 12 Athens
 
#5

AW: ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 29. Jun 2014, 13:16
Bei dieser Gelegenheit frag ich gleich mal, wo gibt es denn wirklich einsteigerfreundliche Literatur zu Datenbanken? Ich habe außerdem Xampp auf meinem System installiert. Der beherrscht auch MySQL. Aber wo gibt es einsteigerfreundliche Tuts dazu?
Da Du für Dich selbst die Tutorials von Delphi Treff nicht viel hergeben (Zitat), wird es für meine Glaskugel schwierig, abzuschätzen, welches der abertausenden Tuts Deinen Ansprüchen gerecht wird.
Vielleicht passt's ja:
Tut von Luckie

Neben den Text-Tuts findest Du bei Youtube auch massig Video-Tutorials.

Wenns ein Buch sein soll:
MySQL Handbuch
Roland
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 29. Jun 2014, 13:28
Zitat:
Möglichst MSSQL, da ich mich an CS Arcitekturen noch nicht heran traue und meine Medienverwaltung ausschließlich auf einem meiner lokalen Computer laufen soll, möglichst portabel auf einem USB Stick. Die Medienverwaltung soll deshalb keine vorinstallierten Datenbankserver voraussetzen.
Bei portabel und nicht installiertem Datenbankserver würde mir MSSQL eigentlich nicht in den Sinn kommen, aber gut
Zitat:
- OLE DB Simple Provider sowie den
- OLE DB Provider für Microsoft Directory Services
Ja, damit würde ich auch keine Verbindung zu - ja zu was denn jetzt - hinbekommen.
Du musst schon den DB Provider bemühen, der auch mit dem Datenbanksystem sprechen kann (die beiden sind es nicht).

Und wenn du schon eine Master-Detail-Beziehung per OI definiert hast, warum willst du da per Code nochmals reinpfuschen? sehr seltsam ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
FragenderHerbert

Registriert seit: 4. Dez 2013
47 Beiträge
 
#7

AW: ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 29. Jun 2014, 16:01
Bei dieser Gelegenheit frag ich gleich mal, wo gibt es denn wirklich einsteigerfreundliche Literatur zu Datenbanken? Ich habe außerdem Xampp auf meinem System installiert. Der beherrscht auch MySQL. Aber wo gibt es einsteigerfreundliche Tuts dazu?
Da Du für Dich selbst die Tutorials von Delphi Treff nicht viel hergeben (Zitat), wird es für meine Glaskugel schwierig, abzuschätzen, welches der abertausenden Tuts Deinen Ansprüchen gerecht wird.
Vielleicht passt's ja:
Tut von Luckie

Neben den Text-Tuts findest Du bei Youtube auch massig Video-Tutorials.

Wenns ein Buch sein soll:
MySQL Handbuch
Danke! Werd mir beide anschauen. Die Leseprobe des MySQL Handbuches sieht gut aus und von Lukie hab ich mir schon die WIN-API Tuts gesaugt. Dort ist die Praxis unter Benutzung von Delphi gut erklärt. Im hier verlinkten Tut von Luclie hab ich jetzt nur kurz gelesen, schaut aber auch gut aus. Werde mich also damit erst mal beschäftigen. Das MySQL Handbuch ist dann zusätzlich.
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#8

AW: ClientDataSet; Datenmenge wird ungewollt zur aktuellen hinzugefügt, warum?

  Alt 2. Jul 2014, 14:22
Die Motivation hierzu ergibt sich aus dem Umstand das ich oft schon SOftwarebibliotheken, heruntergeladene Quelltexte, ... nach langer Zeit mal wieder benutzen will und dann nicht mehr weiß, auf welchem Medium und in welchem Ordner auf diesem Medium ich denn nun das Zeug gespeichert habe.
Abgesehen von deinem Datenbank-Problem: Ich hatte noch nie Schwierigkeiten, irgend eine heruntergeladene Datei wieder zu finden, denn ich verwende ein ganz bestimmtes System, auch für meine Delphi-Projekte:
Mein Archiv-Ordner auf meinem Backup-Laufwerk (3 TB) sieht ungefähr so aus (unvollständig):

Code:
Archiv
 Anwendungen
  Audio
  DBMS
  Grafik
  ...
  Utils
 Coding
  Apps
   Delphi
    Ide-Erweiterungen
    Komponenten
    Tools
   Java
   Lazarus
   ...
  Codes
   Projekte
    Auftrag
    ...
    Test
  Datenbanken
   Access
   Firebird
   MsSQL
   MySQL
  Utils
 Texte
 Grafik
Wenn man heruntergeladene Dateien immer sauber in die entsprechende Kategorie einordnet, findet man das auch wieder, ganz ohne Datenbank. Zu guter Letzt gibt's ja auch noch die Windows-Suchfunktion und den Windows-Indexdienst ...

Geändert von Perlsau ( 2. Jul 2014 um 14:24 Uhr)
  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 04:31 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