2016-03-23 7 views
11

はあなたがModule1と呼ばれるモジュールにこのコードを持って言う:同等のC#コードでVBAではスコープが壊れていますか?

Option Explicit 

Private Type TSomething 
    Foo As Integer 
    Bar As Integer 
End Type 

Public Something As TSomething 

あなたはSomethingフィールドpublicを行った場合、コードはもはやので一貫性のないアクセスの、コンパイルう - タイプをフィールド自体はフィールド自体よりもアクセスしにくい。どちらが理にかなっている。

ただしVBAであなたは Module2で、このコードを持つことができます:

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

そして、それを入力しているときは、インテリセンスを取得し、それがコンパイルし、それが実行され、それが42を出力します。

なぜですか? COMの観点からは、どのように機能しますか?言語仕様の一部ですか?

+0

は、モジュール2では、あなたは 'Module1.TSomething'型の変数を定義することができますし、Module1.Something''にそれを割り当てます? –

+0

@SimonForsbergコンパイルエラー(期待どおり) - "ユーザ定義型が定義されていません" ...言い換えれば、型は宣言には使用できません* ... –

+1

Javaがどのように機能するか、この質問はJavaに関するものではありませんが、とにかくです。それは私には意味がありますが、もう一度...私はJavaの男です。 –

答えて

3

私のコメントによると、VBAはPrivate Enumを公開するのと同じように、Private Typeを公開します。

VBAは、消費コンテキストでTypeInfoを使用できると想定していますが、これらの型または列挙型のインスタンスを宣言または作成することはできません。このC++ answer

は、部分的に有益である:

アクセス制御がに適用される

名のアクセス指定子は

を入力しています、それとは何の関係もありませんしかし、それはおそらくです標準モジュールのプライベートタイプを、のように、のような "PublicNotCreatable"クラスと考えると便利です。パブリックラッパーを提供する場合、そのタイプはホストモジュールの外部からアクセス可能です。

しかし、タイプがパブリッククラスモジュールにある場合、VBAは処理が異なります!

はここだ、あなたの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 
関連する問題