Dezember 07, 2021, 14:23:28

Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!


Export per Makro zu Excel

Begonnen von hjbartel, November 20, 2021, 12:16:03

⏪ vorheriges - nächstes ⏩

hjbartel

Hallo Wissende,

ich habe ein kleines Projekt, bei dem ich gefühlt 99% erfolgreich geschafft habe, aber der vermeintlich kleine Rest treibt mich zur Verzweiflung. Ich habe auch schon "das Internet durchgelesen" und viele Ansätze gefunden, die mir aber nur teilweise geholfen haben.

Es gibt ein Makro "Import". Hier werden bereitgestellte csv-Dateien importiert und mit SQL-Befehlen per Makro angeordnet und in Tabellen in der Anwendung abgelegt. Auf diese Tabellen greifen die Anwender direkt zu, außerdem besteht noch die Besonderheit, dass ich aus einer Tabelle eine kleine Abfrage machen möchte, dessen Ergebnis der Anwender über das Makro "Export" als Excel-Datei sich sonstwohin speichern können soll. Das Makro "Import" ist fertig, bei "Export" klappt fast nichts.

Was ich habe, ist die Zeile
DoCmd.OutputTo acOutputQuery, "Kundenliste", acFormatXLSX
mit folgenden Problemen:
Schwerwiegend: Auf diese Art und Weise kommen bei Excel nur 65535 Zeilen an, die Abfrage umfasst aber ca. 300.000 Datensätze
Nice to have: Ich möchte eigentlich in Access nicht diese Abfrage namens Kundenliste haben - stört den Blick auf die Tabellen und birgt die Gefahr, dass ein Anwender die mal löscht. Ich möchte gern den SQL-Code mit in das Makro integrieren. Ich habe im Netz verschiedene Wege gesehen, mit Erstellung von Objekten, dass man also vor der obenstehenden Zeile eine Abfrage anlegt und danach dann gleich verwendet. Führte aber alles zu Fehlermeldungen.
Kleinigkeit: Am liebsten wäre mir nicht XLSX, sondern CSV, aber das gibt es als acFormat scheinbar nicht, oder hab ich was übersehen?
Sahnehaube: Bisher hat der Anwender sich das Ergebnis irgendwo hingestellt, um es danach per Mail zu versenden (das ist der Sinn dieses Exports). Kann man es vielleicht sogar so machen, dass sich eine neue Mail öffnet und diese Datei beiliegt? Aber wenn das nicht geht oder zu aufwändig ist, gern auch weglassen.

Vielen Dank im voraus!

Hans-Jürgen

MzKlMu

Hallo,
1.)
OutputTo ist hier ungeeignet.
Verwende zum Export die TranferText Methode, da kann man auch als CSV exportieren.
https://docs.microsoft.com/de-de/office/vba/api/access.docmd.transfertext
2.)
Zeige den SQL Code
3.) siehe 1.)

4.)
geht problemlos. Muss man aber nicht neu erfinden.
Da gibt es im Netz jede Menge Beispiele. Z.B.
https://microsoft-programmierer.de/Office-365/Access/Access_colon_-Emails-direkt-aus-der-Datenbank-senden?2300

PS:
Die von Dir oben gezeigte Codezeile ist kein Makro, sondern VBA Code. Das darf man in Access nicht verwechseln. Access Makros sind etwas ganz anderes und werden von den meisten Access Anwendern gemieden.
Gruß
Klaus

DF6GL

Hallo,


Schwerwiegend: 
Das liegt wohl eher an Excel denn an Access. Es stellt sich überhaupt die Frage, was der Empfänger der Liste mit dieser Menge an Datensätzen (Zeilen) denn eigentlich anfangen soll.

Nice to have:
"stört den Blick auf die Tabellen und birgt die Gefahr, dass ein Anwender die mal löscht Bei einer "richtigen" Datenbank erhält der Anwender keinerlei Zugriff auf Tabellen oder Abfragen.
"Führte aber alles zu Fehlermeldungen."  Was wurde denn alles probiert (Code)?  Übrigens, Makros ist nicht gleich (VBA-)Code. Das sind zwei unterschiedliche Dinge.

Kleinigkeit: 
Import von Excel--> Docmd.TransferSpeadsheet  acImport 
Export nach Excel--> Docmd.TransferSpreadsheet  acExport
Export nach CSV-->  Docmd.TransferText acExport  ( evtl. mit  Export-Spezifikation)
"hab ich was übersehen" --> F1 drücken für Hilfe

Sahnehaube: 
Docmd.Sendobject  als einfachste, aber auch unflexibelste Möglichkeit. Besser ist Outlook-Automation oder CDO-Objekt-Modell


Insgesamt denke ich, dass das Gesamtkonzept (Hin- und -Herkopieren zwischen Excel und Access und auch der DB als solche) einer genaueren Prüfung unterzogen werden sollte.

hjbartel

Hallo zusammen,

ich wollte nichts Überflüssiges reinschreiben, aber auf Wunsch gern mehr Kontext. Das Ganze ist für mich "auf Arbeit". Wir haben eine Großrechner-Anwendung mit einer zugrundeliegenden Datenbank, auf die ich keinen Zugriff habe. Die einzige Chance, an die Daten in maschinenverwertbarer Form zu kommen, ist ein Kotau beim Administrator, der mir dann eine CSV-Datei herunterreicht.

