AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Dataset ADOQuery in ein Clientdataset kopieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dataset ADOQuery in ein Clientdataset kopieren

Ein Thema von SusiT · begonnen am 6. Okt 2023 · letzter Beitrag vom 11. Okt 2023
Antwort Antwort
Seite 1 von 2  1 2      
SusiT

Registriert seit: 15. Mai 2014
29 Beiträge
 
#1

Dataset ADOQuery in ein Clientdataset kopieren

  Alt 6. Okt 2023, 11:33
Hallo die Damen und Herren,

mich beschäftigt seit geraumer Zeit ein triviales Problem wie ich vermute.
Ich habe eine ADOQuery, gefüllt mit Daten und möchte diese an ein Clientdataset übergeben.
Dies gelingt aus nicht nachvollziebaren Gründen nicht.

Eine Variante wäre Folgende:

Delphi-Quellcode:
procedure TDataContainer.fillupdataset;
var
  i : Integer;
  s : String;

  TempProvider : TDataSetProvider;
  ClientDataSet1 : TClientDataSet;
begin
  
  ClientDataSet1 := TClientDataSet.Create(nil);
  TempProvider := TDataSetProvider.Create(nil);
  
  TempProvider.DataSet := fDataContainerDbThread.ADOQuery;

  i := TempProvider.DataSet.RecordCount; // ist in Ordnung, i ist größer 0
  
  ClientDataSet1.Data := TempProvider.Data;

  i := ClientDataSet1.RecordCount; // hier ist in i immer 0. Die Übergabe klappt nicht

  TempProvider.Free;

end;
Habe schon eine ganze Menge verschiedene Variante probiert aber es klappt nicht.

Was ist der einfachste Weg, Daten in ein CDS zu duplizieren?

Auch wenn ich das CDS mit einem Provider verknüpfe gibt es nicht den gewünschten Erfolg.

Zusatzfrage:
Alle Komponenten werden in Runtime Created. Welchen Owner kann man hier angeben. Dieser Sollte vom Typ TComponent sein, aber TComponent habe ich nicht, da es keine Formularanwendung ist

Viele Grüße und vielen Dank

Geändert von SusiT ( 6. Okt 2023 um 21:03 Uhr)
  Mit Zitat antworten Zitat
Papaschlumpf73

Registriert seit: 3. Mär 2014
Ort: Berlin
315 Beiträge
 
Delphi 12 Athens
 
#2

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 6. Okt 2023, 14:42
Moin, ich mache das mit dieser proc. TDM ist einfach nur mein DataModule

Delphi-Quellcode:
procedure TDM.CopyDataSetToCDS(Source: TDataSet; Dest: TClientDataSet; CloseSource: boolean);
var dsProvider: TDataSetProvider;
begin
{GetText in der Source funktioniert nicht}
{Filter in der Source funktioniert}
dsProvider:=TDataSetProvider.Create(nil);
try
 dsProvider.DataSet:=Source;
 Dest.SetProvider(dsProvider);
 Dest.Open;
finally FreeAndNil(dsProvider); end;
if CloseSource then Source.Close;
end;
  Mit Zitat antworten Zitat
SusiT

Registriert seit: 15. Mai 2014
29 Beiträge
 
#3

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 6. Okt 2023, 19:10
Besten Dank für dein Feedback.
Ich habe eine kleine Demo gemacht und bekomme die gleichen Probleme wie vorher
Delphi-Quellcode:
unit DM;

interface

uses
  System.SysUtils, System.Classes, Datasnap.Provider, Data.DB, Datasnap.DBClient;

type
  TDataModule1 = class(TDataModule)
    cds1: TClientDataSet;

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure testemal(ds : TDataSet);
    procedure CopyDataSetToCDS(Source: TDataSet; Dest: TClientDataSet; CloseSource: boolean);
  end;

var
  DataModule1: TDataModule1;

implementation

{%CLASSGROUP 'System.Classes.TPersistent'}

{$R *.dfm}

procedure TDataModule1.testemal(ds : TDataSet);
var
  a : Integer;
begin

  a := ds.RecordCount;
  // in a steht 17, das ist auch korrekt

  DataModule1.CopyDataSetToCDS(
      ds,
      cds1,
      false
  );

  a := cds1.RecordCount;
  // in a steht 0. Der Übertrag hat nicht geklappt?!
end;

procedure TDataModule1.CopyDataSetToCDS(Source: TDataSet; Dest: TClientDataSet; CloseSource: boolean);
var dsProvider: TDataSetProvider;
begin
{GetText in der Source funktioniert nicht}
{Filter in der Source funktioniert}
dsProvider:=TDataSetProvider.Create(nil);
try
 dsProvider.DataSet:=Source;
 Dest.SetProvider(dsProvider);
 Dest.Open;
