PDA

Vollständige Version anzeigen : Export von Formulardaten nach Excel


cheaptrick
20.04.2011, 13:30
Hallo,

mit
DoCmd.OutputTo acOutputForm, Me.Name, acFormatXLS, "Überblick Ergebnisse_" & Kunde & ".XLS", True
Exportiere ich den Inhalt eines Formulars nach Excel.
Nun habe ich drei Probleme:

Das Formular hat eine zusätzliche unsichtbare Spalte, deren Inhalt sollte ebenfalls mit in der Excel-Liste angezeigt werden
Die Spaltenköpfe der Excel-liste haben kryptische Namen, die ich teilweise nicht umbenennen kann, da für Teile der angezeigten Werte die Quellfelder der Abfrage erste berechnet werden müssen. Wie kann ich diese Feldnamen gemäß der entsprechenden Einträge im Formularkopf anpassen?
Wie kann ich den Namen des Tabellenblattes ändern? Bisher wird der Formularname übernommen, was nicht optimal ist.


Da das Formular nur einen Teil der zugrunde liegenden Spalten verwendet, welche wird per VBA berechnet, kann ich leider nicht den Inhalt der Abfrage ausgeben.

Gruß

cheapy

Edgar Basler
20.04.2011, 13:46
Ich würde versuchen einen anderen Ansatz zu wählen.
Ich würde hierfür eine eigene Abfrage erstellen, in der nur die Felder aufgenommen sind, die auch an Excel übergeben werden sollen. Vorteil wäre auch, daß mit wenigen Klicks die Felder angepaßt werden können.

cheaptrick
20.04.2011, 13:53
Ich befürchte das wird nicht klappen, da bei der Anzeige des Formulars ein Teil der Felder und ihre Position im Formular dynamisch berechnet werden müssen.
Die Abfrage liefert Kennzahlen des aktuellen und des vorherigen Geschäftsjahres angezeigt werden im Formular aber nur die Daten der letzten 6 Monate.

Edgar Basler
20.04.2011, 14:04
Das Argument ("...ein Teil der Felder und ihre Position im Formular dynamisch berechnet werden müssen...") versteh ich gesagt nicht. Soweit mein Wissen geht, kann ich alle Berechnungen, die ich im Formular mache, auch in einer Abfrage machen.

Oder aber wie reden beim Begriff "dynamisch berechnen" aneinander vorbei. Kann ja auch sein.

ebs17
20.04.2011, 14:19
da bei der Anzeige des Formulars ein Teil der Felder und ihre Position im Formular dynamisch berechnet werden müssen
Wie kann man sich das vorstellen: Schwarze Zahlen links oben, rote Zahlen rechts unten (möglichst außerhalb des unmittelbaren Sichtbereiches)?

cheaptrick
20.04.2011, 14:22
Vielleicht ist der Begriff irreführend.
Im Formular werden ja keine Werte berechnet sonder es wir berechnet welche Spalte aus der Abfrage in welchen Feld im Detailbereich des Formulars angezeigt wird.
Ich glaube nicht, dass ich sowas auch in einer Abfrage machen kann, dann müsste ich ja den SQL-Code der Abfrage manipulieren können.

cheaptrick
20.04.2011, 14:41
Wie kann man sich das vorstellen: Schwarze Zahlen links oben, rote Zahlen rechts unten (möglichst außerhalb des unmittelbaren Sichtbereiches)?

So ähnlich :)
Ich habe 6 Spalten (Felder) für die anzuzeigenden Ergebnisse, beim öffnen des Formulars werden der jeweiligen Datasource dieser Spalten die jeweils aktuellen Felder (Spalten) aus der Abfrage zugeordnet.
Ausgehend vom heutigen Datum würde den jeweiligen Spalten folgendes angezeigt:

Daten aus März 2011
Daten aus Februar 2011
Daten aus Januar 2011
Daten aus Dezember 2010
Daten aus November 2010
Daten aus Oktober 2010


Ich hoffe es ist jetzt verständlicher

ebs17
20.04.2011, 17:35
So ähnlich, wie man die anzuzeigenden Spalten in einem Formular begrenzen kann, könnte man das auch für das zugrunde liegende Recordset selbst auch.

cheaptrick
26.04.2011, 07:34
Nachdem die Daten nach Excel übertragen wurden, ist die Datei ja noch geöffnet, kann ich dann die Überschriftenzeile bearbeiten?

