¿Cómo declaro una variable global en VBA?

132

Escribí el siguiente código:

Function find_results_idle()

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

Y recibo el mensaje de error:

"atributo inválido en Sub o Función"

¿Sabes lo que hice mal?

Traté de usar en Globallugar de Public, pero tuve el mismo problema.

Traté de declarar la función en sí misma como 'Public, pero eso tampoco sirvió de nada.

¿Qué debo hacer para crear la variable global?

Nimrod
fuente

Respuestas:

177

Debe declarar las variables fuera de la función:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1
SLaks
fuente
Cuando intento declarar una matriz como pública, dice: la matriz y los tipos de datos definidos por el usuario no se pueden declarar como públicos.
kapilddit
Por encima de la primera Function/ Sub, no solo afuera: "Las variables a nivel de módulo se pueden declarar con una declaración Dim o Private en la parte superior del módulo sobre la definición del primer procedimiento". (del alcance de las variables en Visual Basic para aplicaciones )
Nickolay
119

Esta es una pregunta sobre el alcance .

Si solo desea que las variables duren la vida útil de la función, use Dim(abreviatura de Dimension ) dentro de la función o sub para declarar las variables:

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 variable global (como señaló SLaks) se declara fuera de la función utilizando la Publicpalabra clave. Esta variable estará disponible durante la vida de su aplicación en ejecución. En el caso de Excel, esto significa que las variables estarán disponibles siempre que ese libro de Excel en particular esté abierto.

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.

También puede tener variables que solo sean accesibles dentro de un módulo (o clase) particular al declararlas con la Privatepalabra clave.

Si está creando una aplicación grande y siente la necesidad de usar variables globales, recomendaría crear un módulo separado solo para sus variables globales. Esto debería ayudarlo a realizar un seguimiento de ellos en un solo lugar.

Ben McCormack
fuente
44
+1 Sigue siendo útil 7 años después. ¿Pero hay algún matiz adicional con respecto a las variables de objeto versus las variables de datos? Me encontré con un problema relacionado con las variables de objeto de alcance que provocó una nueva pregunta. Muy apreciado si tuviera tiempo para echar un vistazo. stackoverflow.com/q/46058096/5457466
Egalth
2
Explicación sucinta de la declaración de variables en VBA.
PhillipOReilly
Intenté todas las otras sugerencias sobre "alcance" y ninguna funcionó. ¡Lo único que funcionó fue un nuevo Módulo específicamente para vars globales y funciona!
Fandango68
18

La pregunta es realmente sobre el alcance, como lo expresó el otro chico.

En resumen, considere este "módulo":

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

Puede consultar esta referencia de MSDN para obtener más información sobre la declaración de variables y esta otra Pregunta de desbordamiento de pila para obtener más información sobre cómo las variables quedan fuera de alcance.

Otras dos cosas rápidas:

  1. Sea organizado cuando use variables de nivel de libro de trabajo, para que su código no sea confuso. Funciones preferidas (con los tipos de datos adecuados) o pasando argumentos ByRef .
  2. Si desea que una variable conserve su valor entre llamadas, puede usar la instrucción estática .
FCastro
fuente
¿Estás seguro de que una variable global se puede usar en diferentes libros? No funciona para mí
Seb
¡Buen punto! Noté que no agregué una referencia de dónde obtuve esa información ... Tampoco la volví a encontrar. Mejor editar la respuesta ...: / Oh, y gracias Seb.
FCastro
14

Si esta función está en un módulo / clase, podría escribirlos fuera de la función, así es Global Scope. Global Scope significa que otra función puede acceder a la variable en el mismo módulo / clase (si usa dimcomo declaración de declaración, use publicsi desea que todas las funciones puedan acceder a las variables en todos los módulos):

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
fuente
1

Crear un número entero público en la Declaración general.

Luego, en su función, puede aumentar su valor cada vez. Ver ejemplo (función para guardar archivos adjuntos de un correo electrónico como 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
fuente
0

Una buena manera de crear variables públicas / globales es tratar el formulario como un objeto de clase y declarar propiedades y usar Public Property Get [variable] para acceder a la propiedad / método. También es posible que deba hacer referencia o pasar una referencia al módulo de formulario instanciado. Obtendrá errores si llama métodos a formularios / informes que están cerrados.
Ejemplo: pasar Me.Form.Module.Parent en sub / function no dentro del formulario.

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

Entonces, en el otro módulo, podrá acceder 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

Si usa el enlace tardío como siempre, siempre verifico los valores nulos y los objetos que son nada antes de intentar realizar cualquier procesamiento.

CPU doble E
fuente
0

También puedes usar -

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

Su probado en la oficina 2010

IshaniNet
fuente