Forum: PC-Programmierung Access-VBA - Formular aktualisieren


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Thomas S. (tom_63)


Bewertung
0 lesenswert
nicht lesenswert
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?

von Manfred S. (Firma: Manfred) (xfred343)


Bewertung
0 lesenswert
nicht lesenswert
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

von Schlaumaier (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von Thomas S. (tom_63)


Bewertung
0 lesenswert
nicht lesenswert
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.
    Do While Not EOF(1)
       zaehler = zaehler + 1
       'Debug.Print zaehler
       zeile = ""
           
       ' den aktuellen Dateinamen im Fenster anzeigen
       Forms!frm_Einlesestatus!Zeile_aktuell = zaehler
       DoCmd.RepaintObject
        'Me.RepaintObject
       .....

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.

: Bearbeitet durch User
von Thomas S. (tom_63)


Bewertung
0 lesenswert
nicht lesenswert
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.

: Bearbeitet durch User
von Schlaumaier (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Schlaumaier (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Thomas S. (tom_63)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe es dann hier eingebaut
               'MsgBox "Datensatz nicht erfasst! "
            'End If ' DeviceTb.NoMatch
       Else
           Einlesefehler = Einlesefehler + 1

       End If 'laenge > 17 And Mid(zeile, 18, 1) = "," And ...
       'DoCmd.RepaintObject
       DoEvents
    Loop

und es funktioniert. i am so happy

Danke

von Schlaumaier (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Froit mich ;)

von Manfred S. (Firma: Manfred) (xfred343)


Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.