Hallo zusammen ich brauche mal wieder eure Unterstützung,
ich möchte gerne Bestimmte Daten an einer bestimmten Zellen in Excel übergeben.
z.B. Bezeichnungsfeld proNummer an Zelle A1 usw. Leider habe ich keine Vorstellung wie das Ganze Anfangen soll
Hallo,
du solltest dich dazu mit der Excel-Automation beschäftigen.
Sieh dir mal folgenden Link an, den finde ich ganz gut erklärt.
https://access-im-unternehmen.de/Excel_automatisieren (https://access-im-unternehmen.de/Excel_automatisieren/)
Der Beitrag ist zwar gekürzt, aber ganz am Ende steht das entscheidende um auf eine Zelle zuzugreifen: objSheet.Cells(1, 1)
Die Kurzform zur Excel-Automation findest du z.B. auch hier:
https://learn.microsoft.com/de-de/office/troubleshoot/excel/transfer-data-to-excel-from-vb
Gruß Andi
Danke sehr hilfreich, komme drozdem nicht weiter, leider
Dann poste doch mal den VBA-Code um den es geht.
Gruß Andi
'Create a Recordset from all the records in the Orders table
Dim TicketVerwaltung As String
Dim conn As New ADODB.Connection
Dim rs As ADODB.Recordset
TicketVerwaltung= _
"Z:\TicketVerwaltung.accdb" conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _TicketVerwaltung & ";" ' Fehler Erwartet: Anweisungsende conn.Open
conn.CursorLocation = adUseClient
Set rs = conn.Execute("Orders", , adCmdTable)
'Create a new workbook in Excel
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Add
Set oSheet = oBook.Worksheets(1)
'Transfer the data to Excel
oSheet.Range("A1").CopyFromRecordset rs
'Save the Workbook and Quit Excel
oBook.SaveAs "C:\Book1.xls"
oExcel.Quit
'Close the connection
rs.Close
conn.Close
Hab mal ein Beispiel ohne Speichern gemacht das bei mir funktioniert:
Public Sub test()
Dim rs As New ADODB.Recordset
Dim i As Long
Dim oExcel As Object
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Application")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
With oExcel
.Visible = True
rs.Open "Tabelle1", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
For i = 0 To rs.Fields.Count - 1
.Cells(1, i + 1) = rs.Fields(i).Name
Next i
.Range("A2").Select
.Selection.Copyfromrecordset rs
End With
Set oExcel = Nothing
rs.Close
End Sub
Hallo Lemmy2902,
anders herum wird ein Schuh daraus. Anstatt per Automation Daten nach Excel zu exportieren, gibt es heute sehr einfache Möglichkeiten, z.B. mit PQ in Excel eine Access-Datenbank zu lesen, daraus eine Tabelle zu erstellen und weiter zu verarbeiten.
Gruß Knobbi38
Zitat von: Hondo am Mai 21, 2025, 10:43:31Hab mal ein Beispiel ohne Speichern gemacht das bei mir funktioniert:
Public Sub test()
Dim rs As New ADODB.Recordset 'Fehler Benutzerdefiniert typ nicht definiert
Dim i As Long
Dim oExcel As Object
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Application")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
With oExcel
.Visible = True
rs.Open "Tabelle1", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
For i = 0 To rs.Fields.Count - 1
.Cells(1, i + 1) = rs.Fields(i).Name
Next i
.Range("A2").Select
.Selection.Copyfromrecordset rs
End With
Set oExcel = Nothing
rs.Close
End Sub
da bekomme ich auch eine Fehlermeldung und wo wird angeben aus welcher datenkank die daten kommen sollen
was ist PQ ? das wir uns richtig vertstehen ich möchte aus einen Formular die daten an eine excel übergeben,da muss ich doch die Quelle und die Felder bestimmen.
PQ = Power Query
Hallo
Zitatda bekomme ich auch eine Fehlermeldung und wo wird angeben aus welcher datenkank die daten kommen sollen
Na aus der in der du gerade arbeitest!!!
Und nicht schreiben Fehlermeldung... sondern welche Fehlermeldung!
Seh grad, im Code fehlt nach .Visible = true folgendes:
.workbooks.Add
Hier eine BeispielDB:
Hallo Lemmy2902,
Zitat von: Lemmy2902 am Mai 21, 2025, 12:42:50was ist PQ ?
PQ ist die übliche Abkürzung für PowerQuery für Excel, was in Excel per AddIN bereitgestellt wird.
Zitat... das wir uns richtig vertstehen ich möchte aus einen Formular die daten an eine excel übergeben,da muss ich doch die Quelle und die Felder bestimmen.
Keine Ahnung, was du damit meinst. Wieso mußt du die Quelle und die Felder bestimmen? Was hat das überhaupt mit einem Formular zu tun?
Zitat... da bekomme ich auch eine Fehlermeldung und wo wird angeben aus welcher datenkank die daten kommen sollen
Alles ganz schön, nur von welcher Fehlermeldung sprichst du hier und wieso mußt du eine Datenbank für die bereitzustellenden Daten auswählen?
Nichts für ungut, aber vielleicht solltest du dich erst einmal mit den Grundlagen von Access beschäftigen, bevor du solche Projekte angehst. So wird es schwierig, da das eigentliche Problem noch nicht mal richtig beschrieben wird.
Gruß Knobbi38
Also die Fehler Meldung steht im Code, ich will die daten nicht über ein Bericht Bereitstellen sondern über Excel, zwecks Berarbeitung
Anmerkung: Bitte keine vollständigen Beiträge zitieren. Das verlängert unnötig die Themen und macht sie unübersichtlich. Was ich sehe, lösche ich dann ohnehin. MzKlMu
die Fehlermeldung ist immer noch die selbe Benutzerdefinierter Typ nicht definiert
Hallo Lemmy,
eigentlich sagt der Fehler doch alles. Wenn du auf die ADODB Bibliothek verwenden möchtest, mußt du natürlich deinem Projekt auch einen Verweis auf diese Bibliothek ( "Microsoft ActiveX Data Objects 6.1 Library") hinzufügen, sonst kannst du diese nicht ansprechen.
Dann solltest du nicht einfach das Schlüsselwort NEW so in diesem Zusammenhang verwenden, sondern mit Set einer Referenzvariable zuweisen. Und ganz wichtig: wenn du Ressourcen verwendest, solltest du diese am Ende wieder freigeben; das gilt auch für Objecte, welche du selber mit Open eröffnest, dann mußt du auch anschließend die Close Methode verwenden. Das gilt um so mehr, wenn du eine andere Anwendung per Automation ansprichst. Wird das nicht ordentlich beendet, gibt es anschließend Probleme mit der Anwendung oder im schlimmsten Fall sogar mit Windows.
Ich nehme mal an, daß du das mit der BeispielDB aus #11 nachvollziehen kannst.
Gruß Knobbi38
Hallo,
hier:
Dim rs As New ADODB.Recordsetwird ein ADO-Recordset deklariert. Wenn Du das verwenden willst, dann mußt Du eine Referenz auf die ADO-Library im VBA-Editor aktivieren, sonst kommt es zu dem Fehler.
Warum Hondo jetzt ein ADO-Recordset verwendet - keine Ahnung. Da Du mit einer Access-Datenbank arbeitest, kannst Du einfach ein DAO-Recordset verwenden, was der übliche Weg ist, auf Access-Tabellen zuzugreifen.
ADO ist vor allem für externe Datenbanken wie SQL Server gedacht. Die Datenbank, auf die zugegriffen wird, findet sich im Connectionstring, und die wird für die lokale Datenbank aus "CurrentProject" bezogen, weil Access grundsätzlich immer einen ADO-Connectionstring bereithält, auch wenn ADO nicht verwendet wird (aus historischen Gründen, Thema ADP).
Wie gesagt - brauchst Du aber nicht, verwende stattdessen die Deklaration DAO.Recordset.
Das Recordset wird mit "Set rs = CurrentDb.OpenRecordset("MeineTabelle") " geöffnet.
Anleitung und Beispiele:
https://learn.microsoft.com/de-de/office/client-developer/access/desktop-database-reference/database-openrecordset-method-dao
Gruß
Christian
den einen Fehler behoben und schon kommt der nächste die lautet wie Unzulässige SQL Anweisung
Zitat von: Bitsqueezer am Mai 21, 2025, 15:16:04Warum Hondo jetzt ein ADO-Recordset verwendet - keine Ahnung.
Hab ich dem Themenstarter zu Liebe gemacht, der hat zuerst ADO verwendet.
Ich selbst verwende eigentlich immer DAO.
Hallo,
...und jetzt sollen alle raten, wie Dein Code dazu aussieht?...
DU willst doch Hilfe, also ist es an Dir, alle notwendigen Informationen bereitzustellen.
Gruß
Christian
Zitat von: Lemmy2902 am Mai 21, 2025, 15:29:14Unzulässige SQL Anweisung
Und wie lautet deine SQL-Anweisung? Tabellennamen korrekt, Feldnamen korrekt?
Man, dass man dir alles aus der Nase ziehen muss.
SELECT tblProjekte.projektID, tblProjekte.proNummer, tblProjekte.proBeschreibung, tblProjekte.proProjektGeschlossen, tblProjekte.proStartDatum
FROM tblProjekte
WHERE (((tblProjekte.proProjektGeschlossen)=False) AND ((tblProjekte.proStartDatum) Like "*" & "2025"));
Hallo,
und wie sieht es damit aus:
SELECT projektID
,proNummer
,proBeschreibung
,proProjektGeschlossen
,proStartDatum
FROM tblProjekte
WHERE proProjektGeschlossen = False
AND Year(proStartDatum) = 2025
Public Sub test()
Dim rs As New ADODB.Recordset
Dim i As Long
Dim oExcel As Object
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Application")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
With oExcel
.Visible = True
.workbooks.Add
rs.Open "tblProjekte", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
For i = 0 To rs.Fields.Count - 1
.Cells(1, i + 1) = rs.Fields(i).Name
Next i
.Range("A2").Select
.Selection.Copyfromrecordset rs
End With
Set oExcel = Nothing
rs.Close
End Sub
Guten Morgen, das ist der Code den ich gerade verwende. wenn ich das strte wird mir der erste daten satz in Excel Geschrieben und dann kommt die Fehlermeldung "die Metohde copyFromRecordset für das Objekt Range ist fehlgeschlagen.
Wenn ich das ganze mit der von die Angepassten Abfrage Versuche kommt der Fehler wieder Unzulässige SQL-Anweisung
Der Code ist Korrekt, ist ja auch von mir - was an sich nichts bedeuten muss.
Hast du die Datenbank von mir mal getestet?
Um die Sache abzukürzen, mach doch mal eine Beispieldb mit Beispielwerten in der Tabelle tblProjekte und lade die hier hoch.
Sind Datensätze in der Tabelle überhaupt vorhanden?
Gruß Andreas
ja ich habe diene Datenbank getestet da klappt alles bestens, tblProjekte hat insgesamt 499 Datensätze und ist aber nur ein teil. das komplette Projekt ist insgesamt 260MB groß
es bringt auch nicht eine neue DB zu erstellen, deine Funktioniert ja, es soll ja mit vorhanden Funktionieren.
so das Problem war ein OLE objekt jetzt kann ich tblProjekte in Excel übertragen, jetzt müsste die Inhalte noch in bestimmten Zellen Ausgegeben werden. z. B Datum auf Zelle A4
Hallo Lemmy,
der Code von Andy ist möglicherweise nicht ganz optimal, aber dazu gab es schon andere Ratschläge, wie man das verbessern könnte. Die hast du aber noch nicht umgesetzt. Schau dir mal diese Codestellen näher an:
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Application")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
Was soll den dieser Code bewirken, außer das im Fehlerfall CreateObject() zweimal aufgerufen wird?
Dim rs As New ADODB.RecordsetDaß das nicht besonders glücklich ist und nur Probleme verursacht, hatten wir schon. Wo werden die Ressourcen wieder freigegeben? Gerade bei Automation ist sorgfältiges Programmieren sehr wichtig, sonst wir dein System instabil.
Einfach alle Tips (#15) ignorieren ist nicht zielführend.
.Range("A2").Select
.Selection.Copyfromrecordset rs
Der Umweg über das Selection-Objekt kannst du dir sparen, sondern du kannst einfach die CopyFromRecordset() Methode vom Range Objekt aufrufen. Schau dir einfach mal das Beispiel in der Hilfe an.
Noch zwei kleine Hinweise:
1. Vor der Verwendung eines Recordsets sollte geprüft werden, ob das Recordset überhaupt Datensätze enthält.
2. Steht zwar nicht im Handbuch, aber CopyFromRecordset() kann bei einer größeren Anzahl von Datensätzen Probleme bereiten. Das sollte man immer im Hinterkopf behalten und ggf. auf eine andere Methode ausweichen.
Knobbi38
PS:
Bei Fehlermeldungen immer auch den Fehlercode mit angeben.
PPS:
Zitatjetzt müsste die Inhalte noch in bestimmten Zellen Ausgegeben werden. z. B Datum auf Zelle A4
Wo ist jetzt das Problem? Die Syntax dafür kennst du doch schon - Stichwort "Cells()".
Private Sub Befehl139_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim i As Long
Dim oExcel As Object
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Applikation")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
Set db = CurrentDb
Set rst = db.OpenRecordset("tblProjekte", dbOpenDynaset)
With oExcel
.Visible = True
.workbooks.Add
For i = 0 To rst.Fields.Count - 1
.Cells(1, i + 1) = rst.Fields(i).Name
Next i
.Range("A2").Select
.Selection.Copyfromrecordset rst
End With
Set oExcel = Nothing
rst.Close
End Sub
Danke für die Hinweise ich habe jetzt den Code etwas Umgebaut von ADO auf DAO, läuft Prima. das mit den Cells ist mir noch etwas zu Hoch, ich weis das in der For-Schleife alle Inhalte srt Zeilenweise geschrieben werden, aber wie mache ich das das ein bestimmter Teil von den eingelesen Daten auf eine bestimmte cells geschrieben wird. ein kleiner Ansatz währe Hilfreich, Danke
Hallo Lemmy,
den Umstieg von ADO nach DAO hast du jetzt vollzogen, ob das in diesem speziellen Fall von Vorteil ist, wird sich noch zeigen. Die anderen Hinweise hast du leider aber nur zum Teil umgesetzt, daran solltest du noch arbeiten.
Was verstehst du denn nun unter "bestimmter Teil" und in welche Zellen soll das dann geschrieben werden?
Knobbi38
ich möchte einen Bericht in Excel machen so wie der Access-Bericht mit Formatierungen und so weiter und dazu müssen die Inhalte an bestimmten Cells sein, name an A2, Baustelle A4, Ticket Nr.: A6 usw.
so sollte es dann in Excel ausschauen.
Hallo Lemmy,
das wird nur mit CopyFromRecordset alleine nicht gehen und natürlich auch nicht in einem Rutsch, den es geht hier um Kopfdaten und Positionsdaten.
Im ersten Schritt kannst du die Kopfdaten per Recordset auslesen und dann jedes Feld einzeln den Zellen zuweisen, wobei benannte Bereiche sicherlich hilfreich sein könnten. Das geht im Prinzp so wie in den Beispielen vorher, also
Range("Name der Zelle").Value = Recordset.Field("Feldname").Value
Im zweiten Schritt werden die Positionsdaten übertragen. Dabei mußt du dir eine Abfrage erstellen, bei welcher die Felder exakt in der gleichen Position sind, wie sie im Bericht benötigt werden. Dann kannst du diese mit CopyFromRecordset an die Zielort zuweisen. Es ginge auch in einer Schleife, Datensatz für Datensatz, aber das wäre nur mehr Aufwand.
Anschließend noch die Formatierungen anpassen und fertig. Wie du die Formatierungen vornimmst, kannst du probehalber mal in Excel mit dem Makrorecorder aufzeichnen und dann analog in Access übertragen.
Aber mal ganz ehrlich, so etwas macht man doch in Access mit einem Report und nicht in Excel. ::)
Knobbi38
danke werde ich mal Versuchen sicher hab ich ja, aber der Wunsch besteht an den Regie-Berichten falls nötig Änderungen vorzunehmen zu können, und da die berichte nur in PDF ausgegeben werden ist das schwierig und ein Export oder in ein anderes office Produkt Umzuwandeln die Formatierungen nicht Übernommen werden.
Hallo Lemmy,
Zitat... ist aber der Wunsch besteht an den Regie-Berichten falls nötig Änderungen vorzunehmen zu können
Entschuldige, aber das halte ich für kompletten Nonsens. Wenn Änderungen zu machen sind, sollten diese ausnahmslos nur in der der Datenbasis gemacht werden dürfen und dann kann man ggf. einen neuen Bericht ausdrucken.
Aber das ist ein anderes Thema.
Knobbi38
Private Sub Befehl139_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim i As Long
Dim oExcel As Object
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Applikation")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
Set rst = CurrentDb.OpenRecordset("qryProjektBericht")
With oExcel
.Visible = True
.workbooks.Add
For i = 0 To rst.Fields.Count - 1
.Range("A6").Value = rst.Fields("projektID").Value
.Range("B6").Value = rst.Fields("proStartDatum").Value
.Range("C6").Value = rst.Fields("proNummer").Value
Next i
End With
Set oExcel = Nothing
rst.Close
End Sub
Das ist jetzt der Code den ich verwende, mit einer Tabelle klappt es mit einer Abfrage leider nicht
Fehlermeldung: 1 Parameter wurde erwartet aber es wurden zu wenig Parameter Übergeben. es liegt an den Filter den ich in der qryProjektBericht Habe.
SELECT tblProjekte.projektID, tblProjekte.proBericht, tblProjekte.prokun_IDRef, tblProjekte.probau_IDRef, tblProjekte.proNummer, tblProjekte.proStartDatum, tblProjekte.proEndDatum, tblProjekte.proBeschreibung, tblProjekte.proOnIce, tblProjekte.proProjektGeschlossen, tblProjekte.proBericht, tblProjekte.proWeitereArbeiten, tblProjekte.proArbeitenAbgeschlossen, tblProjekte.proAnlagen, tblProjekte.proStundenLimit, tblProjekte.Status, tblProjekte.[Schätzung Std], tblProjekte.DatumAenderung, tblAufgaben.aufgabenid, tblAufgaben.aufper_IDRef, tblAufgaben.aufpro_IDRef, tblAufgaben.mitver_IDRef, tblAufgaben.aufDatum, tblAufgaben.aufStunden, tblAufgaben.aufBemerkung, tblAufgaben.aufStundenMonture, tblAufgaben.aufStundenOMonture, tblBaustellen.baustelleID, tblBaustellen.bauStelle, tblBaustellen.bauBemerkung, tblBerufsgruppe.VerhältnissID, tblBerufsgruppe.verBerufsGruppe, tblMitarbeiter.mitarbeiterID, tblMitarbeiter.mitRufname, tblMitarbeiter.mitNameVor, tblMitarbeiter.mitNameNach, tblMitarbeiter.mitNameAnzeige, tblMitarbeiter.mitStatus, tblMitarbeiter.mitNameLang, tblMitarbeiter.mitTel, tblMitarbeiter.mitPass, tblMitarbeiter.mitAdresse, tblMitarbeiter.mitPLZ, tblMitarbeiter.mitOrt, tblMitarbeiter.mitGeboren, tblMitarbeiter.mitActivEnde, tblMitarbeiter.mitActivStart, tblMitarbeiter.mitAlter
FROM (tblBaustellen INNER JOIN tblProjekte ON tblBaustellen.baustelleID = tblProjekte.probau_IDRef) INNER JOIN (tblBerufsgruppe INNER JOIN (tblMitarbeiter INNER JOIN tblAufgaben ON tblMitarbeiter.mitarbeiterID = tblAufgaben.aufper_IDRef) ON tblBerufsgruppe.VerhältnissID = tblAufgaben.mitver_IDRef) ON tblProjekte.projektID = tblAufgaben.aufpro_IDRef
WHERE (((tblProjekte.projektID)=[Formulare]![frmProjekteVerwaltung]![lstAuftragWaelen]));
Hallo Lemmy,
ich hatte doch darum gebeten, die Laufzeitfehlernummer mit anzugeben - der Fehlertext alleine reicht nicht immer aus.
In diesem Fall ist die Ursache aber relativ einfach:
Siehe https://www.donkarl.com?FAQ6.4 (https://www.donkarl.com/?FAQ6.4)
Du solltest die Abfrage in eine Parameterabfrage umwandeln und dann kannst du diesen Parameter aus der Listbox auslesen und übergeben.
Hier ist das eigentlich ganz gut erklärt:
https://www.donkarl.com?FAQ6.16
https://access-im-unternehmen.de/Parameterabfragen_unter_der_Lupe/ (https://access-im-unternehmen.de/Parameterabfragen_unter_der_Lupe/)
Knobbi38
Guten Morgen,
danke für die Antwort und sorry für die Fehlermeldung, aber mit dem Befehl eval komme ich nicht zurecht, wie muss ich das in die Abfrage mit einbauen.
Hallo Lemmy,
wie Eval() angewendet wird, könntest du auch selber in der Hilfe nachschlagen, daß muß ich hier nicht nochmal wiederholen.
Allerdings halte ich in diesem Zusammenhang Parameterabfragen für sinnvoller und möchte das Thema bezügl. Eval() deshalb nicht weiter vertiefen. Wie das mit den Parameterabfragen geht, kannst du den Links aus #37 entnehmen.
Knobbi38
sorry kannst du mir noch mal helfen mit dem Eval
Zum Beispiel so:
SELECT
...
FROM
...
WHERE tblProjekte.projektID=eval([Formulare]![frmProjekteVerwaltung]![lstAuftragWaelen])
danke, bekomme trotzdem den Fehler 3061
SELECT tblProjekte.projektID, tblProjekte.prokun_IDRef, tblProjekte.probau_IDRef, tblProjekte.proNummer, tblProjekte.proStartDatum, tblProjekte.proNummer, tblProjekte.proEndDatum, tblProjekte.proBeschreibung, tblProjekte.proProjektGeschlossen, tblProjekte.proBericht, tblProjekte.proWeitereArbeiten, tblProjekte.proArbeitenAbgeschlossen, tblProjekte.Status, tblWarenEinsatz.materialID, tblWarenEinsatz.matart_IDRef, tblWarenEinsatz.matpro_IDRef, tblWarenEinsatz.warArt_IDRef, tblWarenEinsatz.warson_IDRef, tblWarenEinsatz.warson_IDRef, tblWarenEinsatz.artMenge, tblWarenEinsatz.artMaterial, tblWarenEinsatz.artEinheit, tblArtikel.artikelID, tblArtikel.VKZ, tblArtikel.artNummerSonnePar, tblArtikel.artBeschreibung, tblAufgaben.aufgabenid, tblAufgaben.aufpro_IDRef, tblAufgaben.mitver_IDRef, tblAufgaben.aufDatum, tblAufgaben.aufStunden, tblAufgaben.aufBemerkung, tblBaustellen.baustelleID, tblBaustellen.bauStelle, tblBaustellen.bauBemerkung, tblMitarbeiter.mitRufname
FROM ((tblBaustellen INNER JOIN tblProjekte ON tblBaustellen.baustelleID = tblProjekte.probau_IDRef) INNER JOIN (tblMitarbeiter INNER JOIN tblAufgaben ON tblMitarbeiter.mitarbeiterID = tblAufgaben.aufper_IDRef) ON tblProjekte.projektID = tblAufgaben.aufpro_IDRef) INNER JOIN (tblArtikel INNER JOIN tblWarenEinsatz ON tblArtikel.artikelID = tblWarenEinsatz.matart_IDRef) ON tblProjekte.projektID = tblWarenEinsatz.matpro_IDRef
WHERE tblProjekte.projektID=eval([Formulare]![frmProjekteVerwaltung]![lstAuftragWaelen]);
Hallo Lemmy,
ist denn sichergestellt, daß das Formular "frmProjekteVerwaltung" geöffnet ist und in der Listbox ein Wert selektiert ist?
Solche Unwägbarkeiten mußt du natürlich abfangen, bevor du so eine Abfrage öffnest.
Knobbi38
ja das Formular ist offen und ein Daten Satz ist ausgewählt
Hallo Lemmy,
das tut mir leid, aber aus der Ferne kann ich das Problem so nicht nachvollziehen und das Thema Eval() möchte ich in diesem Zusammenhang auch nicht weiter vertiefen, da es m.M.n. für das Problem eine bessere Lösung gibt.
Knobbi38
Guten Morgen,
ok, und die währe
was komisch ist wenn ich die qry starte wird mir nur der selektiere Datensatz angezeigt.
Hallo,
versuche es mal mit [Forms] statt [Formulare].
Eval benötigt man nicht zum Auslesen eines Formularwertes.
Wenn man sichergehen möchte, kann man den Wert auch in einer VBA-Funktion auslesen und als Rückgabewert (Typ Variant) den ausgelesenen Wert verwenden. Das hat den Vorteil, daß man in der Funktion auch Fehler abfangen kann und ggf. einen Dummy-Wert zurückgeben kann. Ebenso kann man in der Funktion auch prüfen, ob das Formular geöffnet ist.
Die Funktion kann man dann im WHERE-Teil nach dem "=" verwenden, immer mit () am Ende (oder Übergabeparametern zusätzlich, falls benötigt).
Oder man verwendet PARAMETERS, die man auch im Abfragedesigner im Ribbon findet und dort eingeben kann, wenn man die Abfrage per VBA aufrufen will, kann man dann eine QueryDef verwenden und deren Parameters-Collection entsprechend mit dem gesuchten Wert befüllen.
Gruß
Christian
Public Sub test()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim i As Long
Dim oExcel As Object
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Applikation")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
Set rst = CurrentDb.OpenRecordset("qryProjektBericht")
With oExcel
.Visible = True
.workbooks.Add
For i = 0 To rst.Fields.Count - 1
.Range("A6").Value = rst.Fields("projektID").Value
.Range("B6").Value = rst.Fields("proStartDatum").Value
.Range("C6").Value = rst.Fields("proNummer").Value
Next i
End With
Set oExcel = Nothing
rst.Close
End Sub
ist der Code vom Modul
SELECT tblProjekte.proBericht, tblProjekte.projektID
FROM tblProjekte
WHERE (tblProjekte.projektID=eval([Formulare]![frmProjekteVerwaltung]![lstAuftragWaelen]))
ORDER BY tblProjekte.projektID;
und das ist der SQL code.
Ist eigentlich alles wie es sein soll nur der fehler bleibt immer der selbe 3061
Hallo,
hatte kürzlich den gleichen Fehler und was war die Ursache? Ein dummer kleiner Rechtschreibfehler.
Daher könnte ich mir denken dass lstAuftragWaelen eventuell lstAuftragWaehlen heißen sollte?
Helfen könnte dass man anstelle von:
Set rst = CurrentDb.OpenRecordset("qryProjektBericht")
einfach qryProjektBericht durch die Abfrage ersetzt und diese im Code debuggt.
Wie man debugt weißt du?
Direktfenster an,
In den Code schreiben:
Debug.Print Forms("frmProjekteVerwaltung").lstAuftragWaehlen
Außerdem, lass mal das eval() weg und verwende im Code den Begriff Forms anstatt Formulare.
Ansonsten wenn das nichts bringen sollte, mach mal ne abgespeckte Version deiner DB und lade sie hoch.
Gruß Andi
@christian:
Zitat von: Bitsqueezer am Mai 26, 2025, 08:29:24versuche es mal mit [Forms] statt [Formulare].
Spielt in diesem Fall keine Rolle, da in VBA eine Query aufgerufen wird.
ZitatEval benötigt man nicht zum Auslesen eines Formularwertes.
Doch, wenn die Query mit VBA ausgeführt werden soll. Dabei wird kein Expression-Service ausgeführt und deshalb kann die Formular-Referenz nicht ausgewertet werden.
@Lemmy:
Zitat... und die währe
Sag mal, liest du hier eigentlich die Antworten noch mit?
Zitat... was komisch ist wenn ich die qry starte wird mir nur der selektiere Datensatz angezeigt.
Das ist nicht komisch, sondern normales Access Verhalten. Die Begründung steht doch in dem Link zur Webseite von donkarl (Karl Donaubauer).
Zitat For i = 0 To rst.Fields.Count - 1
.Range("A6").Value = rst.Fields("projektID").Value
.Range("B6").Value = rst.Fields("proStartDatum").Value
.Range("C6").Value = rst.Fields("proNummer").Value
Next i
Was möchtest du eigentlich damit erreichen?
Bei allem Respekt, aber wenn du mit Access/VBA weiterkommen möchtest, solltest du dir doch mal die Mühe machen, dir ein paar Grundlagen bezüglich Datenbanken und VBA-Programmierung anzueignen, da das kein Forum leisten kann.
Gruß Knobbi38
PS:
Vielleicht können andere Helfer hier für mich weiter machen?
Wird sind mittlerweile bei 50 Beiträgen ohne erkennbaren Fortschritt, daß sollte i.N. reichen.
Hallo,
@Ulrich: Stimmt, hast Du recht, mit "Forms"-Auswertung. War mir auch noch nicht bekannt, sehr strange.
Ein Grund mehr, keine Form-Referenzen in Abfragen einzubauen.
@Lemmy:
Hier mal zwei Beispiele, wie man das lösen kann:
Public Sub TestQueryWithParams()
Dim rs As DAO.Recordset
'Set rs = CurrentDb.OpenRecordset("SELECT ID FROM qryFormTest WHERE ID = " & Forms!frmBestellungenMain.ID)
Dim qd As DAO.QueryDef
Set qd = CurrentDb.QueryDefs("qryFormTestParam")
qd.Parameters("parID") = Forms!frmBestellungenMain.ID
Set rs = qd.OpenRecordset()
Stop
End SubErste Abfrage im auskommentierten Teil ist ohne Parameter, zweite Abfrage hat einen Long Integer Parameter "parID" im Abfragedesigner erstellt bekommen und als Kriterium für "ID".
Ich würde die 2. Version verwenden. Der Test, ob das Formular geladen ist, kann und sollte natürlich auch bei der ersten Variante erfolgen.
Das Anpassen an Deine Tabellen/Abfragen sollte hoffentlich kein Problem sein.
Gruß
Christian
so ich hab das mal in einer Neuen DB nachgestellt
Also,
da sind m.E. strukturelle Fehler gemacht worden.
Zuerst, die Abfrage gehört als SQL-String in den Code nicht als Referenz auf eine gespeicherte Abfrage.
Dann muss der Fehler abgefangen werden dass der Benutzer kein Projekt auswählt aber trotzdem auf Export klickt.
Entweder indem der Export-Button erst dann aktiv geschaltet wird wenn ein Projekt ausgewählt wurde oder als Abfrage im VBA-Code ob der Wert Null ist.
Anbei eine Version die einwandfrei funktioniert.
Und beachte mal die Schreibweise der Abfrage. keine Klammern, keine überflüssige Tabelle.Feld Bezeichnung, Zeilentrennung über Fortsetzungszeichen.
Du musst nur dann die Tabelle vor das Feld schreiben wenn es mehrere Tabellen gibt bzw. die Zuornung nicht eindeutig ist.
Private Sub expotierenExcel_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim i As Long
Dim strSQL As String
Dim oExcel As Object
If IsNull(Forms("frmProjektVerwaltung").lstAuftragWaelen) Then
MsgBox "Bitte wählen Sie ein Projekt aus!"
Exit Sub
End If
strSQL = "SELECT projektID, proNummer, proBeschreibung, proProjektGeschlossen, proStartDatum " & _
"FROM tblProjekte WHERE projektID=" & Forms("frmProjektVerwaltung").lstAuftragWaelen
On Error Resume Next
Err.Clear
Set oExcel = CreateObject("Excel.Applikation")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
Set rst = CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)
With oExcel
.Visible = True
.workbooks.Add
For i = 0 To rst.Fields.Count - 1
.Range("A6").Value = rst.Fields("projektID").Value
.Range("B6").Value = rst.Fields("proStartDatum").Value
.Range("C6").Value = rst.Fields("proNummer").Value
Next i
End With
Set oExcel = Nothing
rst.Close
End Sub
Gruß Andi
Und wenn du die Excel-Datei noch speichern möchtest und Excel beenden, dann schreibst du direkt vor "End With" folgendes:
.Workbooks(1).SaveAs "Projekt_" & Forms("frmProjektVerwaltung").lstAuftragWaelen & ".xlsx"
.Workbooks(1).Close
.Quit
Gruß Andi
Ach ja, und an diejenigen gerichtet die meinen die Zeile:
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
sei überflüssig, sollten diese doch einfach weglassen und es ausprobieren.
Den Fehler 429 könnt ihr ja dann selbst abfangen.
frage läuft das bei dir ich habe immer noch die selbe Fehlermeldung 3061
wenn ich die abfrage im direkt Fenster mache "Debug.Print Forms("frmProjektVerwaltung").lstAuftragWaelen" wird mir der Ausgewählte Datensatz angezeigt.
Ich kann dir nicht auf den Schoß sitzen und dir jeden Tastendruck vormachen.
Ich hab dir gesagt, du musst lernen Fehler zu debuggen!
Gruß Andi
Dann sieh dir den kompletten SQL-STring im Direktfenster an, poste ihn hier.
Wo an welcher Stelle im Code tritt der Fehler auf?
ja da hast du recht muss noch einiges Lernen, danke es Klappt.
@Hondo ZitatAch ja, und an diejenigen gerichtet die meinen die Zeile:
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
sei überflüssig, sollten diese doch einfach weglassen und es ausprobieren.
Den Fehler 429 könnt ihr ja dann selbst abfangen.
Schau dir doch mal selber den ganzen Quellcode an. Wenn in der Zeile davor CreateObject() einen Fehler 429 bringt, dann kann wird in dieser Zeile mit großer Wahrscheinlichkeit CreateObject() wieder den gleichen Fehler melden, oder?
Möglicherweise sollte man es erst mit GetObject() probieren und im Fehlerfall mit CreateObject() alternativ einer neue Instanz erzeugen? Aber auch nach CreateObject() sollte man die Referenz auf Nothing prüfen.
Beim Beenden der Automation kann man dann noch checken, ob eine neue Instanz erzeugt worden ist, oder eine vorhandene genutzt wird. Ich glaube der Anwender wäre nicht erbaut davon, wenn der Export die aktuelle Excel Instanz jedes mal schließt. Am Schluß ist es zudem wirklich wichtig, alle benötigten Referenzen in der umgekehrten Reihenfolge auf Nothing zu setzen, damit es mit der Automation keine sporadischen Probleme gibt.
Nur mal so ...
Gruß Knobbi38
Zitat von: knobbi38 am Mai 27, 2025, 11:57:41dann kann wird in dieser Zeile mit großer Wahrscheinlichkeit CreateObject() wieder den gleichen Fehler melden, oder?
Nein. Probier es aus.
Zitat von: knobbi38 am Mai 27, 2025, 11:57:41Beim Beenden der Automation kann man dann noch checken, ob eine neue Instanz erzeugt worden ist, oder eine vorhandene genutzt wird
Nicht nötig, es wird immer eine neue Instanz erstellt und diese wieder geschlossen.
Gruß Andi
@Hondo die Logik ist m.E. nicht richtig.
Bei mir wird immer schon bei ersten Aufruf von CreateObject() erfolgreich eine Objektreferenz zurückgegeben und wenn das bei dir so ist, daß ein erst ein zweiter Aufruf von CreateObject() notwendig bzw. erfolgreich ist, dürfte etwas mit deinem COM-System nicht ganz i.O. sein.
Zitat von: Hondo am Mai 27, 2025, 13:19:24ZitatBeim Beenden der Automation kann man dann noch checken, ob eine neue Instanz erzeugt worden ist, oder eine vorhandene genutzt wird
Nicht nötig, es wird immer eine neue Instanz erstellt und diese wieder geschlossen.
Anscheinend hast du nicht ganz verstanden, worauf ich eigentlich hinaus wollte. Das mit CreateObject() immer eine neue Instanz erzeugt wird, ist klar. Hier ging es aber darum, wenn eine vorhandene Instanz verwendet wird, diese nicht einfach blindlings zu schließen.
Gruß Knobbi38
Zitat von: knobbi38 am Mai 27, 2025, 15:03:15diese nicht einfach blindlings zu schließen.
Die wird doch gar nicht geschlossen, sondern nur die neu erzeugte.
Hast du es ausprobiert?
Der Orginal-Code stammt übrigends von Reinhard Kraasch (ehemals DBWiki.de)
Dort schreibt er:
On Error Resume Next
Err.Clear
Set oExcel = GetObject(, "Excel.Application ")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
Und das Speichern/Ausstieg hat er wie folgt gemacht:
With oExcel
...
If MsgBox("Speichern?", vbYesNo + vbQuestion) = vbYes Then
.ActiveWorkbook.SaveAs Me!FName
Else
.ActiveWorkbook.Close SaveChanges:=False
End If
.Quit
End With
Gruß Andreas
By the Way
Ich finde es total Schade dass solche wertvollen Quellen wie DBWiki nicht mehr online sind.
Weiß jemand was Reinhard Kraasch macht?
Gruß Andi
Hallo Andy,
anscheinend reden wir aneinander vorbei. Schau dir den Code von Reinhard nochmal genauer an, dann erkennst du vielleicht, was du anders gemacht hast
On Error Resume Next
Err.Clear
Set oExcel = GetObject(, "Excel.Application ")
If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
On Error GoTo 0
und warum das bei dir doppelt gemoppelt ist.
Gruß Knobbi38
PS:
Du kannst das DBWiki hier noch einsehen:
https://web.archive.org/web/20191028003208/http://dbwiki.net/
Zitat von: knobbi38 am Mai 27, 2025, 21:59:51dann erkennst du vielleicht, was du anders gemacht hast
hab ich doch unten geschrieben?
Außerdem ist das nicht doppelt gemoppelt, bei mir (Office 2010) zumindest geht der Interpreter in den 2. Aufruf des Excel-Opjektes weil beim ersten Fehler 429 kommt.
Von welchem Code redest du, dem von dir oder dem von Reinhard?
Und ja, dein Code ist doppelt gemoppelt!
nehm ich die Zeile: If Err.Number <> 0 Then Set oExcel = CreateObject("Excel.Application")
heraus ist das Objekt nicht instanziert, und in Folge bekome ich Fehler 91 "Objektvariable oder With-Blockvariable nicht festgelegt".
Also ist die Zeile nicht überflüssig sondern notwendig.
Das Verhalten siehst du an der beigehängten gezippten mp4-Datei.
Hallo Andreas,
Ulrich meinte, daß es im Originalcode zuerst "GetObject" heißt und wenn das erfolglos war, "CreateObject" aufgerufen wird. Es macht halt keinen Sinn, zuerst "CreateObject" und dann nochmal "CreateObject" aufzurufen.
Aber diese Variante stammt hier im Thread von Lemmy, wenn ich das richtig gesehen habe, nicht von Dir.
Gruß
Christian