Come posso dichiarare una variabile globale in VBA?


132

Ho scritto il seguente codice:

Function find_results_idle()

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

E ricevo il messaggio di errore:

"attributo non valido in Sub o Funzione"

Sai cosa ho fatto di sbagliato?

Ho provato a usare Globalinvece diPublic , ma ho avuto lo stesso problema.

Ho provato a dichiarare la funzione stessa come `pubblica, ma anche questo non ha funzionato.

Cosa devo fare per creare la variabile globale?

Risposte:


177

È necessario dichiarare le variabili al di fuori della funzione:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1

Quando provo a dichiarare un array come pubblico, si dice: array e tipi di dati definiti dall'utente non possono essere dichiarati come pubblici.
kapilddit,

Sopra il primo Function/ Sub, non solo all'esterno: "Le variabili a livello di modulo possono essere dichiarate con un'istruzione Dim o Private nella parte superiore del modulo sopra la prima definizione della procedura." (da Ambito di variabili in Visual Basic, Applications
Edition

119

Questa è una domanda sull'ambito .

Se vuoi solo che le variabili durino per tutta la durata della funzione, usa Dim(abbreviazione di Dimension ) all'interno della funzione o sub per dichiarare le variabili:

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

Una variabile globale (come sottolineato da SLaks) viene dichiarata al di fuori della funzione usando la Publicparola chiave. Questa variabile sarà disponibile durante la vita dell'applicazione in esecuzione. Nel caso di Excel, ciò significa che le variabili saranno disponibili fino a quando quella particolare cartella di lavoro di Excel sarà aperta.

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.

Puoi anche avere variabili accessibili solo all'interno di un particolare modulo (o classe) dichiarandole con la Privateparola chiave.

Se stai costruendo una grande applicazione e senti la necessità di utilizzare le variabili globali, ti consiglio di creare un modulo separato solo per le tue variabili globali. Questo dovrebbe aiutarti a tenerne traccia in un unico posto.


4
+1 Ancora utile 7 anni dopo. Ma c'è qualche sfumatura aggiuntiva riguardo alle variabili oggetto rispetto alle variabili dati? Ho riscontrato un problema relativo alle variabili dell'oggetto scoping che ha sollevato una nuova domanda. Molto apprezzato se avessi il tempo di dare un'occhiata. stackoverflow.com/q/46058096/5457466
Egalth

2
Spiegazione sintetica della dichiarazione delle variabili in VBA.
PhillipOReilly,

Ho provato tutti gli altri suggerimenti su "scope" e nessuno ha funzionato. L'unica cosa che ha funzionato è stato un nuovo modulo appositamente per varisti globali e funziona!
Fandango68,


18

La domanda riguarda davvero la portata, come ha detto l'altro ragazzo.

In breve, considera questo "modulo":

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). 

È possibile controllare questo riferimento MSDN per ulteriori informazioni sulla dichiarazione delle variabili e su questa altra domanda di overflow dello stack per ulteriori informazioni su come le variabili non rientrano nell'ambito.

Altre due cose veloci:

  1. Sii organizzato quando usi le variabili a livello di cartella di lavoro, in modo che il tuo codice non diventi confuso. Preferisce funzioni (con tipi di dati corretti) o passa argomenti ByRef .
  2. Se si desidera che una variabile mantenga il suo valore tra le chiamate, è possibile utilizzare l' istruzione statica .

Sei sicuro che una variabile globale possa essere utilizzata in diverse cartelle di lavoro? Non funziona per me
Seb

Buon punto! Ho notato che non ho aggiunto un riferimento per dove ho ottenuto quelle informazioni ... Né l'ho trovato di nuovo. Meglio modificare la risposta ...: / Oh, e grazie Seb.
FCastro

14

Se questa funzione è in un modulo / classe, potresti semplicemente scriverli al di fuori della funzione, quindi ha Global Scope. Ambito globale significa che è possibile accedere alla variabile da un'altra funzione nello stesso modulo / classe (se si utilizza dimcome dichiarazione di dichiarazione, utilizzare publicse si desidera che le variabili siano accessibili da tutte le funzioni in tutti i moduli):

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

1

Creare un numero intero pubblico nella Dichiarazione generale.

Quindi nella tua funzione puoi aumentarne il valore ogni volta. Vedi esempio (funzione per salvare gli allegati di una e-mail come 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

0

Un buon modo per creare variabili pubbliche / globali è quello di trattare il modulo come un oggetto di classe e dichiarare proprietà e utilizzare Get proprietà [variabile] per accedere a proprietà / metodo. Inoltre potrebbe essere necessario fare riferimento o passare un riferimento al modulo Modulo istanziato. Si otterranno errori se si chiamano metodi per moduli / report chiusi.
Esempio: passare Me.Form.Module.Parent in sub / funzione non all'interno del modulo.

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

Quindi nell'altro modulo sarai in grado di accedere a:

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

Se usi Late Binding come I, controllo sempre i valori Null e gli oggetti che sono Nothing prima di tentare di eseguire qualsiasi elaborazione.


0

Inoltre puoi usare -

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

È stato testato su Office 2010

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.