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.
Ich habe es dann hier eingebaut
1 | 'MsgBox "Datensatz nicht erfasst! " |
2 | 'End If ' DeviceTb.NoMatch |
3 | Else |
4 | Einlesefehler = Einlesefehler + 1 |
5 | |
6 | End If 'laenge > 17 And Mid(zeile, 18, 1) = "," And ... |
7 | 'DoCmd.RepaintObject |
8 | DoEvents |
9 | Loop |
und es funktioniert. i am so happy Danke
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.