Dblib Objekt
Zuletzt geändert: 10.02.2026 15:24

DBLIB-Objekt (iScript) #

Das DBLIB-Objekt stellt Methoden für komplexe ADO-Recordset-Manipulationen bereit. Es ermöglicht das Klonen, Kopieren und Befüllen von Recordsets aus verschiedenen Quellen.

Set db = Client.CreateObject("DBLIB")

Methoden #

dbCloneRecordset #

function dbCloneRecordset(SourceRs: Recordset): Recordset

Erstellt eine vollständige Kopie eines Recordsets inklusive aller Daten. Die Kopie ist unabhängig vom Original und kann separat navigiert und bearbeitet werden.

Dim rs, rsKopie
Set rs = Client.ExecuteSql("select * from dbo.Artikel")
Set rsKopie = db.dbCloneRecordset(rs)

Hinweis: Die Kopie beginnt am Anfang des Recordsets, sofern der Cursor-Typ dies erlaubt.

dbCloneRecordsetDef #

function dbCloneRecordsetDef(SourceRs: Recordset): Recordset

Erstellt ein leeres Recordset mit derselben Spaltendefinition wie das Quell-Recordset, aber ohne Daten. Das erzeugte Recordset ist editierbar und eignet sich als Ziel für dbCopyArrToRecordset, dbCopyRecordsetRows und dbCopyRecordsetRow.

Dim rs, rsLeer
Set rs = Client.ExecuteSql("select ArtNummer, Kurztext1, VkNetto from dbo.Artikel where 1=0")
Set rsLeer = db.dbCloneRecordsetDef(rs)
' rsLeer hat die gleichen Spalten, aber keine Zeilen

Hinweis: Ein Recordset aus Client.ExecuteSql ist in der Regel nicht direkt editierbar. Mit dbCloneRecordsetDef wird ein editierbares Recordset mit der gleichen Struktur erzeugt.

dbCopyRecordsetRows #

procedure dbCopyRecordsetRows(SourceRs: Recordset, DestRs: Recordset)

Fügt alle Zeilen des Quell-Recordsets an das Ziel-Recordset an. Die Feldnamen beider Recordsets müssen identisch sein.

Dim rsQuelle, rsZiel
Set rsQuelle = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1 from dbo.Artikel where WarenGr = 'A'")
Set rsZiel = db.dbCloneRecordsetDef(rsQuelle)

' Erste Gruppe anfügen
db.dbCopyRecordsetRows rsQuelle, rsZiel

' Weitere Gruppe anfügen
Set rsQuelle = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1 from dbo.Artikel where WarenGr = 'B'")
db.dbCopyRecordsetRows rsQuelle, rsZiel

dbCopyRecordsetRow #

procedure dbCopyRecordsetRow(SourceRs: Recordset, DestRs: Recordset)

Fügt nur die aktuelle Zeile (Cursor-Position) des Quell-Recordsets an das Ziel-Recordset an. Die Feldnamen beider Recordsets müssen identisch sein.

Dim rsQuelle, rsZiel
Set rsQuelle = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1, VkNetto from dbo.Artikel")
Set rsZiel = db.dbCloneRecordsetDef(rsQuelle)

' Nur Artikel mit VkNetto > 100 übernehmen
Do While Not rsQuelle.EOF
  If rsQuelle("VkNetto") > 100 Then
    db.dbCopyRecordsetRow rsQuelle, rsZiel
  End If
  rsQuelle.MoveNext
Loop

dbCopyArrToRecordset #

procedure dbCopyArrToRecordset(SourceArr, DestRs: Recordset, _
  SourceIndexes, TargetIndexes, StartRow)

Kopiert Daten aus einem zweidimensionalen Array in ein Recordset. Über die Umsetzungstabellen SourceIndexes und TargetIndexes wird definiert, welche Spalte des Arrays auf welches Feld des Recordsets abgebildet wird.

Dies ist die vielseitigste Methode des DBLIB-Objekts und unterstützt verschiedene Zuordnungsmodi.

Parameter #

Parameter Typ Beschreibung
SourceArr Variant (2D-Array) Das Quell-Array. Die erste Zeile kann Spaltenüberschriften enthalten.
DestRs Recordset Das Ziel-Recordset (muss geöffnet und beschreibbar sein)
SourceIndexes Array Zuordnungstabelle für die Quellspalten (siehe unten)
TargetIndexes Array Zuordnungstabelle für die Zielfelder (siehe unten)
StartRow Integer Startzeile im Quell-Array (immer 0 übergeben)

Zuordnung der Quellspalten (SourceIndexes) #

