Hallo Forengemeine,
habe mir unter Access 2000 eine DB gebaut, wo alle Tempwerte meiner
Sensoren DS18B20 gespeichert werden. Diese werden über ein VBA-Modul aus
den generierten csv-File eingelesen. Über ein Formular starte ich nun in
dem Modul den Einlesevorgang. Im Formular wird die Zeilennummer, die
Datenzeile, und der Fortschritt immer wieder angezeigt. Soweit okay.
Das Problem entsteht, wenn der Bildschirmschoner aktiv wird. Ab dann
findet keine Aktualisierung im Einlese-Formular mehr statt. Somit weiß
ich dann nicht mehr, wie weit die Routinen denn schon ist. Der
Einlesevorgang selbst läuft aber weiter. Und wenn dann fertig, wird auch
das Formular wieder aktualisiert. Dann steht auch z.B. 'fertig mit
einlesen'.
Bei einer Datei mit ein paar 100 Zeilen kein Problem. Aber es kommt vor,
dass ich zig Dateien mit mehreren Tausend Zeilen einlese, und dann würde
ich schon gerne wissen, wie lange es noch dauert.
Ein Ausschnitt:
' den aktuellen Dateinamen im Fenster anzeigen
Forms!frm_Einlesestatus!Aktuelle_Datei = Dateiname
DoCmd.RepaintObject
' die bereits eingelesenen Dateien aufzählen
Forms!frm_Einlesestatus!gelesene_Dateien = tmp
DoCmd.RepaintObject
Funktioniert solange, wie der Bilschirmschoner nicht aktiv wird.
Was vergess ich, damit dies auch nach dem re-aktivieren wieder
aktualisiert wird?
Hallo, ein paar Ideen:
1) gib im Formular eine Uhrzeit aus und setz das Timer-Ereignis auf 1
sec, das sollte vielleicht das Anspringen des Bildschirmschoners
aufhalten.
2) verwende doEvents im Programm
3) Bildschirmschoner abschalten??
LG
Das Problem hat mit den Bildschirmschoner nicht wirklich was zu tun.
Es tritt IMMER auf, wenn die Form den Focus verloren hat, also irgend
ein anderes Fenster/Programm aktiv ist.
Du kannst es nur Zwingen sich zu aktualisieren wenn der Job in einer
Schleife läuft.
Unter richtigen VB geht das so.
Lauf = true
do while lauf = true
i = i + 1
Textbox1.text = i
My.Application.DoEvents '<- Wenn er auf diese Zeile trifft wird die
Form neu gezeichnet und aktualisiert
loop
Schlaumaier schrieb:> Es tritt IMMER auf, wenn die Form den Focus verloren hat, also irgend> ein anderes Fenster/Programm aktiv ist.
Da wüsste ich jetzt aber nicht, wo der Fokus verloren geht. Es kann dann
nur sein, dass doch der Bildschirmschoner, wenn er beendet wird, und
dass dann das Access-Hauptfenster aktiv wird. Also noch bevor mein
Formular wieder aktualisiert ist. Das ist ja genau die Frage. Ich
vermute ja dies auch eigentlich. Aber wie stelle ich in meiner
VBA-Routine fest, das mein Ausgabefenster nicht mehr aktiv ist? um
darauf zu reagieren.
Ein Auszug, was in dieser Haupschleife stattfindet.
1
Do While Not EOF(1)
2
zaehler = zaehler + 1
3
'Debug.Print zaehler
4
zeile = ""
5
6
' den aktuellen Dateinamen im Fenster anzeigen
7
Forms!frm_Einlesestatus!Zeile_aktuell = zaehler
8
DoCmd.RepaintObject
9
'Me.RepaintObject
10
.....
dies wird alle ms (geschätz] durchlaufen.
irgend was war mit : 'Me.RepaintObject
weshalb ich dieses dann deaktiviert hatte, und dafür DoCmd. genomen
habe.
Es reicht auch aus, wenn eine andere Anwendung, Mozilla, Excel,
sonstiges den Fokus hat, und ich dann wieder zurück gehe auf die
Anwendung. Dann sehe ich eine schöne Sanduhr, aber mehr nicht. Es
scheint, das hier das Winwows-Fenster-Handle verloren geht. Ist er dann
fertig, rückt die gesamte Access-DB mit allen Fenstern 'on Top'. und
alles ist gut. Nur eben ich weiß nicht wie lange das Einlesen dauert, ob
er irgendwo hängt, oder ob Schrott eingelesen wird.
Thomas S. schrieb:> Da wüsste ich jetzt aber nicht, wo der Fokus verloren geht.
Der Focus (auf dein Programm) geht automatisch verloren, wenn ein
anderes Prg. in deinen Fall der Bildschirmschoner sich in den
Vordergrund stellt.
Unter Windows kann nur EIN Fenster aktiv sein. Und das fast immer das
Fenster was im Vordergrund ist. Ergo dein Bildschirmschoner.
Das hat NIX mit VB(A), Access oder sonst was direkt zu tun. Das ist
Grundlage der Windows-GDI.
Und unter VB(a) gibt es noch ein 2. Effekt. Nach einiger (kurzen) Zeit
steht in der Form (schneller wenn sie nicht aktiv ist) "Keine
Rückmeldung". Das bedeutet nix anderes wie das das Programm keine
Rückmeldung an die GDI gibt, und die Form (das Fenster) nicht
aktualisiert ist.
DOEVENTS sagt den Programm, melde dich bei der System-GDI und
aktualisiere alle Anzeigen.
Nachtrag :
https://support.microsoft.com/de-de/office/doevents-funktion-7af41eca-88e0-470d-adaf-0b3d4c2575b0
Da ist Doevents erklärt
Zitat :
DoEvents ist für einfache Vorgänge besonders hilfreich, beispielsweise
um dem Benutzer das Abbrechen eines Prozesses nach dessen Start zu
ermöglichen (z. B. eine Dateisuche).
Leider hat doevent den Nachteil das das Programm ca. 20% langsamer läuft
ich schreibe deshalb ein 3 Zeiler der das Prg. nur weniger % langsamer
laufen lässt.
X = 0
Lauf = true
do while Lauf = true
x = x +1
if x > 100 then
x= 0
My.Application.DoEvents '<- Wenn er auf diese Zeile trifft wird die
Form neu gezeichnet und aktualisiert
end if
loop
Das bedeutet :
mache 100 x was du machen sollst, und zeichne dann den Bildschirm neu.
Wenn ich die Zahl der Läufe kenne oder relativ genau einschätzen kann,
teile ich die Zahl durch 100 und machen ein Ablaufbalken, der pro % das
Prozent übergeben bekommt mit ein Doevents dahinter.
Das sieht dann sogar edel aus.
Schlaumaier schrieb:> Lauf = true> do while Lauf = true
Lauf = true ist ein bisserl unschön doppelt
do while Lauf 'reicht auch!
do while true 'wenn Variable Lauf nicht benötigt wird
> Das bedeutet :> mache 100 x was du machen sollst, und zeichne dann den Bildschirm neu.> Wenn ich die Zahl der Läufe kenne oder relativ genau einschätzen kann,> teile ich die Zahl durch 100 und machen ein Ablaufbalken, der pro % das> Prozent übergeben bekommt mit ein Doevents dahinter.>> Das sieht dann sogar edel aus.
Selbiges gilt auch für andere Bildschirmausgaben, z.B. Statusbar
Man nimmt einen Counter, der je Schleifendurchlauf erhöht ist und mit
if counter%100=0 then..
doevents 'in VBA Office generell
'In Excel z.B. application.statusbar=counter % " Durchläufe.."
end if