Як я можу оголосити глобальну змінну в VBA?


132

Я написав наступний код:

Function find_results_idle()

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

І я отримую повідомлення про помилку:

"недійсний атрибут у підменю або функції"

Ви знаєте, що я зробив не так?

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

Я намагався оголосити саму функцію як "Загальнодоступна, але це також не принесло користі.

Що мені потрібно зробити, щоб створити глобальну змінну?

Відповіді:


177

Вам потрібно оголосити змінні за межами функції:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1

Коли я намагаюся оголосити масив як загальнодоступний, він говорить: масиви та визначені користувачем типи даних не можуть бути оголошені загальнодоступними.
kapilddit

Над першим Function/ Sub, а не лише зовні: "Змінні рівня модуля можуть бути оголошені оператором Dim або Private у верхній частині модуля над першим визначенням процедури." (зі сфери застосування змінних у Visual Basic для додатків )
Миколай

119

Це питання про сферу застосування .

Якщо ви хочете, щоб змінні тривали протягом життя функції, використовуйте Dim(скорочуючи параметр Dimension ) всередині функції або 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

Глобальна змінна (як 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ключовим словом.

Якщо ви будуєте велику програму і відчуваєте необхідність використовувати глобальні змінні, я рекомендую створити окремий модуль саме для ваших глобальних змінних. Це допоможе вам відслідковувати їх в одному місці.


4
+1 Все ще корисно через 7 років. Але чи є якийсь додатковий нюанс щодо об'єктних змінних проти змінних даних? Я зіткнувся з проблемою, пов’язаною з визначенням змінних об'єктів, що підказало нове запитання. Дуже вдячний, якщо ви встигнете поглянути. stackoverflow.com/q/46058096/5457466
Egalth

2
Коротке пояснення декларації змінних у VBA.
PhillipOReilly

Я спробував усі інші пропозиції щодо "сфери застосування", і жодна не працювала. Єдине, що працювало - це новий Модуль спеціально для глобальних варіантів, і він працює!
Fandango68

34

Для використання глобальних змінних Вставте новий модуль з інтерфейсу проекту VBA та оголосіть змінні за допомогою Global

Global iRaw As Integer
Global iColumn As Integer

2
Яка різниця між декларуванням в Publicпорівнянні з Globalключовим словом?
Ремін


18

Питання справді стосується сфери, як це сказав інший хлопець.

Коротше, розглянемо цей "модуль":

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 .

Ви впевнені, що змінна Global може використовуватися в різних робочих книгах? Чи не працює для мене
Себ

Гарна думка! Я помітив, що не додав посилання на те, звідки я отримав цю інформацію ... Також я не знайшов її знову. Краще відредагуйте відповідь ...: / О, і дякую Себ.
FCastro

14

Якщо ця функція знаходиться в модулі / класі, ви можете просто записати їх поза функцією, так вона є Global Scope. 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

1

Створіть загальне ціле число в Загальній декларації.

Тоді у своїй функції ви можете щоразу збільшувати її значення. Див. Приклад (функція збереження вкладень електронної пошти як 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

Хороший спосіб створити загальнодоступні / глобальні змінні - це поводитись з Формою як об'єктом класу та оголошувати властивості та використовувати 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

Якщо ви використовуєте пізнє прив'язування, як я завжди перевіряю наявні значення та об'єкти, які є нічим, перш ніж намагатися здійснити будь-яку обробку.


0

Також ви можете використовувати -

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

Його випробували на офісі 2010 року

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.