finally FreeAndNil(dsProvider); end;
if CloseSource then Source.Close;
end;
end.
Ich erwarte an der Stelle

a := cds1.RecordCount das in a die gleiche Anzahl der Records enthalten ist, wie im dataset ds.

Habe ich hier irgendeinen Gedankenfehler?

Das ganze ist in einem Datamodul und die CDS liegt auf der Form.
Der Aufruf von testemal kommt von aussen, aber im dataset ds ist injedemfall Inhalt.

Es bleibt spannend

Geändert von SusiT ( 6. Okt 2023 um 21:03 Uhr)
  Mit Zitat antworten Zitat
SusiT

Registriert seit: 15. Mai 2014
29 Beiträge
 
#4

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 6. Okt 2023, 21:00
Nach ewigen probieren bin ich zu einer Variante gelangt die anscheinend funktioniert. Es ist mir allerdings ein totales Rätsel warum das so ist.
Delphi-Quellcode:
procedure TDataModule1.CopyDataSetToCDS(Source: TDataSet; var Dest: TClientDataSet; CloseSource: boolean);
var dsProvider: TDataSetProvider;
  I: Integer;
  a: Boolean;
begin
{GetText in der Source funktioniert nicht}
{Filter in der Source funktioniert}
dsProvider:=TDataSetProvider.Create(self);
try
 dsProvider.DataSet:=Source;

 a := Dest.Data = dsProvider.Data;

 Dest.SetProvider(dsProvider);
 Dest.Open;

finally FreeAndNil(dsProvider); end;
if CloseSource then Source.Close;
end;
end.
Wenn exakt an der Stelle oben im Code

 a := Dest.Data = dsProvider.Data; eingefügt wird, dann erhalte ich auch wie erwartet an folgender Stelle den Wert 17

a := cds1.RecordCount; Allerdings, die zugefügte Codezeile ergibt keinen Sinn.
Dest.Data ist an der Stelle immer null, a wird immer False.
trotzdem passiert irgendwas, dass dazu führt, dass im cds aufeinmal alle Daten drin sind.

Ich könnte auch

Delphi-Quellcode:
 if Dest.Data = dsProvider.Data then
 begin
 end;
ergänzen, das hat den selben positiven Effekt.

Ein Timingproblem scheint es nicht zu sein. Ich habe an der Stelle das Programm durch eine Schleife im Ablauf verzögert. Das hat nichts gebracht.

Tja, da weiß ich nicht weiter. Vermutlich fehlt irgendein Schritt mit dem Dest oder dem Provider, der durch die eingefügte Zeile im Hintergrund ausgelöst wird.

Viele Grüße und gute Nacht
  Mit Zitat antworten Zitat
Papaschlumpf73

Registriert seit: 3. Mär 2014
Ort: Berlin
315 Beiträge
 
Delphi 12 Athens
 
#5

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 6. Okt 2023, 23:36
Keine Ahnung, was du da gemacht hast. Hier vielleicht noch ein paar Hinweise - zumindest mache ich es so und es funktioniert immer. Bevor der die Copy-Proc aufgerufen wird sollte:
  • der Datensatzzeiger der Source auf Record 1 stehen; nicht am Ende
  • das ClientDataSet bereits alle Datenfelder enthalten
  • das ClientDataSet leer und geschlossen sein
Wenn das alles nicht hilft, empfiehlt es sich mit einem vereinfachten Beispiel anzufangen, ohne irgendwelche Schleifen, Filter, Calcfields und was da vielleicht sonst noch drin ist.
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
662 Beiträge
 
#6

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 7. Okt 2023, 12:31
Du scheinst, wie Papaschlumpf73 schreibt, auf dem letzten Datensatz zu stehen.

Probiere mal Folgendes aus:

Delphi-Quellcode:
procedure TForm1.CopyDataSetToCDS(Source: TDataSet; Dest: TClientDataSet; CloseSource: boolean);
var
  dsProvider: TDataSetProvider;
  inscount: Integer;
begin
  dsProvider := TDataSetProvider.Create(nil);
  try
   dsProvider.DataSet := Source;

   dsProvider.GetRecords(-1, inscount, 0); // !!! Lade alle Records !!!

   Dest.SetProvider(dsProvider);
   Dest.Open;
  finally
    FreeAndNil(dsProvider);
  end;
  if CloseSource then
    Source.Close;
end;
  Mit Zitat antworten Zitat
SusiT

Registriert seit: 15. Mai 2014
29 Beiträge
 
#7

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 7. Okt 2023, 16:01
Ich kann mich nur bei euch bedanken.

Sowohl den Sourcedatensatz auf .First

setzen als auch die GetRecords Variante führen zum gewünschten Ergebnis.

Soviele verschiedene Varianten die ich probiert habe aber auf die triviale Idee bin ich nicht gekommen.