Jedes Element definiert, aus welcher Spalte des Quell-Arrays gelesen wird:

Wert Beschreibung
Integer Direkte Spalten-Nummer (0-basiert)
String Spaltenname — wird in der ersten Zeile des Arrays gesucht
"*" Wildcard — alle verbleibenden Zielfelder werden automatisch per Namensabgleich zugeordnet
Array von Strings Alternative Spaltennamen — der erste Treffer wird verwendet
Null / Empty Spalte wird übersprungen

Hinweis: Wenn ein Spaltenname im Quell-Array nicht gefunden wird, wird die Zuordnung stillschweigend übersprungen (kein Fehler). Das ermöglicht flexible Zuordnungen bei variierenden Quelldaten.

Zuordnung der Zielfelder (TargetIndexes) #

Jedes Element definiert, in welches Feld des Recordsets geschrieben wird:

Wert Beschreibung
Integer Direkte Feld-Nummer (0-basiert)
String Feldname im Recordset
Null / Empty Feld wird übersprungen

Wichtig: Wenn ein angegebener Feldname im Ziel-Recordset nicht existiert, wird ein Fehler ausgelöst. Das Ziel-Schema ist fix und muss korrekt angegeben werden.

Bekannter Bug bei Spaltennamen (behoben ab 2026.2) #

Bei Verwendung von Spaltennamen (Strings) in SourceIndexes wird die erste Zuordnung fehlerhaft aufgelöst. Die erste benannte Spalte erhält den Wert der letzten Spalte im Array.

Workaround: Einen Dummy-Eintrag an den Anfang der beiden Arrays einfügen. Der Dummy wird mit -1 im TargetIndexes übersprungen:

' Workaround: Dummy-Eintrag an erster Position
db.dbCopyArrToRecordset arr, rs, _
  Array("dummy", "Nummer", "Bezeichnung", "Preis"), _
  Array(-1, "ArtNummer", "Kurztext1", "VkNetto"), 0

Der Dummy-Spaltenname muss nicht im Array existieren — er wird stillschweigend übersprungen.

Header-Erkennung #

Wenn Spaltennamen (Strings) in SourceIndexes verwendet werden, wird die erste Zeile des Arrays automatisch als Kopfzeile interpretiert und beim Kopieren übersprungen. Bei rein numerischer Zuordnung wird keine Kopfzeile erwartet.

Wildcard-Modus #

Der Wildcard "*" in SourceIndexes aktiviert die automatische Namens-Zuordnung ab dieser Position. Für alle nachfolgenden Zielfelder wird im Quell-Array nach einer Spalte mit identischem Namen gesucht. Das ist besonders nützlich, wenn Quelle und Ziel größtenteils gleiche Feldnamen haben.

dbCopyRecordsetFromDataset #

function dbCopyRecordsetFromDataset(Dataset: Dataset): Recordset

Erzeugt ein Recordset aus einem EULANDA-Dataset-Objekt. Das Recordset wird nicht zwingend kopiert, sondern kann intern durch Recordset.Clone() erzeugt werden.

Dim db, ds, rs

Set db = Client.CreateObject("DBLIB")
Set ds = Client.CreateObject("CURRENTDATASET", "AR")
Set rs = db.dbCopyRecordsetFromDataset(ds)

ellib.ShowMessage "Datensätze: " & rs.RecordCount

Set db = Nothing
Set ds = Nothing
Set rs = Nothing

Hilfsfunktion für Beispiele #

Die folgende Sub wird in den nachfolgenden Beispielen zur Ausgabe von Recordsets verwendet:

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Beispiele #

A. Array per Index zuordnen #

Option Explicit

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Dim db, rs, arr(2, 1)

' Quell-Array vorbereiten (2 Spalten, 3 Zeilen)
arr(0, 0) = "4711"    : arr(0, 1) = "Schraube M6"
arr(1, 0) = "4712"    : arr(1, 1) = "Mutter M6"
arr(2, 0) = "4713"    : arr(2, 1) = "Scheibe M6"

Set db = Client.CreateObject("DBLIB")

' Editierbares Ziel-Recordset erstellen
Set rs = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1 from dbo.Artikel where 1=0")
Set rs = db.dbCloneRecordsetDef(rs)

' Spalte 0 → Feld 0 (ArtNummer), Spalte 1 → Feld 1 (Kurztext1)
db.dbCopyArrToRecordset arr, rs, Array(0, 1), Array(0, 1), 0

ShowRS rs

Set db = Nothing
Set rs = Nothing

B. Array per Spaltennamen zuordnen #

Option Explicit

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Dim db, rs, arr(3, 2)

