# Access 2000 Datensatz Duplizieren



## DERHAARKAMM (25. Januar 2010)

Hi @all,

ich habe beim Konvertieren einer Access 97 in eine Access 2000 Datenbank einen Fehler bekommen!

Ein altes Makro, welches einfach den bestehenden Datensatz im Formular kopiert und dann als neues wieder einfügt, 
funktioniert nicht mehr. Ich glaube, dass es ein Problem mit dem Primärschlüssel beim einfügen gibt.

Die bisherige Befehlsreihenfolge lautete

```
AusführenBefehl "Datensatz Markieren"
AusführenBefehl "Kopieren"
GehezuDatensatz "Neuer"
AusführenBefehl "DatensatzMarkieren"
AusführenBefehl "Einfügen"
```

Gibt es eine einfache Lösung?


----------



## Yaslaw (25. Januar 2010)

Uh..... Makros und das noch auf Deutsch.

Kontroliere mal obs alle Befehle in Access2000 noch gibt.
Und hast du wieder eine deutsche version von Access?

Ansonsten währe der Aufbau der Tabelle noch ganz praktisch. Ich kann dir nicht sagen obs Probleme mit einem Schlüssel gibt, wenn ich keine Fehlermeldung habe und nicht weiss wei die Tabelle und deren Indexe/Schlüssel aufgebaut ist.

PS:
Das Problem gehört wohl eher uner Affice-Anwendungen
http://www.tutorials.de/forum/office-anwendungen/


----------



## DERHAARKAMM (25. Januar 2010)

Es gibt die Befehle noch in Access 2000 und es handelt sich hierbei auch wieder um eine deutsche Version.

Ich bin mir jetzt defninitiv sicher, dass der Primary-key schuld ist, da ich vom Access
folgende Fehlermeldung bekomme: 
"Alle Datensätze die von Access nicht eingefügt werden konnten, werden in die Tabelle Einfügefehler abgelegt!"

=> Mein Problem ist, dass beim einfügen eines Datensatzes der Primary-key nicht auf einen Autowert umgestellt wird,
sondern den alten kopierten einfügt.

Bei meinen Daten handelt es sich um Bodenproben und sie haben nur ProbenID als Primärschlüssel!

Gibt es eine einfache Lösung oder kennt wer einen einfachen VBA-Code inkl. Dokumentation für dieses Problem?


----------



## Yaslaw (25. Januar 2010)

DERHAARKAMM hat gesagt.:


> => Mein Problem ist, dass beim einfügen eines Datensatzes der Primary-key nicht auf einen Autowert umgestellt wird,
> sondern den alten kopierten einfügt.



Der stellt sich nicht beim einfügen um. Der ist in der Tabelle hinter dem Feld definiert.


----------



## DERHAARKAMM (25. Januar 2010)

Mir is klar das der in der Tabelle defniert ist, aber beim einfügen sollte er dem kopierten Datensatz eine neue ProbenID zuweisen. Jedoch versucht das Access auch die ProbenID des kopierten Datensatzes einzufügen!


----------



## Biber2 (25. Januar 2010)

Moin DHK,



> Ich bin mir jetzt defninitiv sicher, dass der Primary-key schuld ist, da ich vom Access
> folgende Fehlermeldung bekomme:
> "Alle Datensätze die von Access nicht eingefügt werden konnten, werden in die Tabelle Einfügefehler abgelegt!"


"ich bin mir jetzt definitiv sicher...." ist im normalen Leben keine Aussage, wegen der ich mich zu spontanem  Aktionismus verleiten lasse...
Wenn denn dieser insgesamt EINE unvollendete Datensatz-Clone nun samt Fehlermeldung in der Einfügefehler-Tabelle steht.... könntest du mal bitte reinschauen?
Wir haben doch nix zu verlieren....

Wenn dagegen deine Vermutung stimmt, dass es am PK/AutoWert liegt...

....Dann kann dieses makro auch unter Access 97 niemals gelaufen sein.

Grüße
Biber


----------



## DERHAARKAMM (25. Januar 2010)

Hi Biber,

aber dann versteh ich nicht warum er den kopierten Datensatz nicht einfügt?
In der Tabelle mit den Einfügefehlern wird der Kopiertedatensatz 1:1 eingefügt=> auch die ProbenID
obwohl auf "Autowert" wird übernommen.
Unter Access 97 funktioniert die ganz gleiche Reihenfolge von Befehlen, aber sobald ich die DB
in eine Access 2000 DB konvertiere funktioniert sie nicht mehr!
Gibt es sicher keinen Unterschied bei den Access Versionen?
Was kann dann das Problem sein?

MFG DerHaarkamm


----------



