Definido usuario Forma (UDT) como parámetro en Sub pública en el módulo de clase (VB6)

StackOverflow https://stackoverflow.com/questions/975982

  •  13-09-2019
  •  | 
  •  

Pregunta

He tratado de resolver este problema, pero no puedo encontrar ninguna solución. Tengo un UDT se define en un módulo normal, y quería usarlo como parámetro en una Public Sub en un módulo de clase. Entonces consigo un error de compilación:

  

único usuario público definido tipos definidos en módulos de objeto públicos se pueden utilizar como parámetros o tipo de retorno para los procedimientos públicos de módulos de clase o como campos de tipos definidos por el usuario público

entonces trato de mover la UDT en la clase, declarada como Private. Me sale este error de compilación:

  

Enum privado y los tipos definidos por el usuario no se pueden utilizar como parámetros o tipos de retorno para los procedimientos públicos, miembros de datos públicos, o los campos de tipos definidos por el usuario público.

Me finaly intento de declarar como Public en la clase, y sale este error de compilación:

  

No se puede definir un tipo definido por el usuario público dentro de un módulo de objeto privado.

Entonces, ¿hay alguna manera de tener un UDT pública que se utiliza como parámetro en una sub pública en una clase?

¿Fue útil?

Solución

  

Entonces, ¿hay alguna manera de tener un público   UDT utiliza como parámetro en una pública   sub en una clase?

En una palabra, no. Lo más cerca que se puede llegar con un solo código de VB clásico sería la creación de una clase que se replica la UDT y utilizar en su lugar. Definitivamente, hay ventajas allí, pero usted es una manguera si tiene que pasar a que, por ejemplo, una API también.

Otra opción es definir la UDT en una biblioteca de tipos. Si lo hace, puede ser utilizado como un parámetro para un método público.

Otros consejos

Just definir el sub como alcance Friend. Esto compila bien para mí en una clase de VB6.

Private Type testtype
  x As String
End Type


Friend Sub testmethod(y As testtype)

End Sub

A partir de los mensajes de error que aparece su clase es privado. Si desea que su clase sea pública - es decir, usted está haciendo un exe ActiveX o DLL y desea que los clientes puedan acceder a la sub -. A continuación, sólo hacer que tanto el tipo como el sub públicos:

Ok, aquí está cómo hacerlo, si puedo conseguir mi gato que me dejara sola, es decir.

En Form1 (con el botón de un solo comando en él):

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

En Form2 (no hay controles necesarios). (Esto podría haber sido tan fácilmente un objeto creado con una clase.):

    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

Y por último, esto va en un archivo de módulo (BAS).

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

Sólo tiene que pasar la UDT como parámetro de referencia y funcionará. :)

'method in the class

Public Sub CreateFile(ByRef udt1 As UdtTest)

End Sub

Yo tenía el mismo mensaje de error y tras comprobar la solicitud, he encontrado que en la ventana de propiedades de la clase, el ajuste "Instancias" se establece en "1 - privada" para el objeto de referencia. He cambiado a "5 - bien multiuso" y dieron el mismo mensaje de error. Entonces fui a una versión del módulo de proyecto antes de cuando he añadido que hacía referencia a objeto y añade de nuevo el proyecto - que por defecto en "1 - privada". He cambiado a "5 - bien multiuso" antes de hacer cualquier otra cosa y cerré el proyecto a para que se actualice antes de compilar. Me volvió a abrir el proyecto, comprobé que aún estaba ajustado a. "5 - bien multiuso", a continuación, compila el proyecto y compilado limpiamente sin el mensaje de error

Cuando el mensaje de error que decía que no permitió que haga referencia a un objeto privado, el objeto era muy privado. Una vez que declaré que no es privado, y el módulo de proyecto aceptado que la nueva configuración, que compila limpiamente.

Definición de UDF (tipo de público) en un módulo:

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

y utilizar Friend en clase, módulo de frm:

Friend Function GetArticulo() As TPVArticulo

La UDT debe ser declarado en un objeto público, como:

Public Class Sample

    Public Strucutre UDT
       Dim Value As Object
    End Structure

End Class
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top