Hallo Access-Freunde,
bei einem Nutzer meiner Pilzdatenbank habe ich folgendes Problem. Er hat noch Access 2003 und sein Access stürzt ab, weil folgende Zeile natürlich nicht zu seiner alten Version passt:
On Error Resume Next
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "CSV_Export", MykIS_Root & "expimp\mykdaten_RLZ_Export.xlsx", True
Deshalb habe ich "On Error Resume Next" davor gesetzt. Warum kommt dann trotzdem ein Kompilierfehler und sein Programm stürzt ab? Er benötigt diesen Exceltransfer nicht! Nur die Nutzer ab Access 2007 transferieren Daten und manchmal mehr als 65 000, deshalb muss es eine xlsx-Datei sein.
Beste Grüße
Frank
Hallo,
On Error behandelt Fehler, die zur Laufzeit auftreten.
Ein Kompilierungsfehler entseht bereits beim "Abspeichern" des Codes, denn da wird der Basic Code auf Fehler untersucht und es wird kein ausführbarer Code erstellt.
In diesem Fall müsstest Du vor DoCmd erstmal die Access-Version abfragen und im Falle < 2007 die Zeile überspringen. Besser wäre es die Anweisung so umzubauen, das man den Code auch unter 2003 kompilieren kann.
Hallo,
ein Kompilierungsfehler kann (wie gesagt) durch On Error Resume Next nicht verhindert werden.
So lange ein Kompilierungsfehler besteht, kann VBA erst gar nicht ausgeführt werden, mit On Error Resume Next hat das nichts zu tun.
Zu einem Kompilierungsfehler gibt es aber auch eine Fehlermeldung und die Zeile mit dem Fehler wird markiert.
Und das wären wichtige Infos um zu helfen.
Hallo,
vielen Dank für deine Antwort. Allerdings habe ich auch schon vor dieser Zeile eine If Funktion, wo ein Haken in einem Feld abgefragt wird und der Code sollte damit diese Zeile überspringen. Macht er aber nicht. Habe ich da einen Denkfehler?
LG
Frank
Hier die Fehlermeldung, die mir der Nutzer geschickt hat:
(https://www.tomentella.de/Pages/P1050184.JPG)
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "CSV_Export", MykIS_Root & "expimp\mykdaten_RLZ_Export.xlsx", True
Man sollte sich bewusst machen, dass eine alte Version nicht die Konstante auf ein neueres Excel und auch nicht das neuere XLSX-Format kennt und da zwingend scheitern muss. Korrigiere an diesen beiden Stellen.
=>
acSpreadsheetTypeExcel9
xls
Hallo Eberhard,
mit "acSpreadsheetTypeExcel9" funktioniert bei ihm die Ausführung der Exportfunktion. Wie ich aber schon geschrieben habe, benötige ich die xlsx zwingend für die anderen Nutzer und möchte, dass diese Zeile von seinem Access 2003 ignoriert wird!?
LG
FRank
Hallo,
ZitatMacht er aber nicht. Habe ich da einen Denkfehler?
Ja, bei einem Kompilierungsfehler wird kein Code ausgeführt. Es kommt also gar nicht erst zu der If Funktion.
Syntaxfehler und Kompilierungsfehler verhindern die Ausführung von VBA Code.
Der Fehler kommt auch wenn Du manuell (über das Menü) kompilierst. Was man im Entwicklungsstadium einer DB ohnehin machen sollte.
Hallo Frank,
Du machst einen Denkfehler. Ein Kompilierungsfehler kann nur durch die Korrektur der Syntax oder angesprchenden Objektbezeichnungen, etc. behoben werden.Siehe Eberhards Beitrag.
Ansonsten wird gar kein ausführbarer Code erzeugt. Siehe auch Klaus' Beitrag.
Mit Bedingungsabragen (If, While, etc.) beinflusst Du den Ablauf des Programms (Laufzeit). Da ist der Code aber schon erfolgreich kompiliert.
Ein Laufzeitfehler ist also was ganz anderes als ein Kompilierungsfehler!
Vielen Dank ihr Beiden,
da wird mir mein Problem jetzt klarer.
Selbstverständlich kompiliere ich die Datenbank bevor ich sie weitergebe, aber ich habe Access 2010, was natürlich funktioniert und habe kein Access 2003 zur Verfügung.
LG
Frank
ZitatWie ich aber schon geschrieben habe, benötige ich die xlsx zwingend für die anderen Nutzer und möchte, dass diese Zeile von seinem Access 2003 ignoriert wird!?
Dieser Kerl soll gar nicht exportieren dürfen?
Sollte man nicht die Version prüfen und fallweise entscheiden?
Select Case Application.Version
Case "9.0"
Case "12.0", "14.0"
' mache irgendwas
Case Else
' nanu
End CaseIn anspruchsvolleren Bedingungen könnte man auch in der Registry nachschlagen.
Hallo Eberhard,
würde ich mit dieser Select Case Auswahl eine Ereignisprozedur aufrufen können, die nur für 2003 Benutzer ausführbar ist und eine weitere Ereignisprozedur nur für 2007 Benutzer und höher? Oder werden die Codes eines Formulars immer komplett auf Kompilierfehler geprüft?
Frank
Interessante Frage.
Wenn man erkannt hat, dass man erst prüft und dann handelt, könnte man das fortsetzen mit einer bedingten Kompilierung.
Grundlegendes zu bedingter Kompilierung (https://learn.microsoft.com/de-de/office/vba/language/concepts/getting-started/understanding-conditional-compilation)
#If VBA7 Then
#Else
Public Const acSpreadsheetTypeExcel12Xml As Long = 10
#End IfDa Access 2003 sicher noch nicht VBA7 unterstützt, wird damit die Konstante für A2003 bereitgestellt.
ZitatOder werden die Codes eines Formulars immer komplett auf Kompilierfehler geprüft?
Es wird mind. das ganz Codemodul kompiliert. Ich würde außerdem keinen Code ausliefern, der nicht vollständige kompiliert werden kann.
Zitatwürde ich mit dieser Select Case Auswahl eine Ereignisprozedur aufrufen können, die nur für 2003 Benutzer ausführbar ist und eine weitere Ereignisprozedur nur für 2007 Benutzer und höher?
Eine
Ereignis-Prozedur?
Du kannst mittels Compiler-Anweisung auch anderen Prozedur-Code bereitstellen.
private sub DeineProzedur()
..
#If VBA7 Then
Docmd.Transfer....
#else
msgbox "Du Lauser verwendest noch eine uralte Access-Version!" & vbnewline & "Daher gibt es keinen Export für dich."
#end if
...
end subGruß
Josef
Zitat von: Josef P. am Juni 10, 2024, 15:27:49Da Access 2003 sicher noch nicht VBA7 unterstützt, wird damit die Konstante für A2003 bereitgestellt.
Ähem. Wörtlich genommen zwar richtig, aber was soll das arme A2003 denn dann machen, wenn diese Konstante an DoCmd.TransferSpreadsheet übergeben wird?
Compiler-Anweisungen halte ich hier nur für begrenzt sinnvoll. Es muss eigentlich auf >= A2007 geprüft werden. Dafür gibt es keine geeignete Kompilerkonstate. (VBA7 => A2010 und neuer).
Eine Prüfung zur Laufzeit auf
Application.Version, wie von
@ebs17 vorgeschlagen, ist sicherlich in diesem Fall die sinnvollere Lösung.
Generell empfehle ich die Verwendung von eingebauten Konstanten immer sehr. In diesem konkreten Fall würde ich eine Ausnahme machen und davon abweichen.
Dim TargetSpreadSheetType as Long
If Val(Application.Version) >= 12 then
TargetSpreadSheetType = 10 ' acSpreadsheetTypeExcel12Xml erst ab A2007 verfügbar
Else
TargetSpreadSheetType = acSpreadsheetTypeExcel9
End If
DoCmd.TransferSpreadsheet acExport, TargetSpreadSheetType, ...
Vielen Dank euch allen für die nützlichen Hinweise.
Um für Nutzer aller Access Versionen von Access 2003 bis Access 2019 (32 Bit und 64 Bit) und dann noch unterschiedlichen Windows-Versionen immer alles passend zu machen, ist schon manchmal anspruchsvoll.
@PhilS- Deinen Code füge ich mal ein und lasse ihn vom 2003 Nutzer testen.
Beste Grüße
Frank
ZitatGenerell empfehle ich die Verwendung von eingebauten Konstanten immer sehr. In diesem konkreten Fall würde ich eine Ausnahme machen und davon abweichen.
Warum?
Zur Not wird die Konstante auch für die anderen Versionen definiert.
public const acSpreadsheetTypeExcel12Xml = 10wird auch in Access 365 kein Problem verursachen - zumindest so lange der Wert bei 10 bleibt.
Das in Kombination mit deiner If-Anweisung (bzw. eine globale Property, falls mehrmals benötigt) gefällt mir besser als (möglicherweise mehrmals) 10 in den Code zu schreiben. (Auch wenn es den Enum-Wert überlagert.)
Gruß
Josef
Nochmals Danke!
Es funktioniert. Mein Problem ist damit gelöst.
Beste Grüße
Frank