programing

잘못된 메서드 이름에 대한 VBA 컴파일러 메시지 누락

powerit 2023. 6. 12. 21:56
반응형

잘못된 메서드 이름에 대한 VBA 컴파일러 메시지 누락

다음 코드를 고려합니다.

Public Sub VBACompilerIsMad()

    Dim Ap As Application     
    Dim Wb As Workbook
    Dim Ws As Worksheet

    Debug.Print Ap.XXX ' No compile error
    Debug.Print Wb.XXX ' No compile error
    Debug.Print Ws.XXX ' Compile error

End Sub

할 때, 저는 이파을컴때할기멤참의 합니다.Worksheet줄을 어느 쪽도 오류가 .Application도 아니다Workbook나 속성이 방는또속있습다니이성법▁a▁have다있▁or입니다.XXX마치 내가 선언한 것과 같습니다.Ap그리고.Wb~하듯이Object변수

컴파일러가 처리하는 이유는 무엇입니까?Application/Workbook는 .Worksheet?

컴파일러가 마치 그것들을 다루는 것처럼 보이는, 이와 같은 다른 클래스가 있습니까?Object?

제가 설명한 바와 같이 (각각 칭찬이 갑니다), 이것은 COM 기능입니다.

기본적으로 COM은 인터페이스가 확장 가능하다고 가정합니다. 즉, 런타임에 구성원을 추가할 수 있습니다.원하는 동작이 아닌 경우 인터페이스 정의에 속성을 적용할 수 있습니다. 인터페이스는 형식 라이브러리에 명시적으로 정의된 메서드만 수락함을 선언합니다.

dispinterface _Application그리고.dispinterface _Workbook에 이 플래그가 되어 있지 . Excel 형식 라이브러리의 Excel 입니다.dispinterface _Worksheet 그렇습니다.

마찬가지로 ADO의dispinterface _Connection을 가지고 있지 않음[nonextensible],dispinterface _Command 그렇습니다.

가능한 확장 가알다추참가조음에 하십시오.TypeLib Info프로젝트의 참조 및 실행:

Dim t As tli.TLIApplication
Set t = New tli.TLIApplication

Dim ti As tli.TypeLibInfo
Set ti = t.TypeLibInfoFromFile("excel.exe")

Dim i As tli.InterfaceInfo
For Each i In ti.Interfaces
    If (i.AttributeMask And tli.TYPEFLAG_FNONEXTENSIBLE) <> tli.TYPEFLAG_FNONEXTENSIBLE Then
      Debug.Print i.Name
  End If
Next

여기서는 거의 모든 인터페이스를 확장할 수 있으므로 대부분의 인터페이스가 디버그 창 밖으로 밀려나 마지막 인터페이스만 볼 수 있습니다.변할내용을 합니다.<>=확장할 수 없는 것들을 인쇄하기 위해, 그것들은 훨씬 적습니다.

약간의 가설:

