Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

VBA: verhindern Bildschirm-Abschaltung

Forumthread: VBA: verhindern Bildschirm-Abschaltung

VBA: verhindern Bildschirm-Abschaltung
03.02.2023 12:30:32
Dirk
Ich möchte in Excel verhindern, dass entsprechend der Energieeinstellungen (die ich nicht ändern darf - kein Admin...) nach 10min der Bildschirm ausgeschaltet wird.
Dazu soll das u.g. Windows API eigentlich dienen.
Ich laufe in EXCEL 2016 auf WIN10 Version 22H2.
Ich rufe meine Funktion 'SystemKeepAwake' im Takt von ca 10s, alle unten gezeigten Parameter-Konstellationen sind aber effektfrei.

Private Declare Sub SetThreadExecutionState Lib "kernel32.dll" (ByRef esFlags As EXECUTION_STATE)
' Parameter usage:
' check https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
Private Enum EXECUTION_STATE
    ES_SYSTEM_REQUIRED = &H1
    ES_DISPLAY_REQUIRED = &H2
    ES_USER_PRESENT = &H4
    ES_AWAYMODE_REQUIRED = &H40&
    es_continuous = &H80000000
End Enum
' ist eigentlich ne SUB. So wird verhindert, dass sie direkt in der Liste der ausführbaren Makros erscheint!
Public Function SystemKeepAwake()
'    NO EFFECT
    Call SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
                                 EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
                                 EXECUTION_STATE.es_continuous)
'    NO EFFECT
'    Call SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
'                                 EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
'                                 EXECUTION_STATE.ES_USER_PRESENT Or _                  == geht nicht, siehe obigen Doku-Link!
'                                 EXECUTION_STATE.ES_CONTINUOUS)
'    NO EFFECT
'    Call SetThreadExecutionState(EXECUTION_STATE.es_system_required Or _
'                                 EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
'                                 EXECUTION_STATE.ES_AWAYMODE_REQUIRED Or _
'                                 EXECUTION_STATE.es_continuous)
'    Dim l_state As LongPtr
'    NO EFFECT
'    l_state = EXECUTION_STATE.es_system_required Or _
'              EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
'              EXECUTION_STATE.es_continuous
    
'    NO EFFECT
'    l_state = EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
'              EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
'              EXECUTION_STATE.ES_AWAYMODE_REQUIRED Or _
'              EXECUTION_STATE.ES_CONTINUOUS
'    Call SetThreadExecutionState(l_state)
    
End Function
' ist eigentlich ne SUB. So wird verhindert, dass sie direkt in der Liste der ausführbaren Makros erscheint!
Public Function SystemToStandard()
    Call SetThreadExecutionState(EXECUTION_STATE.es_continuous)
End Function
Anzeige

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
ist eigentlich ne SUB
03.02.2023 12:37:53
Rudi
Hallo,
Public Sub SystemKeepAwake(Optional dummy)
verhindert auch, dass die Sub in der Makroliste auftaucht.
Alternativ: Schreibe Option Private Module in den Kopf des Moduls.
Gruß
Rudi
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 12:48:21
volti
Hallo Dirk,
ich hatte mal eine Bildschirmschoneraufrufverhinderung dadurch bewirkt, dass ich einfach die Maus bewegt habe.
Stichwort: SetCursorPos
Müsste eigentlich auch hier funktionieren und wäre ggf. auch überlegenswert.
Gruß
Karl-Heinz
Anzeige
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 14:03:25
dirk
Danke Karl-Heinz.
Damit hatte ich begonnen. Dachte, ich lass die Maus einfach spiralieren und gut is.
Leider Fehlanzeige.
Ich hab die Datei mal hochgeladen; s.u. . Bei Interesse: Makro 'MouseInSpirals' und Maus nach Makrostart nicht mehr bewegen.
Bei Tastatur oder Maus-Aktion bricht das Makro sofort - gewollt - ab.
Nur geht leider nach 10 min der Monitor aus.
https://www.herber.de/bbs/user/157628.xlsm
Anzeige
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 12:48:42
max.kaffl@gmx.de
Hallo Dirk,
so funktioniert das nicht. Du kannst das nur am Anfang eines Makros setzen, damit der Bildschirm zur Laufzeit nicht abgeschaltet wird. Am Ende des Makros schlägt die Systemeinstellung wieder zu.
Gruß
Nepumuk
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 13:03:57
dirk
also darf ich die API nicht kapseln sondern nur direkt verwenden?
So?

