Làm cách nào để khai báo một biến toàn cục trong VBA?


132

Tôi đã viết đoạn mã sau:

Function find_results_idle()

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

Và tôi nhận được thông báo lỗi:

"thuộc tính không hợp lệ trong Sub hoặc Function"

Bạn có biết những gì tôi đã làm sai?

Tôi đã cố gắng sử dụng Globalthay vì Public, nhưng gặp vấn đề tương tự.

Tôi đã cố gắng tự khai báo hàm là `Công khai, nhưng điều đó cũng không tốt.

Tôi cần làm gì để tạo biến toàn cục?

Câu trả lời:


177

Bạn cần khai báo các biến ngoài hàm:

Public iRaw As Integer
Public iColumn As Integer

Function find_results_idle()
    iRaw = 1
    iColumn = 1

Khi tôi cố gắng khai báo một mảng là công khai, nó nói: các kiểu dữ liệu do người dùng và mảng xác định không thể được khai báo là công khai.
kapilddit

Phía trên đầu tiên Function/ Sub, không chỉ bên ngoài: "Các biến cấp độ mô-đun có thể được khai báo bằng câu lệnh Dim hoặc Private ở đầu mô-đun phía trên định nghĩa thủ tục đầu tiên." (từ Phạm vi của các biến trong Visual Basic cho Ứng dụng )
Nickolay

119

Đây là một câu hỏi về phạm vi .

Nếu bạn chỉ muốn các biến kéo dài trọn đời của hàm, hãy sử dụng Dim(viết tắt của Dimension ) bên trong hàm hoặc phụ để khai báo các biế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

Một biến toàn cục (như SLaks đã chỉ ra) được khai báo bên ngoài hàm bằng Publictừ khóa. Biến này sẽ có sẵn trong suốt vòng đời của ứng dụng đang chạy của bạn. Trong trường hợp của Excel, điều này có nghĩa là các biến sẽ có sẵn miễn là sổ làm việc Excel cụ thể đó được mở.

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.

Bạn cũng có thể có các biến chỉ có thể truy cập được trong một mô-đun (hoặc lớp) cụ thể bằng cách khai báo chúng bằng Privatetừ khóa.

Nếu bạn đang xây dựng một ứng dụng lớn và cảm thấy cần phải sử dụng các biến toàn cục, tôi khuyên bạn nên tạo một mô-đun riêng cho các biến toàn cục của mình. Điều này sẽ giúp bạn theo dõi chúng ở một nơi.


4
+1 Vẫn hữu ích 7 năm sau. Nhưng có một số sắc thái bổ sung liên quan đến các biến đối tượng so với các biến dữ liệu? Tôi gặp phải một vấn đề liên quan đến các biến đối tượng phạm vi dẫn đến một câu hỏi mới. Nhiều đánh giá cao nếu bạn sẽ có thời gian để có một cái nhìn. stackoverflow.com/q/46058096/5457466
Egalth

2
Giải thích ngắn gọn về khai báo biến trong VBA.
PhillipOReilly

Tôi đã thử tất cả các đề xuất khác về "phạm vi" và không có kết quả nào. Điều duy nhất hoạt động là một Mô-đun mới dành riêng cho các bình toàn cầu và nó hoạt động!
Fandango68


18

Câu hỏi thực sự là về phạm vi, như những người khác đặt nó.

Tóm lại, hãy xem xét "mô-đun" này:

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

Bạn có thể kiểm tra tham chiếu MSDN này để biết thêm về khai báo biến và Câu hỏi tràn ngăn xếp khác này để biết thêm về cách các biến đi ra khỏi phạm vi.

Hai điều nhanh chóng khác:

  1. Được tổ chức khi sử dụng các biến mức của sổ làm việc, để mã của bạn không bị lẫn lộn. Hàm ưa thích (với các kiểu dữ liệu phù hợp) hoặc truyền đối số ByRef .
  2. Nếu bạn muốn một biến duy trì giá trị của nó giữa các cuộc gọi, bạn có thể sử dụng câu lệnh Tĩnh .

Bạn có chắc chắn về một biến toàn cầu có thể được sử dụng trong các sổ làm việc khác nhau không? Không làm việc cho tôi
Seb

Điểm tốt! Tôi nhận thấy tôi đã không thêm một tài liệu tham khảo cho nơi tôi có được thông tin đó ... Tôi cũng không tìm thấy nó nữa. Tốt hơn là chỉnh sửa câu trả lời ...: / Oh, và cảm ơn Seb.
FCastro

14

Nếu hàm này nằm trong một mô-đun / lớp, bạn có thể chỉ cần viết chúng bên ngoài hàm, vì vậy nó có Global Scope. Phạm vi toàn cầu có nghĩa là biến có thể được truy cập bởi một chức năng khác trong cùng mô-đun / lớp (nếu bạn sử dụng dimlàm câu lệnh khai báo, hãy sử dụng publicnếu bạn muốn các biến có thể được truy cập bởi tất cả các chức năng trong tất cả các mô-đun):

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

Tạo một số nguyên công khai trong Tuyên bố chung.

Sau đó, trong chức năng của bạn, bạn có thể tăng giá trị của nó mỗi lần. Xem ví dụ (chức năng lưu tệp đính kèm của email dưới dạng 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

Một cách tốt để tạo các biến Công khai / Toàn cầu là coi Biểu mẫu giống như một đối tượng lớp và khai báo các thuộc tính và sử dụng Thuộc tính Công cộng Nhận [biến] để truy cập thuộc tính / phương thức. Ngoài ra, bạn có thể cần tham chiếu hoặc chuyển Tham chiếu đến mô-đun Biểu mẫu được khởi tạo. Bạn sẽ gặp lỗi nếu bạn gọi các phương thức tới các biểu mẫu / báo cáo đã bị đóng.
Ví dụ: truyền Me.Form.Module.Parent vào sub / function không bên trong biểu mẫu.

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

Vì vậy, trong các mô-đun khác, bạn sẽ có thể truy cập:

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

Nếu bạn sử dụng Binding muộn như tôi luôn kiểm tra các giá trị Null và các đối tượng không có gì trước khi thử thực hiện bất kỳ xử lý nào.


0

Ngoài ra bạn có thể sử dụng -

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

Nó đã được thử nghiệm trên văn phòng 2010

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.