' Erste Zeile = Spaltenüberschriften
arr(0, 0) = "Nummer"  : arr(0, 1) = "Bezeichnung" : arr(0, 2) = "Preis"
arr(1, 0) = "4711"    : arr(1, 1) = "Schraube M6" : arr(1, 2) = 1.50
arr(2, 0) = "4712"    : arr(2, 1) = "Mutter M6"   : arr(2, 2) = 0.80
arr(3, 0) = "4713"    : arr(3, 1) = "Scheibe M6"  : arr(3, 2) = 0.30

Set db = Client.CreateObject("DBLIB")

' Editierbares Ziel-Recordset erstellen
Set rs = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1, VkNetto from dbo.Artikel where 1=0")
Set rs = db.dbCloneRecordsetDef(rs)

' Zuordnung per Namen: Nummer → ArtNummer, Bezeichnung → Kurztext1, Preis → VkNetto
db.dbCopyArrToRecordset arr, rs, _
  Array("Nummer", "Bezeichnung", "Preis"), _
  Array("ArtNummer", "Kurztext1", "VkNetto"), 0

ShowRS rs

Set db = Nothing
Set rs = Nothing

C. Wildcard-Modus für gleichnamige Felder #

Option Explicit

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Dim db, rs, arr(2, 2)

' Spaltenköpfe identisch mit Recordset-Feldnamen
arr(0, 0) = "ArtNummer" : arr(0, 1) = "Kurztext1" : arr(0, 2) = "VkNetto"
arr(1, 0) = "4711"      : arr(1, 1) = "Schraube"  : arr(1, 2) = 1.50
arr(2, 0) = "4712"      : arr(2, 1) = "Mutter"    : arr(2, 2) = 0.80

Set db = Client.CreateObject("DBLIB")

' Editierbares Ziel-Recordset erstellen
Set rs = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1, VkNetto from dbo.Artikel where 1=0")
Set rs = db.dbCloneRecordsetDef(rs)

' "*" ordnet alle Felder automatisch per Namensabgleich zu
db.dbCopyArrToRecordset arr, rs, _
  Array("*"), _
  Array("ArtNummer", "Kurztext1", "VkNetto"), 0

ShowRS rs

Set db = Nothing
Set rs = Nothing

D. Alternative Spaltennamen #

Wenn die Quelldaten je nach Herkunft unterschiedliche Spaltenbezeichnungen verwenden:

Option Explicit

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Dim db, rs, arr(2, 1)

' Array mit abweichenden Spaltennamen
arr(0, 0) = "ArtNr"       : arr(0, 1) = "Kurztext1"
arr(1, 0) = "4711"        : arr(1, 1) = "Schraube M6"
arr(2, 0) = "4712"        : arr(2, 1) = "Mutter M6"

Set db = Client.CreateObject("DBLIB")

' Editierbares Ziel-Recordset erstellen
Set rs = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1 from dbo.Artikel where 1=0")
Set rs = db.dbCloneRecordsetDef(rs)

' Erster Treffer aus dem Array gewinnt
db.dbCopyArrToRecordset arr, rs, _
  Array(Array("ArtNummer", "ArtNr", "Artikelnr"), "Kurztext1"), _
  Array("ArtNummer", "Kurztext1"), 0

ShowRS rs

Set db = Nothing
Set rs = Nothing

E. Recordset klonen und selektiv befüllen #

Option Explicit

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Dim db, rsQuelle, rsZiel

Set db = Client.CreateObject("DBLIB")

' Quelle laden (MASTER_Artikel enthält BestandVerfuegbar)
Set rsQuelle = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1, VkNetto, BestandVerfuegbar " & _
  "from dbo.MASTER_Artikel order by ArtNummer")

' Leeres Ziel mit gleicher Struktur
Set rsZiel = db.dbCloneRecordsetDef(rsQuelle)

' Nur Zeilen mit Bestand > 0 übernehmen
Do While Not rsQuelle.EOF
  If rsQuelle("BestandVerfuegbar") > 0 Then
    db.dbCopyRecordsetRow rsQuelle, rsZiel
  End If
  rsQuelle.MoveNext
Loop

ellib.ShowMessage "Artikel mit Bestand: " & rsZiel.RecordCount
ShowRS rsZiel

Set db = Nothing
Set rsQuelle = Nothing
Set rsZiel = Nothing

F. Zwei Gruppen in ein Recordset zusammenführen #

Option Explicit

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Dim db, rsQuelle, rsZiel

Set db = Client.CreateObject("DBLIB")

' Erste Gruppe laden
Set rsQuelle = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1 from dbo.Artikel where WarenGr = 'A'")
Set rsZiel = db.dbCloneRecordsetDef(rsQuelle)
db.dbCopyRecordsetRows rsQuelle, rsZiel

