Pergunta

Eu tentei resolver este problema, mas não consegue encontrar qualquer solução. Eu tenho um UDT definido em um módulo normal, e queria usá-lo como parâmetro em um Public Sub em um módulo de classe. Eu, então, obter um erro de compilação:

tipos definidos único usuário pública definidos no módulos de objectos pública podem ser usados ??como parâmetros ou tipo de retorno para procedimentos públicos de módulos de classe ou como campos de tipos definidos pelo usuário public

Eu, então, tentar mover minha UDT na classe, declarada como Private. Eu recebo este erro de compilação:

Privada Enum e tipos definidos pelo usuário não pode ser utilizada como parâmetros ou tipos de retorno para procedimentos públicos, membros de dados públicos, ou campos de tipos definidos pelo usuário público.

Eu finalmente tentar declará-lo como Public na classe, e obter este erro de compilação:

Não é possível definir um tipo definido pelo usuário Pública dentro de um módulo objeto particular.

Então, há alguma maneira de ter um UDT pública usado como um parâmetro em um sub público de uma classe?

Foi útil?

Solução

Então, há alguma maneira de ter um público UDT usado como um parâmetro em uma pública sub em uma classe?

Em uma palavra, não. O mais próximo que você pode vir com apenas um código VB clássico seria a criação de uma classe que replica a UDT e utilizá-lo. Há definitivamente vantagens lá, mas você é metralhado se você precisa passar isso para, digamos, uma API bem.

Outra opção é definir o UDT em um typelib. Se você fizer isso, ele pode ser usado como um parâmetro para um método público.

Outras dicas

Apenas definir o sub como escopo Friend. Isso compila bem para mim em uma classe VB6.

Private Type testtype
  x As String
End Type


Friend Sub testmethod(y As testtype)

End Sub

De suas mensagens de erro que aparece sua classe é privado. Se você quer sua classe para ser público - ou seja, você está fazendo um exe ActiveX ou DLL e você quiser que os clientes para ser capaz de acessar o sub - então apenas fazer o tipo e o sub Pública

.

Ok, aqui está como fazê-lo, se eu conseguir o meu gato para me deixar em paz, isso é.

Em Form1 (com um botão de comando sobre ele):

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

Em form2 (nenhum controle necessário). (Isto poderia ter sido facilmente um objeto criado com uma classe.):

    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

E, finalmente, isso vai em um módulo (BAS) arquivo.

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

Basta passar o URL como parâmetro de referência e ele vai trabalhar. :)

'method in the class

Public Sub CreateFile(ByRef udt1 As UdtTest)

End Sub

Eu tive a mesma mensagem de erro e depois de verificar a aplicação, descobri que na janela de propriedade para a classe, a definição "Instancing" foi definido como "1 - Private" para o objeto referenciado. Eu mudei para "5 - MultiUse" e tem a mesma mensagem de erro. Eu, então, voltou para uma versão do módulo de projeto antes de quando eu acrescentou que objeto referenciado e acrescentou-lo novamente o projeto - é padrão para "1 - Private". Eu mudei para "5 - MultiUse" antes de fazer qualquer outra coisa e fechou o projeto para para-lo para atualizar antes de compilar. Eu re-abriu o projeto, verificou-se ainda foi definido para. "5 - MultiUse", em seguida, compilado o projeto e compilada limpa sem a mensagem de erro

Quando a mensagem de erro foi dizendo que não permitiu fazer referência a um objeto particular, o objeto era realmente privado. Uma vez que eu declarou que não privado, eo módulo de projeto aceita que a nova configuração, é compilado de forma limpa.

Definir UDF (tipo de público) em um módulo:

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

e uso Friend na classe, módulo o FRM:

Friend Function GetArticulo() As TPVArticulo

A UDT deve ser declarado em um objeto Público, como:

Public Class Sample

    Public Strucutre UDT
       Dim Value As Object
    End Structure

End Class
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top