Excel Makro blauer Kreis durch Msg Box ersetzen

cesar

Stammgast
Guten Morgen zusammen



Ich hab ein Excel Makro erstellt, dessen Abarbeitung etwas dauert. In dieser Zeit wird ja der blaue drehende Kreis angezeigt. (auf jeden Fall bei mir)

Ich möchte nun den blauen Kreis durch eine Msg Box ersetzen, die zB. den Text enthält: "Marko läuft, bitte warten".

Ist sowas überhaupt möglich?

Oder wie kann ich zB. den Kreis durch ein anderes Zeichen ersetzen?

Danke für Antworten
gruss
cesar
 

nochEinAndreas

Stammgast
Ein paar Ideen

Hallo cesar,

es gibt einige Möglichkeiten, wie man so etwas lösen könnte:
- Ich vermute, dass dein Makro so lange läuft, weil er Schleifen enthält. Wenn dem so ist, kannst du in die Schleifen das Kommando
Code:
 DoEvents
einbauen. Damit kriegst du schon mal den Wartekringel weg.

- Du könntest am Anfang des Makros eine Meldung in die Statuszeile am unteren Fensterrand schreiben:
Code:
Application.StatusBar = "Mako läuft"
und am Ende wieder löschen mit
Code:
Application.StatusBar = ""

- Eine MessageBox geht nicht, weil der Makro stehen bleibt, sobald die Box angezeigt wird.

- Statt dessen könntest du eine Userform anzeigen (mit einer Meldung in einer Textbox) im Modeless-Modus, damit der Makro währen der Anzeige weiterläuft.

- Wenns ganz nobel sein soll, könntest du auch einen Fortschrittsbalken auf die Userform setzen.

Wenn du genauere Hilfe/Beispiele brauchst, melde dich noch mal.

Grüße, Andreas
 

weer

Stammgast
Wenns ganz nobel sein soll, könntest du auch einen Fortschrittsbalken auf die Userform setzen.

Grüezi Andreas

Fortschrittsbalken in der StatusBar verwende ich wegen der "Noblesse" oft bei Schleifen. Wie ist das aber bei einem Makro, das lange läuft, aber keine Schleifen enthält: Gibt es da überhaupt eine Möglichkeit, in der StatusBar Fortschrittsbalken anzeigen zu lassen? Also sozusagen ein (Sub-)Makro, das parallel zum eigentlichen Makro läuft und den Fortschrittsbalken z. B. jede 10tel-Sekunde verlängert?

Geht das nur mit dem Modeless-Modus, den Du in Deinem Beitrag andeutest? Mit Modeless-Modus kenne ich mich überhaupt nicht aus und mit "Fortschrittsbalken auf die Userform setzen" auch nicht. Da steh ich wie der Ochs am Berg.

Viele Grüsse Niclaus
 

nochEinAndreas

Stammgast
... und da habe ich keine Ahnung

Hallo Niclaus,

du verwendest den Fortschrittsbalken in der StatusBar? Das finde ich richtig interessant. Wie geht das? Das habe ich noch nie gemacht. keine Ahnung.

Zum Thema "Fortschrittsbalken ohne Schleifen": Ich hatte mal eine Anfrage, wo der Fortschrittsbalken möglichst "zeitecht" sein sollte (ohen Schleifen). Ich habe dann erst mal versucht, rauszufinden, wie lange der Makro für einzelne Teile braucht. Dafür habe ich die Windows API Funktion GetTickCount benutzt. Sie gibt die Zeit seit dem Rechnerstart in Millisekunden aus. Damit kann man also berechnen, wieviel Zeit ein bestimmter Teil eine Makros braucht. Hier mal Pseudocode für einen Makro ohne Schleifen:

Code:
Public Declare PtrSafe Function GetTickCount Lib "kernel32.dll" () As Long

Sub ZeitTesten
   Dim jetzt As Long
   Dim zeit1 as Long
   Dim zeit2 as Long
   Dim zeit 3 as Long

   jetzt = GetTickCount
   ' Hier läuft Teil 1 des Makros
   zeit1=GetTickCount - jetzt
   ' Hier läuft Teil 2 des Makros
   zeit2 = GetTickCount - zeit1
   ' Hier läuft Teil 3 des Makros
   zeit3 = GetTickCount - zeit2
End Sub

Wir haben also jetzt 3 Zeiten (in ms) für die 3 Teile des Makros.

Auf eine Userform (nennen wir sie "UserForm1") setzen wir einen Forschrittsbalken. Dieser ist in der Liste der Steuerelemente anfangs nicht vorhanden. Mach einen Rechtsklick auf die Steuerelemente-Toolbox und klicke "Zusätzliche Steuerelemente".
Dann kreuze in der Liste "Microsoft ProgressBar Contol, version 6.0" an und klicke OK.
Jetzt kannst du den Fortschrittsbalken auf deine UserForm ziehen.
Nun addiere die 3 Zeiten zeit1, zeit2 und zeit3 aus deinem Code und setzte die Summe als Max-Wert des Fortschrittsbalkens auf deiner UserForm ein.
Jetzt kannst du deinen Code noch erweitern:
Code:
Public Declare PtrSafe Function GetTickCount Lib "kernel32.dll" () As Long

Sub ZeitTesten
   Dim jetzt As Long
   Dim zeit1 as Long
   Dim zeit2 as Long
   Dim zeit 3 as Long

   jetzt = GetTickCount
   UserForm1.ProgressBar.Value = 0
   ' Hier läuft Teil 1 des Makros
   zeit1=GetTickCount - jetzt
   UserForm1.Progressbar.Value = zeit1
   ' Hier läuft Teil 2 des Makros
   zeit2 = GetTickCount - zeit1
   UserForm1.Progressbar.Value = zeit1 + zeit2
   ' Hier läuft Teil 3 des Makros
   zeit3 = GetTickCount - zeit2
   UserForm1.Progressbar.Value = zeit1 + zeit2 + zeit3
End Sub

In deinem eingetlichen Code musst du also zu Anfang die Userform1 anzeigen lassen:
UserForm1.Show vbModeless
vbModeless ist eine VBA-Konstante (0), die angibt, dass die UserForm quasi als eigene Instanz läuft. D.h., die UserForm wird angezeigt, aber der Makro läuft trotzdem weiter. Lässt man das "vbModeless" weg, würde die UserForm auch erscheinen. Der Makro läuft aber erste weiter, wenn die UserForm wieder geschlossen wird.
Mit vbModeless läuft also der Makro weiter.
Wenn er dann an die Zeile "UserForm1.Progressbar.Value = zeit1" kommt, wird der Fortschrittsbalken aktualisiert, und zwar genau mit dem Wert, den der Makro bis dahin an Zeit gebraucht hat.
Usw., bis er beim Maximalwert angekommen ist.

Wenn man also im Test mal mit der Windows API GetTickCount die Zeiten ausgemessen hat, die der Makro für bestimmte Teile braucht, kann man den Fortschrittsbalken recht genaue Zeiten anzeigen lassen.

Ich hoffe, das war jetz nicht zu kryptisch und kompliziert. Melde dich, wenns noch weitere Fragen gibt.

Grüße und einen schönen Abend,
Andreas
 

weer

Stammgast
du verwendest den Fortschrittsbalken in der StatusBar? Das finde ich richtig interessant. Wie geht das?

Hallo Andreas, das verrate ich Dir gern!

Mein Beispiel hängt mit mehreren 1000 Datensätzen zusammen, die ich Zeile für Zeile verarbeiten muss. Wie gesagt: Die Anzeige des Fortschrittsbalkens ist eine noble Spielerei (Spinnerei?).

Code:
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub ttt()
zz = 1500
If zz > 120 Then
    k = zz / 120
Else: k = 1
End If
For i = 1 To zz
    If i Mod k = 0 Then
        aa = aa & ">"
        Application.StatusBar = aa & "  " & i
        Sleep 100
    End If