' Zweite Gruppe anfügen
Set rsQuelle = Client.ExecuteSql( _
  "select ArtNummer, Kurztext1 from dbo.Artikel where WarenGr = 'B'")
db.dbCopyRecordsetRows rsQuelle, rsZiel

ShowRS rsZiel

Set db = Nothing
Set rsQuelle = Nothing
Set rsZiel = Nothing

G. Temporäre SQL-Tabelle befüllen (AddNew und Array) #

Dieses Beispiel zeigt den kompletten Roundtrip: Temporäre Tabelle anlegen, per AddNew und dbCopyArrToRecordset befüllen, auf den Server zurückschreiben und das Ergebnis auslesen.

Option Explicit

Sub ShowRS(rs)
  If Not rs.BOF Then rs.MoveFirst
  ellib.ShowStrings Client.RenderData(rs, "CSV")
End Sub

Sub Main()
  Dim cn, db, rs, sql, arr(2, 2)

  Set cn = Client.Connection
  Set db = Client.CreateObject("DBLIB")

  ' Temp-Tabelle anlegen (Spaltenreihenfolge weicht bewusst vom Array ab)
  sql = "if object_id('tempdb..#temp') is not null drop table #temp; " & _
    "create table #temp (" & _
    "ArtNummer varchar(80), " & _
    "Kurztext1 varchar(100), " & _
    "VkNetto numeric(18,2))"
  cn.Execute sql

  ' Editierbares Recordset auf der Temp-Tabelle öffnen
  Set rs = Client.CreateObject("ADODB.Recordset")
  rs.CursorLocation = 3
  rs.Open "#temp", cn, _
    consts.adOpenKeyset, consts.adLockBatchOptimistic, consts.adCmdTable

  ' Einzelne Zeile per AddNew anfügen (über Feld-Indizes)
  rs.AddNew Array(0, 1, 2), Array("HAND-01", "Handbuchbeispiel", 99.90)

  ' Mehrere Zeilen aus Array anfügen (Spaltennamen-Zuordnung)
  arr(0, 0) = "ArtNummer" : arr(0, 1) = "Kurztext1" : arr(0, 2) = "VkNetto"
  arr(1, 0) = "4711"      : arr(1, 1) = "Schraube"  : arr(1, 2) = 1.50
  arr(2, 0) = "4712"      : arr(2, 1) = "Mutter"    : arr(2, 2) = 0.80

  db.dbCopyArrToRecordset arr, rs, _
    Array("ArtNummer", "Kurztext1", "VkNetto"), _
    Array("ArtNummer", "Kurztext1", "VkNetto"), 0

  ' Alle Änderungen auf den Server zurückschreiben
  rs.UpdateBatch

  Set rs = Nothing
  Set db = Nothing

  ' Ergebnis aus der Temp-Tabelle auslesen
  ShowRS Client.ExecuteSql("select * from #temp")
End Sub

Main

Hinweis: Client.Connection liefert das ADO-Connection-Objekt der aktuellen Datenbankverbindung. Die ADO-Konstanten adOpenKeyset, adLockBatchOptimistic und adCmdTable sind über das consts-Objekt verfügbar.

Technische Hinweise #

Voraussetzungen für dbCopyArrToRecordset #

  • Das Ziel-Recordset muss geöffnet und beschreibbar sein. Ein Recordset aus Client.ExecuteSql ist in der Regel nicht direkt editierbar. Verwenden Sie dbCloneRecordsetDef, um ein editierbares leeres Recordset mit der gleichen Struktur zu erstellen.
  • SourceIndexes und TargetIndexes müssen die gleiche Anzahl Einträge haben (Ausnahme: bei Verwendung von "*" können die SourceIndexes kürzer sein)
  • Der Parameter StartRow muss immer explizit übergeben werden (VBScript unterstützt keine Delphi-Defaultwerte). Übergeben Sie 0, um am Anfang des Arrays zu beginnen.

Fehlerverhalten #

Situation Verhalten
Ziel-Feldname nicht im Recordset Fehler (Exception)
Quell-Spaltenname nicht im Array Kein Fehler, Spalte wird übersprungen
Ungültiger Typ in TargetIndexes Fehler (Exception)
Ungültiger Typ in SourceIndexes Fehler (Exception)

dbCopyRecordsetRows / dbCopyRecordsetRow #

Beide Methoden erfordern identische Feldnamen in Quell- und Ziel-Recordset. Die Spaltenreihenfolge muss nicht übereinstimmen.

Siehe auch #