Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid2 (https://www.delphipraxis.net/55631-angeklickte-zeile-dbgrid1-als-neuen-eintrag-dbgrid2.html)

Avax2k 24. Okt 2005 16:18

Datenbank: Access • Version: 2003 • Zugriff über: SQL, OLE

angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid2
 
Wie die Überschrift bereits sagt, suche ich einen Befehl mit dem ich eine bereits im DbGrid1 angeklickte Zeile, die markiert ist, durch Knopfdruck als neuen Eintrag in DbGrid2 kopiere.
habe bereits dies ausprobiert:
DbGrid2.Fields[DbGrid1.SelectedField.asString];
geht aber nicht wenn der Eintrag ein Text ist, wenn es eine Zahl ist, passiert gar nicht sprich selbst die Zahl erscheint nach dem klicken des Buttons nicht im neuen leeren DbGrid2.

Hoffe jemand von euch kann mir diesbezüglich weiterhelfen.

PS. habe hier schon die Suchfunktion benutzt jedoch nichts passendes gefunden..habe auch das ganze Buch: Datenbankprogrammierung mit Delphi 6/7 durchgeblättert und finde zu dieser Thematik GAR NICHTS..nur eben wie ich markierte Einträge im DBText darstellen kann.

marabu 24. Okt 2005 17:13

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Das DBGrid dient nur der Visualisierung, die unterliegenden Datasets müssen für das Kopieren herangezogen werden. Wenn du mit Queries (du hast die Zugriffskomponenten nicht angegeben) arbeitest, dann ist es besonders einfach:

SQL-Code:
INSERT INTO target SELECT * FROM source WHERE NAME = :name
Grüße vom marabu

Avax2k 24. Okt 2005 18:01

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
benutze keine Queris keine Table..habe nur ADODataSet, DataSource und eben die DbGrids,

mit den Queries habe ich keine Ahnung wie ich das anstellen soll. Du hast mir zwar den befehl gepostet aber wo soll der hin ?? ..habe dies versucht was aber wohl totaler Blödsinn ist..sorry habe aber davon gar keine Ahnung :-(

ADOQuery1.DataSource := 'INSERT INTO DbGrid2.Columns.Add SELECT * FROM Datenbank Where Bezeichnung := Test';

dann bleibt ja noch die Ausgabe in DbGrid2 ..habe auch keinen Schimmer wie die lauten soll..

wäre auch dankbar, wenn ich mich irgendwo eben schlau lesen könnte falls Ihr nun keine Lust haben solltet mir den kompletten Quelltext dafür zu nennen.

Danke schonmal für die Mühen!!

marabu 24. Okt 2005 19:55

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Wie du deine DBGrids mit Daten belieferst (ADODataSet?) ist eigentlich egal, solange du weißt, wie du den gerade markierten Datensatz indentifizieren kannst. Und für den Kopiervorgang kannst du dann eine statische oder dynamische Komponente ADOQuery verwenden. Du musst dann etwa das hier machen:

Delphi-Quellcode:
var
  currentID: integer;
begin
  with ADOQuery do
  begin
    // currentID := GetCurrentIdFromSourceGrid;
    SQL.Text := 'INSERT INTO target SELECT * FROM source WHERE id = :id';
    Parameters.ParamValues['id'] := currentID;
    ExecSQL;
  end;
end;
Vorher hast du natürlich noch die richtige Connection eingetragen.

marabu

Avax2k 24. Okt 2005 22:19

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Zitat:

var
currentID: integer;
begin
with ADOQuery do
begin
// currentID := GetCurrentIdFromSourceGrid;
SQL.Text := 'INSERT INTO target SELECT * FROM source WHERE id = :id';
Parameters.ParamValues['id'] := currentID;
ExecSQL;
end;
end;
wenn ich das hier eingebe im Richtigen bezug zur Ausgabe der ID kommt folgender Fehler:
SYNTAX ERROR in INSERT INTO Statement!

wenn ich es so schreibe
Zitat:

...
SQL.Text := 'INSERT INTO target SELECT * FROM source WHERE id = id';
...
kommt ADOQuery1: Parameter 'ID' not found !!
dabei ist in beiden Tabelle die AutoZählfunktion als Spaltennamen ID eingetragen... keine Ahnung warum das jetzt nicht geht.

wer kann helfen???

marabu 25. Okt 2005 05:23

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Guten Morgen Avax2k,

du solltest einen Schritt nach dem anderen machen. Bevor du das Kopieren mit Delphi umsetzt kannst du dich in ACCESS mit dem notwendigen SQL-Statement interaktiv vertraut machen. Da ich deine Datenbank und die betroffenen Tabellen nicht kenne, habe ich dir ein allgemein gehaltenes Statement hingeschrieben. Dieses Statement geht davon aus, dass deine beiden Tabellen exakt gleich strukturiert sind und dass es keine AutoInc-Spalte gibt.

Wenn du dich mit dem INSERT-INTO-SELECT Statement anhand deiner Dokumentation vertraut gemacht hast, dann weißt du, dass du an Stelle des Sterns auch eine Spaltenliste einsetzen kannst. In deinem Fall musst du das tun, weil die Zieltabelle eine AutoInc-Spalte besitzt:

SQL-Code:
INSERT INTO target(col2, col3, col4) SELECT col2, col3, col4 FROM source WHERE id = 42
Die Spalten müssen sich von Bedeutung und Typ her entsprechen, die Namen müssen nicht in beiden Tabellen gleich sein.

Sobald du nach dem Einsetzen der korrekten Spalten- und Tabellenamen mit obigem Statement in ACCESS erfolgreich warst, übernimmst du das Statement nach Delphi. Bei der Zuweisung an ADOQuery.SQL.Text ersetzt du dann die feste Schlüsselnummer 42 durch die Parameter-Variable :id - der Name ist egal, der Doppelpunkt davor ist notwendig. Beim Setzen von SQL.Text untersucht Delphi das Statement nach solchen Parametern und stellt sie automatisch in der Eigenschaft ADOQuery.Parameters zur Verfügung, wenn ADOQuery.ParamCheck = TRUE ist (Standard). Nachdem du dann den Parameter 'id' (diesmal ohne Doppelpunkt) mit dem gewünschten Schlüsselwert initialisiert hast, kannst du das Statement ausführen.

Die von dir berichteten Fehler passen irgendwie nicht zu der von dir beschriebenen Vorgehensweise. Kann es sein, dass du beides vertauscht hast? Wenn der Parameter 'id' nicht bekannt ist, dann hast du den Doppelpunkt im SQL-Statement vergessen oder ParamCheck ist bei dir FALSE.

Jetzt tief Luft holen und systematisch vorgehen...

Freundliche Grüße vom marabu

Avax2k 25. Okt 2005 11:04

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Zitat:

danke schonmal für die hilfestellung jedoch komme ich gar nicht weiter.

der Syntax Error kommt immer wieder.
Die Ursache kann dafür sein, dass meine Access Tabelle NUR AUS TABLES besteht..ich habe da gar keine Queries drin in der Datenbank, denke deshalb geht das mit dem Query-Befehl in Delphi nicht!
Auch kann ich keine SQL Statements in einem Table in Access eintippen, in der Hilfe steht nur, dass dies mit Queries möglich ist aber wie gesagt meine Tabelle besteht nur aus Tables.

den Table-Befehl habe ich versucht aber der kennt in Delphi keine Param.Values und kein SQL.. somit bin ich soweit wie zuvor auch schon :( nämlich am Anfang.

kann ich die Tables in Queries in Access umwandeln oder wie stelle ich es dann jetzt an?..ich weiss ich nerve und man merkt es mir an, dass ich von Access und Tabellen usw. gar keine Ahnung habe..trotzdem hoffe ich, dass man geduldig mit mir ist.
habe es in Access jetzt doch geschafft auszuprobieren... der Syntax Error kam weil ich den einen der beiden Tables, Table genannt habe..nach dem Umbenennen in Kopie ist kein fehler mehr gekommen sondern eben die Meldung, dass 1 Row kopiert werden soll und danach die Undo Funktion nicht mehr geht. Somit scheint es nun zu funktionieren..In Delphi funktioniert es nun auch Ohne fehlermeldung und der markierte Eintrag ist auch schön in den Table "Kopie" hineinkopiert worden..

Danke marabu für deine Hilfestellung!!

marabu 25. Okt 2005 11:21

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Keine Panik.

Wenn du ACCESS öffnest, dann solltest du eine Übersicht finden, in der Tabellen, Reports, etc. aufgeführt werden. Unter Tabellen findest du die dir vertrauten Tabellen-Namen. Es sollte auch ein Punkt Abfragen bzw. Auswertungen oder Sichten (den genauen Namen kann ich dir nicht sagen, da ich nicht mit diesem Produkt arbeite) vorhanden sein, der bei dir allerdings leer sein wird. Wenn du diesen Punkt auswählst und dort im Kontextmenü "Neue Abfrage" auswählst, dann solltest du einen SQL-Designer vorfinden. Über einen Schalter in der Symbolleiste müsstest du ein SQL-Fenster öffnen können, in dem du ein beliebiges Statement eingeben und von dort auch ausführen kannst.

Die Query in Delphi ist etwas ähnliches. Während die Abfragen in ACCESS gespeichert werden und eigentlich Views darstellen, ist die von mir angesprochene Query in Delphi dynamisch und das Ergebnis existiert nur so lange wie du es im Programm brauchst.

Das SQL-Fenster in ACCESS brauchst du eigentlich nur zum Spielen und Üben. Dein Delphi-Programm kannst du auch ohne diesen Zwischenschritt schreiben. Ich wusste nicht, dass du auch mit ACCESS auf Kriegsfuß stehst. Ich könnte dir einen Programmrohling erstellen, wenn du mir eine Datenbank mit deinen Tabellen zur Verfügung stellst. Die Tabellen sollten natürlich leer sein.

marabu

Avax2k 25. Okt 2005 12:13

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Zitat:

begin
with ADOQuery1 do
begin
SQL.Text := 'INSERT INTO Kopie SELECT * FROM Datenbank WHERE ID = :ID';
Parameters.ParamValues['ID'] := AdoDataSet1.RecNo;
ExecSQL;
end;
so habe ich es nun zum Laufen gebracht, einziges Problem, dass ich habe ist, dass wenn ich die entsprechende Zeile kopiert habe, diese nicht sofort im DbGrid2 erscheint sondern erst bei Neustart des Programmes.

marabu 25. Okt 2005 12:17

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Wenn deinem DBGrid2 ein AdoDataSet unterliegt, dann kannst du mit dessen Methode ReQuery das Grid aktualisieren.

marabu

Avax2k 25. Okt 2005 14:25

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
wie zu erwarten bekomme ich selbst das nicht hin...gebe ein ADODataSet2.Requery();

nichts tut sich..in der Delphi Hilfe kommt auch nicht wie man den befehl verwenden soll..
auch mit ADODataSet2.Close;
und gleich ADODATASet2.Open;
lässt sich das DbGrid2 nicht aktualisieren, obwohl refresh ja auch nur das gleiche tut :(

marabu 25. Okt 2005 16:48

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe mir die Northwind-Demo-Datenbank für ACCESS besorgt. Darin erzeuge ich mir zwei Tabellen ORIGINAL und KOPIE mit (ID, NACHNAME, VORNAME) als Spalten. So wird kopiert mit anschließendem Requery:

Delphi-Quellcode:
const
  SQL_COPY
    = 'INSERT INTO kopie (id, nachname, vorname) '
    + 'SELECT id, nachname, vorname FROM original '
    + 'WHERE id = :id';

procedure TDemoForm.btnCopyClick(Sender: TObject);
var
  id: integer;
begin
  id := ADODataSet1.FieldValues['id'];
  with ADOQuery do
  begin
    SQL.Text := SQL_COPY;
    Parameters.ParseSQL(SQL.Text, true);
    Parameters.ParamValues['id'] := id;
    try
      ExecSQL;
      ADODataSet2.Requery([]);
    except
      on E: Exception do
        ShowMessage(E.Message);
    end;
  end;
end;
Wenn du das Demo-Projekt öffnest, dann musst du in der ADOConnection den Pfad zur Datenbank anpassen. Kannst auch deine eigene eintragen. Die beiden Testtabellen werden beim Programmstart erzeugt und du kannst sie mit dem Drop-Button wieder in den Eimer treten.

Viel Spaß

marabu

Avax2k 25. Okt 2005 17:43

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Danke für die Zip, hast mir wirklich weiter geholfen!!

wenn ich den ADOData AfterConnection Befehl raus nehme dann geht aber gar nichts mehr..somit war es auch unmöglich vorher nur mit dem Query und DataSet die Aktualisierung zu schaffen.

Außerdem verstehe ich nicht wieso sich die befehle wiederholen müssen damit es funktioniert..sprich die After.Connection macht ja nur das was der Copy Button macht sprich benutzt den selben Befehl..das alles scheint für mich ein Rätsel zu sein, wozu man es braucht :(..
Ohne deine Hilfe wäre ich gar nicht darauf gekommen..jetzt muss ich es nur noch irgendwie hinbekommen in mein Programm dass alles zu implementieren..wobei ich den After.Connection Event gar nicht gefunden habe..den gibt es gar nicht wenn man auf Events bei dem klickt ... naja

marabu 25. Okt 2005 18:36

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Zitat:

Zitat von Avax2k
wenn ich den ADOData AfterConnection Befehl raus nehme dann geht aber gar nichts mehr

Weil ich da die beiden Tabellen zum Spielen erzeuge. In deiner Anwendung existieren die richtigen Tabellen ja schon, also brauchst du dort dieses event nicht.

Zitat:

Zitat von Avax2k
sprich die After.Connection macht ja nur das was der Copy Button macht

Na, da hast du dich aber gewaltig verguckt. AfterConnection() erzeugt zwei Tabellen und btnCopyClick() kopiert einen markierten Datensatz aus ORIGINAL nach KOPIE.

marabu

Avax2k 25. Okt 2005 19:25

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
ja stimmt, habe mich wirklich verguckt..sorry deswegen.

was aber nicht geklärt ist, wieso funktioniert nun der Refresh Bfefehl nicht wenn man die After.Connection weglässt..sprich wenn man schon die Tabellen hat und nicht erstellt und keine ADOConnection verwendet geht es bei mir nicht.

ich verwende nur DataSource, Dataset, Query und die DbGrids sollte ja ausreichen da ja die After Connection nur dazu benutzt wird um die Tabellen zu erstellen.

Sorry wenn ich nerven sollte, aber wenn man wie ich den ganzen tag damit verbringt es zum Laufen zu bringen und trotz der von dir bereits funktionierenden Lösung es immer noch nicht begreift..kommt ein wenig der Frust auf :(

hinzu kommt noch, dass wenn man bei deiner Lösung die AfterConnection auch nach dem ersten Start weglässt, die Refresh FUnktion nicht geht..wenn du Lust und Zeit hast wäre es gut wenn du das bestätigen könntest.

marabu 25. Okt 2005 20:03

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Zitat:

Zitat von Avaxk2
da ja die After Connection nur dazu benutzt wird um die Tabellen zu erstellen

Die letzten zwei Befehle in AfterConnect() öffnen die beiden Spiel-Tabellen und müssen in meiner Demo auf jeden Fall weiter vorhanden sein!! Wenn das Open nicht ausgeführt wird, dann dürftest du in meiner Demo nicht nur mit dem Requery (warum schreibst du Refresh?) Probleme haben...

marabu

Avax2k 25. Okt 2005 20:08

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
in meinem Programm habe ich den Übernehmen-Knopf so geschrieben:

Zitat:

procedure TForm1.Button1Click(Sender: TObject);
begin
with ADOQuery1 do
begin
SQL.Text := 'INSERT INTO Kopie SELECT * FROM Datenbank WHERE ID = :ID';
Parameters.ParseSQL(SQL.Text, true);
Parameters.ParamValues['ID'] := AdoDataSet1.FieldValues['ID'];
ExecSQL;
AdoDataSet2.Requery([]);
end;
wie du siehst habe ich in meiner Datenbank 2 Tables..der eine heißt Kopie und der andere Datenbank.
Wenn ich nun auf den Button drücke wird das was ich angeklickt habe auch kopiert..nur eben das DbGrid2 welches von DataSet2 gefüttert wird, wird erst nach neustart der Applikation aktualisiert, obwohl der Refresh des AdoDataset2 drin ist und funktionieren müsste..tut er das aber nicht und ich weiss jetzt eben nicht warum.

eine Connection brauche ich dafür nicht..oder etwa doch ??

marabu 25. Okt 2005 20:13

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Du brauchst nur eine Connection pro Datenbank. Es irritiert übrigens, wenn du eine Tabelle mit DATENBANK benennst, aber das nur nebenbei. Wenn deine Daten zwar kopiert, aber nicht angezeigt werden, dann verrate mir mal, welchen IsolationLevel du bei deiner Connection eingestellt hast.

marabu

Avax2k 25. Okt 2005 20:21

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
IsolationsLevel ist ilCursorStability

marabu 25. Okt 2005 20:30

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Ich verwende den gleichen IsolationLevel und bei mir funktioniert es. Bei den von dir verwendeten Namen unterstelle ich mal, dass du mit einer Testapplikation auf einer Testdatenbank arbeitest. Wenn da keine geheimen Daten drin stehen und du magst, kannst du Quellen PAS, DFM, DPR, RES und Daten MDB einpacken und hier einstellen oder auch per PN an mich. Ich weiß sonst nicht wie ich dir weiter helfen kann, denn meine Demo funktioniert doch auch bei dir, wenn du das Open im AfterConnect() ausführst - oder?

marabu

Avax2k 25. Okt 2005 20:39

Re: angeklickte Zeile in DBGrid1 als neuen Eintrag in DBGrid
 
Hallo marabu,

dankeschön für das Angebot, jedoch bin ich endlich auf den Fehler gekommen an dem es lag, dass es nicht aktualisiert hat und zwar habe ich die Query nicht mit AdoConnection sondern mit DataSource1 verbunden gehabt..ich Trottel :roll:

jetzt wird DbGrid2 sofort aktualisiert, wenn ich den Hinzufügen Button klicke! :mrgreen:

hab nochmal vielen Dank für deine Zeit und Geduld!


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz