Unload Me löscht globale Variablen

.. das wohl mächtigste Werkzeug in Bill Gates' Büro-Sippe. Ob reine Formeln, PowerQuery oder VBA. Hier bleiben kaum Wünsche unerfüllt.
xlKing
Beiträge: 67
Registriert: 30. Mai 2024, 19:42
Hat sich bedankt: 9 Mal
Danksagung erhalten: 57 Mal
Kontaktdaten:

Unload Me löscht globale Variablen

#1

Beitrag von xlKing »

Hallo ihr,

ich bin schon seit längerem einem merkwürdigem Phänomen auf der Spur, das selbst für mich einfach nicht greifbar ist. Und zwar will ich Text aus einer TextBox im Userform in eine globale öffentliche Variable übergeben. Das klappt auch. Allerdings möchte ich nach dem Schließen des Userforms durch Unload Me, mit den Werten der Variablen weiter arbeiten. Solange das das Userform aufrufende Makro läuft, kein Problem. Sobald aber End Sub ausgeführt wird, wird das Userform endgültig entladen und geht in den Entwurfsmodus über. Im Einzelschritt wird dann das Modul mit dem Userform im Designmodus aktiviert. Dadurch werden leider alle globalen Variablen zurückgesetzt, auch solche die ich zuvor direkt definiert habe. Falls jemand dieses Problem nachvollziehen möchte, hier ein Testcode.

In ein Userform1, das eine Textbox1 und einen Commandbuton1 enthält kommt dieser Code:

Code: Alles auswählen

Private Sub CommandButton1_Click()
  Test1 = TextBox1.Text
  setTest2 TextBox1.Value
  Unload Me
End Sub
in ein allgemeines Modul kommt dann dieser Code

Code: Alles auswählen

Option Explicit
Public Test1 As String
Public Test2 As String

Static Sub Test()
  
  Static Test3 As String
  
  Debug.Print "Test1_ALt: " & Test1
  Debug.Print "Test2_Alt: " & Test2
  Debug.Print "Test3_Alt: " & Test3
  
  Test2 = 1
  
  UserForm1.Show
  
  Test3 = "Dies ist Test3"
  
  Debug.Print "Test1_Neu:" & Test1
  Debug.Print "Test2_Neu:" & Test2
  Debug.Print "Test3_Neu:" & Test3
  
End Sub

Public Sub setTest2(ByVal txt As String)
  Test2 = txt
End Sub
Wenn ich nun die Sub Test mehrmals ausführe erwarte ich eigentlich, dass die alten, zuvor definierten Werte zurückgegeben werden, bevor ich die neuen setze. Ist aber leider nicht der Fall. Die neuen Werte werden immer in leere Variablen gesetzt.

Und jetzt kommt der Witz: In manchen Fällen klappt es doch. Ich habe hier zwei Dateien mit exakt dem gleichen Code und Aufbau. Bei der einen Datei geht's, bei der anderen nicht. Sehr rätselhaft. Aber ich glaube eine Lösung gefunden zu haben, für alle die sich mit dem gleichen Problem rumschlagen: Wenn man das Userform mit dem Schlüsselwort New einer Variablen zuweist und dann die Variable mit Show aufruft, scheint das Phänomen nicht aufzutreten und alles läuft wie geplant. Zumindest bislang.

Der Code im allgemeinen Modul muss also wie folgt geändert werden.

Code: Alles auswählen

Option Explicit
Dim frm As UserForm1
Public Test1 As String
Public Test2 As String

Static Sub Test()
  Set frm = New UserForm1
  Static Test3 As String
  
  Debug.Print "Test1_ALt: " & Test1
  Debug.Print "Test2_Alt: " & Test2
  Debug.Print "Test3_Alt: " & Test3
  
  Test2 = 1
  
  frm.Show
  
  Test3 = "Dies ist Test3"
  
  Debug.Print "Test1_Neu:" & Test1
  Debug.Print "Test2_Neu:" & Test2
  Debug.Print "Test3_Neu:" & Test3
  
End Sub

Public Sub setTest2(ByVal txt As String)
  Test2 = txt
End Sub

Und schon kann man seinen VBAsteleien weiter frönen.

Gruß Mr. K.
Folgende Benutzer bedankten sich beim Autor xlKing für den Beitrag:
d'r Bastler
Paul1206
Beiträge: 35
Registriert: 29. Aug 2022, 20:22
Hat sich bedankt: 5 Mal
Danksagung erhalten: 14 Mal

Re: Unload Me löscht globale Variablen

#2

Beitrag von Paul1206 »

Hallo Mr. K.,

Das ist eins der Top Argumente um solche (seltsamen) Sachen mit der Property Anweisung zu verhindern. Zumindest in soweit die private Variable nicht aus irgendeinen Grund (so programiert) geleert wird.

Gruß Uwe
Paul1206
Beiträge: 35
Registriert: 29. Aug 2022, 20:22
Hat sich bedankt: 5 Mal
Danksagung erhalten: 14 Mal

Re: Unload Me löscht globale Variablen

#3

Beitrag von Paul1206 »

Hallo Mr. K.,

ich habe mir die Sache mal genauer angeschaut. Siehe da bei Userfom1.Show Aufruf wird egal via Terminate oder Unload die Variable egal ob Public oder Property geleert.

Auch der Versuch statt Initialize die Variable im Activate zu füllen hilft nicht.
Nur bei manuellem Start des Userforms passiert dies nicht.

Ein Weg, der die Variable wieder herstellt ohne Zellen oder so was zu Bemühen ist z.B. in: ActiveWorkbook.CustomDocumentProperties() den Wert abzulegen und falls Variable leer diese aus den CustomDocumentProperties zu holen.

