Autor Beitrag
Olli_Sahr
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 83


D5 Prof, D7 Architect
BeitragVerfasst: Mi 10.05.06 07:48 
Hallo,

ich habe eine Access Datenbank, die ich mit KaDao an meine Anwendung anbinde.
Das ist aber nicht das Problem, da ich die Datensätze mit TDataSource Komponenten anspreche.

Ich habe also

FActiveDataSource.DataSet.Insert (neuen Datensatz hinzu)
FActiveDataSource.DataSet.Edit (aktuellen Datensatz editieren)
FActiveDataSource.DataSet.Delete (aktuellen Datensatz löschen)
FActiveDataSource.DataSet.Post (aktuellen Datensatz speichern)
FActiveDataSource.DataSet.Cancel (aktuellen Datensatz rückgängig, also nicht speichern)

Die gesamte Kommunikation mit den Daten funktioniert also über ein TDataSource.

Nun stehe ich vor dem Problem, dass ich den aktuellen Kunden duplizieren will (also eine 1:1 Kopie).
Das sollte doch auch irgendwie über ein TDataSource möglichn sein, ohne dass ich manuell jedes Feld des Kunden per Hand kopieren muss.

Wer hat bitte eine Idee für mich?

Danke und Gruß


OLLI
Olli_Sahr Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 83


D5 Prof, D7 Architect
BeitragVerfasst: So 28.05.06 17:07 
Liebe Community,

hat wirklich niemand eine Lösung?
Das Problem ist, dass sich meine Anzahl der Datenelemente verändern kann (bei den Kundendaten können noch Felder dazu kommen) und ich will da nicht auch noch eine Datensatz-Kopier-Funktion jedes mal anpassen.

Gruß und Danke


OLLI
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: So 28.05.06 17:13 
Eine Funktion/Methode die gaenau das macht kenne ich nicht du kannst die aber den Datensatz wegschreiben und dann einfügen. (.GetFieldsData/.setFields)

_________________
Markus Kinzler.
Robert.Wachtel
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 895
Erhaltene Danke: 7

Windows 7 Ultimate x64
D5 Ent, D7 Arch, RAD Studio 2010 Pro, VS 2008
BeitragVerfasst: So 28.05.06 20:55 
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:
25:
26:
27:
28:
29:
{ Duplizieren des aktuellen Records des übergebenen Datasets }

procedure DuplicateCurrentRecord(aDataSet: TDataSet);
var
  Data: array of variant;
  aRecord: array of TVarRec;
  i: integer;
  max: integer;
begin
  max := aDataSet.fields.count - 1;
  // set the lenghth of the arecord array to be the same as the number of
  // elements in the data array
  SetLength(arecord, max + 1);
  SetLength(data, max + 1);

  // set the variant type pointers to the data array
  for i := 0 to max do
  begin
    arecord[i].VType := vtVariant;
    arecord[i].VVariant := @data[i];
  end;

  // Copy the Record to the Array
  for i := 0 to max do
    Data[i] := aDataSet.fields[i].value;

  aDataSet.Insert;
  aDataSet.SetFields(aRecord);
end;
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 29.05.06 08:32 
Hier noch eine andere Variante:
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:
procedure KopiereAktuellenDatensatzMitAppend(qQuelle, qZiel : TDataset; Speichern : Boolean);
var
  cnt : Integer;
  arr : array of variant;
begin
  if qQuelle.Active and (not DBEmpty(qQuelle)) then
  begin
    SetLength(arr, qQuelle.FieldCount);
    for cnt := 0 to qQuelle.FieldCount - 1 do
    begin
      arr[cnt] := qQuelle.Fields[cnt].AsVariant;
    end;
    qZiel.Append;
    for cnt := 0 to qZiel.FieldCount - 1 do
    begin
      qZiel.Fields[cnt].AsVariant := arr[cnt];
    end;
    if Speichern then
    begin
      qZiel.Post;
    end;
  end;
end;

Dafür benötigst du noch diese Funktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Function DBEmpty(dts : TDataSet) : Boolean;
begin
  Result := not dts.Active;
  if not Result then
  begin
    Result := dts.eof and dts.bof;
  end;
