User Defined Type (UDT) als Parameter in der öffentlichen Unter in Klassenmodul (VB6)

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

  •  13-09-2019
  •  | 
  •  

Frage

Ich habe versucht, dieses Problem zu lösen, aber eine Lösung nicht finden kann. Ich habe ein UDT in einem normalen Modul definiert, und wollte mich als Parameter in einem Public Sub in einem Klassenmodul verwenden. Ich erhalte dann einen Compiler-Fehler:

  

Nur öffentliche benutzerdefinierte Typen in öffentlichen Objektmodulen definiert sind, können als Parameter verwendet werden, oder die Art der öffentlichen Verfahren von Klassenmodulen oder als Felder öffentlicher Benutzer definierte Typen zurückgeben

ich dann versuche, meine UDT in der Klasse zu bewegen, erklärt als Private. Ich erhalte diesen Compiler-Fehler:

  

Privat Enum und definierte Benutzertypen können nicht als Parameter verwendet werden, oder Typen für öffentliche Verfahren, öffentliche Datenelemente zurückgeben oder Bereiche öffentlichen benutzerdefinierte Typen.

ich endlich versuchen, es so Public in der Klasse zu erklären, und sie erhalten einen Compiler-Fehler:

  

Es kann keine öffentlichen benutzerdefinierten Typ in einem privaten Objektmodul definieren.

So ist es eine Möglichkeit, einen öffentlichen UDT als Parameter in einer öffentlichen Unter in einer Klasse verwendet hat?

War es hilfreich?

Lösung

  

So ist es eine Möglichkeit, ein Publikum zu haben   UDT verwendet als Parameter in einem öffentlichen   Unter in einer Klasse?

In einem Wort, nein. Die nächstgelegene Sie mit nur klassischen VB-Code kommen würde, eine Klasse zu erstellen, die die UDT und verwendet, die stattdessen repliziert. Es gibt definitiv Vorteile, aber Sie abgespritzt sind, wenn Sie das zu übergeben müssen, sagen wir, eine API als auch.

Eine andere Möglichkeit ist es, die UDT in einem typelib zu definieren. Wenn Sie das tun, kann es als Parameter für eine öffentliche Methode verwendet werden.

Andere Tipps

definieren Sie einfach die Unter als Friend Umfang. Dies kompiliert für mich in einer VB6 Klasse in Ordnung.

Private Type testtype
  x As String
End Type


Friend Sub testmethod(y As testtype)

End Sub

Von Ihren Fehlermeldungen es erscheint Ihre Klasse privat ist. Wenn Sie Ihre Klasse öffentlich sein wollen - das heißt Sie eine ActiveX-exe oder DLL machen und Sie möchten Kunden in der Lage sein, der Unter zugreifen -. Dann macht nur sowohl die Art und den öffentlichen Unter

Ok, hier ist, wie es zu tun, wenn ich meine Katze zu bekommen, mich allein zu lassen, das ist.

In Form1 (mit einem Befehl Taste darauf):

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

In form2 (keine Kontrollen erforderlich). (Dies erfolgt ganz einfach, wie könnte ein Objekt gewesen mit einer Klasse erstellt.):

    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

Und schließlich das geht in einem Modul (BAS) Datei.

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

Übergeben Sie einfach die UDT als Referenz-Parameter und es wird funktionieren. :)

'method in the class

Public Sub CreateFile(ByRef udt1 As UdtTest)

End Sub

hatte ich die gleiche Fehlermeldung und nach der Anwendung überprüft, fand ich, dass für die Klasse im Eigenschaftsfenster wurde die „Instancing“ Einstellung auf „1 - Privat“ für das referenzierte Objekt. Habe ich es auf „5 - MultiUse“ und bekam die gleiche Fehlermeldung. Ich ging dann zurück zu einer Version des Projektmoduls vor, wenn ich fügte hinzu, dass Objekt referenziert und es wieder hinzugefügt, das Projekt - es standardmäßig auf „1 - Privat“. Habe ich es auf „5 - MultiUse“, bevor irgendetwas anderes und schloss das Projekt zu tun für sie vor dem Kompilieren zu aktualisieren. Ich das Projekt erneut geöffnet, überprüft es noch gesetzt wurde. „5 - MultiUse“, dann das Projekt zusammengestellt und es sauber, ohne die Fehlermeldung kompiliert

Wenn die Fehlermeldung sagt, es war es nicht möglich ein eigenes Objekt verweist, war das Objekt wirklich privat. Einmal erklärte ich es nicht privat, und das Projektmodul akzeptiert, dass neue Einstellung, es sauber zusammengestellt.

definiert UDF (public-Typ) in einem Modul:

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

und verwenden Friend in der Klasse, Modul o frm:

Friend Function GetArticulo() As TPVArticulo

Die UDT muss in einem öffentlichen Objekt deklariert werden, wie:

Public Class Sample

    Public Strucutre UDT
       Dim Value As Object
    End Structure

End Class
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top