MS Excel Makro Pausieren ohne Excel komplett zu pausieren?
Hi, Ich arbeite an einer art "Schiffe Versenken" für MS Excel und arbeite grade daran, dass man auf Zeit Spielen kann. dafür brauche ich logischerweise nen Timer, der die eingestellte Zeit Herunterzählt und das Spiel Beendet. Das war kein Großes Problem für mich, bis auf eine Sache: Das Makro funktioniert zwar, aber ich habe keinen Befehl gefunden der es zulässt, dass man, während der Timer läuft, noch das Spielfeld benutzen kann, da auch Excel pausiert wird und keine Änderung an den Zellen zulässt. Kennt einer von euch einen Befehl, bei dem nur das Makro angehalten wird und nicht das komplette Programm? Mein Makro sieht bis jetzt so aus:
Sub Schaltfläche1_Klicken()
Dim SE As Integer
Dim MN As Integer
Dim I As Integer
I = 0
Do While I = 0
I = 0
SE = Sheets("Eigene Flotte").Range("O26").Value
MN = Sheets("Eigene Flotte").Range("N26").Value
If SE > 0 Then
SE = SE - 1
Sheets("Eigene Flotte").Range("O26").Value = SE
Else
If MN > 0 Then
MN = MN - 1
SE = 59
(hier soll der Befehl zum Pausieren hin)
Sheets("Eigene Flotte").Range("O28").Value = SE
Sheets("Eigene Flotte").Range("N26").Value = MN
Else
Range("A1:L30").Value = ""
I = 1
End If
End If
Loop
End Sub
4 Antworten
Ich hab mir mal deine Prozedur genommen und sie ein bisschen umgebaut. (Achtung, du musst die Zellbezüge wieder richtig einstellen). Die While-Schleife ist jetzt weg, dafür ist die Methode "Application.OnTime" jetzt drin. Die sorgt dafür, dass die Funktion jede Sekunde einmal aufgerufen wird, wodurch der Zähler runtergezählt wird. Es kann sein, dass ab und zu eine Sekunde übersprungen wird, deshalb sollte man vielleicht anstatt mit den Variablen "SE" und "MN" mit einer Date-Variable arbeiten, die beim ersten Start gefüllt wird und die echte Zeitdifferenz seit dem Programmstart anzeigt.
Sub Schaltfläche1_Klicken()
Dim SE As Integer
Dim MN As Integer
SE = Sheets(1).Range("B1").Value
MN = Sheets(1).Range("A1").Value
If SE > 0 Then
SE = SE - 1
Sheets(1).Range("B1").Value = SE
Application.OnTime DateAdd("s", 1, Now), "Schaltfläche1_Klicken"
Else
If MN > 0 Then
MN = MN - 1
SE = 59
Sheets(1).Range("B1").Value = SE
Sheets(1).Range("A1").Value = MN
Application.OnTime DateAdd("s", 1, Now), "Schaltfläche1_Klicken"
Else
Range("A1:L30").Value = ""
End If
End If
End Sub
DANKE!
Mein Makro sieht jetzt so aus(das mit dem kernal32 hab ich schon mal im Internet gesehen und habs ausprobiert. Konnte nichts verändern damit)
Sub Schaltfläche1_Klicken()
Dim SE As Integer
Dim MN As Integer
SE = Sheets("Eigene Flotte").Range("O26").Value
MN = Sheets("Eigene Flotte").Range("N26").Value
If SE > 0 Then
SE = SE - 1
Sheets("Eigene Flotte").Range("O26").Value = SE
Else
If MN > 0 Then
MN = MN - 1
SE = 59
Sheets("Eigene Flotte").Range("O28").Value = SE
Sheets("Eigene Flotte").Range("N26").Value = MN
Else
Sheets("Eigene Flotte").Select
Range("A1:L30").Value = ""
Exit Sub
End If
End If
Application.OnTime Now + TimeValue("00:00:1"), "Schaltfläche1_Klicken"
End Sub
Bitte :)
Bei deiner Version könnte es Probleme geben, weil die Funktion auch nach Ablauf der Zeit immer wieder neu aufgerufen wird. Ansonsten sieht das aber gut aus.
Nein, nachdem das Spielfeld geleert wurde wird doch Exit Sub aufgerufen und beendet das Makro.
Achso, das ist mir gar nicht aufgefallen. Ja, dann passt es.
Das einfachste wäre es, beim Start des Spiels die Uhrzeit festzuhalten und nach jeder (relevanten) Aktion zu prüfen, ob die neue, aktuelle Uhrzeit über dem Limit liegt.
Der Vorteil ist, dass kein paralleler Thread laufen muss (Ich bin mir nicht einmal sicher, ob VBA das überhaupt kann).
Eventuell kommt doch das OnTimer-Ereignis, welches IamIam vorgeschlagen hat, für dich infrage. Wenn Spielzeit rum, wird der Timer ausgelöst.
Der Nachteil meines Vorschlags ist, dass eben nicht automatisch eine Meldung kommt, wenn die Zeit rum ist, sondern erst, wenn man probiert, die nächste Aktion durchzuführen.
Es gibt zwar den Befehl
NeuZeit = Now + Frequenz
Application.OnTime NeuZeit, "xBlinkmakro"
Wobei Frequenz die Wartezeit ist und xBlinkmakro der Ort, in dem der Befehl steht, so dass es sich im Abstand von Frequenz selber immer wieder aufruft, aber das blockiert xl -wenn auch nicht völlig, so doch-unverschämt stark.
Besser ist es wohl, Du schreibst den aktuellen Wert Now immer wieder neben die Aktionszelle, wo Du auch die Auswahl für die Ziele tätigst (vermutlich ja als fortlaufende Liste, zur Vereinfachung Spieler A und B in der gleichen Zeile. Du kannst dann in einer weiteren Spalte immer wieder die Differenz zur Eingabe von Mitspieler (also Deine verbrauchte Bedenkzeit) bilden und die von einer Zwischensummenzelle sofort abziehen - soviel als allgemeine Anweisung, ich mag jetzt Deine speziellen Gegebenheiten nicht nachvollziehen.
Sowas kannst Du sowohl auf Deinem wie auch auf dem Blatt des Mitspielers anlegen oder auf einem gemeinsamen dritten Blattl, so dass keiner die Schiffe des anderen sieht.
Frag ggf zurück!
Sorry, ich kapier nicht ganz, wie du das meinst. Ich habe ein Spielfeld mit den Schiffen von Zelle A1 bis L30. Dort platziert man seine eigenen Schiffe indem man die zugehörige Nummer einträgt. Danach Wechselt der erste Spieler auf ein anderes Arbeitsblatt, in dem er einträgt, ob in der Zelle, auf die er feuert ein Schiff war oder nicht. Wenn ein Schiff getroffen wurde, muss der Gegenüber das entsprechende Schiff gegen ein x austauschen. Der Timer soll dafür sorgen, dass das Komplette Spiel z.B. 10 Minuten dauern soll. Danach soll er die eigene Flotte löschen und auf das Blatt der Feindlichen Flotte wechseln, wo man schauen kann, ob man mehr Schiffe als der Gegner versenkt hat. Die Zeit stellt man über die beiden Zellen ein, die vom makro ausgelesen werden.
Ah, ich dachte, JEDER hat eine begrenzte Zeit -so wie beim Blitzschach- wäre das nicht sinnvoller? Aber eine Gesamtzeit vereinfacht wahrscheinlich das Verfahren!
Ausserdem bin ich davon ausgegangen, dass jeder im eigenen Blatt eine Liste seiner eigenen Schüsse und auch eine Liste der Schüsse seines Gegners hat, zusätzlich zum x im Feld.
Muss ich nochmal nachdenken (aber erst heit nacht oder morgen), ich glaube, ich hatte da schon mal was!
ich hab das jetzt zwar gefuden, muss es aber aus einem anderen Kontext
herauslösen und selbst erst wieder verstehen! (sind für mich keine
Standardbefehle!)
Hab die Vorlage dafür gda gefunden:
erstellt von HajoZiplies@web.de *
'* http://Hajo-Excel.de/
-falls ich das nicht in Kürze hinkriege!
auf was soll das Makro warten? Wenn es nach einer Eingabe erst weitergehen soll, dann kannst Du das Makro nach dem SE=59 beenden und den restlichen Ablauf mit einem worksheet_change o.ä. starten.
Danke für die schnelle antwort. Das makro soll einfach herunterzählen im Sekundentakt und nachdem MN und SE beide 0 erreicht haben einfach das Spielfeld der Eigenen Flotte leeren, weil es zählt, wie viele teile von Schiffen versenkt wurden. Das trägt man auf nem anderen Arbeitsblatt ein.
Andere Variante, die für dich aber wahrscheinlich eher uninteressant sein wird:
Ich hab mir irgendwann mal den Spaß gemacht, und Snake in Excel programmiert. Leider finde ich die xls nicht mehr. Jedenfalls hab ich da soweit ich weiß diese beiden Libs verwendet:
Mit Sleep kannst du angeben, wieviele Millisekunden die Anwendung pausieren soll. Mit GetAsyncKeyState kannst du einzelne Tasten abfragen, ob sie grade gedrückt sind. Bei meinem Snake-Programm hab ich damit halt die Cursor-Tasten und die ESC-Taste abgefragt. Alles andere war zur Laufzeit nicht bedienbar.