sub main()
       Call SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
                                 EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
                                 EXECUTION_STATE.es_continuous)
       call diverse unterroutinen....
       Call SetThreadExecutionState(EXECUTION_STATE.es_continuous)
end sub

Anzeige
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 13:07:39
Nepumuk
Hallo Dirk,
ja genau.
Gruß
Nepumuk
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 13:27:57
dirk
@Nepumuk:
Das "Entkapseln" hat leider auch nichts gebracht.

Option Explicit
Private Declare Sub SetThreadExecutionState Lib "kernel32.dll" (ByRef esFlags As EXECUTION_STATE)
' Parameter usage:
' check https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
Private Enum EXECUTION_STATE
    ES_SYSTEM_REQUIRED = &H1
    ES_DISPLAY_REQUIRED = &H2
    ES_USER_PRESENT = &H4
    ES_AWAYMODE_REQUIRED = &H40
    ES_CONTINUOUS = &H80000000
End Enum
Public Sub MouseInSpirals()
 Dim screensize As Ty_S_ScreenSize
 Dim x As Long, y As Long
 Dim i As Long
 Dim radius As Single
 Dim l_Aborted As Boolean
 
'------------------------------------------------------------------
' KEIN EFFEKT
 Call SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
                              EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
                              EXECUTION_STATE.ES_CONTINUOUS)
'------------------------------------------------------------------
                              
                              
                              
 ' kleine Wartezeit. Sonst führt der leiseste Mausruckler zum Prozedurende
 WaitMilliSeconds 200
 
 'Startpunkt: Bildschirm-Mitte!
 screensize = get_screensize()
 x = screensize.width / 2
 y = screensize.height / 2
 
 Call SetMouseCursor(x, y)
 
 Dim l_idle As Long, l_idle_max As Long
 l_idle_max = 0
 l_idle = GetSystemIsIdleSince()
 
 l_Aborted = False
 Do While (l_idle >= l_idle_max)
    
    radius = 155 ' immer wieder setzen, um Rundungsproblemen aus dem Weg zu gehen
    i = 0
    While (i  10) And (Not l_Aborted)
        i = i + 1
        l_Aborted = move_mouse_in_spiral(x, y, radius, 0.03, 2, True)
    Wend
    i = 0
    While (i  10) And (Not l_Aborted)
        i = i + 1
        l_Aborted = move_mouse_in_spiral(x, y, radius, -0.03, 2, False)
    Wend
    
    l_idle_max = l_idle
    l_idle = GetSystemIsIdleSince()
    
'    Call SystemKeepAwake
 Loop
 
 Call SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
'    Call SystemToStandard
'------------------------------------------------------------------
' KEIN EFFEKT
' Call SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
'------------------------------------------------------------------
End Sub

