Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

mehrere Datensätze aus Abfrage per Code ans ende einer Tabelle kopieren

Begonnen von bmwoholic, Oktober 21, 2014, 14:12:47

⏪ vorheriges - nächstes ⏩

bmwoholic

Hallo zusammen,

ich bin langsam am verzweifeln. Ich habe eine recht umfangreiche Datenbank geerbt, die ich seit einem Jahr betreue. Bin langsam in das Thema reingewachsen und somit kein Frischling mehr. Trotzdem komme ich hiermit nicht weiter klar.
Folgendes Problem:
die Datenbank dient zur Versuchsverwaltung. Dabei kommt es immer wieder vor das etliche Randbedingungen sich stark ähneln und man sich mal schnell über eine Halbe Stunde Zeit sparen könnte wenn man bestimmte Parameter aus einer Abfrage kopieren und mit EINEM geänderten Bezugsfeld wieder speichern könnte. (soviel zur Relationalen Datenbank)
ich finde leider keine Sinnvolle Möglichkeit zum Kopieren und wieder Einfügen dieser Daten. Nochmal zur Erklärung das Szenario.

Tabelle1 wird mit Abfrage1 aufgerufen und nach kriterium1 gefiltert. Dies wirft ca. 1-50 Datensätze aus, oder auch mehr. Diese möche ich ans Ende von Tabelle1 anfügen und SpalteXY für alle kopierten Datensätze mit einem festen Wert versehen, den ich Per Variable eingebe.

sorry für den langen text, aber ich weiss im Moment weder mit VBA, noch Abfragen bzw. Kombination der beiden das Problem zu lösen. Bitte innigst um Hilfe  :-\

Danke im Vorraus - bin offen für alles

MaggieMay

Hallo,

du könntest die Anfügeabfrage per VBA dynamisch erzeugen und ausführen.
Beispiel:strSQL = "Insert Into tabelle1 (feld1, feld2, ...) " & _
            "Select feld1, '" & variable1 & "', ..." & _
            "From abfrage1 " & _
            "Where " & kriterium1
CurrentDB.Execute strSQL, dbFailOnError

Hinweis:
bei Zahlen werden keine Hochkommata gesetzt.
Freundliche Grüße
MaggieMay

bmwoholic

Prinzipiell hört sich das gut an, habe es auch schon in die Richtung hin probiert.
Mein Problem ist aber gerade noch folgendes. Wenn Angenommen meine Abfrage hat 5 Datensätze, wie kann ich dann zuweisen das ich den wert des ersten, bzw. zweiten oder... Datensatzes auslesen /kopieren möchte?

Und kann ich bei der Gelegenheit auch sagen das Spalte 5 beim Einfügen bereits einen gezielten Wert zugewiesen bekommt? Im Zweifelsfall könnte ich das damit lösen das ich Spalte 5 einfach nicht mitkopiere, und später mit einer Aktionsabfrage per VBA einfach nach Kriterium "Null" filtere und da den Variablenwert setze.


MaggieMay

Hi,

das Auslesen (und Kopieren) der einzelnen Datensätze wird durch das Select-Statement gewährleistet und die Zuweisung eines konstanten Wertes zu einer Spalte ist in meinem Beispiel ebenfalls enthalten.
Freundliche Grüße
MaggieMay

bmwoholic

sorry,
das ist mir gerade zu abstrakt, obwohl ich das selbst so geschrieben habe ;)

hab ich das so richtig verstanden?

"Insert Into tabelle1 (feld1, feld2, ...) " & _
            "Select feld1, '" & variable1 & "', ..." & _
            "From abfrage1 " & _
            "Where " & kriterium1

tabelle 1 = Tabellenname - klar
feld1 = [Spaltenname]
variable1 = ist hier anstelle von Spalte2?

Kann ich hier bei Kriterium eingeben Datensatz(x) der Abfrage1? da ich mit dcount die menge der gefilterten datensätze rausfinden kann, könnte ich so sauber eine schleife laufen lassen. geht sowas?

MaggieMay

Mein Beispiel bezieht sich auf deine eigenen Worte:
ZitatTabelle1 wird mit Abfrage1 aufgerufen und nach kriterium1 gefiltert. Dies wirft ca. 1-50 Datensätze aus, oder auch mehr. Diese möche ich ans Ende von Tabelle1 anfügen und SpalteXY für alle kopierten Datensätze mit einem festen Wert versehen, den ich Per Variable eingebe.
wobei "SpalteXY" im Beispiel "feld2" ist und ich davon ausgegangen bin, dass alle Bausteine (Name von Tabelle und Abfrage, Variable zur Übergabe des festen Wertes, sowie der Kriterienstring) verfügbar sind.

Was hast du mit der Schleife vor? Die Abfrage macht eine Verarbeitungsschleife überflüssig, weil sie automatisch die ausgewählten Datensätze berücksichtigt.
Freundliche Grüße
MaggieMay

bmwoholic

ich glaub jetzt versteh ich worauf die hinaus willst. D.h. wenn ich diesen string benutze, dann wird bereits der GESAMTE Inhalt der Abfrage an die Tabelle angefügt. Das ist natürlich genau das was ich will :D ich bin von einzelnen Datensätzen ausgegangen. Also mit

for n = 1 to Dcount
insert Datensatz to tabelle
next n

das ist natürlich schick. Das werde ich dann gleich mal testen. Besten Dank.

Noch rein informativ. Gibt es denn die Möglichkeit z.B. Datensatz3 der AbfrageX direkt anzusprechen? wenn man das passende Kriterium nicht kennt?

MaggieMay

Wenn du bspw. ein Formular so filterst, dass es nur die gesuchten Datensätze enthält, so kannst du eine Verarbeitungsschleife über das Recordset laufen lassen:Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
For i = 1 to rs.RecordCount    ' alternativ: Do While Not rs.EOF
    If i = 3 Then
     ' mach was mit dem Datensatz
        Exit For   ' fertig!
    End If
    rs.MoveNext
Next i

Der x-te Datensatz ist aber keine gute Wahl, da x von der aktuellen Sortierung abhängt. Gezielte Zugriffe auf bestimmte Datensätze macht man tunlichst über die Datensatz-ID, den Primärschlüssel.
Freundliche Grüße
MaggieMay

bmwoholic

So, ich war mal eben fleissig.
Das ist gerade mein Code, hat noch eine Fehlermeldung:

Public Sub test()
   
        Dim db As DAO.Database
        Dim strSQL As String
        Dim Nummer_neu As Long
        Dim nummer_alt As Long
        Set db = CurrentDb
   
    nummer_alt = "1261"
    Nummer_neu = "1262"
   
    strSQL = "Insert Into Programme ([BlockNr], [Profilname], [Durchläufe], [BlockCnt], [StufeNr], [Nummer]) " & _
            "Select [BlockNr], [Profilname], [Durchläufe], [BlockCnt], [StufeNr], '" & Nummer_neu & "'" & _
            "From A_Erprobungsparameter_Programme_Basis " & _
            "Where [Nummer] = '" & nummer_alt & "'"
    CurrentDb.Execute strSQL, dbFailOnError
   
   
    'Abschluss Variable leeren
    Set db = Nothing
   
End Sub



Laufzeitfehler '3061': 1 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben.



MaggieMay

Wenn "Nummer" den Datentyp "Zahl" hat, so lass die Hochkommata weg.
Freundliche Grüße
MaggieMay

bmwoholic

jetzt bekomme ich Laufzeitfehler '3075':
Syntaxfehler (fehlender Operator) in Abfrageausdruck '5245From A_Erprobungsparameter_Programme_Basis Where [Nummer] = 5244'

mit folgendem Code:


Public Sub test()
   
        Dim db As DAO.Database
        Dim strSQL As String
        Dim Nummer_neu As Long
        Dim nummer_alt As Long
        Set db = CurrentDb
   
    nummer_alt = "5244"
    Nummer_neu = "5245"
   
    strSQL = "Insert Into Programme ([BlockNr], [Profilname], [Durchläufe], [BlockCnt], [StufeNr], [Nummer]) " & _
            "Select [BlockNr], [Profilname], [Durchläufe], [BlockCnt], [StufeNr], " & Nummer_neu & _
            "From A_Erprobungsparameter_Programme_Basis " & _
            "Where [Nummer] = " & nummer_alt
    CurrentDb.Execute strSQL, dbFailOnError
   
   
    'Abschluss Variable leeren
    Set db = Nothing
   
End Sub

DF6GL

Hallo,

