Type défini par l'utilisateur (UDT) comme paramètre Public Sub dans le module de classe (VB6)

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

  •  13-09-2019
  •  | 
  •  

Question

J'ai essayé de résoudre ce problème, mais ne peut pas trouver une solution. J'ai un UDT défini dans un module normal et je voulais l'utiliser comme paramètre dans un Public Sub dans un module de classe. J'obtiens alors une erreur de compilation:

  

Seuls les utilisateurs publics types définis définis dans les modules objets publics peuvent être utilisés en tant que paramètres ou le type de retour pour les procédures publiques de modules de classe ou de champs utilisateur publique types définis

J'essaie ensuite de déplacer mon UDT dans la classe, déclarée comme Private. Je reçois cette erreur de compilation:

  

privé Enum et types définis par l'utilisateur ne peuvent pas être utilisés en tant que paramètres ou types de retour pour les procédures publiques, les membres de données publiques, ou des champs d'utilisateurs publics types définis.

J'essaie de le déclarer finaly comme Public dans la classe, et obtenir cette compilation d'erreur:

  

Impossible de définir un type défini par l'utilisateur public dans un module objet privé.

Ainsi est-il possible d'avoir une UDT publique utilisée comme paramètre dans un sous public dans une classe?

Était-ce utile?

La solution

  

Ainsi est-il possible d'avoir un partenariat public   UDT utilisé comme paramètre dans public   sous dans une classe?

En un mot, non. Le plus proche vous pouvez venir avec juste le code classique VB serait de créer une classe qui reproduit l'UDT et de l'utiliser à la place. Il y a certainement des avantages là-bas, mais vous êtes bloqué, si vous devez passer que, disons, une API ainsi.

Une autre option consiste à définir l'UDT dans un typelib. Si vous faites cela, il peut être utilisé comme paramètre pour une méthode publique.

Autres conseils

il suffit de définir la sous comme champ d'Friend. Cette compile très bien pour moi dans une classe VB6.

Private Type testtype
  x As String
End Type


Friend Sub testmethod(y As testtype)

End Sub

De vos messages d'erreur, il semble que votre classe est privée. Si vous ne voulez que votre classe soit publique - à savoir que vous faites un exe ActiveX ou DLL et vous voulez que les clients puissent accéder au sous -. Puis juste faire le type et le sous public

Ok, voici comment le faire, si je peux obtenir mon chat me laisser seul, ce qui est.

Dans Form1 (avec un bouton de commande sur elle):

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

Dans form2 (pas de contrôles nécessaires). (Cela aurait pu tout aussi bien été un objet créé avec une 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

Enfin, cela va dans un fichier de module (BAS).

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

Il suffit de passer le UDT en tant que paramètre de référence et il fonctionnera. :)

'method in the class

Public Sub CreateFile(ByRef udt1 As UdtTest)

End Sub

J'ai eu le même message d'erreur et après avoir vérifié l'application, je trouve que dans la fenêtre de propriétés de la classe, le réglage « instanciation » a été réglé sur « 1 - privé » pour l'objet référencé. Je l'ai changé à « 5 - MultiUse » et a obtenu le même message d'erreur. Je suis ensuite allé à une version du module de projet avant quand j'ai ajouté cet objet référencé et l'a ajouté à nouveau le projet - il réglé par défaut sur « 1 - privé ». Je l'ai changé à « 5 - MultiUse » avant de faire quoi que ce soit d'autre et fermé le projet pour lui mettre à jour avant de compiler. Je relance le projet, il était encore vérifié la valeur. « 5 - MultiUse », puis compilé le projet et compilé proprement sans message d'erreur

Lorsque le message d'erreur a dit qu'elle ne permettait pas référence à un objet privé, l'objet était vraiment privé. Une fois que je déclarai-il pas privé, et le module de projet accepté ce nouveau cadre, il a compilé proprement.

Définir UDF (type public) dans le module:

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

et utiliser Friend en classe, le module o FRM:

Friend Function GetArticulo() As TPVArticulo

Le UDT doit être déclarée dans un objet public, comme:

Public Class Sample

    Public Strucutre UDT
       Dim Value As Object
    End Structure

End Class
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top