end;

Meine Variante hat den Vorteil, dass vorher noch geprüft wird, ob überhaupt kopiert werden kann (DataSet ist Active und es sind Daten vorhanden), die DataSets können auch unterschiedlich sein und man kann bestimmen, ob der Datensatz automatisch gespeichert wird oder nicht. Bei Roberts Variante gefällt mir das hier besser: aDataSet.SetFields(aRecord);
Was Roberts und meine Routinen nicht berücksichtigen, sind Tabellenfelder mit AutoInc-Funktion. Solltest du sowas haben, musst du das entsprechend anpassen.
JohannPeter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Do 24.04.14 17:02 
Hallo,
Bin auf der Suche nach Datensatz kopieren aus dem DBGrid zu diesen Beitrag gestoßen.
Ich verwende eine Access- (mdb und accdb) und eine Paradox-Datenbank. Kann ich diesen Quellcode auch verwenden wenn ich den Primären Index auf den ReordCount habe? Denn dieser soll sich ja erhöhen.
Ich verwende TADOTable mit TDataSource.

Vielen Dank für eure Hilfe
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 28.04.14 08:11 
Ja, aber:
Du musste entweder den Code anpassen, weil er im jetzigen Zustand alle Felder kopiert. Du müsstest also beim Aufruf übergeben, welches Feld nicht kopiert werden soll und welchen Wert das Feld dann haben soll. Das kann man natürlich auch direkt im Code fest einbauen. Das ist Geschmackssache.
Oder:
Du setzt den Parameter "Speichern" auf False und setzt das Feld für den primären Index nach dem Aufruf manuell und kümmerst dich dann selbst um das "Post".
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 28.04.14 10:20 
user profile iconJohannPeter hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
Bin auf der Suche nach Datensatz kopieren aus dem DBGrid zu diesen Beitrag gestoßen.
Ich verwende eine Access- (mdb und accdb) und eine Paradox-Datenbank.

Verstehe ich dich richtig: Du willst einen Datensatz aus einer Paradox-Datenbank in eine Access-Datenbank übertragen?
JohannPeter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Mi 05.11.14 18:32 
Einen schönen Abend.

Entschuldigung, dass ich mich erst jetzt melde.
Befasse mich erst jetzt wieder mit diesen Problem.
@Perlsau:
Nein, dass hast du leider falsch verstanden. Ich will einen Datensatz in einer Access-Datenbank kopieren aber so dass sich der RecordCount um 1 erhöht.
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 06.11.14 09:04 
user profile iconJohannPeter hat folgendes geschrieben Zum zitierten Posting springen:
Einen schönen Abend.

Entschuldigung, dass ich mich erst jetzt melde.
Befasse mich erst jetzt wieder mit diesen Problem.
@Perlsau:
Nein, dass hast du leider falsch verstanden. Ich will einen Datensatz in einer Access-Datenbank kopieren aber so dass sich der RecordCount um 1 erhöht.


Dann war deine Erwähnung der Paradox-Datenbank nicht nur unnötig, sondern grob irreführend :lol:

Also der RecordCount (auf deutsch: Anzahl der Datensätze) erhöht sich immer, wenn du einen neuen (bzw. weiteren) Datensatz anlegst. Was du vermutlich meinst, ist der Wert der Id-Spalte, die du vermutlich auf AutoInc gestellt hast. Gibt es in deiner Tabelle überhaupt eine solche Spalte?

Als Anregung dürfte es vielleicht nützlich sein, Anfragen in Fachforen immer so konkret wie nur möglich zu stellen, wenn man wirklich konkrete Hilfe erwartet. Ansonsten drohen Hilfeversuche in eine wenig hilfreiche Herumraterei auszuarten ...
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 06.11.14 22:18 
Das einfachste ist einfach den ActiveBuffer zu nutzen. Einfach komplett in einen anderen Speicherbereich kopieren, neuen Datensatz anlegen und den Bufferinhalt wieder in ActiveBuffer schreiben. Schneller geht es nicht.