wenn Du die Fehlermeldung (oder die Codezeile) genau ansiehst, kommst Du auch auf den Fehler....
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

bmwoholic

#12
ok, also wenn du den Leerraum meintest nach Nummer_neu, so ist dieser jetzt drin.
zusätzlich war noch ein Ei mit eingelegt welches ich vom Ersteller der Datenbank geerbt habe in der Spaltenbenennung. Nachdem ich das korrigiert habe bin jetzt einen schritt weiter.
normal wäre noch eine weitere spalte die ich hier nicht mit kopiere. der Primärindex. (den nehme ich absichtlich nicht mit um Probleme mit dem Primärschlüssel zu vermeiden (so mein Gedankengang).

Jetzt bekomme ich aber den Laufzeitfehler '3022':
die von Ihnen vorgenommenen Änderungen an der Tabelle konnten nicht vorgenommen werden, d der Index, Primärschlüssel oder die Beziehung mehrfach vorkommende Werte enthalten würde. Ändern Sie die Daten in den Feldern die gleiche Daten enthalten, entfernen sie den Index, oder definieren sie den Index neu, damit doppelte einträge möglich sind, und versuchen sie es erneut.

Wie kann ich da was sinnvolles in meinen Code einbauen um dieses Problem zu lösen?

Sorry das ich da so nervig bin, komme mir vor wie ein kleines Kind. Aber die Funktion ist mir sehr wichtig das ich sie sauber einbaue. Danke nochmal für eure Geduld.

DF6GL

Hallo,

ein zusätzlicher Code wird wohl nicht viel helfen..  Knackpunkt ist wiederum die Fehlermeldung...  Es wird wohl eines oder mehrere der benutzten Felder ([BlockNr], [Profilname], [Durchläufe], [BlockCnt], [StufeNr], [Nummer]) einen eindeutigen Index (d. h. Index ohne Duplikate) besitzen, wodurch eine Mehrfachspeicherung desselben Wertes nicht möglich ist.


BTW:  diese Zuweisungen
nummer_alt = "5244"
Nummer_neu = "5245"

sind definitiv falsch...
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

bmwoholic

Komme ich jetzt leider nicht ganz nach.

Also meine Tabelle hat folgende Inhalte:
BlockNr - Long
Dys_Name - String
Durchläufe - Long
BlockCnt - Long
StufeNr - Long
Nummer - Long
ID_Programme - Autowert (Primärschlüssel)

Aus diesen Feldern ist praktisch folgende Aufteilung:
ID_Programme Systemrelevant, aber für mich vom inhalte einfach irgendeine hochzählende Nummer.
Gefiltert wird nach "Nummer". Dieser Wert wird in einer anderen Tabelle einem bestimmten Ojekt zugewiesen, und ich möchte alle Inhalte der gleichen "Nummer" in dem Formular mit angezeigt bekommen, aufsteigend sortiert nach den ID_Programmen.
Alle weiteren Haben definitiv keinen Erkennungscharakter, sondern sind ausschliesslich Daten.

Wie bereits im allerersten Beitrag beschrieben, soll beim kopieren des Anderen Datensatzes, welcher die Nummer erzeugt, auch angestoßen werden dass alle Datensätze dieser Tabelle mit dem entsprechenden Wert für Nummer kopiert werden, und diesen der entsprechende neue Wert gegeben wird. Das ist auch nicht redundant, sondern einfach notwendig. Nur will ich mir halt jedes mal eine halbe stunde händischer Eingaben sparen. Dies betrifft nämlich 8 weitere Tabellen welche nach dem gleichen Schema laufen. Alle haben den Bezugswert "Nummer" und eine Tabellen_ID mit Autowert.

die Abfrage aus welcher ich die Daten nehme bezieht sich wie oben beschrieben auf die gleiche Tabelle wo ich meine Daten nach einer Bedingung ruasfiltere (der "Nummer) und dann laut Ratschlag mit obigem SQL in die gleiche Tabelle wieder unten anfügen möchte. Dabei ist ja gewollt das die ID_Programme (Primärschlüssel) hochzählt.
ich hoffe ich konnte mein Problem halbwegs erklären. Die Nummer welche oben im Code ist, wird nur beispielhaft direkt gesetzt, natürlich ist dies eine Variable die eben aus dem alten, bzw. neuen Formular nach generierung der Nummer in der Abfrage angewendet wird.