2009-06-10 26 views
14

私はこの問題を解決しようとしましたが、解決策は見つかりませんでした。私は通常のモジュールで定義されたUDTを持っていて、それをクラスモジュールのPublic Subでパラメータとして使用したかったのです。私は、コンパイルエラーを取得:クラスのモジュール(VB6)のpublic Subのパラメータとしてユーザー定義型(UDT)

Only public user defined types defined in public object modules can be used as parameters or return type for public procedures of class modules or as fields of public user defined types

私はその後、Privateとして宣言され、クラスで私のUDTを移動しよう。私は、このコンパイルエラーを取得:

Private Enum and user defined types cannot be used as parameters or return types for public procedures, public data members, or fields of public user defined types.

私はfinalyクラスでPublicとして宣言しようとすると、このコンパイルエラーを取得:

Cannot define a Public user-defined type within a private object module.

ように使用される公開UDTを持っているどのような方法がありますクラス内のpublicサブのパラメータ?ただ、Friendスコープとして、サブを定義

Public Class Sample 

    Public Strucutre UDT 
     Dim Value As Object 
    End Structure 

End Class 

答えて

9

So is there any way to have a public UDT used as a parameter in a public sub in a class?

クラシックVBコードに最も近いのは、UDTを複製して代わりに使用するクラスを作成することです。間違いなくそこには利点がありますが、APIにも同様に渡す必要がある場合には、あなたはホースしています。

もう1つのオプションは、タイプライブラリにUDTを定義することです。これを行うと、パブリックメソッドのパラメータとして使用できます。

+3

私は少し遅れていると思いますが、私は完全に公開UDTを私のExcel VBAアプリのPublic Sub(クラスの)です。 –

+1

私は後になっても、... @アンドレ・ネヴェス私は私もできることを確認します。しかし、UDTの定義は、私が見つけ出す限り、カプセル化することはできません。 –

+0

@Cool Blue、UDTの定義がカプセル化できないということはどういう意味ですか?クラスモジュール内のパブリック関数からコードモジュールで定義されたパブリックUDTを返すことができないので、皆さんが私を助けることができるなら、皆さんは「遅れて」いません。私はC#アプリケーションから呼び出す必要があり、Public関数でなければならないので、明確にするために、私はFriendとして関数を作ることができません。また、UDTをByRefパラメーターとしてクラス関数に渡すことはできません。 – AllSolutions

-3

UDTは次のように、パブリック・オブジェクトに宣言する必要があります。これはVB6クラスで私にとってうまくコンパイルされます。

Private Type testtype 
    x As String 
End Type 


Friend Sub testmethod(y As testtype) 

End Sub 

エラーメッセージから、あなたのクラスはプライベートであるようです。あなたのクラスを公開する、つまりActiveXのexeやDLLを作成して、クライアントがサブにアクセスできるようにしたい場合は、型とサブの両方をpublicにします。

+2

クラスpublic。これは、プロジェクトがActiveXのexeまたはDLLである場合にのみVB6で可能になります。質問者がクラスを公開することを実際には望んでいないかもしれません。 – MarkJ

16

+1

これは「正解」とマークされます。 –

+0

@MaikenRoskildeは本当にありません。 「友人」の解決法は一般的なケースでは機能しません。 UDTからクラスを作ることははるかに柔軟です:あなたはUDT型などのプロパティを持つことができます。 –

6

私の猫が私を去らせることができれば、ここでそれを行う方法があります。

をForm1に(その上に1つのコマンドボタン付き):Form2の中

Option Explicit 
' 
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dst As Long, ByVal src As Long, ByVal nBytes As Long) 
' 

