Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Einfache Tabelle mit TClientDataSet (https://www.delphipraxis.net/199290-einfache-tabelle-mit-tclientdataset.html)

DualCoreCpu 12. Jan 2019 07:45

Datenbank: MyBase • Version: 10.3 • Zugriff über: localhost

Einfache Tabelle mit TClientDataSet
 
Hallo nochmal,


bevor ich mit dem Studium der Tutorals richtig beginne, habe ich mal eine einfache Datentabelle mit TDataSource und TClientDataSet aufgebaut. Leider kann ich immer noch keine Daten eingeben. Was mache ichda noch falsch?

Hier die dfm Datei:

Delphi-Quellcode:
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 477
  ClientWidth = 565
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object DBGrid1: TDBGrid
    Left = 8
    Top = 80
    Width = 549
    Height = 329
    DataSource = DataSource1
    TabOrder = 0
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'Tahoma'
    TitleFont.Style = []
    Columns = <
      item
        Expanded = False
        FieldName = 'Medium'
        Width = 94
        Visible = True
      end
      item
        Expanded = False
        FieldName = 'Autor'
        Width = 112
        Visible = True
      end
      item
        Expanded = False
        FieldName = 'Titel'
        Visible = True
      end>
  end
  object DBNavigator1: TDBNavigator
    Left = 152
    Top = 32
    Width = 240
    Height = 25
    DataSource = DataSource1
    TabOrder = 1
  end
  object btnSave: TButton
    Left = 16
    Top = 440
    Width = 75
    Height = 25
    Caption = 'Speichern'
    TabOrder = 2
  end
  object DataSource1: TDataSource
    DataSet = ClientDataSet1
    Left = 56
    Top = 16
  end
  object ClientDataSet1: TClientDataSet
    PersistDataPacket.Data = {
      6D0000009619E0BD0100000018000000030000000000030000006D00096D6564
      69616B696E64010049000000010005574944544802000200030006617574686F
      720100490000000100055749445448020002001E00057469746C650100490000
      0001000557494454480200020028000000}
    Active = True
    Aggregates = <>
    Params = <>
    Left = 56
    Top = 72
    object ClientDataSet1mediakind: TStringField
      FieldName = 'mediakind'
      Size = 3
    end
    object ClientDataSet1author: TStringField
      FieldName = 'author'
      Size = 30
    end
    object ClientDataSet1title: TStringField
      FieldName = 'title'
      Size = 40
    end
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = ClientDataSet1
    Left = 56
    Top = 128
  end
end
Hier die Formular Unit:

Delphi-Quellcode:
unit main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Vcl.ExtCtrls, Vcl.DBCtrls,
  Vcl.Grids, Vcl.DBGrids, Datasnap.Provider, Datasnap.DBClient, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    DataSource1: TDataSource;
    ClientDataSet1: TClientDataSet;
    DataSetProvider1: TDataSetProvider;
    ClientDataSet1mediakind: TStringField;
    ClientDataSet1author: TStringField;
    ClientDataSet1title: TStringField;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    btnSave: TButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientDataSet1.FileName := ExtractFilePath(ParamStr(0))+'media.xml';
  {
  if FileExists(ClientDataSet1.FileName) then
    ClientDataSet1.LoadFromFile(ClientDataSet1.FileName)
  else
    ClientDataSet1.CreateDataSet;
  }

  if FileExists(ClientDataSet1.FileName) then
    ClientDataSet1.Open
  else begin
    with ClientDataSet1.FieldDefs do begin
      Clear;
      Add('media', ftString, 3);
      Add('author', ftString, 30);
      Add('title', ftString, 40);
    end;
    ClientDataSet1.CreateDataSet;
  end;

  ClientDataSet1.LoadFromFile('media.xml');
end;

end.
Nach dem Tutorial zu MyBase in Delphi Treff aufgebaut. Habe halt nur das AutoIncrement Feld aus diesem Tutorial weggelassen.

Das Programm wird korrekt übersetzt, ich kann aber keine Daten eingeben. Warum ist das so?

Entfernung der Komponente TDataSetProvider bringt keine Besserung. Den TDataSetProvider brauche ich erst später, um eine Verbindung zu weiteren Tabellen herzustellen, wenn ich die Normalform der Datenbank erstellt habe.

Ich habe die Komponentennamen im Original belassen, um zu zeigen, das ich hier TClientDataSet verwende, um das Tutorial im Delphi Treff durchzuarbeiten.

newIndy 12. Jan 2019 09:42

AW: Einfache Tabelle mit TClientDataSet
 
// Daten anhängen
ClientDataSet1.Append;
ClientDataSet1.FieldByName('media').AsString := 'media';
ClientDataSet1.FieldByName('author').AsString := 'author';
ClientDataSet1.FieldByName('title').AsString := 'title';
if ClientDataSet1.State in [dsEdit, dsInsert] then ClientDataSet1.Post;
// Datensatz ändern
ClientDataSet1.Edit;
ClientDataSet1.FieldByName('media').AsString := 'media';
ClientDataSet1.FieldByName('author').AsString := 'author';
ClientDataSet1.FieldByName('title').AsString := 'title';
if ClientDataSet1.State in [dsEdit, dsInsert] then ClientDataSet1.Post;
// Wenn man Wert auf Geschwindigkeit legt, speichert man die Dateien im Binärformat als 'dfBinary':
ClientDataSet1.SaveToFile(ClientDataSet1.FileName, DBClient.dfBinary);

Uwe Raabe 12. Jan 2019 09:48

AW: Einfache Tabelle mit TClientDataSet
 
Die Spalten im Grid verweisen auf die Felder "Medium", "Autor" und "Titel", aber die eigentlichen Feldnamen sind "mediakind" bzw. "media", "author" und "title".

DualCoreCpu 12. Jan 2019 17:57

AW: Einfache Tabelle mit TClientDataSet
 
@Uwe Raabe:

Ich wollte einen Displaynamen für die Spalten verwenden. Habe das aber korrigiert im Objektinspektor. Vorher Kontextmenü von DBGrid aufgerufen, dort den Spalteneditor. Dort habe ich 3 Spalten angelegt, mit Feldname(n) gemäß denen in meiner Datenbaktabelle. Dann gibt es da in DBGrid.Columns[Index] die Eigenschaft Feldname, der ich den Feldnamen meiner Dantenbanktabelle bergeben habe und eine Eigenschaft Title vom Typ TColumnTitle. Dort gibt es die Eigenschaft Caption, die ich mit der von mir gewünschten Spaltenüberschrift gefüllt habe.

@newIndy:

Danke für den Tipp. Geschwindigkeit optimiere ich später. Jetzt ist erst mal XML Format Ok. Kann man dies später in ein beliebiges anderes Datenformat umwandeln (Firebird, Acess, Paradox, ...), gibt es da Tools?

Die Dateneingabe funktionierte zwar zunächst immer noch nicht. Hatte mit dem Spalteneditor von DBGrid 3 Spalten angelegt, mit Feldname einer derjenigen in meiner Datentabelle und DBGrid.Column[Index].Title.Caption meine von mir gewünschte Spaltenüberschrift. Wenn ich das nutze, funktioniert die Dateneingabe nicht, wenn ich keine Spalten mit dem Spalteneditor von DBGrid anlege, funktioniert die Dateneingabe. Warum das?

Ich kann jetzt endlich Daten in meine Tabelle eingeben.

Delphi.Narium 12. Jan 2019 19:53

AW: Einfache Tabelle mit TClientDataSet
 
Lass bitte zuerstmal jede Konfiguration im DBGrid weg, damit es die Chance hat die Tabelle, so wie sie ist, anzuzeigen.

Wenn das dann mal geht, kannst Du die Optik immernoch verschönern.

Du hast doch auch 'nen DBNavigator auf dem Formular.
Sind bei dem irgendwelche Buttons beim Programmstart aktiviert oder sind welche ausgegraut / deaktiviert.
Kannst Du das mal beschreiben oder 'nen Scrennshot anhängen?


Zuerst: Datenbank / ClientDataSet öffnen.

Geht das?

Dann die Daten anzeigen.

Geht das?

Dann Daten eingeben, verändern, speichern?

Geht das?

Dann um die Optik kümmern.

Was hilft es, wenn ich beim Hausbau zuerst eine schöne Fassade habe, aber Fenster zum Rausgucken und die Türe zum Reingehen vergessen wurde? ;-)

