Datensatz einer Access-Tabelle kopieren
Häufig hat man die Situation, dass man einen Datensatz in der Access-Datenbank kopieren will wobei die meisten Werte gleich bleiben und sich nur wenige Werte ändern sollen.
Ein einfaches
Insert into tblXXX select * from tblXXX where ID=3
geht in der Regel nicht, weil die Tabelle eine AutoWert-ID enthält und der INSERT dann eine Schlüsselverletzung zur Folge hat.
man muss also alle Feldnamen (Spaltennamen) angeben und bei vielen Feldern ist das eine mühsame Angelegenheit:
Insert into tblXXX (feld1, feld2, feld3, ...) select feld1, feld2, feld3, ... from tblXXX where ID=3
Außerdem soll vielleicht feld3 ersetzt werden durch einen anderen Wert.
Beispielsweise wird ein Artikel-Datensatz in der Tabelle tblArtikel kopiert, wobei sich nur der Artikelname unterscheiden soll und alle anderen Felder gleich bleiben, weil es z.B. der gleiche Artikel in einer anderen Farbe ist:
Insert into tblXXX (feld1, feld2, feld3, ...) select feld1, feld2, 'Neuer Wert' as feld3, ... from tblXXX where ID=3
Funktion zum Erstellen einer Feldliste
Zunächst benötigen wir eine Funktion zum Erstellen einer Liste der Felder einer Tabelle, wobei einzelne felder auch leicht ausgenommen oder ersetzt werden können:
Public Function FieldList(strTable As String, ParamArray varReplace() As Variant) As String
' gibt kommagetrennte Liste von Feldnamen zur Tabelle oder Abfrage zurück
' mit varReplace kann man Felder rausnehmen oder durch "xy as Feldname" erstezen
' varReplace muss die Form Feld_x,Ersetzung_x, feld_y,Ersetzung_y haben
' Ersetzung_x ist NULL, wenn Feld entfallen soll
' Beispiele:
' FieldList(strTable) -> "ID, Nachname, Vorname, ID_Status, Alter"
' FieldList(strTable,ID,Null) -> "Nachname, Vorname, ID_Status, Alter"
' FieldList(strTable,ID,Null,ID_Status,7) -> "Nachname, Vorname, 7 as ID_Status, Alter"
' jede ungerade Position in varReplace ist also Feldname, darauffolgend immer ein konstanter ausdruck
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field
Dim arrFields As Variant
Dim strField As String
Dim varReplaceField As Variant
On Error GoTo ErrHandle
Set rs = New ADODB.Recordset
rs.Open "select * from " & strTable & " where 1=0", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
' Alle Felder durchlaufen
For Each fld In rs.Fields
' Ist es ein Feld, das ersetzt oder weggelassen werden soll?
If ArrayContains(varReplace, fld.Name) Then
varReplaceField = varReplace(ArrayPos(varReplace, fld.Name) + 1)
If IsNull(varReplaceField) Then
' Feld soll weggelassen werden
strField = ""
Else
' Feld soll durch Wert ersetzt werden
strField = varReplaceField & " as " & fld.Name
End If
Else
strField = fld.Name
End If
If strField <> "" Then ArrayAdd arrFields, strField
Next
FieldList = Join(arrFields, ", ")
rs.Close
Set rs = Nothing
Exit Function
ErrHandle:
Select Case err
Case Else
MsgBox err.Description
End Select
End Function
Erläuterung:
Verwendete Array-Funktionen
Die Funktionen ArrayContains, ArrayPos und ArrayAdd sind nützliche Array-Funktionen, die in diesem Beitrag zu finden sind:
Nützliche Array-Funktionen
Verweise auf ADO-Bibliothek
Damit das Beispiel funktioniert, muss unter den Projekt-Verweisen die ADO-Bibliothek aktiviert sein:

In der Regel wird die Bibliothek mit der höchsten Version ausgewählt.
Tabellen-Felder durchlaufen
Mit rs.Open ... wird ein ‚leerer‘ Recordset der Tabelle geöffnet um dann mit For Each fld In rs.Fields jede Spalte der Tabelle zu durchlaufen.
Tabellen-Felder erstzen
Mit dem Funktionsparameter varReplace() kann man festlegen, welche Felder ersetzt bzw. ausgenommen werden sollen.
Es muss immer eine gerade Anzahl von Parametern übergeben werden.
Dabei ist Parameter X ein Feldname, Parameter X+1 entweder NULL (Feld wird weggelassen) oder ein beliebiger Wert (Feldwert wird ersetzt).
Beispiel:
Tabelle tblMitarbeiter enthält die Spalten: ID, Nachname, Vorname, ID_Status, Alter
Dann liefert
(1) komplette Feldliste
FieldList(strTable) -> „ID, Nachname, Vorname, ID_Status, Alter“
(2) Feld ID weglassen:
FieldList(strTable,ID,Null) -> „Nachname, Vorname, ID_Status, Alter“
(3) Feld ID wird weggelassen und ID_Status durch „7 as ID_Status“ ersetzen:
FieldList(strTable,ID,Null,ID_Status,7) -> „Nachname, Vorname, 7 as ID_Status, Alter“
Datensatz duplizieren
Mit dieser Funktion lässt sich dann einfach ein Select-Statement erzeugen, mit dem man einen Datensatz klonen kann:
Public Sub CloneRecord()
Dim strSQL As String
Dim strTable As String
Dim strFieldListAll As String
Dim strFieldListInsert As String
strTable = "tblArtikel"
strFieldListAll = FieldList(strTable, "ID", Null)
strFieldListInsert = FieldList(strTable, "ID", Null, "Artikelname", "'Kugelschreiber rot'")
strSQL = "Insert into " & strTable & " (" & strFieldListAll & ") " & _
"select " & strFieldListInsert & " from tblArtikel where ID = 3"
CurrentProject.Connection.Execute strSQL
End Sub
Erläuterung:
Die Tabelle tblArtikel enthalte folgende Felder:

Der Datensatz mit der ID = 3 soll dupliziert werden, wobei sich der Artikelname unterscheiden, nämlich „Kugelschreiber rot“ sein soll.
Mit Hilfe der Feldlisten-Funktion wird folgendes Select-Statement erzeugt:
Insert into tblArtikel (Artikelname, Preis, Einstelldatum, Kategorie, Beschreibung, ImSortiment)
select 'Kugelschreiber schwarz' as Artikelname, Preis, Einstelldatum, Kategorie, Beschreibung, ImSortiment from tblArtikel where ID= 3