Private Sub Command1_Click() 
' Okay, this is what won't work in VB6: 
'  Dim MyUdt1 As MyUdtType ' Declare a variable with a publicly defined UDT (no problem). 
'  Form2.Show    ' We could have created some object with a class. This was just easier for the demo. 
'   INSIDE OF FORM2: 
'    Public Sub MySub(MyUdt2 As MyUdtType) ' It won't even let you compile this. 
'     Msgbox MyUdt2.l 
'     MyUdt2.l = 5 
'    End Sub 
'  Form2.MySub MyUdt1        ' You'll never get this far. 
'  Unload Form2 
'  Msgbox MyUdt1.l 
' 
' The following is a way to get it done: 
' 
Dim MyUdt1 As MyUdtType   ' Declare a variable with a publicly defined UDT (no problem). 
Dim ReturnUdtPtr As Long  ' Declare a variable for a return pointer. 
MyUdt1.l = 3     ' Give the variable of our UDT some value. 
Form2.Show      ' Create our other object. 
' 
' Now we're ready to call our procedure in the object. 
' This is all we really wanted to do all along. 
' Notice that the VarPtr of the UDT is passed and not the actual UDT. 
' This allows us to circumvent the no passing of UDTs to objects. 
ReturnUdtPtr = Form2.MyFunction(VarPtr(MyUdt1)) 
' 
' If we don't want anything back, we could have just used a SUB procedure. 
' However, I wanted to give an example of how to go both directions. 
' All of this would be exactly the same even if we had started out in a module (BAS). 
CopyMemory VarPtr(MyUdt1), ReturnUdtPtr, Len(MyUdt1) 
' 
' We can now kill our other object (Unload Form2). 
' We probably shouldn't kill it until we've copied our UDT data 
' because the lifetime of our UDT will be technically ended when we do. 
Unload Form2     ' Kill the other object. We're done with it. 
MsgBox MyUdt1.l     ' Make sure we got the UDT data back. 
End Sub 

(不要コントロール)。 (これはクラスで作成されたオブジェクトと同じように簡単にできます):

Option Explicit 
' 
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dst As Long, ByVal src As Long, ByVal nBytes As Long) 
' 

Public Function MyFunction(ArgUdtPtr As Long) As Long 
' Ok, this is how we get it done. 
' There are a couple of things to notice right off the bat. 
' First, the POINTER to the UDT is passed (using VarPtr) rather than the actual UDT. 
' This way, we can circumvent the restriction of UDT not passed into objects. 
' Second, the following MyUdt2 is declared as STATIC. 
' This second point is important because the lifetime of MyUdt2 technically ends 
' when we return from this function if it is just DIMmed. 
' If we want to pass changes back to our caller, we will want to have a slightly longer lifetime. 
Static MyUdt2 As MyUdtType 
' Ok, we're here, so now we move the argument's UDT's data into our local UDT. 
CopyMemory VarPtr(MyUdt2), ArgUdtPtr, Len(MyUdt2) 
' Let's see if we got it. 
MsgBox MyUdt2.l 
' Now we might want to change it, and then pass back our changes. 
MyUdt2.l = 5 
' Once again, we pass back the pointer, because we can't get the actual UDT back. 
' This is where the MyUdt2 being declared as Static becomes important. 
MyFunction = VarPtr(MyUdt2) 
End Function 

最後に、これはモジュール(BAS)ファイルに格納されています。

Option Explicit 
' 
' This is just the UDT that is used for the example. 
Public Type MyUdtType 
    l As Long 
End Type 
' 
+1

+1は純粋な堅実さ;-)私はそれがうまくいくと信じますが、誰がこれを使用しますか? – Dabblernl

1

参照パラメータとしてUDTを渡すだけで正常に動作します。 :)

'method in the class 

Public Sub CreateFile(ByRef udt1 As UdtTest) 

End Sub 
+0

申し訳ありませんが、私の希望はこのものですが、それは単に正しくありません。 – Dabblernl

+0

実際これは私のために働いた:) – seFausto

1

私は同じエラーメッセージを持っていたし、アプリケーションをチェックした後、私はクラスのプロパティウィンドウで、「インスタンス化」設定に設定していることが分かっ「1 - プライベート」参照されたオブジェクトのために。私はそれを "5 - MultiUse"に変更し、同じエラーメッセージを受け取りました。その後、プロジェクト・モジュールのバージョンに戻って、参照オブジェクトを追加してプロジェクトをもう一度追加しました。これはデフォルトで「1 - プライベート」に設定されていました。他の作業をする前に "5 - MultiUse"に変更し、コンパイルする前にアップデートするプロジェクトを閉じました。私はプロジェクトを再オープンし、まだ "5 - MultiUse"に設定されていることを確認した後、プロジェクトをコンパイルし、エラーメッセージなしできれいにコンパイルしました。

プライベートオブジェクトを参照できないというエラーメッセージが表示されたとき、そのオブジェクトは実際にプライベートであった。私がプライベートではないと宣言し、プロジェクトモジュールがその新しい設定を受け入れると、それはきちんとコンパイルされました。

0

モジュールにUDF(公開型)を定義します。

Public Type TPVArticulo 
    Referencia As String 
    Descripcion As String 
    PVP As Double 
    Dto As Double 
End Type 

とクラスでFriendを使用し、モジュール0のFRM:VB.NETではなく、VB6のだし、あなたが作った

Friend Function GetArticulo() As TPVArticulo 
関連する問題