DualCoreCpu 12. Jan 2019 20:28

AW: Einfache Tabelle mit TClientDataSet
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1423206)
Lass bitte zuerstmal jede Konfiguration im DBGrid weg, damit es die Chance hat die Tabelle, so wie sie ist, anzuzeigen.

Wenn das dann mal geht, kannst Du die Optik immernoch verschönern.

Du hast doch auch 'nen DBNavigator auf dem Formular.
Sind bei dem irgendwelche Buttons beim Programmstart aktiviert oder sind welche ausgegraut / deaktiviert.
Kannst Du das mal beschreiben oder 'nen Scrennshot anhängen?


Zuerst: Datenbank / ClientDataSet öffnen.

Geht das?

Ja.

Zitat:

Zitat von Delphi.Narium (Beitrag 1423206)
Dann die Daten anzeigen.

Geht das?

Ja, außer dem zuletzt eingegebenen Satz. Muss dann übernehmen auslösen, um dies zu vermeiden.

Zitat:

Zitat von Delphi.Narium (Beitrag 1423206)
Dann Daten eingeben, verändern, speichern?

Geht das?

Ja. Allerdings Übernehmen klappt, aber Update Aktualisieren nicht. Der Button des DBNavigators ist standardmäßig allerdings auch nicht ausgewählt, ich hab ihn aber probeweise mal aktiviert. Nur Übernehmen klappt, Aktualisieren aber nicht mit dem standardmäßig nicht angezeigten Button. Eingeben von Daten, diese Verändern und dann Übernehmen klappt dann, ich kann die eingegebenen Daten dann auch nach Neustart meiner Anwendung anzeigen. Habe diesen Button Update Aktualisieren (im OI nbApplyUpdates) wieder deaktiviert. Mit Übernehmen (im OI nbPost) erreiche ich ja mein Ziel.


