用户定义类型(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,你希望客户能够访问子 - 那只是让这两个类型和副公开
好吧,这里是如何做到这一点,如果我能得到我的猫留下我一个人,那就是。
在Form1中(与在其上一个命令按钮):
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 - MultiUse的”,并得到了相同的错误消息。我后来当我补充说,引用对象并再次添加它的项目之前,又回到一个版本的项目模块的 - 它默认为“1 - 私人”。我改成了“5 - MultiUse的”做任何事情之前,并关闭了项目,它在编译之前更新。我重新打开的项目,验证它仍然设置为“5 - 的MultiUse”,然后被编译项目并将其没有错误消息干净地编译
在该错误信息是说,它不容许引用私有对象,该对象确实是私有的。有一次,我宣布它不是私人的,而项目模块接受新的设置,它完全编译好的。
的模块中定义的UDF(公共型):
Public Type TPVArticulo
Referencia As String
Descripcion As String
PVP As Double
Dto As Double
End Type
和在类中使用Friend
,模块öFRM:
Friend Function GetArticulo() As TPVArticulo
在UDT必须在公共对象进行声明,如:
Public Class Sample
Public Strucutre UDT
Dim Value As Object
End Structure
End Class