Hi,
ich kann mittels ADO per Code (Set rs = New ADODB.Recordset) einen leeren Recordset erstellen und darin mittels rs.fields.append neue Felder bzw. Spalten anlegen.
Wie funktioniert dies mit DAO?
In DAO funktioniert das so nicht. DAO-Recordsets können nur über die Methode OpenRecordset eines Datenbank-Objekts erzeugt werden. Durch Angabe des Options-Arguments dbAppendOnly könnte man ein Recordsetset vom Typ Dynaset erstellen, das anfänglich keine Datensätze enthält. Das gleiche könnte man erzielen durch die Angabe einer Bedingung in Where-Klausel einer Abfrage, die als Resultat Falsch (False) liefert. SELECT ... WHERE 0;
in DAO musst du den Umweg über eine Tabelle gehen.
Also per VBA eine Tabelle erstellen, Recordset auf Basis der Tabelle öffnen.
Zu welchem Zweck möchtest du das machen?
LG Markus
Ok danke erstmal. Ich habe mal weiter mit ADODB experimentiert.. Ich muss sagen, dass Recordsets was ganz neues für mich sind. Im Grunde möchte ich eine Tabelle in eine Variable übergeben, dort in der Variablen eine Spalte zufügen, den dann erstellten Recordset an ein Form übergeben. Hier Daten ändern, Recordset nach geänderten Daten durchsuchen und die Daten dann in die Tabelle schreiben.
Ich bin schon so weit:
Option Compare Database
Option Explicit
Dim rs As ADODB.Recordset
Private Sub Form_Load()
Dim conn As ADODB.Connection
Dim sql As String
Set conn = CurrentProject.Connection
Set rs = New ADODB.Recordset
sql = "SELECT * FROM Tabelle ORDER BY ID"
With rs
Set .ActiveConnection = conn
.Source = sql
.LockType = adLockOptimistic
.CursorLocation = adUseClient
.CursorType = adOpenKeyset
End With
With rs.Fields
.Append "YesNo", adBoolean
End With
rs.Open
Set Me.Recordset = rs
Me.chk1.ControlSource = "YesNo"
End Sub
Im Formular wird mir nun alles angezeigt. Leider kann ich dort im aber nix bearbeiten. Ich erhalte immer den Hinweis, dass das Formular schreibgeschützt ist...
Also dir fehlt noch etwas das Grundverständis zu ADO.
Schau dir mal diesen Artikel an:
https://activevb.de/tutorials/tut_adokurs/adokurs.html (https://activevb.de/tutorials/tut_adokurs/adokurs.html)
Eines der Probleme bei ADO ist, dass man viele Angaben machen kann und ohne Fehlermeldung werden deine Angaben nicht umgesetzt. Nach dem Motte ich mach was geht.
z.B diese Kombi ist nicht möglich.
.CursorLocation = adUseClient
.CursorType = adOpenKeyset
Entweder weißt du nicht was ein Keyset ist, oder du weißt nicht was die CursorLocation bedeutet.
Felder zur Laufzeit anfügen funktioniert so auch nicht.
Um das zu erreichen gibt es drei Möglichkeiten, wenn man die Daten bearbeiten möchte:
alle Felder selbst erstellen.
Daten mittels Shape Provider abrufen und gleichzeitig Felder anfügen.
Die dritte Möglichkeit lasse ich mal weg, da sie nirgends dokumentiert ist.
Da solltest du mal die VBA Hilfe zu ADO ansehen.
Das Problem dabei. DAO kann ca. 20% von dem was ADO kann und ca 1% von dem was Ado.net kann.
Das führt dann auch zu mehr Komplexität und man muss im Gegensatz zu DAO mehr Verständnis mitbringen. Also lies dich etwas ein.
Von dem was ich neu Programmiere mache ich 80% in ADO und kenne mittlerweile die Vorteile und Tücken.
LG Markus
Edit:
man kann ein Feld natürlich auch per SQL Anweisung einbinden, so wie ein berechnetes Feld bei DAO.
Das lässt sich dann aber nur "offline bearbeiten".
Zitat von: datekk am Juli 17, 2016, 16:36:13
Im Grunde möchte ich eine Tabelle in eine Variable übergeben, dort in der Variablen eine Spalte zufügen, den dann erstellten Recordset an ein Form übergeben. Hier Daten ändern, Recordset nach geänderten Daten durchsuchen und die Daten dann in die Tabelle schreiben.
So weit ich mich erinnere, stammt das von mir, hab ich doch vor einiger Zeit mal ein kleines Beispiel dazu hier gepostet, was iirc auch funktioniert hat.
Ich verwende gerne ungebundene Recordsets als tabellenartige Datenstruktur, die nicht an ein SQL gebunden ist.
Solange Du noch nicht rs.open gesagt hast, kennt das Recordset die Felder aus dem SQL noch nicht, und nach dem rs.open kann man so weit ich weiß keine Felder mehr hinzufügen.
Jedenfalls wenn Du mit ADO einmal gut zurecht kommst (man braucht nicht allen Schnick-Schnack), bist Du nicht mehr auf DAO angewiesen.
Hier nochmal mein Beispiel. Das ist mit manuellem Erzeugen der Felder, solide Handarbeit, die aber immer funktioniert. Ich würde mir auch angewöhnen, die Erzeugung der Recordsets nicht in der Form_Load Methode direkt zu schreiben, sondern in einem Modul. Dann kannst Du die Recordsets leichter austauschen und testen, ohne immer ein Formular offen zu haben.
@Wurliwurm
du erstellst ein ungebundenes Recordset und kopierst die Daten hinein. Das ist unnötig.
Mit einem einfachen Select auf die Tabelle und der Einbindung des zusätzlichen Feldes über die Select Anweisung erreichst du das gleiche - nur halt performant.
Wie ich bereits im letzten Kommentar erwähnt habe, sind auch Deine Angaben zum Öffnen des Recordsets unstimmig, und zeigen ein mangelndes Verständnis zu ADO.
Schau einfach mal deinen Code an und was von den Anweisungen nicht umgesetzt wird da die Kombinationen nicht möglich sind.
Ich würde dir auch empfehlen die Info zu ADO in der VBA Hilfe anzusehen.
LG Markus
Zitat von: markus888 am Juli 18, 2016, 13:06:40
Mit einem einfachen Select auf die Tabelle und der Einbindung des zusätzlichen Feldes über die Select Anweisung erreichst du das gleiche - nur halt performant.
Dafür kann man das Recordset dann frei aufbauen, und ändern etc. Es ist eine freie Datenstruktur und hat nicht die Grenzen einer SQL-Abfrage.
Zitat
Wie ich bereits im letzten Kommentar erwähnt habe, sind auch Deine Angaben zum Öffnen des Recordsets unstimmig, und zeigen ein mangelndes Verständnis zu ADO.
Schau einfach mal deinen Code an und was von den Anweisungen nicht umgesetzt wird da die Kombinationen nicht möglich sind.
Ich hoffe, daß das den Threadstarter jetzt nicht erschlägt.
Das weiß ich, daß ein Cursor bei einem lokalem Recordset nicht einschlägig ist. Meine Deklarationen sind teilweise i.d.T. überflüssig und "misleading". Allgemein bin ich aber schon vom Fach und habe sogar ein Buch nur über ADO. :-)
Hallo Wurliwurm :) Das hast Du gleich richtig erkannt, dass ich an Deinem Code arbeite. Mittlerweile hab ich es geschafft die Hilfstabelle als Recordset aufzubauen und das Formular daran zu binden. 8) Es ist auch wieder in Module aufgeteilt... Nur wenn ich mich an etwas ranarbeite, dann mach ich das lieber erstmal in einer einzig Sub, um nicht ständig hin und her schalten zu müssen und um den Code zu verstehen.
Zuerst dachte ich DAO wäre fortschrittlicher. Nun habe ich das aber auf Basis von ADO erfolgreich abgewickelt. Ich erstelle zuerst ein Recordset über die Select Anbindung, dann erstelle ich ein ungebundenes Recordset und kopiere dort alles rein.
Mein Code geht Spalte für Spalte durch und kopiert den Aufbau und die Daten. Die Spalten lege ich so an:
Dim i As Integer
i = Originaltabelle.Fields.Count
' Tabellenspalten in Hilfstabelle übernehmen
For i = 0 To i - 1
Hilfstabelle.Fields.Append Originaltabelle.Fields(i).Name, adChar, 200
Next
Wie man sieht, werden alle Felder als Textfelder eingefügt. Wie kann ich denn aus der Originaltabelle (es ist keine Tabelle sondern bereits ein eigenes RS) den Datentyp auslesen und ebenfalls beim erstellen der Hilfstabelle (auch ein RS) per Code übergeben?
In meinem Beispiel habe ich eine Routine erstellt, die aus einem SQL-gebundenen Recordset ein leeres ungebundenes Recordset aufbaut. Es werden die Spalten des Recordsets abgefragt und die Felder an das ungebundene Recordset angefügt:
Private Function erzeugeUngebundenesRecordset(ByRef rsOriginal As ADODB.Recordset) As ADODB.Recordset
Dim i As Integer
Dim rsUngebunden As ADODB.Recordset
Set rsUngebunden = New ADODB.Recordset
With rsUngebunden
.CursorLocation = adUseClient
'.CursorType = adOpenKeyset 'überflüssig
.LockType = adLockOptimistic
End With
With rsUngebunden.Fields
For i = 0 To rsOriginal.Fields.Count - 1
If rsOriginal.Fields(i).Type < 202 Then
.Append rsOriginal.Fields(i).Name, rsOriginal.Fields(i).Type
Else 'Textfeld, braucht zusätzich die Länge
.Append rsOriginal.Fields(i).Name, rsOriginal.Fields(i).Type, rsOriginal.Fields(i).DefinedSize
End If
Next i
End With
Set erzeugeUngebundenesRecordset = rsUngebunden
End Function
Es wird so aufgerufen:
String sql = "SELECT * FROM tblBeispiel ORDER BY Id"
rsO.Open sql, conn, adOpenForwardOnly, adLockReadOnly
Dim rsU As ADODB.Recordset
Set rsU = erzeugeUngebundenesRecordset(rsO)