Knusperklumpen: VBA - Probleme mit Public-Variable

Hi.
Ich erstelle gerade ein VBA-Projekt.
Dort gibt es eine UserForm, ein Modul und die Arbeitsmappe selbst.
Hinter diesen 3 liegen Funktionen (also Code).
Nun möchte ich eine Variable als Public definieren, so dass sie im Code der UserForm, des Moduls und der Arbeitsmappe verwendet werden kann. Leider funktioniert das nicht, wie ich mir das denke. Ich habe die Public-Definition nun schon überall mal hingeschrieben aber es funktioniert irgendwie nicht. Ist es nicht möglich eine Variable so Public zu setzen, dass sie auch wirklich im gesamten Projekt definiert ist (so, wie das Handbuch es eigentlich vorgibt) oder mache ich (wahrscheinlich) nur einen Fehlen?

Danke und mfg
Knusperklumpen

  1. Moin,

    Dort gibt es eine UserForm, ein Modul und die Arbeitsmappe selbst.
    Ist es nicht möglich eine Variable so Public zu setzen, dass sie auch wirklich im gesamten Projekt definiert ist (so, wie das Handbuch es eigentlich vorgibt) oder mache ich (wahrscheinlich) nur einen Fehlen?

    deklariere die Variable in einem allgemeinen Modul z. B. mit Global oder Public.

    Erstelle im selben allgemeinen Modul eine Sub, die der Variablen den Wert zuweist, eventuell mit Übergabeparametern. Beispiel:

    Global strTemp as string

    sub Festlegen(byval strWert as string)
    strtemp = strWert
    end sub

    Nun kannst Du von überall aus die Sub aufrufen und die Variable steht zur Verfügung:

    'Mach was
    Festlegen "Mein Text"
    'Mach was

    Viele Grüße

    Jörg

    1. Hi ... danke, hat funktioniert.
      Finde ich zwar etwas umständlich, dass man ne Funktion braucht um die Variable mit dem Wert zu belegen aber naja ... wird seinen Grund haben.

      mfg
      Knusperklumpen

      1. Hi,

        Finde ich zwar etwas umständlich, dass man ne Funktion braucht um die Variable mit dem Wert zu belegen aber naja ... wird seinen Grund haben.

        naja, irgendwie muss der Variablen ja ein Wert zugewiesen werden.

        Ansonsten kannst Du auch eine Konstante in einem allgemeinen Modul verwenden:

        Global Const strTemp As String = "Mein Text"

        Die kannst Du dann auch von überall aus verwenden.

        Viele Grüße

        Jörg

        1. Hi ... das mit der Konstante ist sogar noch besser!!
          Danke!

          mfg
          Knusperklumpen

          P.S. Das mit der Wertzuweisung der Variable ist ja klar aber wozu da extra ne Funktion benötigt wird und man die nicht einfach so belegen kann versteh ich nich.

          1. Hi,

            P.S. Das mit der Wertzuweisung der Variable ist ja klar aber wozu da extra ne Funktion benötigt wird und man die nicht einfach so belegen kann versteh ich nich.

            wie soll denn sonst einer Variablen ein Wert zugewiesen werden?

            Viele Grüße

            Jörg

            1. Hi,

              P.S. Das mit der Wertzuweisung der Variable ist ja klar aber wozu da extra ne Funktion benötigt wird und man die nicht einfach so belegen kann versteh ich nich.

              wie soll denn sonst einer Variablen ein Wert zugewiesen werden?

              Viele Grüße

              Jörg

              Anstatt die Funktion aufzurufen, die der Variablen einen Wert zuweist, könnte ich doch selbst der Variablen einen Wert zuweisen.

              Variable = Wert;

              Oder nicht? Ist die vielleicht gar schreibgeschützt von hier aus?

              Ansonsten könnte ich aus dem gleichen Grund, aus dem ich eine Schreib-Funktion benutze, eine Lese-Funktion benutzen.

              1. Hi,

                Anstatt die Funktion aufzurufen, die der Variablen einen Wert zuweist, könnte ich doch selbst der Variablen einen Wert zuweisen.

                puh, nun muss ich doch mal auf einen Fehler hinweisen, den ich bisher übergangen habe. Ich gehe jetzt mal nur auf Funktionen und Routinen ein, nicht aber auf Property & Co.

                Eine Funktion gibt immer einen Rückgabewert zurück. Sie beginnt mit Function und endet mit End Function. Insofern ist es eigentlich falsch, wenn wir hier von Funktionen reden. Das heißt, dass das Ganze hier mit Funktionen eigentlich nichts im eigentlichen Sinne zu tun hat.

                Eine Routine (Sub) _bewirkt_ irgendwas. Sie gibt im eigentlichen Sinne nichts zurück, sondern führt etwas aus, wie zum Beispiel die Zuweisung eines Wertes an eine Variable.

                In VB/VBA beginnt jede Folge von Anweisungen usw. mit einer Überschrift. Das kann Function sein, wie auch Sub, Property Get, usw.  Beendet wird das Ganze mit End, wie z. B. End Function, End Sub, End Property, usw. Ohne diese Überschrift kann VB/VBA nichts mit irgendwelchen  Zeilen anfangen - es sei denn, es handelt sich um Konstanten oder andere Deklarationen. Also: Keine Überschrift, keine Ausführung.

                Variable = Wert;

                So, wo soll nun diese Zeile stehen (abgesehen vom überflüssigen Semikolon)? VB/VBA weiß damit nichts anzufangen. Soll es eine Funktion sein? Soll es eine Sub sein? Soll damit ein Objekt erstellt werden?

                Oder nicht? Ist die vielleicht gar schreibgeschützt von hier aus?
                Ansonsten könnte ich aus dem gleichen Grund, aus dem ich eine Schreib-Funktion benutze, eine Lese-Funktion benutzen.

                Wie geschrieben: Mit Funktionen hat es gar nichts zu tun, wie auch mit Schreibschutz nicht. Es ist halt nur eine Eigenart einer Sprache.

                Viele Grüße

                Jörg

                1. Nun, anstelle dieser Zeile:

                  call setVariable(wert)

                  schreibe ich diese Zeile:

                  variable = wert

                  Überall da, wo die Funktion/Sub aufgerufen würde, wird nun stattdessen die Wertzuweisung hingeschrieben. Und sonst nirgendwo.
                  Wofür brauche ich dann diese Funktion/Sub?

                  1. Moin,

                    Nun, anstelle dieser Zeile:

                    call setVariable(wert)

                    schreibe ich diese Zeile:

                    variable = wert

                    ja, das kannst Du auch machen, aber nur unter einer Bedingung: Die Zuweisung muss in dem Modul erfolgen, in dem die Variable deklariert ist.

                    Wofür brauche ich dann diese Funktion/Sub?

                    Hier ging es darum, dass eine Userform, ein allgemeines und ein Klassenmodul verwendet werden, in denen die Variable zur Verfügung stehen soll. Eine globale Variable wird dabei in einem allgemeinen Modul deklariert, die Wertzuweisung muss in diesem Modul erfolgen. Deshalb kann man nicht z. B. im Klassenmodul der UF den Wert zuweisen, sondern man muss von diesem Klassenmodul aus die Variable im allgemeinen Modul zuweisen. Da diese Anweisung aber nicht lose in einem Modul stehen darf, braucht man halt eine Sub.

                    Aber ich verweise auch nochmal auf das, was Vinzenz geschrieben hat: Statt sich zu sehr mit diesen globalen Variablen zu beschäftigen, ist es besser, Funktionen/Subs mit Übergabeparametern zu verwenden.

                    Viele Grüße

                    Jörg

          2. Hallo

            Hi ... das mit der Konstante ist sogar noch besser!!
            P.S. Das mit der Wertzuweisung der Variable ist ja klar aber wozu da extra ne Funktion benötigt wird und man die nicht einfach so belegen kann versteh ich nich.

            Wenn Du schon so schlimme Sachen wie globale Variablen benutzen willst, dann kannst Du sie nur dann sinnvoll benutzen, wenn Du dieser Variablen einen Wert zuweist. Eine solche Anweisung kann nur innerhalb einer Funktion (oder Prozedur) stehen. Selbstverständlich kannst Du in 200 verschiedenen Funktionen den Inhalt dieser Variablen abändern, das Ergebnis wird sein, dass Du Dir über den Inhalt nicht sicher sein kannst.

            Globale Konstanten sind im Gegensatz zu globalen Variablen meistens sinnvoll. In Deinem Fall wolltest Du ja auch nur eine Konstante benutzen.

            Nochmals: Verwaiste außerhalb jeglicher Funktion/Prozedur stehender Anweisungen mit Zuweisung von Werten an Variablen sind syntaktisch falsch. Sie würden außerdem nie ausgeführt werden.

            Freundliche Grüße

            Vinzenz

            1. Moin,

              grundsätzlich sehe ich es auch so.

              Selbstverständlich kannst Du in 200 verschiedenen Funktionen den Inhalt dieser Variablen abändern, das Ergebnis wird sein, dass Du Dir über den Inhalt nicht sicher sein kannst.

              Das ist natürlich ein Problem, das man nur durch saubere Arbeit vermeiden kann. Aber es gibt dennoch ein paar Ausnahmen, in denen sich globale Variablen bewähren, z. B.:

              Eine Anwendung besteht aus mehreren Modulen. Die Anwendung benötigt Unterordner, soll aber an beliebiger Stelle laufen können; man weiß also nie, in welchem Ordner die Anwendnung gespeichert ist. Nun könnte man bei Bedarf, also wenn man mit den Unterordnern arbeiten muss, immer deren relative Pfade zusammenbasteln. Man spart sich aber etwas Arbeit, wenn man die Pfade einmal beim Aufruf zusammenbastelt und dann als globale Variablen zur Verfügung stellt.

              Klar, man könnte auch Objekte erstellen, aber das wäre hier wie die berühmten Kanonen.

              Nochmals: Verwaiste außerhalb jeglicher Funktion/Prozedur stehender Anweisungen mit Zuweisung von Werten an Variablen sind syntaktisch falsch. Sie würden außerdem nie ausgeführt werden.

              Eben.

              Viele Grüße

              Jörg

        2. Hi ... du hast mir ja bisweilen sehr gut geholfen, dann weißt du sicher auch Rat bei dem nächsten Problem.
          Wie kann ich in VBA typecasten?

          Danke und mfg
          Knusperklumpen

          1. Hi,

            Wie kann ich in VBA typecasten?

            Du meinst Typumwandlungen? Normalerweise sollte sowas nicht erforderlich sein, da man ja weiß, welcher Datentyp erwartet wird …

            Ansonsten hast Du zwei Möglichkeiten:

            1. als Variant deklarieren (bei größeren Sachen nicht gut für die Performance)

            2. Funktionen benutzen, die mit "C" beginnen (CInt, CDbl, …). Mehr dazu steht in der Hilfe.

            Viele Grüße

            Jörg