AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Einfache Tabelle mit TClientDataSet

Einfache Tabelle mit TClientDataSet

Ein Thema von DualCoreCpu · begonnen am 12. Jan 2019 · letzter Beitrag vom 13. Jan 2019
Antwort Antwort
Seite 1 von 2  1 2   
DualCoreCpu

Registriert seit: 11. Sep 2009
206 Beiträge
 
#1

Einfache Tabelle mit TClientDataSet

  Alt 12. Jan 2019, 08:45
Datenbank: MyBase • Version: 10.3 • Zugriff über: localhost
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.

Geändert von DualCoreCpu (12. Jan 2019 um 08:51 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von newIndy
newIndy

Registriert seit: 18. Dez 2018
Ort: Bad Dürkheim
7 Beiträge
 
Delphi XE3 Professional
 
#2

AW: Einfache Tabelle mit TClientDataSet

  Alt 12. Jan 2019, 10:42
// 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);
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
6.503 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Einfache Tabelle mit TClientDataSet

  Alt 12. Jan 2019, 10:48
Die Spalten im Grid verweisen auf die Felder "Medium", "Autor" und "Titel", aber die eigentlichen Feldnamen sind "mediakind" bzw. "media", "author" und "title".
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
DualCoreCpu

Registriert seit: 11. Sep 2009
206 Beiträge
 
#4

AW: Einfache Tabelle mit TClientDataSet

  Alt 12. Jan 2019, 18:57
@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.

Geändert von DualCoreCpu (12. Jan 2019 um 21:06 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
770 Beiträge
 
Delphi 7 Professional
 
#5

AW: Einfache Tabelle mit TClientDataSet

  Alt 12. Jan 2019, 20:53
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?
  Mit Zitat antworten Zitat
DualCoreCpu

Registriert seit: 11. Sep 2009
206 Beiträge
 
#6

AW: Einfache Tabelle mit TClientDataSet

  Alt 12. Jan 2019, 21:28
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.

Dann die Daten anzeigen.

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

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.


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.

Geändert von DualCoreCpu (12. Jan 2019 um 22:03 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
770 Beiträge
 
Delphi 7 Professional
 
#7

AW: Einfache Tabelle mit TClientDataSet

  Alt 12. Jan 2019, 22:31
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?
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
6.503 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Einfache Tabelle mit TClientDataSet

  Alt 13. Jan 2019, 00:07
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
DualCoreCpu

Registriert seit: 11. Sep 2009
206 Beiträge
 
#9

AW: Einfache Tabelle mit TClientDataSet

  Alt 13. Jan 2019, 09:08
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.

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.

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.
  Mit Zitat antworten Zitat
DualCoreCpu

Registriert seit: 11. Sep 2009
206 Beiträge
 
#10

AW: Einfache Tabelle mit TClientDataSet

  Alt 13. Jan 2019, 09:28
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!

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.

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.

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.

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.

Geändert von DualCoreCpu (13. Jan 2019 um 09:31 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 02:01 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf