2016-03-23 3 views
11

Скажет, у вас есть этот код в модуле под названием Module1:Обнаруживается в VBA?

Option Explicit 

Private Type TSomething 
    Foo As Integer 
    Bar As Integer 
End Type 

Public Something As TSomething 

в эквиваленте C# код, если вы сделали Something поля public, код больше не будет компилировать, из-за противоречивые доступностями - в типа поля менее доступным, чем само поле. Это имеет смысл.

Однако в VBA вы могли бы иметь этот код в Module2:

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

И вы получите IntelliSense, печатая его, и он собирает, и он работает, и он выводит 42.

Почему? Как это работает, с точки зрения COM? Является ли это частью спецификации языка?

+0

В module2, вы можете определить переменную типа 'Module1.TSomething' и назначить, что' Module1.Something' ? –

+0

@SimonForsberg Ошибка компиляции (как и ожидалось) - «Определенный пользователем тип не определен» ... другими словами, тип виден * для использования *, но не * для деклараций * ... –

+1

Звучит exaclty, как работает Java, не то, что этот вопрос касается Java, но в любом случае. Это имеет смысл для меня, но опять же ... Я парень Java. –

ответ

3

Согласно моему комментарию, VBA предоставляет закрытый тип, так же как он предоставляет частное перечисление.

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

Это C++ answer частично информативны:

Контроль доступа применяется к имен

Спецификатор доступа для имени, не имеет ничего общего с его типа

Но это, возможно, полезно придумать частный тип в стандартном модуле, как-то как класс «PublicNotCreatable». Если вы предоставляете общедоступную оболочку, тип доступен вне хост-модуля.

Но VBA обрабатывает вещи по-разному, когда Type находится в модуле открытого класса!

Вот ваш Module1 расширен:

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 расширен:

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 
Смежные вопросы