ebs17
26.04.2011, 08:43
Eine offene ungeschützte Datei ist selbstverständlich bearbeitbar.
Ich bezweifle allerdings, dass eine per OutputTo erzeugte Mappe offen ist.

cheaptrick
26.04.2011, 08:50
Private Sub Befehl82_Click()
On Error GoTo Err_Befehl82_Click
Dim Kunde As String

Kunde = Me.GroupLevel2.Value
DoCmd.OutputTo acOutputForm, Me.Name, acFormatXLS, "Kundenergebnisse_" & Kunde & ".XLS", True
Exit_Befehl82_Click:
Exit Sub

Err_Befehl82_Click:
MsgBox Err.Description
Resume Exit_Befehl82_Click

End Sub

Die so erzeugte Excel-Liste ist jedenfalls offen.

ebs17
26.04.2011, 09:22
Ach, da gibt es einen Parameter dafür (ich verwende OutputTo praktisch nicht).

Um die Mappe bearbeiten zu können, benötigst Du einen Zugriff auf diese, etwa ...
Dim oWb As Object
Dim oSh As Object

Set oWb = GetObject("VollständigerPfadDerExcelmappe")
Set oSh = oWb.Worksheets("NameArbeitsblatt")
oSh.Cells(1, 2) = "WasAnderes"
' ... weitere Anweisungen

cheaptrick
27.04.2011, 08:23
Hallo Eberhard,

das Problem an der Stelle ist, das durch das OutputTo die Excel-Datei ja bereits geöffnet ist.
Wenn ich versuche die Datei mit GetObject zu öffnen, dann ist sie anschließend wieder leer. Leider habe ich noch nichts gefunden, wie ich eine bereits geöffnete und noch nicht gespeicherte Excel-Datei bearbeiten kann bzw. wie ich an dieses Objekt heran kommen kann.

cheaptrick
27.04.2011, 09:11
So, mit diesem Code funktioniert es erstmal:
Private Sub Befehl82_Click()
On Error GoTo Err_Befehl82_Click
Dim Kunde As String
Dim xls As Excel.Application
Dim i As Integer

Kunde = Me.Kundenname
DoCmd.OutputTo acOutputForm, Me.Name, acFormatXLS, "Kundenergebnisse_" & Kunde & ".XLS", True

Set xls = GetObject(, "Excel.Application")

If xls.ActiveWorkbook.Name = "Kundenergebnisse_" & Kunde & ".XLS" Then
For i = 4 To 9
'Monatsname/Jahr als Spaltenkopf eintragen
xls.Cells(1, i) = Me("Spaltenbezeichner" & CStr(i)).Caption
Next i
xls.ActiveWorkbook.Close
End If

Exit_Befehl82_Click:
Exit Sub

Err_Befehl82_Click:
MsgBox Err.Description
Resume Exit_Befehl82_Click

End Sub


Hab's ausprobiert mit mehreren geöffneten EXCEL-Dateien und bei den Versuchen habe ich immer die richtige erwischt. Sollte die Zieldatei zuvor schon geöffnet worden sein, dann schlägt ja die OnError-Bedingung zu.

ebs17
27.04.2011, 09:25
Wenn ich versuche die Datei mit GetObject zu öffnen, dann ist sie anschließend wieder leer.
Das kann ich nicht glauben. GetObject holt sich die Referenz auf ein (vorhandenes) Objekt, also den Verweis auf dessen Speicheradresse, und macht weiter gar nichts, also auch kein Löschen/Zerstören von irgendetwas.

Nicht nur nebenbei: Es wirkt meist etwas unglücklich, erst eine Datei zu erzeugen und hinterher zu probieren, einen Zugriff auf diese Datei zu gewinnen. Überzeugender wäre der Weg, über Automation gleich die neue Datei inklusive der Exportinhalte zu erzeugen. Dann hat man von Haus aus die Referenz auf diese Datei und kann mit beliebigen Maßnahmen fortfahren (Agieren statt Reagieren!).

Nachtrag:
Set xls = GetObject(, "Excel.Application")
If xls.ActiveWorkbook.Name = "Kundenergebnisse_" & Kunde & ".XLS" Then ...
Du machst hier etwas völlig anderes als ich vorschlug: Statt die Referenz auf eine bestimmte Mappe zu holen, holst Du eine Referenz auf eine Excelinstanz. Falls es mehrere offene Instanzen von Excel gibt, hast Du ein Problem, die richtige mit der gewünschten Mappe zu finden. Und ActiveWorkbook ist auch dem Zufall ein Stück näher als wenn man eine Mappe gleich mit dem Namen anspricht. Deine Prüfung unterstreicht dies.