Next i
MsgBox zz & " Datensaetze verarbeitet"
Application.StatusBar = False
End Sub

Anstelle der Zeile "Sleep 100" werden in meinem Original-Makro die Daten zeilenweise verarbeitet! Die Zeile "Declare Sub Sleep" entfällt dabei selbstverständlich.

Ich habe mir zu diesem uralten Makro notiert:

In der Statusbar werden entsprechend dem Verlauf der Schleife ">>>" angezeigt. Wenn die Zahl zz grösser ist als 120, haben die ">>>" keinen Platz auf der Statusbar und es kommt zu Fehlermeldung. Deshalb die Verkleinerung mit k.
Wenn statt ">" der Buchstabe "x" als Zeichen verwendet wird, haben 200 "x" Platz.


Die Zahlen 120 und 200 galten für einen uralten Röhrenbildschirm!

Deine Angaben zum Thema "Fortschrittsbalken ohne Schleifen": Die muss ich mir genau anschauen, wenn ich mal ein paar Tage Zeit habe ;-) Auf jeden Fall ganz herzlichen Dank!

Ich wünsche Dir ein schönes WE und grüsse herzlich
Niclaus
 

nochEinAndreas

Stammgast
Aah, OK, danke

Danke für den Code Niclaus,

verstehe es bitte nicht abwertend, das soll es ganz und gar nicht sein. Aber auch dieser Code erzeugt keinen echten Fortschrittsbalken, sondern er schreibt einen länger werdenden "Text" in die Statuszeile.
Ich hatte nach "Excel Fortschrittsbalken in Statuszeile" gegoogelt. Da kommen dann viele solcher Lösungen mit "Text".
Ich dachte aber eher an einen "echten" Fortschrittsbalken, wie er in vielen Programmen auftaucht, und wie er auch auf eine Userform gelegt werden kann (siehe Anhang).
So etwas auf der Statuszeile. Bisher habe ich im Netz noch neimanden gefunden, der das hinbekommen hat.
Also, bitte nicht als Kritik verstehen.

Grüße, Andreas
 

Anhänge

  • Balken.JPG
    Balken.JPG
    10,7 KB · Aufrufe: 11

weer

Stammgast
… dieser Code erzeugt keinen echten Fortschrittsbalken, sondern er schreibt einen länger werdenden "Text" in die Statuszeile.

Hallo Andreas

Du hast recht! Was ich produziert habe, kann man gemäss Wikipedia als "unbestimmten Fortschrittbalken" bezeichnen, "der statt eines Bargraphen einen Teilbalken ohne Prozentangabe verwendet, der sich fortwährend in eine Richtung bewegt …"

Und da mein Makro aus dem letzten Jahrtausend stammt, kann man ebenfalls Wikipedia zitieren: "Bei Geräten, vor allem in früheren Zeiten, als die Grafikfähigkeiten noch nicht so entwickelt waren, wurden Fortschrittsbalken auch oft in Textdarstellung aus einer wachsenden Reihe von (gleichartigen) Zeichen gebildet, wie beispielsweise XXXXXX...."

Ich habe nun mein Makro etwas abgeändert, damit die Anzeige in der Statuszeile eher dem entspricht, was Wikipedia als "Bestimmte Fortschrittsanzeige" mit %-Anzeige bezeichnet. Aber es kommt immer noch steinzeitlich daher. Oder ist das etwa schon Retrolook?

Code:
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub m1aa()
zz = 1500   ' Anzahl "Datensaetze"
If zz > 200 Then
    k = zz / 200
Else: k = 1
End If
' je nach verwendeten Zeichen fuer "stb" (und Schriftart in der Statuszeile?)
' muss die Zahl 200 reduziert werden - z. B. auf 120
m = zz \ k
stb = String(m, ".")
For i = 1 To zz
    If i Mod k = 0 Then
        j = j + 1
        Mid(stb, j, 1) = Chr(124)  ' senkrechter Strich
        Application.StatusBar = stb & "    " & (i * 100.5) \ zz & " %"
        Sleep 100
    End If
