클래스 모듈 (VB6)에서 공개 서브의 매개 변수로서 UDT (User Defined Type)

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

  •  13-09-2019
  •  | 
  •  

문제

이 문제를 해결하려고했지만 해결책을 찾을 수 없습니다. UDT가 일반 모듈에 정의되어 있으며이를 매개 변수로 사용하고 싶었습니다. Public Sub 클래스 모듈에서. 그런 다음 컴파일 오류가 발생합니다.

공개 객체 모듈에 정의 된 공개 사용자 정의 유형 만 클래스 모듈의 공개 절차 또는 공개 사용자 정의 유형의 필드로 매개 변수 또는 반환 유형으로 사용할 수 있습니다.

그런 다음 수업에서 UDT를 옮기려고합니다. Private. 이 컴파일 오류가 발생합니다.

개인 열거 및 사용자 정의 유형은 공개 절차, 공개 데이터 구성원 또는 공개 사용자 정의 유형의 분야에 대한 매개 변수 또는 반환 유형으로 사용할 수 없습니다.

마지막으로 선언하려고합니다 Public 클래스 에서이 컴파일 오류를 받으십시오.

개인 객체 모듈 내에서 공개 사용자 정의 유형을 정의 할 수 없습니다.

그렇다면 공개 UDT를 수업에서 공개 서브에서 매개 변수로 사용하는 방법이 있습니까?

도움이 되었습니까?

해결책

그렇다면 공개 UDT를 수업에서 공개 서브에서 매개 변수로 사용하는 방법이 있습니까?

한마디로, 아니요. 클래식 VB 코드만으로 올 수있는 가장 가까운 것은 UDT를 복제하고 대신 사용하는 클래스를 만드는 것입니다. 여기에는 분명히 장점이 있지만 API도 전달해야한다면 호출됩니다.

또 다른 옵션은 Typelib에서 UDT를 정의하는 것입니다. 그렇게하면 공개 메소드의 매개 변수로 사용할 수 있습니다.

다른 팁

서브를 다음과 같이 정의하십시오 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

마지막으로 이것은 모듈 (BAS) 파일로 들어갑니다.

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

UDT를 참조 매개 변수로 전달하면 작동합니다. :)

'method in the class

Public Sub CreateFile(ByRef udt1 As UdtTest)

End Sub

동일한 오류 메시지가 있었고 응용 프로그램을 확인한 후 클래스의 속성 창에서 "Instancing"설정이 참조 된 객체의 "1- 비공개"로 설정되어 있음을 알았습니다. "5- 다중 사용"으로 변경하고 동일한 오류 메시지를 받았습니다. 그런 다음 참조 된 객체를 추가하고 프로젝트를 다시 추가하기 전에 프로젝트 모듈의 버전으로 돌아갔습니다. 다른 작업을 수행하기 전에 "5- 다중 사용"으로 변경하고 컴파일하기 전에 업데이트하도록 프로젝트를 닫았습니다. 프로젝트를 다시 열었고 여전히 "5- 멀티 사용"으로 설정되었다고 확인한 다음 프로젝트를 컴파일하고 오류 메시지없이 깨끗하게 컴파일했습니다.

오류 메시지가 개인 객체를 참조하는 것을 허용하지 않았다고 말할 때 객체는 실제로 비공개였습니다. 개인이 아니라고 선언하고 프로젝트 모듈은 새로운 설정을 받아 들였으며 깨끗하게 컴파일했습니다.

모듈에서 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