نوع المستخدم المستخدم (UDT) كمعلمة في الوحدة الفرعية العامة في الوحدة النمطية (VB6)

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

  •  13-09-2019
  •  | 
  •  

سؤال

لقد حاولت حل هذه المشكلة، ولكن لا يمكن العثور على أي حل. لدي UDT محددة في وحدة نمطية طبيعية، وأردت استخدامها كمعلمة في Public Sub في وحدة فئة. ثم احصل على خطأ في ترجمة:

يمكن استخدام الأنواع المحددة للمستخدمين العامين المحددين في وحدات الكائنات العامة كمعلمات أو نوع إرجاع للإجراءات العامة لوحدات النمطيات أو كحقول أنواع محددة من المستخدمين

ثم أحاول نقل UDT الخاص بي في الفصل، حسب Private. وبعد أحصل على هذا الخطأ ترجمة:

لا يمكن استخدام أنواع ENUM الخاصة والمستخدمين الخاصة كمعلمات أو أنواع عودة للإجراءات العامة وأعضاء البيانات العامة أو حقول أنواع محددة من قبل المستخدمين.

أنا أخيرا حاول أن أعلن ذلك Public في الفصل، واحصل على خطأ ترجمة هذا:

لا يمكن تحديد نوع محدد من المستخدمين في وحدة كائن خاص.

فهل هناك أي طريقة للحصول على UDT عام يستخدم كمعلمة في عام عام في الفصل؟

هل كانت مفيدة؟

المحلول

فهل هناك أي طريقة للحصول على UDT عام يستخدم كمعلمة في عام عام في الفصل؟

في كلمة، لا. أقرب ما يمكن أن تأتي مع رمز VB الكلاسيكي فقط هو إنشاء فئة تكرار UDT واستخدامها بدلا من ذلك. هناك مزايا بالتأكيد هناك، لكنك تصيح إذا كنت بحاجة إلى تمرير ذلك، على سبيل المثال، API أيضا.

خيار آخر هو تحديد UDT في Typelib. إذا قمت بذلك، فيمكن استخدامه كمعلمة لطريقة عامة.

نصائح أخرى

فقط حدد الفرعية 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

في Form2 (لا حاجة لضوابط). (قد يكون هذا مجرد كائن تم إنشاؤه بسهولة مع فئة.):

    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

وأخيرا، يحدث هذا في ملف الوحدة النمطية (باس).

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

فقط اجتياز UDT كمرجع Parametre وسيعمل. :)

'method in the class

Public Sub CreateFile(ByRef udt1 As UdtTest)

End Sub

كان لدي نفس رسالة الخطأ وبعد التحقق من التطبيق، وجدت أنه في نافذة الخاصية للفئة، تم ضبط إعداد "Instancing" على "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 في الصف، الوحدة النمطية O FRM:

Friend Function GetArticulo() As TPVArticulo

يجب إعلان UDT في كائن عام، مثل:

Public Class Sample

    Public Strucutre UDT
       Dim Value As Object
    End Structure

End Class
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top