Ich habe den Thread "Einfügefehler - Aber Warum?" auf gelöst gesetzt, weil ich den Fehler gefunden habe.
Es scheint doch so zu sein, dass dieses Access Vorgabemakro nur für ganz normale Felder funktioniert.
Sobald man ein Feld hat, das kein Feld für Datenbankdaten ist, die gespeichert werden, ist das Makro hinfällig.
Es wäre interessant, ob es da eine Möglichkeit gibt, bestimmte Feld von dieser DS Copy-Methode auszuschließen.
Man stelle sich mal vor, ein Formular mit 50 Datenfeldern. Jetzt kann man diesen DS nicht kopieren, weil eines der Felder diesen Einfügefehler hervorruft. Das ist doch ärgerlich.
Hat dafür jemand einen Tipp wie man in diesem Standard-Makro Felder ausschließen kann?
Gruß Achim
Hallo,
ZitatSobald man ein Feld hat, das kein Feld für Datenbankdaten ist
... und das wäre?
Wobei ich mir auch die Frage stelle, wozu du in deiner Datenbank Datensätze von Tabelle 'A' nach Tabelle 'B'
KOPIEREN willst?
Hallo,
Zitat... und das wäre?
vermutlich ungebunden Felder.
Aber die DS Copy-Methode halte ich für diesen Fall ohnehin für ungeeignet. Egal ob mit Makro oder VBA. Man kann keine Felder ausschließen.
Besser wäre es eine Anfügeabfrage zu verwenden, die nur die Felder beinhaltet die man auch benötigt bzw. kopieren will. Diese Abfrage kann man dann per VBA (oder notfalls per Makro) ausführen.
Aber auch stelle mir die Frage, wozu man ganze Datensätze kopieren will.
Das sollte man in einer Datenbank nicht benötigen.
Hallo,
Zitat...Man kann keine Felder ausschließen...
Um das zu erreichen müsstest du statt einer vorgefertigten Funktion selbst eine schreiben - in VBA - oder eben den Vorschlag von MzKlMu verwenden
... und bitte - wenn's irgend wie machbar ist vergiss die Makros :'(
Ich glaube, ich muss hier noch etwas weiter ausholen mit meiner Erklärung.
Also,
ich habe ein einziges Formular und eine einzige Tabelle mit den Daten dazu.
Der Fehler wird produziert, weil beim Versuch den DS zu kopieren und hinten wieder anzufügen dieses eine ungebundene Feld "Unifilter" nicht kopiert werden kann.
Es ist mein "Universalsuchfeld über viele Datenfelder"
Siehe hier:
Private Sub UniFilter_Change() 'Universalfilter
Me.Filter = "Art_Tool & Bearbeitungsart & Mitarbeiter & Kunde & Werkzeug & Schneidstoff & Festigkeit & Beschichtung & C & Material & Bezeichnung & Durchmesser & Durchmesser_Zusatz & Maschinentyp & Bemerkungen like '*" & Me!UniFilter.Text & "*'"
Me.FilterOn = True
End Sub
Private Sub UniFilter_DblClick(Cancel As Integer) 'Universalfilter Feld leeren
Me.UniFilter = ""
Me.Filter = ""
Me.FilterOn = False
End Sub
Und jetzt ergibt sich folgende Situation:
Ich will einen neuen DS eingeben und brauche lediglich nur 3 von 40 Formularfelder ändern, der Rest ist gleich. Der zu kopierende DS ist aber nicht der letzte in der DB, sondern irgendeiner mittendrin.
Da ist doch die vorgefertigte Makro-Routine (Copy, hinten anfügen) von Access im Grunde genommen gut geeignet.
Geht aber nicht, weil diese Feld "UniFilter" die Methode nicht unterstützt.
Wie also kann ich einen DS kopieren und hinten anfügen?
Ich hoffe, mein Anliegen jetzt besser dargestellt habe.
Gruß Achim
Hallo,
Wie also kann ich einen DS kopieren und hinten anfügen? Ich hoffe, mein Anliegen jetzt besser dargestellt habe.Dein Anliegen war die ganze Zeit klar. Du hast auch schon Hinweise bekommen zur Lösung. Mit der Copy Methode geht es nicht.
Du musst die bereits vorgeschlagene Anfügeabfrage verwenden, mit der Du gezielt nur die Felder kopieren kannst die in der Tabelle auch enthalten sind. Eine solche Abfrage kannst Du auch mit einem Button über VBA Code aufrufen.
CurrentDb.Execute "Abfragename", dbFailOnErrorDie Abfrage musst Du erstellen und speichern.
Zitat
und brauche lediglich nur 3 von 40 Formularfelder ändern, der Rest ist gleich.
Sind das immer die gleichen 3 Felder die geändert werden?
Ich kann euren ganzen Ausführungen nicht folgen, weil da vieles an mir vom Verständnis her vorbeigeht. Anfügeabfrage? Ich habe ja nicht mal 2 Tabellen. Wie soll ich denn da was anfügen?
Ich werde dieses Thema hier mal beenden, weil ich es mir mit niemanden hier verderben will. Ihr habt mir schon sooft geholfen. Dafür bin ich sehr dankbar.
Ich habe mir mal eine für mich ganz einfach Lösung gestrickt.
Ich habe das Formular 2x in meinem System.
Und dieses 2. "Annähernd - Klone - Formular" hat lediglich nur die Felder drin, die auch kopiert werden können.
Und wenn ich einen DS kopieren will und hinten anfügen, dann wechsele ich einfach in das andere Formular und schon gibt es keine Probleme mehr.
Ist vielleicht eine blöde Lösung, aber die kann ich nachvollziehen.
Gruß Achim
Hallo,
ZitatWie soll ich denn da was anfügen?
na an die gleiche Tabelle. Mit einer Anfügeabfrage kannst Du an die gleiche Tabelle anfügen. Dazu benötigst Du keine weitere Tabelle.
Man könnte Dir ja möglicherweise bessere Ratschläge geben, aber Du beantwortest ja auch keine Fragen:
Zitat von: MzKlMuAber auch ich stelle mir die Frage, wozu man ganze Datensätze kopieren will.
und:
Sind das immer die gleichen 3 Felder die geändert werden?
Ich habe mir eine kleine DB gebastelt, die ich beruflich nutze, um mal etwas nachzuschlagen.
Es handelt sich um Einsatzdaten / Parameter von Werkzeugen, die bei einem Kunden im Einsatz sind.
Das sind etwas mehr als 40 Datenfelder.
Beispiel:
Ein Kunde, der ein Problem hat ein Tool richtig einzusetzen, bittet mich um Hilfe. Jetzt gehe ich in meine DB und schau mal, was ich da so finde.
Nun entscheide ich mich die gleichen Daten zu nehmen wie ich sie hier für einem anderen Kunden finde. Ich nehme diese Daten; sie funktionieren gut mit ein paar kleinen Änderungen wichtiger Parameter.
So, jetzt sind Beispielsweise von den etwas mehr als 40 Datenfeldern lediglich 7, die andere Werte erhalten. Welch ein Aufwand, wenn ich jetzt einen neuen DS einfüge und alle Felder eintragen muss. Grauenhaft.
Also macht es doch totalen Sinn, einen DS als Kopie hinten anzufügen und lediglich die 7 Felder zu verändern, oder?
Zitat
Aber auch stelle mir die Frage, wozu man ganze Datensätze kopieren will.
Das sollte man in einer Datenbank nicht benötigen
Dazu darf ich mir hier als "Nullchecker" doch die Bemerkung erlauben und nachfragen warum Access dieses DS kopieren und hinten anfügen von Haus aus mitbringt, oder?
Okay, kommen wir nochmal auf diese Anfügeabfrage zurück.
Ich bin in meinem Formular und habe einen DS gefunden, den ich jetzt hinten in der Tabelle anfügen will. Jetzt bin ich wieder bei meinem CommandButton, wo ich draufklicke, der DS als Anfügeabfrage hinten dran gesetzt wird und nun als neuer DS bearbeitet werden kann. Und während dieser ganzen Aktion verlasse ich mein Formular nicht mal. Also alles im Hintergrund. Das bekomme ich nicht hin.
Daher ist der einfachste Weg für mich mit 2 Formularen zu arbeiten.
Gruß Achim
Hallo,
ZitatAlso macht es doch totalen Sinn, einen DS als Kopie hinten anzufügen und lediglich die 7 Felder zu verändern, oder?
das möchte ich bezweifeln. Eine solche Tabelle ist ja nicht normalisiert. Und um vernünftig mit Access arbeiten zu können, ist nun mal eine datenbankgerechte Datenstruktur erforderlich.
Du benötigst ja mindestens mal eine reine Kundentabelle die nur die Kundendaten enthält.
Ein neuer Kunde ist dann ein neuer Datensatz, der dann auch komplett neu angelegt werden muss. Die Parameter sind in einer eigenen Tabelle zu führen mit einem Bezug zum Kunden. Wahrscheinlich sind noch mehr Tabellen erforderlich.
Zitatdoch die Bemerkung erlauben und nachfragen warum Access dieses DS kopieren und hinten anfügen von Haus aus mitbringt, oder?
bei Access gibt es jede Menge Dinge die man nicht benötigt, obwohl diese von Haus aus drin sind.
Ich danke da z.B. an Nachschlagefelder in Tabellen oder in den neueren Versionen die Mehrwertfelder. Diese Felder verhindern sogar den sauberen Aufbau einer DB obwohl von Haus aus eingebaut.
Es gibt z.B. auch Menübefehle die man über VBA mit Menünummern aufrufen kann. Wenn man jetzt per VBA ein Menü ändert, führen die von Haus aus eingebauten VBA Befehle zum Absturz von Access.
Also was in Access vorhanden ist, ist keinesfalls ein Merkmal für die Sinnhaftigkeit.
Zitatkommen wir nochmal auf diese Anfügeabfrage zurück.
Du kannst Dir mit dem Abfrageentwurf eine Anfügeabfrage zusammenbauen die einen Datensatz mit einem bestimmten Kriterium hinten anfügt. Für 2 Felder sieht eine Abfrage so aus:
INSERT INTO TabellenName ( TextA, IDFeld )
SELECT TextA, IDFEld
FROM TabelleName
WHERE IDFeld=11Für das Kriterium 11 kann dann das ID Feld des aktuellen Datensatzes im Formular verwendet werden.
Als Code für den Button dann:
CurrentDb.Execute "INSERT INTO TabellenName ( TextA, IDFeld ) SELECT TextA, IDFeld FROM TabelleName WHERE IDFeld= " & Me.FormularfeldMitID, dbFailOnError
Ich glaube, dass ist mir alles zu kompliziert und bleibe besser bei meiner "Nullchecker-Lösung".
Gruß Achim
Na Komm,
aufgegeben wird ein Brief!
Das ist doch gar nicht so schwer ...
Ich habe dir ein kleines Beispiel dazu erstellt, mit einer Tabelle, einem Formular und einer Abfrage.
Am Formular befindet sich ein Button, der das Kopieren des aktuell angezeigten Datensatzes veranlasst und danach auf den neu angefügten Datensatz springt.
Es werden alle Daten angefügt nur das Feld 'Status' soll leer bleiben.
Die gespeicherte Abfrage soll dir als Veranschauungsmuster dienen, ausgeführt wird die ganze Kopieraktion per VBA.
Den Code habe ich - hoffentlich - verständlich auskommentiert.
Wenn du das in deiner DB so nachbaust sollte eigentlich nix schiefgehen. ::)
Beachte bitte unabhängig von der vorgeschlagenen Lösung, dass wie MzKlMu bereits angemerkt hat,
das Datenkonstrukt, welches du da zum Einsatz bringst nicht normalisiert ist.
Auch bei kleinen Datenbanken schadet es kaum sich an die Regeln und Vorgaben eines relationalen Datenbankdesigns zu halten 8) ;)
Bei Fragen melde dich einfach wieder
Okay, ich habe mal deine Beispieldatei versucht umzusetzen.
Ich habe nur einige Datenfelder genommen.
Was hat das zu bedeuten?
"WHERE P_ID = " & Me.K_ID, dbFailOnError
Der Primärschlüssel P_ID lautet bei mir Tool_ID. Das ist okay und klar.
Aber das K_ID habe ich nicht; es ist bei dir ein reines Bezeichnungsfeld, scheinbar ohne Funktion. Also habe ich einfach mal irgendein Bezeichnungsfeld genommen.
Starte ich das Makro, bekomme ich einen Laufzeitfehler 438. Methode wird nicht unterstützt.
Das kann doch nicht an diesem einen Bezeichnungsfeld liegen.
Und dann gibt es da noch eine Abfrage ohne einer echten Entwurfsansicht. (qryDatensatzAnfuegen)
Private Sub DS_Copy_Click()
CurrentDb.Execute "INSERT INTO Daten(Mitarbeiter, Kunde,Ort, Bearbeitungsart, Werkzeug, Durchmesser, Durchmesser_Zusatz, Schneidstoff)" & _
"SELECT Mitarbeiter, Kunde,Ort, Bearbeitungsart, Werkzeug, Durchmesser, Durchmesser_Zusatz, Schneidstoff" & _
"FROM Daten " & _
"WHERE Tool_ID = " & Me.B_127, dbFailOnError
Me.Requery 'Formulardaten aktualisieren
DoEvents
DoCmd.GoToRecord , , acLast
Hallo,
zwischen Schneidstoff und From fehlt ein Leerzeichen. Füge es vor dem From noch ein.
Das DoEvents braucht es nicht.
Das ist es leider nicht. Der Fehler 438 ist immer noch da.
Es muss einen anderen Grund haben.
Tool_ID ist mein Primärschlüssel
T_ID ist das Bezeichnungsfeld des Primärschlüssels.
Also alles wie in der Beispiel DB.
Private Sub DS_Copy_Click()
CurrentDb.Execute "INSERT INTO Daten(Mitarbeiter, Kunde, Ort, Bearbeitungsart, Werkzeug, Durchmesser )" & _
"SELECT Mitarbeiter, Kunde, Ort, Bearbeitungsart, Werkzeug, Durchmesser " & _
"FROM Daten " & _
"WHERE Tool_ID= " & Me.T_ID, dbFailOnError
Me.Requery 'Formulardaten aktualisieren
DoCmd.GoToRecord , , acLast
End Sub
Hallo,
ZitatT_ID ist das Bezeichnungsfeld des Primärschlüssels
Das Bezeichnungsfeld darfst du nicht ansprechen sondern das Datenfeld. Wenn du Me. eingibst sollte das Feld aus dem Kontext auswählbar sein.
Wenn du das ID-Feld am Formular anklickst und dessen Eigenschaften aufrufst, siehst du den tatsächlichen Namen des Feldes - den musst du verwenden.
ZitatAber das K_ID habe ich nicht...
Um dich nicht vollends zu verwirren - das ist der Feldname MEINES ID-Feldes am Formular.
Da ich das Beispiel auf die Schnelle zusammengeschoben habe, habe ich übersehen, den Namen des Feldes anzupassen.
Im Anhang findest du nun das berichtigte Beispiel nochmals.
DoEvents stand bei mir noch im Code, da ich was probiert hatte - ob das drin steht oder nicht hat keinen Einfluss auf die Funktionalität des Beispiels.
Ich glaube, ich bin kurz vor dem Ziel.
Also, die Copy-Funktion geht jetzt.
So weit so gut.
Jetzt ist es aber so, dass ich den eben gerade kopierten DS natürlich editieren will.
Aber nach dem Makrodurchlauf steht die DB zwar am letzten DS, trotz des Befehls
DoCmd.Gotorecord, , aclast.
Aber das ist NICHT der eben kopierte.
Ich habe das Me.Requery zum aktualisieren mal deaktiviert.
Aber der eben kopierte DS ist dennoch nicht ganz hinten.
Eigentlich ist es ja egal wo der jetzt steht, doch ich will natürlich, dass der jetzt kopierte angezeigt wird zum editieren meiner Werte.
Hast du dafür auch eine Idee?
Gruß Achim
Hallo,
ich nehme stark an (bzw. hoffe das inständig ;) ) , dass der neu kopierte DS einen Primärschlüssel(wert) beinhaltet...
Dieser ist für die Positionierung des Cursors heranzuziehen.
http://www.donkarl.com/?FAQ4.4
bzw.
http://www.donkarl.com/?FAQ4.5
Also das Tool_ID ist der Primärschlüssel.
Aktuell z.B. ist der letzte Primärschlüssel, also DS die 280.
Klicke ich auf meinen CommandButton wird das Makro ausgeführt und der DS kopiert.
Das passt alles.
Der DS erhält als laufende Nummer den Wert 281.
Mein Formular ist grundsätzlich so eingestellt, dass es beim Öffner nach Datum Abwärts sortiert erscheint. Das soll auch so bleiben. Spielt ja für meinen kopiervorgang keine Rolle, denn die DB ist ja offen und das Formular wird ja nicht nochmal geöffnet.
Ich müsste vielleicht nach dem Copy-Vorgang die Sortierung auf Tool_ID DESC stellen.
Dann wäre ich nach dem Kopieren auf dem DS, oder?
Gruß Achim
Hallo,
irgendwie verstehst Du nicht...
der akt. Datensatz wird mit einer POSITIONIERUNG der Formular-Cursors eingestellt und nicht mit einer Sortierung oder auf-/ab-Bewegung (des Cursors)
Me.Recordset.Findfirst "Tool_ID=" & Me!Tool_ID
(Wenn in "Me!Tool_ID" der neue Primärschlüsselwert drinsteht. Ansonsten halt eine Variable oder sonstwas heranziehen, die den neuen PK-Wert enthält.)
Du hast Recht. Ich bekomme es nicht gebacken.
Ich habe mal das Feld Tool_ID, also meinen Primärschlüssel in meinem Formular auf "Sichtbar" geändert.
Beim Öffnen der DB wird die Tabelle nach Tool_ID DESC sortiert ins Formular eingelesen; nicht mehr nach Datum DESC.
Aktuell sind jetzt 280 DS drin.
Gelöst habe ich es jetzt so:
Beispiel:
Ich gehe jetzt mal zum DS mit Primärschlüssel Nummer 262.
Ich klicke auf meinen CommandButton.
Der DS 262 wird nun kopiert, erhält den Primärschlüssel 281 und
ist wird zum Editieren angezeigt,
weil die Sortierung nach Tool_ID DESC den letzten DS, also Nummer 281 anzeigt.
Sicher keine perfekte Lösung, aber sie funktioniert.
Gruß Achim