Zitat:

Zitat von Delphi.Narium (Beitrag 1423206)
Dann um die Optik kümmern.

Was hilft es, wenn ich beim Hausbau zuerst eine schöne Fassade habe, aber Fenster zum Rausgucken und die Türe zum Reingehen vergessen wurde? ;-)

Auch wahr.

Hier mein Screenshot:
https://1drv.ms/f/s!Akh20VYLxLoYg0RqLA005iRYqCWz

Allerdings klappt das Eingeben, Verändern und Löschen von Daten nur Interaktiv, aber nicht mit newIndys Quellcode.

Delphi.Narium 12. Jan 2019 21:31

AW: Einfache Tabelle mit TClientDataSet
 
Der DBNavigator sieht so ok aus.

Der Haken und des X bzw. der Pfeil rechts sind nur aktiv, wenn es Änderungen gab.

Der Haken, um eine im Grid gemachte Änderung zu speichern, das X, um sie zu verwerfen. Rechts der Kringelpfeil kann genutzt werden, um 'ne Datenmenge neu zu laden. (Ist hier aber wohl nicht wirklich sinnvoll einzusetzen.)

Bevor wir uns darum kümmern, ob newIndys Quelltext funktioniert oder nicht, zuerst mal die Frage:

Willst Du die Daten programmatisch in Deine Datenbank schreiben oder soll die Eingabe händisch (via Grid oder Eingabefelder) erfolgen?

Wenn die Daten nur in der Oberfläche erfasst werden sollen, dann ist der Quelltext nicht erforderlich.

Das Speichern von Änderung funktioniert übrigens gewöhlich auch durch das Scrollen im Grid, 'ne Zeile vor, 'ne Zeile zurück mit den Cursortasten. Der letzte Satz wird also gespeichert, wenn man 'ne Zeile nach oben geht. Klar geht auch alles per Maus und DBNavigator. Verwerfen einer Eingabe geht auch per ESC-Taste.

Achso: Wenn sowas, wie newIndys Quelltext sinnvoll eingesetzt werden soll.
Hast Du die Daten schon irgendwie vorliegen, wenn ja, wie?
Oder willst Du sie irgendwie programmatisch von Tonträgern, aus MP3-Dateien ... einlesen?

Uwe Raabe 12. Jan 2019 23:07

AW: Einfache Tabelle mit TClientDataSet
 
Zitat:

Zitat von DualCoreCpu (Beitrag 1423205)
Ich wollte einen Displaynamen für die Spalten verwenden.

Dazu kannst du entweder bei jedem Feld das Property DisplayLabel setzen oder direkt im Grid bei der Column das Property Title.Caption. Der erste Ansatz ist in der Regel vorzuziehen, weil man damit auch die automatische Spalten-Erzeugung im Grid verwenden kann, wenn keine Columns angelegt sind.

DualCoreCpu 13. Jan 2019 08:08

AW: Einfache Tabelle mit TClientDataSet
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1423212)
Zitat:

Zitat von DualCoreCpu (Beitrag 1423205)
Ich wollte einen Displaynamen für die Spalten verwenden.

Dazu kannst du entweder bei jedem Feld das Property DisplayLabel setzen

So habe ich das jetzt auch gemacht.

Zitat:

