Blatt aktualisieren
#1
Ich will ein Arbeitsblatt aktualisieren wenn es den Fokus bekommt. "Workbook_Activate()" wird nur aufgerufen wenn ich von einer anderen Mappe die Mappe aufrufe, die besagte Prozedur beinhaltet. Wenn ich von einem ganz anderen Programm die Mappe anfahre, passiert nichts.
"Worksheet_Activate" liefert auch nicht das gewünschte verhalten.
Antworten Top
#2
Code:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)

End Sub
Zum übersetzen von Excel Formeln:

http://dolf.trieschnigg.nl/excel/index.p...gids=en+de
Antworten Top
#3
Worksheet_Activate  wird nur dann aufgerufen, wenn ich den Tab wechsele.
Antworten Top
#4
Code:
Private Sub Workbook_WindowActivate(ByVal Wn As Window)

End Sub
Zum übersetzen von Excel Formeln:

http://dolf.trieschnigg.nl/excel/index.p...gids=en+de
Antworten Top
#5
Danke, aber das liefert auch nicht das gewünschte Resultat.
Antworten Top
#6
Hi,

kannst du den Zweck darstellen? Das Excel-Objektmodell stellt kein Event zur Verfügung, dass gefeuert wird, wenn die Excel-Application das aktive Fenster wird. Wenn man allerdings wüsste, warum du denkst, das zu brauchen, könnte man dir vielleicht Umwege zeigen.

Viele Grüße
derHöpp
Antworten Top
#7
Ach, ich war gerade eh dabei:

Du kannst eine eigene Klasse ApplicationWindow schreiben, die über den Handle der Application überwacht, ob die Excel-Application aktiviert wurde. Hierzu benötigst du zunächst einmal einen API-Aufruf von GetActiveWindow() aus der user32-Klasse. Die kommt in ein Allgemeines Modul (bei mir WINAPI genannt, hier für 32Bit):
Code:
Option Explicit

Declare Function GetActiveWindow Lib "user32" () As Long
Als nächstes die (rudimentär zusammengeklöppelte, undokumentierte und nicht sehr stabile(!!!)) Klasse, die dir ein Activated-Event für das ApplicationWindow spendiert. Die Klasse habe ich ApplicationWindow genannt. Weil VBA erstmal keinen Timer kennt, der in einem kürzeren Intervall als sekündlich funktioniert, läuft hier eine Dauerschleife, die alle 1000 schleifendurchläufe überprüft, ob das eingestellte Zeitintervall abgelaufen ist, um anschließend festzustellen, ob das Handle der Application mit dem gerade in Windows aktiven Windows-Handle übereinstimmt und das vorher nicht getan hat. Das ist nicht sehr stabil und nicht sehr ökonomisch sinnvoll. Letztlich kannst du deinen Rechner dabei als Heizung einsetzen. Als netten Nebeneffekt, kannst du deinen VBA-Editor während der Laufzeit nicht verwenden. Weitere Nebeneffekte sind ebenfalls nicht auszuschließen:
Code:
Option Explicit

Private HWND As Long
Private isRunning As Boolean
Private isactive As Boolean
Public Event Activated()

Private Sub Class_Initialize()
    HWND = Application.HWND
End Sub

Private Sub Class_Terminate()
    isRunning = False
End Sub

Sub start(intervalMiliSeconds As Long)
    Dim lasttimestamp As Long
    Dim stepper As Long
    lasttimestamp = Timer
    isRunning = True
    isactive = True
    Do While isRunning
        stepper = stepper + 1
        If stepper Mod 1000 = 0 Then
            stepper = 1
            If Timer > lasttimestamp + (intervalMiliSeconds / 1000) Then
                If WINAPI.GetActiveWindow() = HWND Then
                    If Not isactive Then
                        RaiseEvent Activated
                        isactive = True
                    End If
                Else
                    If isactive Then isactive = False
                End If
                lasttimestamp = Timer
            End If
        End If
        DoEvents
    Loop
End Sub

Sub stopMe()
    isRunning = False
End Sub
Ob die Schleife über den Stepper Rechenpower spart, oder ob ein dauerhaftes Abfragen des Timers genau so funktionieren würde, müsstest du selbst ausprobieren.

Zum Testen, habe ich einfach zwei Buttons in ein Worksheet-Objekt eingefügt, und in dessen Codebehind den Event-Handler für eine eigene ApplicationWindow-Instanz implementiert. Die beiden Buttons starten und stoppen die Überwachung:
Code:
Option Explicit

Private WithEvents Wind As ApplicationWindow

Sub starten()
    If Wind Is Nothing Then Set Wind = New ApplicationWindow
    Wind.start 500
End Sub

Sub stoppen()
    Wind.stopMe
    Set Wind = Nothing
End Sub

Private Sub Wind_Activated()
    Debug.Print Application.Name & " activated at " & Now()
End Sub

Private Sub CommandButton1_Click()
    starten
End Sub

Private Sub CommandButton2_Click()
    stoppen
End Sub

Ein Deactivated-Event ließe sich entsprechend einfach in der Hauptschleife der Klasse im Else-Zweig einbauen.

Viel Vergnügen damit und denk daran, dass das Unterfangen eher nicht nützlich ist.
Viele Grüße
derHöpp
Antworten Top
#8
Danke, aber die Lösung dürfte nicht auf Macs laufen.  Und für LibreOffice müsste man dann dort auch rufrickeln. Ich denke, dass mein Use Case zu speziell ist und den dürfte kaum jemand haben.
Antworten Top
#9
Moin,

Vielen Dank für die Erinnerung daran, dass ich mir das Helfen sparen kann, solange Rahmenbedingungen und Zielrichtung nicht deutlich formuliert sind.

-.-
[-] Folgende(r) 1 Nutzer sagt Danke an derHoepp für diesen Beitrag:
  • snb
Antworten Top
#10
Als ich die Lösung gesehen habe, habe ich erst einmal die Hände über den Kopf geschlagen, weil die Lösung so komplex ist. Ich denke, dass ich mittlerweile die Lösung verstanden habe. Demnach ist dann Excel ständig am Laufen. Statt dessen kann man mittels CreateThread einen neuen Thread starten und Application.Wait verwenden. Ich habe eben einen Code, den ich von ChatGPT bekommen habe, versucht . Jetzt ist Excel abgestürzt und ich hatte meine Daten nicht abgespeichert. Ich dachte, dass Excel dann die Daten wieder herstellt, was aber leider nicht der Fall ist.
Antworten Top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste