Hallo,
ich muss in eine Access DB eine Menge Excel Files einlesen die ich nicht verändern kann. Es klappt auch alles - abgesehen von der folgenden Meldung vor den Schließen der xlsm: "es befinden sich eine große menge in der Zwischenablage".
Versuche, die Zwischenablage vor dem Schließen zu leeren waren erfolglos:
Set FSO = CreateObject("Scripting.FileSystemObject")
Set Datei = FSO.GetFile(strret(i))
....
Set rs = Nothing
ZwischenablageLöschen
Threading.Thread.Sleep (1000)
oWS.Close saveChanges:=True
oXL.Quit
Set oWS = Nothing
Set oXL = Nothing
...
Modul:
Option Compare Database
Option Explicit
Declare Function CloseClipboard Lib "user32" () As Long
Declare Function EmptyClipboard Lib "user32" () As Long
Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
Declare Function SetClipboardData Lib "user32" (ByVal wFormat As Long, _
ByVal hMem As Long) As Long
Declare Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, _
ByVal lpString2 As Any) As Long
Public Function ZwischenablageLöschen()
If OpenClipboard(0&) <> 0 Then
Call EmptyClipboard
Call CloseClipboard
End If
End Function
Hat jemand eine Idee?
Hallo,
welchen Grund gibt es, die Zwischenablage für den Import zu bemühen ( falls ich das richtig interpretiere).?
Threading.Thread.Sleep (1000) ist kein Objekt/Methode in Access, eher .Net.
Gibt es Code in der xlsm-Datei , die die Zwischenablage benutzt?
Ergänzend:
Zitateine Menge Excel Files einlesen
...
vor den Schließen der xlsm
Man sieht es in der Darstellung nicht genau, aber ich würde auch und gerade bei vielen Files nur genau eine Excelinstanz für alle statt eine Excelinstanz pro File verwenden. Wenn 57 Leute einen Saal betreten, ist es ist effizienter, wenn man die Tür offen lässt statt sie nach jedem Eintretenden zu schließen.
Das eigentliche Einlesen sieht man dann gleichfalls nicht. Gerade dort dürfte die Datenmasse entstehen, die nicht plangemäß entladen wird.
Zitat von: DF6GL am März 29, 2020, 09:45:24
Hallo,
welchen Grund gibt es, die Zwischenablage für den Import zu bemühen ( falls ich das richtig interpretiere).?
Threading.Thread.Sleep (1000) ist kein Objekt/Methode in Access, eher .Net.
Gibt es Code in der xlsm-Datei , die die Zwischenablage benutzt?
Ich brauche die Zwischenablage nicht. Bekomme allerdings beim Einlesen der Excel Files besagte Meldung. Deswegen probierte ich mit oben stehenden Code die Zwischenablage vor dem Schließen einfach zu leeren. Vermutlich hat sich aber Excel die Zwischenablage exclusiv reserviert.
ZitatMan sieht es in der Darstellung nicht genau, aber ich würde auch und gerade bei vielen Files nur genau eine Excelinstanz für alle statt eine Excelinstanz pro File verwenden. Wenn 57 Leute einen Saal betreten, ist es ist effizienter, wenn man die Tür offen lässt statt sie nach jedem Eintretenden zu schließen.
Das eigentliche Einlesen sieht man dann gleichfalls nicht. Gerade dort dürfte die Datenmasse entstehen, die nicht plangemäß entladen wird.
Wie funktioniert das Code Technisch mehrere Dateien in einer Instanz einzulesen?
ZitatWie funktioniert das Code Technisch mehrere Dateien in einer Instanz einzulesen?
Prinzip:
Öffnen Excelinstanz
Schleife über Dateien
Mappe in Instanz öffnen
Auslesen und Daten importieren
Mappe schließen
Ende Schleifenkörper
Excelinstanz schließen (wenn nicht mehr benötigt)Eine solche Maßnahme hat aber kaum etwas mit der Inanspruchnahme der Zwischenablage zu tun, sondern mehr mit Performance und Ressourcenschonung (und angewandter Logik).
Bei Import müsste man ggf. auch darauf achten, dass die XLSM keine Eigendynamik durch Events und eigene Prozesse entwickeln und da eigenständig Ressourcen binden.
Zitat von: ebs17 am März 29, 2020, 12:44:43
Bei Import müsste man ggf. auch darauf achten, dass die XLSM keine Eigendynamik durch Events und eigene Prozesse entwickeln und da eigenständig Ressourcen binden.
Das ist IMO genau die richtige Überlegung. - Ich formuliere sie noch etwas deutlicher aus.
Wenn Excel beim Schließen nach der Zwischenablage fragt, dann hat auch die Excel-Instanz dort Daten reingeschoben. Entweder über Automatisierung des Excel-Objektes aus Access oder, was ich für wahrscheinlicher halte, durch eigene Makros die während der Automatisierung aktiviert wurden. - Die Dateiendung xsl
m ist explizit für Excel-Dateien mit Makros vorgesehen, die verwendet man nicht, wenn keine Makros da sind.
Man könnte über die
AutomationSecurity-Property die Ausführung von Makros in Excel deaktivieren.
Ja, die Excel Files (xlsm) haben eigene Makros, die beim Start ablaufen. Wie gesagt kann ich die zu importierenden Dateien inhaltlich nicht verändern. Würde es funktionieren die Files vor dem Import in xls umzubenennen und anschließend wieder in xlsm rückzubenennen? Kann man beim beim öffnen sagen, dass die Makros nicht laufen sollen (hier habe ich leider nichts brauchbares im Netz gefunden)...
ZitatMan könnte über die AutomationSecurity-Property die Ausführung von Makros in Excel deaktivieren.
Geht das über VB mit anschließender Reaktivierung? Eine dauerhafte Deaktivierung auf dem PC ist nicht möglich?
Öffnen der Arbeitsmappe verhindern, wenn Macros deaktiviert (http://www.office-loesung.de/ftopic288447_0_0_asc.php):
ZitatEs ist so, dass eine Exceldatei, die über ein Script (.VBS) aufgerufen wird immer mit aktivierten Makros geöffnet wird - unabhängig von der Sicherheitseinstellung des Users.
Bei einem Import aus einer Excelmappe würde ich allerdings auch nicht den Zugriff über Automation bevorzugen, sondern, ganz im Blute eines Datenbänklers, primär versuchen, meine Daten als Tabelle zu greifen (=> verknüpfte Tabelle) und dann ordentliche SQL-Methoden zu verwenden - schon mal, weil es schneller und für mich komfortabler und einfacher geht.
Zitat von: hackepeter am März 29, 2020, 15:00:23
Kann man beim beim öffnen sagen, dass die Makros nicht laufen sollen (hier habe ich leider nichts brauchbares im Netz gefunden)...
ZitatMan könnte über die AutomationSecurity-Property die Ausführung von Makros in Excel deaktivieren.
Ja, genau das kann man. Folgende Suche wäre doch naheliegend, oder?
-> https://www.google.com/search?q=excel+AutomationSecurity
Vielen Dank für die Antworten! Geholfen hat folgender Hinweis:
ZitatThreading.Thread.Sleep (1000) ist kein Objekt/Methode in Access, eher .Net.
Die Pause mache ich nun via:
Option Compare Database
Private Declare Sub sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Public Sub SleepFor(ByVal MilliSeconds As Long)
sleep MilliSeconds
End Sub
Aufruf:
SleepFor 500 '0.5 seconds delayMit einer kleinen Pause nach dem Löschen der Zwischenablage und vor dem Speichern/Schließen des Excel Files funktioniert es nun.