Gruß Uwe
knobbi38
Beiträge: 62
Registriert: 20. Okt 2024, 14:15
Hat sich bedankt: 4 Mal
Danksagung erhalten: 36 Mal
Kontaktdaten:

Re: Unload Me löscht globale Variablen

#4

Beitrag von knobbi38 »

Hallo,

ich kann an dem Code nichts "merkwürdiges" entdecken - das Verhalten ist exakt so, wie in der Doku beschrieben und zu erwarten wäre. Wo genau ist das Problem mit dem Verhalten?

Bitte im Hinterkopf behalten, daß mit dem Aufruf UF.Show immer mit der Default-Instanz einer Klasse gearbeitet wird. Diese verhält sich etwas anderes als eine "normale" Instanz eine Klasse, welche erst mit dem Schlüsselwort New erzeugt wird und man sollte bedenken, daß mit dem Ende der Codeausführung oder bei einem unbehandelten Fehler immer alle Variablen ihren Inhalt verlieren, weil der dafür reservierte Speicher automatisch freigegeben wird; daran ändern auch nichts die Verwendung des Schlüsselworts Static.

Gruß Knobbi38
Paul1206
Beiträge: 35
Registriert: 29. Aug 2022, 20:22
Hat sich bedankt: 5 Mal
Danksagung erhalten: 14 Mal

Re: Unload Me löscht globale Variablen

#5

Beitrag von Paul1206 »

Hallo Ulrich,

hier mal das Problem in einer kleinen Datei.

Beim 1. Weg wird die Variable entleert.
Beim 2. Weg bleibt diese erhalten.

Gruß Uwe
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
knobbi38
Beiträge: 62
Registriert: 20. Okt 2024, 14:15
Hat sich bedankt: 4 Mal
Danksagung erhalten: 36 Mal
Kontaktdaten:

Re: Unload Me löscht globale Variablen

#6

Beitrag von knobbi38 »

Hallo Uwe,

tut mir leid, aber ich kann dein Problem nicht nachvollziehen. Der Wert in der Variablen bleibt bei mir solange gespeichert, bis der Code "invalid" wird, z.B. bei der ersten Änderung des Codes, egal wie die Userform gestartet oder beendet wird. Auch die Modalität spielt dabei keine Rolle.

Gruß Ulrich
knobbi38
Beiträge: 62
Registriert: 20. Okt 2024, 14:15
Hat sich bedankt: 4 Mal
Danksagung erhalten: 36 Mal
Kontaktdaten:

Re: Unload Me löscht globale Variablen

#7

Beitrag von knobbi38 »

Nachtrag:

Mit der Anweisung End wird der Code explizit beendet. Du kannst deinen Code mal so modifizieren:

Code: Alles auswählen

Sub FormStart()
    UserForm1.Show
    End
End Sub
Damit werden dann nach dem Unload wirklich alle Variablen zurückgesetzt.

Siehe auch:
https://learn.microsoft.com/en-us/offic ... -variables

Btw.: normalerweise würde man Userforms auch nicht unbedingt entladen, sondern nur verstecken und bei Bedarf wieder sichtbar machen.
https://gregmaxey.com/word_tip_pages/us ... _tips.html

Grüße Ulrich
Paul1206
Beiträge: 35
Registriert: 29. Aug 2022, 20:22
Hat sich bedankt: 5 Mal
Danksagung erhalten: 14 Mal

Re: Unload Me löscht globale Variablen

#8

Beitrag von Paul1206 »

Hallo Miteinander,

das ist ja ein Ding, könnte man so sagen. Ich habe auf Grund Ulrichs Aussage jetzt den selben Kram mal auf meinem Laptop getestet und siehe da die Public Variable wird nicht geleert.

Es scheint also an O2019 auf Win10 zu liegen. O2021 auf Win11 lässt sich dieses Verhalten nicht nachvollziehen.

Mir wäre dies nie aufgefallen, da ich eigentlich die Dinge immer so zusammenstelle, dass nach Beendigung die damit im Zusammenhang stehenden Variablen nicht mehr verwendet werden müssen.

Einzig bei notwendig zu entladenden Objektvariablen achte ich darauf, dass dies geschieht.

Gruß Uwe
knobbi38
Beiträge: 62
Registriert: 20. Okt 2024, 14:15
Hat sich bedankt: 4 Mal
Danksagung erhalten: 36 Mal
Kontaktdaten:

Re: Unload Me löscht globale Variablen

#9

Beitrag von knobbi38 »

Hallo Uwe,

sind denn die beiden Installation Offs2K19 und Offs2K21 vergleichbar in Bezug auf Einstellungen und AddIns?
Schließe mal alle Dateien in der VBE und probiere das nochmal aus.
Eigentlich sollten die Variablen nur geleert werden, wenn in der VBE Code "dirty" wird, also sich etwas geändert hat. Das kann man leicht an dem "Kompilieren"-Icon in der VBE erkennen, wenn diese aktiviert ist.

Gruß Ulrich
Paul1206
Beiträge: 35
Registriert: 29. Aug 2022, 20:22
Hat sich bedankt: 5 Mal
Danksagung erhalten: 14 Mal

Re: Unload Me löscht globale Variablen

#10

Beitrag von Paul1206 »

Hallo Ulrich,

eigentlich sollte es so sein.

Ich habe grad mal rumprobiert und siehe da das Visual Studio Add-In scheint das Problem zu sein.

Gruß Uwe
Antworten

Wer ist online?

Mitglieder in diesem Forum: Ahrefs [Bot] und 0 Gäste