ADODB에서 저장 프로시저를 호출할 수 있습니다.기본 메서드와 같은 연결 개체(하단).(여러 msdn 사이트에서 에 대한 예제는 이상하게 엉망으로 보입니다.
따라서 VBS/VBA에는 '익명/동적 방법'과 같은 메커니즘이 있습니다.과 비슷한 메커니즘일 수 있습니다.Application그리고.Workbook수업 - 어디서 어떻게 하는지는 정확히 알 수 없지만요.

테스트는 기본 아이디어를 지원합니다.
나는 이것을 다음과 관련하여 테스트했습니다.Microsoft ActiveX Data Objects 2.8 Library:

Public Sub testCompiler()
    Dim cn As ADODB.Connection
    Dim cmd As ADODB.Command

    Debug.Print cn.XXX
    Debug.Print cmd.XXX
End Sub

cn.XXX컴파일 오류를 발생시키지 않습니다.cmd.XXX 그렇습니다.

GSerg의 답변은 정말 훌륭합니다. 저는 전체 COM 유형 라이브러리 IDL과 일부 속성이 Excel VBA IDE의 동작을 제어할 수 있는 방법을 좋아합니다.COM에 대한 이 놀라운 지식이 전해지기를!그리고, 저는 그 대답을 더 많이 하기 위해 이 질문이 보상을 받았다는 것을 깨달았지만, 보상이 설정되면 그것이 제 레이더에 나타나고 이 문제에 대한 견해를 갖게 됩니다.

따라서 GSerg의 답변은 메커니즘을 제공하지만 이유는 제공하지 않습니다. 즉, 방법은 제공하지만 이유는 제공하지 않습니다.그 이유에 대해 대답해 보겠습니다.

왜 마틴 롤러(OP)가 이미 그의 논평에서 제공한 답의 일부.Application그리고.WorksheetFunction이것은, 내게, 내가 지켜야 할 설득력 있는 이유입니다.Application확장 가능하며 고려하지 않을 것입니다.Application더.

로 눈을 돌립시다.Workbook그리고.Worksheet그리고 우리는 시연할 코드로 시작하는 것이 가장 좋습니다. 그래서 당신은 두 권의 새로운 워크북으로 시작해야 합니다. 그들에게 전화하세요.MyWorkbook.xlsm그리고.OtherWorkbook.xlsm몇 가지 지침:

OtherWorkbook.xlsm코드 모듈로 이동ThisWorkbook코드를 붙여넣습니다.

Option Explicit

Public Function SomeFunctionExportedOffOtherWorkbook() As String
    SomeFunctionExportedOffOtherWorkbook = "Hello Matt's Mug!"
End Function

MyWorkbook.xlsm가다, 가다, 가다, 가다, 가다, 가다, 가다, 가다, 가다, 나다Sheet1코드 모듈 및 코드 붙여넣기

Option Explicit

Public Function SomeFunctionExportedOffCodeBehindSheet1() As String
    SomeFunctionExportedOffCodeBehindSheet1 = "Hello Martin Roller!"
End Function

이제 VBA IDE에서 다음의 코드 이름을 변경합니다.Sheet1로.codebehindSheet1이제, 의 새로운 표준 모듈에서MyWorkbook.xlsm다음 코드를 추가합니다.

Sub TestingObjectLikeInterfacesOfWorkbookAndCodeBehindWorksheet_RunMany()

    '* For this example please rename the 'CodeName' for Sheet1 to be "codebehindSheet1" using the IDE
    Debug.Assert ThisWorkbook.Worksheets.Item("Sheet1").CodeName = "codebehindSheet1"


    Dim wb As Workbook
    Set wb = Application.Workbooks.Item("OtherWorkbook")

    '* Workbook dispinterface needs to not marked with nonextensible attribute
    '* so that it doesn't trip up over exported function in another workbook
    '* below SomeFunctionExportedOffOtherWorkbook is defined in the ThisWorkbook module of the workbook "OtherWorkbook.xlsm"
    Debug.Print wb.SomeFunctionExportedOffOtherWorkbook


    '*Not allowed --> Dim foo As Sheet1
    '*have to call by the 'code behind' name which is usually Sheet1 but which we changed to illustrate the point
    Debug.Print codebehindSheet1.SomeFunctionExportedOffCodeBehindSheet1


End Sub

이제 위의 코드를 실행합니다.

여러분은 아마 코드를 읽고 제가 말하고 있는 요점을 이해했을 것입니다. 하지만 제가 자세히 설명해 드리겠습니다.필요합니다Workbook메서드나 함수를 내보낼 수 있는 다른 워크북에 대한 참조가 포함되어 있을 수 있으며 컴파일 오류가 발생하지 않도록 하기 위해 확장 가능한 상태로 유지합니다.

그러나, 다음의 경우에는Worksheet유사한 내보내기를 수행하기 위해 다시 모듈 뒤의 코드에 코드를 추가하지만 모듈을 참조하는 데 차이가 있습니다. VBA 코드 이름을 사용하여 모듈 뒤의 코드에 대한 참조를 캡처하면 대부분의 사람들이 시트 1에서 이를 변경하지 않습니다(그래서 위에서 변경하도록 초대받았습니다).

따라서 모듈 이름 뒤에 있는 코드로 얻은 인터페이스는 Excel이 아닌 확장 가능해야 합니다.워크시트 인터페이스.

추신. TLI.dll 사본 가진 사람?

해결 방법으로는 여전히 자체 개발이 가능할 수 있습니다.interface이 인터페이스를 구현합니다.그런 다음 변수를 다음과 같이 선언합니다.INewInterface그리고 모든 컴파일러 메시지는 거기에 있을 것입니다 :).은 사용자 입니다.UserForm

인터페이스

Public CancelButton As MSForms.CommandButton
Public DataList As MSForms.ListBox
Public CommandBox As MSForms.TextBox

실행

Implements IMyForm

Private Property Set IMyForm_CancelButton(ByVal RHS As MSForms.ICommandButton)

End Property

Private Property Get IMyForm_CancelButton() As MSForms.ICommandButton

End Property

Private Property Set IMyForm_CommandBox(ByVal RHS As MSForms.IMdcText)

End Property

Private Property Get IMyForm_CommandBox() As MSForms.IMdcText

End Property

Private Property Set IMyForm_DataList(ByVal RHS As MSForms.IMdcList)

End Property

Private Property Get IMyForm_DataList() As MSForms.IMdcList

End Property

사용.

여기에 이미지 설명 입력

참고:MyForm프로젝트에 추가된 기존 VBA 양식입니다.

언급URL : https://stackoverflow.com/questions/28218373/missing-vba-compiler-message-for-wrong-method-name

반응형