Anzeige
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 13:31:21
Nepumuk
Hallo Dirk,
kann ich nicht nachvollziehen. Ich lass die Frage offen.
Gruß
Nepumuk
AW: VBA: verhindern Bildschirm-Abschaltung
03.02.2023 13:33:42
dirk
Danke Dir trotzdem. :-)
FeedBack
03.02.2023 16:44:35
dirk
Hallo Nepumuk,
mittlerweile habe ich mir das Excel nach Hause geschickt und in Excel 2013 (64bit) auf WIN10 Home laufen lassen.
Dabei wurden mir sofort alle die DECLAREs als fehlerhaft gemeldet. Ich musste die jeweiligen SafePtr-Versionen der APIs verwenden.
Danach funktionierte es zu Hause und zwar auch gekapselt, d.h. innerhalt meiner Funktion 'SystemKeepAwake'.
Ich habe dann die gleiche Datei wieder in den Betrieb geschickt, wo ja Excel 2016 läuft. Dort funktioniert es wieder nicht.
Für alle, die mit "Excel 2013, 64bit" die Bildschirmabschaltung verhindern wollen:
Mit diesem Code geht es. Den Code habe ich in ein öffentliches Modul gepackt und die private API in der öffentlichen Funktion "SystemKeepAwake" gewrapped.
Diese könnt Ihr dann an geschickter Stelle in Euren eigenen Code einbauen und am Ende das Standardverhalten mit "SystemToStandard" wieder herstellen.
Falls noch jemand Tipps wegen 2016 hat: immer her damit. Ich höre an dieser Stelle leider auf. Das geht ab jetzt weit über meinen Horizont.
Dank nochmal an Dich Nepumuk. Auch die initiale Idee hatte ich aus einem Deiner Posts hier.
LG
Dirk

#If VBA7 Then
    Private Declare PtrSafe Function SetThreadExecutionState Lib "Kernel32.dll" (ByVal esFlags As Long) As Long
#Else
    Private Declare Function SetThreadExecutionState Lib "Kernel32.dll" (ByVal esFlags As Long) As Long
#End If
'' Parameter usage:
'' check https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
 
Private Enum EXECUTION_STATE
    ES_SYSTEM_REQUIRED = &H1
    ES_DISPLAY_REQUIRED = &H2
    ES_USER_PRESENT = &H4
    ES_AWAYMODE_REQUIRED = &H40
    ES_CONTINUOUS = &H80000000
End Enum
' ist eigentlich ne SUB. So wird verhindert, dass sie direkt in der Liste der ausführbaren Makros erscheint!
Public Function SystemKeepAwake()
    
    Call SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
                                 EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
                                 EXECUTION_STATE.ES_CONTINUOUS)
End Function
' ist eigentlich ne SUB. So wird verhindert, dass sie direkt in der Liste der ausführbaren Makros erscheint!
Public Function SystemToStandard()
    Call SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
End Function

Anzeige
;
Anzeige
Anzeige

Infobox / Tutorial

Bildschirmabschaltung in Excel mit VBA verhindern


Schritt-für-Schritt-Anleitung

Um zu verhindern, dass der Bildschirm in Excel aufgrund der Energieeinstellungen nach einer bestimmten Zeit abgeschaltet wird, kannst Du die Windows API SetThreadExecutionState verwenden. Hier ist eine Schritt-für-Schritt-Anleitung:

  1. Öffne den VBA-Editor:

    • Drücke ALT + F11, um den VBA-Editor in Excel zu öffnen.
  2. Füge ein neues Modul hinzu:

    • Rechtsklicke auf „VBAProject (DeinWorkbookName)“ > Einfügen > Modul.
  3. Füge den folgenden Code ein:

    #If VBA7 Then
       Private Declare PtrSafe Function SetThreadExecutionState Lib "Kernel32.dll" (ByVal esFlags As Long) As Long
    #Else
       Private Declare Function SetThreadExecutionState Lib "Kernel32.dll" (ByVal esFlags As Long) As Long
    #End If
    
    Private Enum EXECUTION_STATE
       ES_SYSTEM_REQUIRED = &H1
       ES_DISPLAY_REQUIRED = &H2
       ES_CONTINUOUS = &H80000000
    End Enum
    
    Public Sub SystemKeepAwake()
       Call SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
                                     EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
                                     EXECUTION_STATE.ES_CONTINUOUS)
    End Sub
    
    Public Sub SystemToStandard()
       Call SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
    End Sub
  4. Verwende die Funktionen in Deinem Hauptmakro: Stelle sicher, dass Du SystemKeepAwake am Anfang Deines Makros aufrufst und SystemToStandard am Ende.

    Sub main()
       Call SystemKeepAwake
       ' Füge hier deine anderen Unterroutinen hinzu
       Call SystemToStandard
    End Sub
  5. Teste Dein Makro:

    • Führe das Hauptmakro aus, um sicherzustellen, dass die Bildschirmabschaltung erfolgreich verhindert wird.