Zusatzfrage: Wenn die offene Mappe ein Problem ist, warum erzeugst Du sie nicht geschlossen (Parameter True -> False).

Josef P.
27.04.2011, 09:46
@Eberhard: du kannst mit GetObject aber auch eine Excel-Instanz öffnen, wenn du einen Dateinamen angibst.
Dim wb As Excel.Workbook
Set wb = GetObject(FileName)

Unter Ac2010 wird aber anscheinend die Excel-Datei beschädigt, wenn man folgendes ausführt:
1. Excel-Datei per DoCmd.OutputTo erzeugen
2. Excel-Datei per Excel-Automation über GetObject öffnen und speichern

DoCmd.OutputTo acOutputTable, "Tabelle", acFormatXLSX, FileName, False
Set wb = GetObject(FileName) ' = Excel.Workbook
wb.Save
wb.Close
=> Wenn man später die Excel-Datei öffnet, wird nichts mehr angezeigt.

DoCmd.OutputTo acOutputTable, "Tabelle", acFormatXLSX, FileName, False
Set ea = New Excel.Application
Set wb = ea.Workbooks.Open(FileName)
wb.Save
wb.Close
=> Kein Problem.

mfg
Josef

cheaptrick
27.04.2011, 09:55
Nun, ob Du es jetzt nun glaubst oder nicht, nach dem Erzeugen sind in der offenen Excel-Liste die exportierten Daten, verwende ich direkt danach GetObject, dann ist die Tabelle leer.
Das war dann auch der Grund, weshalb ich das anders gelöst habe.
Ich habe die Geschichte mit zusätzlich geöffneten EXCEL-Dateien getestet und hatte immer die richtige Excel-Liste. Da ich aber schon Pferde vor der Apotheke habe ..., sprich ich Microsoft nicht traue, habe ich diese zusätzliche Abfrage eingebaut. Sicherheit ist hat die Mutter der Porzellankiste.

Josef P.
27.04.2011, 09:57
Sicherheit ist hat die Mutter der Porzellankiste.
Die Sicherheit beginnt aber beim Programmieren. ;)
Set xls = GetObject(, "Excel.Application")
'mit
xls.ActiveWorkbook
ist Programmieren mit Glück. :)

mfg
Josef

cheaptrick
27.04.2011, 09:57
Hallo Eberhard,

ob Du es jetzt nun glaubst oder nicht, nach dem Erzeugen sind in der offenen Excel-Liste die exportierten Daten, verwende ich direkt danach GetObject, dann ist die Tabelle plötzlich leer.
Das war dann auch der Grund, weshalb ich das anders gelöst habe.
Ich habe die Geschichte mit zusätzlich geöffneten EXCEL-Dateien getestet und hatte immer die richtige Excel-Liste. Da ich aber schon Pferde vor der Apotheke habe ..., sprich ich Microsoft nicht traue, habe ich diese zusätzliche Abfrage eingebaut. Sicherheit ist hat die Mutter der Porzellankiste.

ebs17
27.04.2011, 10:06
du kannst mit GetObject aber auch eine Excel-Instanz öffnen, wenn du einen Dateinamen angibst
Zu einer offenen Mappe (das war mein Ansatzpunkt für GetObject) muss es ja auch eine zugehörige Instanz geben, also gewinnt man auch auf diese den Zugriff, etwa ...
Dim xls As Excel.Application
Dim wb As Excel.Workbook
Set wb = GetObject(FileName)
Set xls = wb.Application
Eine geschlossene Mappe könnte man (in einer beliebigen Excelinstanz) per Workbooks.Open öffnen (hoffentlich).

Der Hinweis auf das Problem ist interessant, neue Versionen bieten auch hin und wieder "Überraschungen". Allerdings möchte ich noch einmal auf meinen Vorbeitrag hinweisen: Manche Probleme muss man nicht haben, wenn man Gestaltungen verwendet, die diese nicht auftreten lassen.

cheaptrick
27.04.2011, 10:13
Ich hatte beim GetObject den Dateinamen ja angegeben.