Mein Import-Progrämmchen liest das alles ein, analysiert usw usw. Unter anderem sind auch Kundennummern drin, und da brauche ich von einem anderen Administrator weitere Kundendaten. Ich habe konkret aus dem Import eine Tabelle tbl3_BET mit - unter anderem - dem Feld "Knr". Die rund 300.000 Knr gebe ich per Mail weiter. Dieser zweite Administrator hat ebenso eine Großrechner-Datenbank, nimmt meine 3000.000 Kundennummern und JOINt mir dazu bestimmt weitere Kundendaten (so stelle ich es mir jedenfalls vor). Das lese ich dann wiederum mit einem Import ein.

Die beiden Datenbanken und deren Admis haben nichts miteinander zu tun (Großkonzern), meine Kollegen und ich, wir sind das einzige Bindeglied. Weil ich auch in ein paar Jahren aufhöre zu arbeiten, versuche ich gleich, die Anwendung möglichst anwenderfreundlich zu machen, deshalb möchte ich in der Seitenleiste von Access möglichst nur die Tabellen, nichts anderes.

Weil MzKlMu fragt: Den SQL habe ich auf Arbeit, aber er müsste eigentlich lauten
SELECT Knr FROM tbl3_BET WHERE Len (Knr) = 10 ORDER BY Knr(Echte Kundennummern sind zehnstellig, nur die gebe ich weiter. Pseudonummern sind zwölfstellig und werden damit eliminiert). Und ja, sorry für den Begriff "Makro", ich meine VBA-Code. Aber ich muss meinem Chef immer mal Bericht erstatten, und da spreche ich von "Makro", weil er es immer so nennt. Lustig, wie sich die Sprache auch ins Denken überträgt.

Zu meinen Fragen:

1.) [Beschränkung auf 65535] vielen Dank, ich versuche es dann mal als csv mit TransferText. Weil es da jede Menge Parameter gibt: Hat jemand von euch noch einen Tipp, worauf man achten muss?

2.) [Abfrage in den Code integrieren] Was ich bereits versucht habe: Ich erinnere mich an ein Muster aus dem Internet, etwa so:
DIM irgendwas as QueryDef
SET Irgendwas as CreateQuery ("Kundenliste", "SELECT KNr FROM tbl3_BET")
DoCmd.OutputTo acOutputQuery, "Kundenliste", acFormatXLSX
SET Irgendwas = Nothing
Nicht wörtlich zu nehmen, weiß ich nicht mehr so genau, aber ich hatte mehrere Dinge gefungen, die alle einen mir unerklärlichen Fehler gebracht haben. Aber von der Struktur war es so, zunächst eine Abfrage zu definieren, um sie im nächsten Schritt auszuführen und zu exportieren.

3 und 4 sind ja erledigt.

Vielen Dank nochmals!

Hans-Jürgen


hjbartel

Hallo zusammen,

hat jemand von euch noch einen Tipp, wie ich die Abfrage für den Export direkt in den VBA-Code integrieren kann? (meine Frage 2)

Vielen Dank!

Hans-Jürgen

DF6GL

Hallo,

ZitatDie beiden Datenbanken und deren Admis haben nichts miteinander zu tun (Großkonzern),

Und Du bist sicher, damit nicht illegal zu handeln? Stichwort: DSGVO und Unlauterer Wettbewerb.


Ich jedenfalls gebe dazu keine weitere Hilfe, die Du eh schon bekommen hast..


hjbartel

DSGVO: Ja, ich bin sicher.

Ich fand dies Forum eigentlich nett und ansprechend und hatte mir vorgenommen, hier mit meinem beschränkten Wissen, z.B. zu Abfragen zu helfen.

Aber das hat sich mit deiner Antwort radikal geändert. Wenn man nach mehr Input gefragt wird, den liefert, aber dann so abgewatscht wird, macht das keinen Spaß.

Ich werde hier noch ein paar Tage mitlesen (vielleicht mag mir jemand anders helfen), dann melde ich mich wieder ab. Für solche unfreundliche Kommunikation ist mir die Zeit zu schade.

DF6GL

Hallo,

was ist da unfreundlich?

Die betreffende Aussage ist zumindest eine Nachfrage wert und ich habe nur meine Bedenken geäußert. 
Wenn das nicht zutrifft, soll es Recht sein, es ist eh Dein Problem.

Deine Frage (2) habe ich ja auch schon beantwortet:
ZitatExport nach Excel--> Docmd.TransferSpreadsheet  acExport  , Abfrage

Siehe VBA-Hilfe zur Erklärung zu den Parametern.

hjbartel

wahrscheinlich wollte ich letzte Woche zu viel gleichzeitig. Habe mich daher in Einzelschritten genähert.

Zunächst das "Problem", dass die Abfrage für den Export nicht als solches in der Objektliste stehen sollte (schon deswegen nicht, weil das nur sinnvoll, wenn vorher importiert wurde). Hier muss ich wohl einen Tippfehler gemacht haben, denn folgendes funktioniert:

Dim objExportKundenliste As QueryDef
Set objExportKundenliste = CurrentDb.CreateQueryDef("ExportKundenliste", "SELECT * FROM Sonstwo")

So richtig nervig war das "Trial & Error" mit dem Export einer csv-Datei ohne Mengenbegrenzung. Falls es jemanden interessiert, so gehts:
DoCmd.TransferText acExportDelim, "Exportpezifikation", "ExportKundenliste", Filename (Pfad, Dateiname mit csv)wobei ich im Rahmen eines Test-Exports eine Spezifikation mit diesem Namen angelegt habe (unter Beachtung der dort vorgegebenen Parameter), ExportKundenliste ist ein Platzhalter für die definierte Abfrage, die exportiert werden soll.