ユーザ定義型(UDT)クラスモジュール内のパブリックサブにおけるパラメータ(VB6)として
-
13-09-2019 - |
質問
私はこの問題を解決しようとしたが、任意の解決策を見つけることができません。私は、通常のモジュールで定義されているUDTを持ち、そしてクラスモジュールでPublic Sub
にパラメータとしてそれを使用していました。私は、コンパイルエラーを取得します:
パブリックオブジェクトモジュールで定義されたのみパブリックユーザ定義型は、パラメータとして、またはクラスモジュールのパブリック・プロシージャまたはパブリックユーザ定義型のフィールドとして型を返すことができる
私は、クラスで私のUDTを移動しようと、Private
として宣言。私は、このコンパイルエラーを取得します:
プライベート列挙し、ユーザ定義型がパラメータとして使用されるか、または公共の手順、パブリックデータメンバー、またはパブリックユーザ定義型のフィールドの型を返すことができない。
私はfinalyクラスのPublic
として宣言しようとすると、このコンパイルエラーを取得します:
プライベートオブジェクトモジュール内のパブリック・ユーザー定義型を定義することはできません。
だから、クラスのパブリックサブでパラメータとして使用されるパブリックUDTを持ってする方法はありますか?
解決
だから、国民を持っているどのような方法があります 公共のパラメータとして使用さUDT クラスのサブ?
言葉で、ありません。あなただけのクラシックVBのコードで来ることができる最も近いUDTを複製するクラスを作成し、代わりにそれを使用することであろう。そこ利点が確かにありますが、あなたにも、たとえば、にAPIをそれに合格する必要がある場合は、まずいしています。
別のオプションは、タイプライブラリにUDTを定義することです。あなたがそれを行う場合、それは公共のメソッドのパラメータとして使用することができます。
他のヒント
ただ、Friend
スコープとしてサブを定義します。これは、VB6のクラスで私のために罰金コンパイルします。
Private Type testtype
x As String
End Type
Friend Sub testmethod(y As testtype)
End Sub
あなたのエラーメッセージから、あなたのクラスがプライベートで表示されます。あなたのクラスは、公開になりたいならば - あなたがActiveX EXEやDLLを作っている、あなたは、クライアントがサブにアクセスできるようにする、すなわち - 。その後、ちょうどタイプとサブ公開の両方を作る
[OK]を、ここで私は一人で私を残して私の猫を得ることができる場合、それを行う方法だ、つまります。
をForm1に(その上に1つのコマンドボタンを持つ):
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
フォーム2で(なしのコントロールは必要ありません)。 (これは、同じように簡単にクラスを使用して作成したオブジェクトされている可能性が。):
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
'
あくまでも参考パラメータとしてUDTをパスし、それが動作します。 :)
'method in the class
Public Sub CreateFile(ByRef udt1 As UdtTest)
End Sub
私は、同じエラーメッセージを持っていたし、アプリケーションをチェックした後、私はクラスのプロパティウィンドウで、「インスタンス化」設定に設定していることが分かっ「1 - プライベート」参照されたオブジェクトのために。私はそれを変更し、「5 - 多目的」と同じエラーメッセージが表示されました。私は、以前私が参照されたオブジェクトを追加したときに戻って、プロジェクトのモジュールのバージョンに行き、プロジェクト再びこれを追加しました - それがデフォルトに「1 - プライベート」。何かを行う前に - 「多目的5」と、それはコンパイルする前に更新するためにプロジェクトを閉じて、私はそれを変更しました。 I再度開いているプロジェクト、それはまだ「5 - 多目的」に設定した検証。その後、プロジェクトをコンパイルし、それがエラーメッセージを表示せずにきれいにコンパイルされ、
エラーメッセージは、それがプライベートオブジェクトを参照することができませんでしたと言っていた場合には、、オブジェクトが本当にプライベートました。私はそれがプライベートではないと宣言、およびプロジェクトのモジュールは、新しい設定が、それはきれいにコンパイルすることを受け入れ一度ます。
モジュールにUDF(パブリックタイプ)を定義
Public Type TPVArticulo
Referencia As String
Descripcion As String
PVP As Double
Dto As Double
End Type
と、クラスにFRM OモジュールをFriend
を使用する:
Friend Function GetArticulo() As TPVArticulo
UDTは次のように、パブリック・オブジェクトで宣言する必要があります:
Public Class Sample
Public Strucutre UDT
Dim Value As Object
End Structure
End Class