## Biber2 (25. Januar 2010)

Moin DHK,

sagen wir so.... mit diesem AutoWert/AutoIncrement-Gelumpe arbeite ich weder unter Access noch in erwachsenen DBMSen ..

Aber WENN es unter Access97 diese COUNTER-Frelder schon gab (und da bin ich relativ sicher), 
dann galt auch auch für diese "maximal ein AutoWert-Feld pro Tabelle, Jeder Autowert-Wert ist  pro Tabelle unique".


Dein Makro...das unter Acc97 KANN also auch niemals funktioniert haben, denn wenn du beispielsweise Satz 37 von 100 (ja, den mit der ProbenID 37, genau) mit ALLEN Feldern kopierst/clonst als neuen 101sten Datensatz, dann würde der ja auch wieder den bereits vorhandenen Autowert 37 bekommen...
---> Widerspruch, kann nicht sein, kann auch nie so gewesen sein.

Es sei denn, im Formular ist das Feld "ProbenID" nicht sichtbar, nicht als Datenquelle angesprochen und das "AusführenBefehl kopieren"  bezieht sich nur auf alle anderen Felder....

Grüße
Biber


----------



## Slizzzer (26. Januar 2010)

Ich nutze folgende VBA-Befehlsfolge zum duplizieren. Diese wurde vom VBA-Assistenten erstellt:

    DoCmd.DoMenuItem acFormBar, acEditMenu, 8, , acMenuVer70
    DoCmd.DoMenuItem acFormBar, acEditMenu, 2, , acMenuVer70
    DoCmd.DoMenuItem acFormBar, acEditMenu, 5, , acMenuVer70

Nur mal zum testen kannst ja einen Button auf dein Formular ziehen und im Assistenten dann Datensatz duplizieren wählen.

Bei mir wird der Autowert erhöht, wie es auch sein soll. Mit dem Ausgangsdatensatz verknüpfte Daten werden natürlich nicht mitkopiert.

Gruß
Ralf


----------



## DERHAARKAMM (16. Februar 2010)

Ich hab nund versucht das ganze Duplizieren mit Hilfe des VBA Codes zu machen
bekomme aber noch immer eine Fehlermeldung


```
Dim db  As DAO.Database
    Dim rst As DAO.Recordset
    Dim ds  As DAO.Recordset
    Dim ds2 As DAO.Recordset
    Dim neue_Proben_id As Integer
    Dim fld As DAO.Field
    
    ' Verweis auf die aktuelle Db setzen
    Set db = CurrentDb
    'Recordset auf die Tabelle 1Proben
    Set rst = db.OpenRecordset("1Proben")
    
    'Ermittlung der Maximalen ID
    Set ds2 = db.OpenRecordset("Select max(ID) From 1Proben")
    'Neue ID (ProbenID) zwischenspeichern
    neue_Proben_id = rst!ID
    neue_Proben_id = neue_Proben_id + 1
    
    'Datensatz der kopiert wird
    Set ds = db.OpenRecordset("SELECT * FROM 1Proben " & _
                              "WHERE ID = " & ID)
    'Neuen Datensatz einfügen
    rst.AddNew
    
    For Each fld In ds.Fields
        If fld.Name <> "ID" Then
            rst(fld.Name) = ds(fld.Name)
        Else
            rst(fld.Name) = neue_Proben_id
            
        End If
    Next fld
    rst.Update
```

Jetzt bekomme ich den Laufzeitfehler 3022 welcher mir sagt, dass der Index mehrfachvorkommende Werte beinhaltet!
Kann mir jemand einen Tipp geben?!


----------



## Yaslaw (16. Februar 2010)

Hast du noch andere Eindeutige Indexe?

Zudem ist in deinem folgenden Code die Variable ID nicht definiert

```
Set ds = db.OpenRecordset("SELECT * FROM 1Proben " & _
                              "WHERE ID = " & ID)
```

Am besten machst du mal ein Printscreen deiner Tabelle in der Entwurfsansicht und einer des Index-Fensters.
Oder du exportierst das Resultat des Access-Dokumentireres (nur für diese Tabelle!) in ein Textfile und postest dieses.
Das sieht dann etwa so aus wie im Anhang

Nachtrag:
Bei einer Tabelle mit Autowert in der ID und keinem weiteren Unique Index geht bei mir das folgende kleine Query

```
INSERT INTO bewertung ( PersNr, von, bis )
SELECT PersNr, von, bis
FROM bewertung
WHERE ID=4;
```


----------



## Biber2 (16. Februar 2010)

Moin DERHAARKAMM,