Zitat von Uwe Raabe (Beitrag 1423212)
oder direkt im Grid bei der Column das Property Title.Caption.

Da hatte bei mir das Erfassen neuer Daten nicht funktioniert. Habe das dann in die erstere Variante geändert und die DBGrid Spalten gelöscht.

Zitat:

Zitat von Uwe Raabe (Beitrag 1423212)
Der erste Ansatz ist in der Regel vorzuziehen, weil man damit auch die automatische Spalten-Erzeugung im Grid verwenden kann, wenn keine Columns angelegt sind.


Ok, dann lasse ich das so und werde dies in Zukunft auch so halten.

DualCoreCpu 13. Jan 2019 08:28

AW: Einfache Tabelle mit TClientDataSet
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1423208)
Der DBNavigator sieht so ok aus.

Der Haken und des X bzw. der Pfeil rechts sind nur aktiv, wenn es Änderungen gab.

Der Haken, um eine im Grid gemachte Änderung zu speichern, das X, um sie zu verwerfen. Rechts der Kringelpfeil kann genutzt werden, um 'ne Datenmenge neu zu laden. (Ist hier aber wohl nicht wirklich sinnvoll einzusetzen.)

Alles klar, danke!

Zitat:

Zitat von Delphi.Narium (Beitrag 1423208)
Willst Du die Daten programmatisch in Deine Datenbank schreiben oder soll die Eingabe händisch (via Grid oder Eingabefelder) erfolgen?

Händisch über DBGrid oder Eigabefelder. Die programmatische Eingabe könnte aner später interessant werden, wenn ich Daten kopieren will.

Außerdem hätte ich gerne eine Anwendung, die mir die Erstellung einer Datenbanktabelle auch dann ermöglicht, wenn ich keine Serververbindung habe. Firebird-Explorer aber verlangt zuerst eine Verbindung mit dem Server, bevor ich beginnen kann. Der Menüpunkt Create Table ist dort solange noch keine Verbindung besteht, ausgegraut. Dann brauche ich allerdings für Firebird, Interbase und Co. ein Konvertierungstool von XML nach FDB.

Zitat:

Zitat von Delphi.Narium (Beitrag 1423208)
Wenn die Daten nur in der Oberfläche erfasst werden sollen, dann ist der Quelltext nicht erforderlich.

Ist verstanden. Trotzdem wundert mich, das die Daten so nicht übernommen werden, ich hätte erwartet, die Namen meiner Felder noch mal in meinem Datensatz angezeigt zu sehen.

Zitat:

Zitat von Delphi.Narium (Beitrag 1423208)
Das Speichern von Änderung funktioniert übrigens gewöhlich auch durch das Scrollen im Grid, 'ne Zeile vor, 'ne Zeile zurück mit den Cursortasten. Der letzte Satz wird also gespeichert, wenn man 'ne Zeile nach oben geht. Klar geht auch alles per Maus und DBNavigator. Verwerfen einer Eingabe geht auch per ESC-Taste.

Ok, verstanden.

Zitat:

Zitat von Delphi.Narium (Beitrag 1423208)
Achso: Wenn sowas, wie newIndys Quelltext sinnvoll eingesetzt werden soll.
Hast Du die Daten schon irgendwie vorliegen, wenn ja, wie?
Oder willst Du sie irgendwie programmatisch von Tonträgern, aus MP3-Dateien ... einlesen?

Nein, habe ich nicht, ich gebe alles über mein DBGrid ein. Hätte gemäß dem Quelltext aber erwartet, dass ich meine Feldnamen in meiner Datentabelle angezeigt bekomme.

Delphi-Quellcode:
ClientDataSet1.Append;
ClientDataSet1.FieldByName('media').AsString := 'media';
ClientDataSet1.FieldByName('author').AsString := 'author';
ClientDataSet1.FieldByName('title').AsString := 'title';
if ClientDataSet1.State in [dsEdit, dsInsert] then ClientDataSet1.Post;
An das Feld media wird der String 'media' zugewiesen, an das Feld author der String 'author', an das Feld title der String 'title'. Diese Strings sollte ich doch dann in meiner Tabelle sehen?

Die Felder werden doch so hier angelegt:

Delphi-Quellcode:
    with ClientDataSet1.FieldDefs do begin
      Clear;
      Add('media', ftString, 3);
      Add('author', ftString, 30);
      Add('title', ftString, 40);
    end;
    ClientDataSet1.CreateDataSet;
Oder interaktiv im Designer zur Entwurfszeit.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:00 Uhr.
Seite 1 von 2  1 2      

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