Next i
MsgBox zz & " Datensaetze verarbeitet"
Application.StatusBar = False
End Sub

Wie vor ein paar Tagen gesagt: Die StatusBar-Anzeige funktioniert nur innerhalb von Schleifen. Und: Statt der Zeile "Sleep 100" werden in meinem Makro grosse Datensätze verarbeitet, was auch eine bestimmte Zeit lang dauert.

Ich bin gespannt, was Du dazu meinst!

Eine Frage an Dich habe ich: Ab und zu (nicht immer!), wenn ich im Makro Aenderungen vorgenommen habe oder wenn ich die Datei neu geladen habe, funktioniert die Anzeige in der StatusBar nicht richtig oder gar nicht (keine Fehlermeldung). Erst bei einem zweiten Start des Makros klappt es ohne Probleme. Hast Du eine Ahnung, warum es zu diesem "Fehlverhalten" kommt?

Zu Deinem Beitrag zum Thema "Fortschrittsbalken ohne Schleifen": Ich bin noch nicht dazu gekommen, vor allem auch, weil da Gebiete angesprochen werden, von denen ich keine Ahnung habe. Ich melde mich ganz bestimmt noch deswegen.

Einen schönen Sonntagabend wünsche ich Dir und eine gute neue Woche.
Viele Grüsse Niclaus
 

nochEinAndreas

Stammgast
Danke für deine "Zurück-Fütterung" (feedback)

Hallo Niclaus,

ich glaube, wir sind uns einig: In der Statuszeile scheint es nichts anderes als Text zu geben. Aus welchem Font der stammt, ist mir auch noch nicht klar: Wenn ich in einer Excel-Zelle den Reiter Einfügen-Symbol benutze und dann aus dem Zeichensatz Wingdings mehrmals das Zeichen 110 benutze, erhalte ich so etwas wie im Anhang.
Wenn ich das aber in der StatusBar benutze, kommt "nnnnnnnnnnn" raus, also der ganz normale Zeichensatz, kein Wingdings. Es scheint, Excel kann in der StatusBar nur "normalen" Text (da sind sich auch die Poster in diversen Foren recht einig).
Wie vor ein paar Tagen gesagt: Die StatusBar-Anzeige funktioniert nur innerhalb von Schleifen.
Dem wage ich zu widersprechen: Application.StatusBar = ... kannst du überall im Code verwenden. Es wird dann halt immer der Text angezeigt, der in deiner Anweisung steht.
Natürlich, wenn du den StatusBar als Fortschrittsbalken "missbrauchen" willst, ist es am bequemsten, wenn du das in einer Schleife machen kannst: Application.StatusBar = Application.StatusBar & nächstenZeichen.
Damit bekommst du am einfachsten den Balken verlängert.
Es geht aber natürlich auch in Makros ohne Schleifen. Dabei kommt es dann darauf an, um wieviel (%) du die Anzeige erhöhen möchstest. Es liegt dann an dir, ob du das zeitlich möglichst genau willst (das müsstest du dann vorher mit einer API-Funktion wie GetTickCount testen), oder ob du einfach nur die Anzeige erhöhen möchtest, ganz egal, wie lange ein Teil des Makros dauert. Dann setzt du meinetwegen den gesamten Makro auf 100 Zeichen. Wenn der Makro aus 4 Teilen besteht, erhöhst du die Anzeige nach jedem Teil um 25 Zeichen.

Zu deiner Frage, warum die StatusBar bei dir ab und zu nicht richtig funktioniert, kann ich hier leider nichts sagen. Da müsste man sich ganz genau anschauen, was vorher passiert (oder nicht passiert).

Melde dich, wann immer du magst. Ich habe immer Spaß am Diskutieren und Fragen beantworten.

Grüße, Andreas
 

Anhänge

  • Wingdings 110.JPG
    Wingdings 110.JPG
    9,5 KB · Aufrufe: 12
Oben