Abgesehen von der in der Luft hängenden Variablen "ID", auf die yaslaw bereits hingewiesen hat, 
ist auch die halbherzig begonnene Max(vorhandenerAutowert)-Ermittlung nie so richtig aus dem Ei gekommen.

Der dafür vermutlich vorgesehene ResultSet "ds2" hätte _eigentlich_ auch "Soda" heißen können, denn genauso liegt er rum.

Das Hochzählen der "neueProbenID" machst du wiederum nicht etwa auf der MaxVorhandenenId, sondern im wahrsten Sinne des Wortes auf irgendeiner beliebigen. 
Anzunehmenderweise auf der Kleinsten... nicht weiter verwunderlich, wenn dir Access dann einen "3022" zeigt, wenn du die kleinste-Id-plus-eins nochmal einfügen willst.

Wie yaslaw schon vorgeschlagen hat- FASS EINFACH DIE ID GAR NICHT AN.
Ein AddNew() und alle Felder AUSSER dem albernen AutoWert-Feld füllen.

Grüße
Biber


----------



## DERHAARKAMM (23. Februar 2010)

Danke nochmal für die hilfreichen Tipps! ID ist ein Textfeld aus einem Access Formular und natürlich muss
ich das SQL - Statement mit der Value des Textfeldes machen.

Soweit so gut, jedoch habe ich noch ein Problem beim rst.Update, nämlich dass ich nicht weiß welchen Wert ich
beim rst.update für die ID verwenden soll. Null löst einen Compilerfehler aus und wenn ich die ID nicht befülle steht der Wert des ersten Datensatzes in der Tabelle!


```
Dim db  As DAO.Database
    Dim rst As DAO.Recordset
    Dim ds  As DAO.Recordset
    Dim fld As DAO.Field
    
    ' Verweis auf die aktuelle Db setzen
    Set db = CurrentDb
    'Recordset auf die Tabelle 1Proben
    Set rst = db.OpenRecordset("1Proben")
       
    'Inhalt des aktuellen Datensatzes wird ausgelesen
    Set ds = db.OpenRecordset("SELECT * FROM 1Proben " & _
                              "WHERE ID = " & ID.Value)
    'Neuen Datensatz einfügen
    rst.AddNew
    
    For Each fld In ds.Fields
        If fld.Name <> "ID" Then
            rst(fld.Name) = ds(fld.Name)
        Else
            rst(fld.Name) = Null
        End If
    Next fld
    rst.Update
```


----------



## Biber2 (24. Februar 2010)

Moin DERHAARKAMM,

dass du meine Formulierung _"..alle Felder AUSSER dem albernen AutoWert-Feld füllen..."_, an der ich sehr, sehr lange gefeilt habe, 
übersetzt in die Empfehlung "In das Autowert-Feld ID muss ich den Wert NULL reintrümmern, sonst Biber traurig"...

...das stürzt mich in die fünfte (oder schon sechste?) mitteltiefe Glaubenskrise. 
Ich glaub es nicht.

Ich geh mal in mich...
@yaslaw
Kannst du vielleicht versuchen, es verständlicher zu formulieren? Danke

Grüße
Biber


----------



## Yaslaw (24. Februar 2010)

Biber2. Nun gut, mein letzter Versuch, denn es kann unmöglich mein Problem sein.

@DERHAARKAMM
Ich glaube nicht das hinter dem Feld ID ein Autowert steht. Ansonsten würde es funktionieren das ID-Feld zu ignorieren. Habs selber getestet. Und zwar mit deinem Code. 


```
For Each fld In ds.Fields
        If fld.Name <> "ID" Then
            rst(fld.Name) = ds(fld.Name)
        End If
    Next fld
    rst.Update
```


----------



## DieterB (16. Oktober 2010)

Moin,

hab diesen Thread mal eben überflogen.
Ihr habt ja 'ne geile Art zu schreiben *g*

Ok, Kinners
bei mir taucht das selbe Prob auf.
@yaslaw: funktioniert deine Lösung mit dem (im letzten Post vorgestellten) Code?
Ansonsten sind bei mir die gleichen Fehler aufgelaufen, ich habe alle Indizies entfernt.

Eigentlich sollte es funktionieren.
Meine Situation: ich habe ein Form, in dem werden Datensätze angelegt.
Habe ich einen angelegt, soll der kopiert werden.

Ich habe in anderen Foren zu diesem Problem häufig die Frage nach dem Sinn gelesen:

'Zitat an'
Hintergrund: auf ein und dem selben Schiff kommen 10 CNTR für den gleichen Kunden rein.
Damit nicht 10mal der Schiffsname oder die CNTR-Nr geschrieben werden muss,
soll ein bestehender datenstz kopiert werden. 
'Zitat aus'


----------

