2016-03-23 55 views
11

Giả sử bạn có mã này trong một module gọi là Module1:Phạm vi có bị hỏng trong VBA không?

Option Explicit 

Private Type TSomething 
    Foo As Integer 
    Bar As Integer 
End Type 

Public Something As TSomething 

Trong tương đương C# mã nếu bạn thực hiện Something lĩnh vực public, mã sẽ không còn biên dịch, vì không phù hợp khả năng tiếp cận - loại của trường ít truy cập hơn chính trường đó. Điều đó có ý nghĩa.

Tuy nhiên trong VBA bạn có thể có mã này trong Module2:

Sub DoSomething() 
    Module1.Something.Bar = 42 
    Debug.Print Module1.Something.Bar 
End Sub 

Và bạn nhận được IntelliSense trong khi gõ nó, và nó biên dịch, và nó chạy, và nó kết quả đầu ra 42.

Tại sao? Làm thế nào nó thậm chí làm việc, từ một quan điểm COM? Nó là một phần của thông số ngôn ngữ?

+0

Trong module2, bạn có thể xác định một biến kiểu 'Module1.TSomething' và gán cho 'Module1.Something' ? –

+0

@SimonForsberg Lỗi biên dịch (như mong đợi) - "Loại do người dùng định nghĩa không được xác định" ... nói cách khác, loại có thể nhìn thấy * để sử dụng *, nhưng không * để khai báo * ... –

+1

Âm thanh exaclty cách Java hoạt động, không phải là câu hỏi này là về Java, nhưng dù sao đi nữa. Nó có ý nghĩa với tôi, nhưng sau đó một lần nữa ... Tôi là một anh chàng Java. –

Trả lời

3

Theo nhận xét của tôi, VBA cho thấy một Loại riêng tư, giống như nó cho thấy một Enum riêng.

VBA giả định rằng bạn có thể sử dụng TypeInfo trong ngữ cảnh tiêu thụ, nhưng nó sẽ không cho phép bạn khai báo hoặc tạo các thể hiện của các loại hoặc enums đó.

C++ answer Đây là một phần thông tin:

Access Control được áp dụng cho tên

Từ khoá truy cập cho tên không có gì để làm với nó gõ

Nhưng nó có lẽ hữu ích khi nghĩ về Loại tư nhân trong mô-đun chuẩn, dưới dạng một cái gì đó như một lớp "PublicNotCreatable". Nếu bạn cung cấp trình bao bọc công khai, thì loại có thể truy cập được bên ngoài mô-đun máy chủ.

Nhưng VBA xử lý mọi thứ khác nhau khi Loại nằm trong Mô-đun lớp công khai!

Dưới đây là bạn Module1 mở rộng:

Option Explicit 

Private Type TSomething 
    Foo As Integer 
    Bar As Integer 
End Type 

Public Type TOtherThing 
    Foo As Integer 
    Bar As Integer 
End Type 

Public Type TWrapperThing 
    Something As TSomething 
End Type 

Public Something As TSomething 
Public Otherthing As TOtherThing 
Public Wrapperthing As TWrapperThing 

Public Function GetSomething() As TSomething 
    GetSomething.Foo = 1 
End Function 

Public Function GetOtherthing() As TOtherThing 
    GetOtherthing.Foo = 1 
End Function 

Module2 mở rộng:

Option Explicit 

Sub DoThings() 

'Compile Error: User-defined type not defined 
    'Dim oSomething As TSomething 
    Dim vSomething As Variant 

    Dim oOtherthing As Module1.TOtherThing 
    Dim vOtherthing As Variant 
    Dim oWrapperthing As Module1.TWrapperThing 

    Module1.Something.Foo = 42 
    Module1.Otherthing.Foo = 42 
    Module1.Wrapperthing.Something.Foo = 42 

    'Compile Error: Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions 
    'vSomething = Module1.Something 
    'vOtherthing = Module1.Otherthing 

    oOtherthing = Module1.Otherthing 
    oOtherthing.Foo = 43 

    'Is 43 > 42? 
    Debug.Assert oOtherthing.Foo > Module1.Otherthing.Foo 

'Compile Errors: "GetSomething" User-defined type not defined 
    'Module1.GetSomething.Foo = 42 
    'Module1.GetSomething().Foo = 42 

    Module1.GetOtherthing.Foo = 42 
    Module1.GetOtherthing().Foo = 42 

End Sub 
Các vấn đề liên quan