Как объявить глобальную переменную в VBA?

Я написал следующий код:

Function find_results_idle()

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

И я получаю сообщение об ошибке:

"недопустимый атрибут в подпрограмме или функции"

Вы знаете, что я сделал не так?

Я попытался использовать Global вместо Public, но возникла та же проблема.

Я попытался объявить саму функцию как Public, но это тоже не помогло.

Что мне нужно сделать, чтобы создать глобальную переменную?


person Nimrod    schedule 27.04.2010    source источник


Ответы (8)


Вам нужно объявить переменные вне функции:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1
person SLaks    schedule 27.04.2010
comment
Когда я пытаюсь объявить массив общедоступным, он говорит: массив и пользовательские типы данных не могут быть объявлены общедоступными. - person kapilddit; 13.11.2019
comment
Над первым _1 _ / _ 2_, а не только снаружи: переменные уровня модуля могут быть объявлены с помощью оператора Dim или Private в верхней части модуля над определением первой процедуры. (из Объем переменные в Visual Basic для приложений) - person Nickolay; 29.01.2020

Это вопрос о области действия.

Если вы хотите, чтобы переменные действовали только в течение всего времени существования функции, используйте Dim (сокращение от Dimension) внутри функции или подпрограммы для объявления переменных:

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

глобальная переменная (как указал SLaks) объявляется вне функции с использованием ключевого слова Public. Эта переменная будет доступна в течение всего срока службы вашего запущенного приложения. В случае Excel это означает, что переменные будут доступны, пока открыта конкретная книга Excel.

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.

Вы также можете иметь переменные, которые доступны только в определенном модуле (или классе), объявив их с помощью ключевого слова Private.

Если вы создаете большое приложение и чувствуете необходимость использовать глобальные переменные, я бы рекомендовал создать отдельный модуль только для ваших глобальных переменных. Это должно помочь вам отслеживать их в одном месте.

person Ben McCormack    schedule 28.04.2010
comment
+1 Все еще полезен 7 лет спустя. Но есть ли какие-то дополнительные нюансы относительно объектных переменных по сравнению с переменными данных? Я столкнулся с проблемой, связанной с определением переменных объекта, из-за которой возник новый вопрос. Буду признателен, если у вас будет время взглянуть. stackoverflow.com/q/46058096/5457466 - person Egalth; 05.09.2017
comment
Я попробовал все другие предложения по поводу объема, и ни один из них не сработал. Единственное, что сработало, - это новый модуль специально для глобальных варов, и он работает! - person Fandango68; 27.09.2019

Чтобы использовать глобальные переменные, вставьте новый модуль из пользовательского интерфейса проекта VBA и объявите переменные с помощью Global

Global iRaw As Integer
Global iColumn As Integer
person YOU    schedule 27.04.2010
comment
В чем разница между объявлением с Public и Global ключевым словом? - person Przemyslaw Remin; 22.01.2019

Вопрос действительно в размахе, как выразился другой парень.

Вкратце, рассмотрим этот «модуль»:

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

Вы можете ознакомиться с этим справочником MSDN для получения дополнительной информации об объявлении переменной и этом другом заголовке Вопрос о переполнении стека для получения дополнительной информации о том, как переменные выходят за пределы области видимости.

Еще две быстрые вещи:

  1. Будьте организованы при использовании переменных уровня книги, чтобы не запутать ваш код. Отдайте предпочтение функциям (с правильными типами данных) или передаче аргументов ByRef.
  2. Если вы хотите, чтобы переменная сохраняла свое значение между вызовами, вы можете использовать оператор Static.
person FCastro    schedule 08.02.2017
comment
Вы уверены, что глобальную переменную можно использовать в разных книгах? У меня не работает - person Seb; 16.03.2017
comment
Хорошая точка зрения! Я заметил, что не добавил ссылку на то, откуда я получил эту информацию ... Я не нашел ее снова. Лучше отредактировать ответ ...: / Да и спасибо, Себ. - person FCastro; 17.03.2017

Если эта функция находится в модуле / классе, вы можете просто написать их вне функции, так что у нее будет Global Scope. Глобальная область действия означает, что переменная может быть доступна другой функции в том же модуле / классе (если вы используете dim как оператор объявления, используйте public, если хотите, чтобы переменные были доступны для всех функций во всех модулях) :

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
person Zai    schedule 28.04.2010

Также вы можете использовать -

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

Протестировано в Office 2010

person IshaniNet    schedule 18.09.2018

Создайте публичное целое число в Общей декларации.

Затем в своей функции вы можете каждый раз увеличивать ее значение. См. Пример (функция сохранения вложений электронного письма в формате 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
person Dan Bidner    schedule 13.04.2016

Хороший способ создания общедоступных / глобальных переменных - рассматривать форму как объект класса, объявлять свойства и использовать Public Property Get [переменная] для доступа к свойству / методу. Также вам может потребоваться указать или передать ссылку на созданный модуль формы. Вы получите ошибки, если вызовете методы для закрытых форм / отчетов.
Пример: передайте Me.Form.Module.Parent в подпункт / функцию не внутри формы.

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

Таким образом, в другом модуле вы сможете получить доступ:

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

Если вы используете Late Binding, как я, всегда проверяю значения Null и объекты, которые Nothing, прежде чем пытаться выполнить какую-либо обработку.

person Double E CPU    schedule 16.08.2018