Vielen Lieben Dank an euch!
  Mit Zitat antworten Zitat
SusiT

Registriert seit: 15. Mai 2014
29 Beiträge
 
#8

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 8. Okt 2023, 11:16
Hallo, ich muss euch doch nochmal belästigen.

Grundsätzlich dachte ich, dass es funktioniert. Das tut es auch allerdings nur im ersten Durchlauf. Danach wird das ZielCds nicht erneut aktualisiert.

Folgende 2 Varianten habe ich erstellt:

Einmal mit einem CDS das global erstellt wurde und bei jedem Durchlauf geleert werden soll:

Delphi-Quellcode:

testCDS_global : TClientDataSet;
...
testCDS_global := TClientDataSet.Create(self);
Delphi-Quellcode:
procedure TDataContainer.fillupdataset;
var
  a,b : Integer;
begin
  try
    if testCDS_global.Active then
    begin
      testCDS_global.Open;
      testCDS_global.EmptyDataSet;
    end;
  except
    a:=a;
  end;

  try
    // a = Anzahl der Einträge im ADOquery dataset
    a := fDataContainerDbThread.ADOQuery.RecordCount;

    CopyDataSetToCDS(
      fDataContainerDbThread.ADOQuery,
      testCDS_global,
      false
    );

    b := testCDS_global.RecordCount;
  finally

  end;
end;
Diese Prozedur füllt das testCds nur beim ersten Durchlauf, sobald das CDS einmal erstellt, gefüllt und beim Durchlauf EmptyDataSet gemacht wurde, dann klappt das nicht mehr.


Folgende Prozedur führt zu einer Aktualisierung bei jedem Durchlauf:

Delphi-Quellcode:
procedure TDataContainer.fillupdataset2;
var
  a,b : Integer;
  testCDS_lokal : TClientDataSet;
begin
  testCDS_lokal := TClientDataSet.Create(nil);

  try
    // a = Anzahl der Einträge im ADOquery dataset
    a := fDataContainerDbThread.ADOQuery.RecordCount;

    CopyDataSetToCDS(
      fDataContainerDbThread.ADOQuery,
      testCDS_lokal,
      false
    );

    b := testCDS_lokal.RecordCount;
  finally
    FreeAndNil(testCDS_lokal);
  end;
end;
Heißt, es muss einen Unterschied zwischen einem neu createden CDS und einem CDS das mit EmptyDataSet behandelt wurde geben.
Ich komme nicht drauf


Vollständigkeitshalber:

Delphi-Quellcode:
procedure TDataContainer.CopyDataSetToCDS(Source: TDataSet; Dest: TClientDataSet; CloseSource: boolean);
var
  dsProvider: TDataSetProvider;
  a,b : Integer;
begin
  dsProvider := TDataSetProvider.Create(nil);
  try
    Source.First;
    dsProvider.DataSet := Source;

    dsProvider.GetRecords(-1, a, 0); // !!! Lade alle Records !!!

    Dest.SetProvider(dsProvider);
    Dest.Open;
  finally
    FreeAndNil(dsProvider);
  end;
  if CloseSource then
    Source.Close;
end;
Zusatzfrage:
Wenn die Variable dsProvider auf FreeAndNil gesetzt wird, woher kennt das das Sourcedataset im Anschluss dann noch seinen Provider? Das scheint an dieser Stelle egal zu sein? Der dsProvider ist ja ohnehin nur in dieser Prozedur verfügbar..
  Mit Zitat antworten Zitat
Papaschlumpf73

Registriert seit: 3. Mär 2014
Ort: Berlin
315 Beiträge
 
Delphi 12 Athens
 
#9

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 8. Okt 2023, 11:38
Das hier ist schon mal nicht so toll.

Delphi-Quellcode:
   if testCDS_global.Active then
    begin
      testCDS_global.Open;
      testCDS_global.EmptyDataSet;
    end;
Wenn das CDS aktiv ist, dann soll er es öffnen? Nein, das kann es nicht sein.
Das würde ich erstmal ändern in:

Delphi-Quellcode:
   if testCDS_global.Active then
   begin
     testCDS_global.EmptyDataSet;
     testCDS_global.Close;
   end;
Dann hast du für die Copy-proc ein leeres, geschlossenes ClientDataSet.
  Mit Zitat antworten Zitat
SusiT

Registriert seit: 15. Mai 2014
29 Beiträge
 
#10

AW: Dataset ADOQuery in ein Clientdataset kopieren

  Alt 8. Okt 2023, 13:13
An der Stelle habe ich auch schon probiert. Ich bekomme beim Close immer einen "schwerwiegenden Fehler" angezeigt.
Aus diesem Grund habe ich das Close wieder entfernt.

Aber grundsätzlich macht das Sinn was du schreibst.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 19:18 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