Häufige Fehler und Lösungen

  1. Der Bildschirm schaltet sich trotzdem ab:

    • Stelle sicher, dass Du SystemKeepAwake direkt am Anfang Deines Hauptmakros aufrufst und dass keine anderen Makros zwischenzeitlich den Zustand zurücksetzen.
  2. Fehlermeldungen bei Deklarationen:

    • Wenn Du Excel 2013 oder eine 64-Bit-Version verwendest, achte darauf, die richtigen PtrSafe Deklarationen zu verwenden, wie im obigen Beispiel gezeigt.
  3. Makro erscheint nicht in der Liste:

    • Um zu vermeiden, dass die Funktion in der Makroliste auftaucht, kannst Du die Funktion als Sub deklarieren oder Option Private Module verwenden.

Alternative Methoden

  • Mausbewegung simulieren: Ein anderer Ansatz, den Bildschirm wach zu halten, besteht darin, die Mausbewegung zu simulieren. Hierzu kannst Du die API SetCursorPos verwenden. Dies kann jedoch unzuverlässig sein, wenn die Mausbewegung von einer anderen Anwendung oder vom Benutzer unterbrochen wird.

  • Verwendung eines Bildschirmschoners: Stelle sicher, dass der Bildschirmschoner deaktiviert ist, wenn Du an einem Projekt arbeitest, das lange Zeit in Anspruch nimmt.


Praktische Beispiele

Hier ist ein einfaches Beispiel, das die Maus in Spiralen bewegt, um den Bildschirm wach zu halten:

Public Sub MouseInSpirals()
    Dim x As Long, y As Long
    x = 100 ' Startposition X
    y = 100 ' Startposition Y

    Call SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or _
                                 EXECUTION_STATE.ES_DISPLAY_REQUIRED Or _
                                 EXECUTION_STATE.ES_CONTINUOUS)

    For i = 1 To 100
        SetCursorPos x + i, y + i ' Maus bewegt sich in einer Spirale
        Application.Wait Now + TimeValue("00:00:01") ' 1 Sekunde warten
    Next i

    Call SystemToStandard
End Sub

Tipps für Profis

  • Kombiniere Funktionen: Du kannst SystemKeepAwake und MouseInSpirals kombinieren, um eine stabilere Lösung zu schaffen, die sowohl den Bildschirm wach hält als auch die Maus simuliert.

  • Regelmäßige Überprüfung: Implementiere eine Schleife, die regelmäßig überprüft, ob die Mausbewegung oder die API-Einstellungen noch aktiv sind.

  • Debugging: Nutze Debugging-Tools in VBA, um sicherzustellen, dass die Funktionen wie gewünscht arbeiten. Überprüfe den Status der API nach jedem Aufruf.


FAQ: Häufige Fragen

1. Warum funktioniert SetThreadExecutionState nicht immer?
Es kann sein, dass andere Prozesse oder Energieeinstellungen des Systems die API-Aufrufe überschreiben. Achte darauf, dass Du die API zu Beginn Deines Makros aufrufst.

2. Gibt es eine Möglichkeit, die Mausbewegung zu stoppen?
Ja, Du kannst eine Bedingung einfügen, die die Schleife unterbricht, wenn eine bestimmte Taste gedrückt wird oder eine andere Bedingung erfüllt ist.

3. Welche Excel-Versionen unterstützen diese Methode?
Die Methode funktioniert in Excel 2013, Excel 2016 und höher, solange die richtigen PtrSafe Deklarationen verwendet werden.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige