Datensatz klonen oder duplizieren

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:

ADO-Verweis

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:

datensatz-duplizieren

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
Datensatz klonen oder duplizieren
Markiert in:         

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert