VBA'da global bir değişkeni nasıl bildiririm?


132

Aşağıdaki kodu yazdım:

Function find_results_idle()

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

Ve hata mesajını alıyorum:

"Alt veya İşlevde geçersiz öznitelik"

Neyi yanlış yaptığımı biliyor musun?

Onun Globalyerine kullanmayı denedim Publicama aynı sorunu yaşadım .

İşlevin kendisini `` Herkese Açık '' olarak ilan etmeye çalıştım ama bu da işe yaramadı.

Global değişkeni oluşturmak için ne yapmam gerekiyor?

Yanıtlar:


177

Fonksiyonun dışındaki değişkenleri tanımlamanız gerekir:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1

Bir diziyi genel olarak bildirmeye çalıştığımda şunu söylüyor: dizi ve kullanıcı tanımlı veri türleri genel olarak bildirilemez.
kapilddit

Üstü ilk Function/ Sub, sadece dış: "Modül düzeyi değişkeni bir Dim veya yukarıdaki ilk yordamı tanım modülünün üst Özel deyimi ile bildirilebilir." ( Visual Basic for Applications'taki değişkenlerin kapsamından )
Nickolay

119

Bu, kapsamla ilgili bir sorudur .

Değişkenlerin yalnızca işlevin yaşam süresine dayanmasını istiyorsanız, değişkenleri bildirmek için işlev veya alt işlevin içinde Dim( Dimension için kısa ) kullanın :

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

Bir küresel değişkeni (SLaks belirttiği gibi) kullanılarak fonksiyonu dışında ilan edilir Publicanahtar kelimeyi. Bu değişken, çalışan uygulamanızın ömrü boyunca kullanılabilir olacaktır. Excel söz konusu olduğunda bu, değişkenlerin söz konusu Excel çalışma kitabı açık olduğu sürece kullanılabileceği anlamına gelir.

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.

Ayrıca, yalnızca belirli bir modül (veya sınıf) içinde erişilebilen değişkenleri Privateanahtar sözcükle bildirerek sahip olabilirsiniz .

Büyük bir uygulama oluşturuyorsanız ve global değişkenleri kullanma ihtiyacı hissediyorsanız, sadece global değişkenleriniz için ayrı bir modül oluşturmanızı tavsiye ederim. Bu, onları tek bir yerden takip etmenize yardımcı olacaktır.


4
+1 7 yıl sonra hala yararlı. Ancak veri değişkenlerine karşı nesne değişkenleriyle ilgili bazı ek nüanslar var mı? Nesne değişkenlerinin kapsamını belirleme ile ilgili yeni bir soruya neden olan bir sorunla karşılaştım. Bakmak için zamanınız olursa çok sevinirim. stackoverflow.com/q/46058096/5457466
Egalth

2
VBA'da değişken bildiriminin kısa ve öz açıklaması.
PhillipOReilly

"Kapsam" ile ilgili diğer tüm önerileri denedim ve hiçbiri işe yaramadı. İşe yarayan tek şey, özellikle küresel değişkenler için yeni bir Modüldü ve işe yarıyor!
Fandango68


18

Diğer adamın söylediği gibi soru gerçekten kapsamla ilgili.

Kısacası, bu "modülü" düşünün:

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

Değişken bildirimi ve bu diğer Yığın Taşma Sorusu hakkında daha fazla bilgi için bu MSDN referansına göz atabilirsiniz. değişkenlerin kapsam dışına nasıl çıktığı hakkında daha fazla bilgi için göz atabilirsiniz.

Diğer iki hızlı şey:

  1. Çalışma kitabı düzeyindeki değişkenleri kullanırken organize olun, böylece kodunuz kafa karıştırmaz. Tercih İşlevleri (uygun veri türleriyle) veya ByRef bağımsız değişkenlerini iletme .
  2. Bir değişkenin, çağrılar arasında değerini korumasını istiyorsanız, Statik ifadesini kullanabilirsiniz .

Global bir değişkenin farklı çalışma kitaplarında kullanılabileceğinden emin misiniz? Benim için çalışmıyor
Seb

İyi bir nokta! Bu bilgiyi nereden aldığım için bir referans eklemediğimi fark ettim ... Ne de tekrar bulamadım. Cevabı düzenlemek daha iyi ...: / Oh, ve teşekkürler Seb.
FCastro

14

Bu işlev bir modül / sınıf içindeyse, bunları işlevin dışında yazabilirsiniz, öyle de vardır Global Scope. Global Kapsam, değişkene aynı modül / sınıftaki başka bir işlev tarafından erişilebileceği anlamına gelir ( dimbildirim ifadesi olarak kullanırsanız public, değişkenlere tüm modüllerdeki tüm işlevler tarafından erişilebilmesini istiyorsanız kullanın ):

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

Genel Beyanda bir genel tam sayı oluşturun.

Daha sonra işlevinizde her seferinde değerini artırabilirsiniz. Örneğe bakın (bir e-postanın eklerini CSV olarak kaydetme işlevi).

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

Genel / Global değişkenler oluşturmanın iyi bir yolu, Formu bir sınıf nesnesi gibi ele alıp özellikleri bildirmek ve özelliğe / yönteme erişmek için Genel Özellik Get [değişken] 'i kullanmaktır. Ayrıca, somutlaştırılmış Form modülüne başvurmanız veya bir Başvuruyu iletmeniz gerekebilir. Kapatılan formlara / raporlara yöntemler çağırırsanız hatalar alırsınız.
Örnek: Me.Form.Module.Parent'i form içinde olmayan alt / işleve geçirin.

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

Yani diğer modülde şunlara erişebileceksiniz:

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

Benim gibi Geç Bağlamayı kullanırsanız, herhangi bir işlem yapmaya başlamadan önce her zaman Boş değerleri ve Hiçbir Şey olmayan nesneleri kontrol edin.


0

Ayrıca kullanabilirsiniz -

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

Ofis 2010'da test edildi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.