Wie deklariere ich eine globale Variable in VBA?

132

Ich habe folgenden Code geschrieben:

Function find_results_idle()

    Public iRaw As Integer
    Public iColumn As Integer
    iRaw = 1
    iColumn = 1

Und ich bekomme die Fehlermeldung:

"ungültiges Attribut in Sub oder Funktion"

Weißt du was ich falsch gemacht habe?

Ich habe versucht, Globalanstelle von zu verwenden Public, bekam aber das gleiche Problem.

Ich habe versucht, die Funktion selbst als `Public zu deklarieren, aber das hat auch nichts gebracht.

Was muss ich tun, um die globale Variable zu erstellen?

Nimrod
quelle

Antworten:

177

Sie müssen die Variablen außerhalb der Funktion deklarieren:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1
SLaks
quelle
Wenn ich versuche, ein Array als öffentlich zu deklarieren, heißt es: Array- und benutzerdefinierte Datentypen können nicht als öffentlich deklariert werden.
Kapilddit
Über dem ersten Function/ Sub, nicht nur außerhalb: "Variablen auf Modulebene können mit einer Dim- oder Private-Anweisung am oberen Rand des Moduls über der ersten Prozedurdefinition deklariert werden." (aus Umfang der Variablen in Visual Basic für Anwendungen )
Nickolay
119

Dies ist eine Frage zum Umfang .

Wenn die Variablen nur die Lebensdauer der Funktion haben sollen, deklarieren Sie die Variablen mit Dim(kurz für Dimension ) in der Funktion oder im Sub:

Function AddSomeNumbers() As Integer
    Dim intA As Integer
    Dim intB As Integer
    intA = 2
    intB = 3
    AddSomeNumbers = intA + intB
End Function
'intA and intB are no longer available since the function ended

Eine globale Variable (wie SLaks hervorhob) wird außerhalb der Funktion mit dem PublicSchlüsselwort deklariert. Diese Variable ist während der Lebensdauer Ihrer laufenden Anwendung verfügbar. Im Fall von Excel bedeutet dies, dass die Variablen verfügbar sind, solange diese bestimmte Excel-Arbeitsmappe geöffnet ist.

Public intA As Integer
Private intB As Integer

Function AddSomeNumbers() As Integer
    intA = 2
    intB = 3
    AddSomeNumbers = intA + intB
End Function
'intA and intB are still both available.  However, because intA is public,  '
'it can also be referenced from code in other modules. Because intB is private,'
'it will be hidden from other modules.

Sie können auch Variablen verwenden, auf die nur innerhalb eines bestimmten Moduls (oder einer bestimmten Klasse) zugegriffen werden kann, indem Sie sie mit dem PrivateSchlüsselwort deklarieren.

Wenn Sie eine große Anwendung erstellen und globale Variablen verwenden möchten, würde ich empfehlen, ein separates Modul nur für Ihre globalen Variablen zu erstellen. Dies soll Ihnen helfen, sie an einem Ort im Auge zu behalten.

Ben McCormack
quelle
4
+1 7 Jahre später immer noch nützlich. Aber gibt es einige zusätzliche Nuancen in Bezug auf Objektvariablen gegenüber Datenvariablen? Ich bin auf ein Problem im Zusammenhang mit dem Scoping von Objektvariablen gestoßen, das eine neue Frage ausgelöst hat. Sehr geschätzt, wenn Sie Zeit hätten, einen Blick darauf zu werfen. stackoverflow.com/q/46058096/5457466
Egalth
2
Kurze Erklärung der Variablendeklaration in VBA.
PhillipOReilly
Ich habe alle anderen Vorschläge zum "Umfang" ausprobiert und keiner hat funktioniert. Das einzige, was funktioniert hat, war ein neues Modul speziell für globale Vars und es funktioniert!
Fandango68
18

Die Frage ist wirklich über Umfang, wie der andere Typ es ausdrückte.

Kurz gesagt, betrachten Sie dieses "Modul":

Public Var1 As variant     'Var1 can be used in all
                           'modules, class modules and userforms of 
                           'thisworkbook and will preserve any values
                           'assigned to it until either the workbook
                           'is closed or the project is reset.

Dim Var2 As Variant        'Var2 and Var3 can be used anywhere on the
Private Var3 As Variant    ''current module and will preserve any values
                           ''they're assigned until either the workbook
                           ''is closed or the project is reset.

Sub MySub()                'Var4 can only be used within the procedure MySub
    Dim Var4 as Variant    ''and will only store values until the procedure 
End Sub                    ''ends.

Sub MyOtherSub()           'You can even declare another Var4 within a
    Dim Var4 as Variant    ''different procedure without generating an
End Sub                    ''error (only possible confusion). 

In dieser MSDN-Referenz finden Sie weitere Informationen zur Variablendeklaration und in dieser anderen Frage zum Stapelüberlauf. Dort erfahren Sie mehr darüber, wie Variablen den Gültigkeitsbereich verlassen.

Zwei weitere schnelle Dinge:

  1. Seien Sie organisiert, wenn Sie Variablen auf Arbeitsmappenebene verwenden, damit Ihr Code nicht verwirrend wird. Bevorzugen Sie Funktionen (mit geeigneten Datentypen) oder übergeben Sie Argumente ByRef .
  2. Wenn eine Variable ihren Wert zwischen Aufrufen beibehalten soll, können Sie die statische Anweisung verwenden.
FCastro
quelle
Sind Sie sicher, dass eine globale Variable in verschiedenen Arbeitsmappen verwendet werden kann? Funktioniert nicht für mich
Seb
Guter Punkt! Mir ist aufgefallen, dass ich keine Referenz hinzugefügt habe, woher ich diese Informationen habe ... Ich habe sie auch nicht wiedergefunden. Besser die Antwort bearbeiten ...: / Oh, und danke Seb.
FCastro
14

Wenn sich diese Funktion in einem Modul / einer Klasse befindet, können Sie sie einfach außerhalb der Funktion schreiben Global Scope. Globaler Bereich bedeutet, dass auf die Variable von einer anderen Funktion in demselben Modul / derselben Klasse zugegriffen werden kann (wenn Sie dimals Deklarationsanweisung verwenden, verwenden publicSie , wenn Sie möchten, dass alle Funktionen in allen Modulen auf die Variablen zugreifen können):

Dim iRaw As Integer
Dim iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1
End Function

Function this_can_access_global()
    iRaw = 2
    iColumn = 2
End Function
Zai
quelle
1

Erstellen Sie eine öffentliche Ganzzahl in der Allgemeinen Erklärung.

Dann können Sie in Ihrer Funktion den Wert jedes Mal erhöhen. Siehe Beispiel (Funktion zum Speichern von Anhängen einer E-Mail als CSV).

Public Numerator As Integer

Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim FileName As String

saveFolder = "c:\temp\"

     For Each objAtt In itm.Attachments
            FileName = objAtt.DisplayName & "_" & Numerator & "_" & Format(Now, "yyyy-mm-dd H-mm-ss") & ".CSV"
                      objAtt.SaveAsFile saveFolder & "\" & FileName
                      Numerator = Numerator + 1

          Set objAtt = Nothing
     Next
End Sub
Dan Bidner
quelle
0

Eine gute Möglichkeit, öffentliche / globale Variablen zu erstellen, besteht darin, das Formular wie ein Klassenobjekt zu behandeln, Eigenschaften zu deklarieren und mit Public Property Get [Variable] auf Eigenschaft / Methode zuzugreifen. Möglicherweise müssen Sie auch eine Referenz auf das instanziierte Formularmodul verweisen oder übergeben. Sie erhalten Fehler, wenn Sie Methoden für geschlossene Formulare / Berichte aufrufen.
Beispiel: Übergeben Sie Me.Form.Module.Parent an Sub / Funktion, die sich nicht in der Form befindet.

Option Compare Database 
Option Explicit
''***********************************''
' Name: Date: Created Date Author: Name 
' Current Version: 1.0
' Called by: 
''***********************************''
' Notes: Explain Who what when why... 
' This code Example requires properties to be filled in 
''***********************************''
' Global Variables
Public GlobalData As Variant
''***********************************''
' Private Variables
Private ObjectReference As Object
Private ExampleVariable As Variant
Private ExampleData As Variant
''***********************************''
' Public properties
Public Property Get ObjectVariable() As Object
   Set ObjectVariable = ObjectReference
End Property 
Public Property Get Variable1() As Variant 
  'Recommend using variants to avoid data errors
  Variable1 = ExampleVariable
End property
''***********************************''
' Public Functions that return values
Public Function DataReturn (Input As Variant) As Variant
   DataReturn = ExampleData + Input
End Function 
''***********************************''
' Public Sub Routines
Public Sub GlobalMethod() 
   'call local Functions/Subs outside of form
   Me.Form.Refresh
End Sub
''***********************************''
' Private Functions/Subs used not visible outside 
''***********************************''
End Code

Im anderen Modul können Sie also auf Folgendes zugreifen:

Public Sub Method1(objForm as Object)
   'read/write data value
   objForm.GlobalData
   'Get object reference (need to add Public Property Set to change reference object)
   objForm.ObjectVariable
   'read only (needs Public property Let to change value)
   objForm.Variable1
   'Gets result of function with input
   objForm.DataReturn([Input])
   'runs sub/function from outside of normal scope
   objForm.GlobalMethod
End Sub

Wenn Sie Late Binding wie ich verwenden, suchen Sie immer nach Nullwerten und Objekten, die Nothing sind, bevor Sie versuchen, eine Verarbeitung durchzuführen.

Doppelte E-CPU
quelle
0

Auch können Sie verwenden -

Private Const SrlNumber As Integer = 910

Private Sub Workbook_Open()
    If SrlNumber > 900 Then
        MsgBox "This serial number is valid"
    Else
        MsgBox "This serial number is not valid"
    End If
End Sub

Es wurde im Büro 2010 getestet

IshaniNet
quelle