programing

VBA TypeOf 연산자가 실패하는 이유

muds 2023. 9. 8. 21:48
반응형

VBA TypeOf 연산자가 실패하는 이유

저는 엑셀 2007 문제로 며칠째 싸우고 있습니다.다음은 제가 생각할 수 있는 관련된 모든 사실의 목록입니다.

  1. IDetailSheet는 여러 메서드가 있는 VBA 프로젝트에서 선언된 클래스로 클래스 이니셜라이저에 오류를 발생시켜 인스턴스화할 수 없습니다(추상적으로 만듭니다).

  2. Option Explicit은 모든 모듈에 설정됩니다.

  3. VBA 프로젝트의 10개 워크시트는 ID DetailSheet를 구현하고 (전체 프로젝트와 마찬가지로) 깨끗하게 컴파일합니다.

  4. CdetailSheets는 Collection 개체를 래핑하고 Collection 개체를 Collection of IDetailSheet로 노출하는 VBA 프로젝트에서 선언된 클래스입니다.또한 모든 컬렉션 멤버에 대해 IDetailSheet의 특정 메서드를 수행하는 몇 가지 추가 방법도 제공합니다.

  5. Class initializer(Workbook_Open 이벤트 핸들러에서 호출되고 전역 변수에 할당됨)에서 CDetailSheet는 다음 코드를 실행하여 개인 컬렉션 DetailSheet를 채웁니다.

    Dim sht as EXCEL.WorkSheet
    For Each sht in ActiveWorkbook.Worksheets
      If TypeOf sht is IDetailSheet Then
        Dim DetailSheet as IDetailSheet
        Set DetailSheet = sht
        DetailSheets.Add DetailSheet, DetailSheet.Name
      End If
    Next sht
    
  6. 특정 리본 콜백에서는 다음 코드가 실행됩니다.

       If TypeOf ActiveWorkbook.ActiveSheet is IDetailSheet Then
          Dim DetailSheet as IDetailSheet
          Set DetailSheet = ActiveWorkbook.ActiveSheet
          DetailSheet.Refresh  *[correction]*
       End If
    
  7. 다른 안정성 문제가 확인된 후 워크북에서 모든 ActiveX 컨트롤이 제거되었습니다(원래는 수십 개가 있었습니다).원래 ActiveX 컨트롤과 연결된 기능을 대체하기 위해 Fluent Interface Ribbon이 생성되었습니다.

  8. 회사 템플릿에서 Hyperion 추가 기능이 있지만 이 워크북에서는 사용되지 않습니다.

모두 말하고 실행하면 워크북을 실행할 때 다음과 같은 증상이 나타납니다.

  • IdetailSheets Initializer에서 IdetailSheets Initializer의 인스턴스 수는 1(가장 일반적)에서 때때로 2 또는 3까지 인식됩니다.0도 아니고, 3도 안 되고, 10도 안 되는 것이 가장 확실합니다.(항상 같은 것은 아니지만, 세트의 앞쪽에 있으면 인식될 가능성이 높아지는 것 같습니다.)
  • IDetailSheet 구현 인스턴스가 CDetailSheets initializer에서 검색되는 경우(그리고 제가 판단할 수 있는 범위 내에서는 해당 인스턴스만 TypeOf...로 인식됩니다. 리본 콜백에 있어요

대부분의 유형이... 운영이 실패하고 있습니까?아니면 그 문제를 어떻게 해결할 것인가요?

v-table을 수동으로 만듭니다(예: big uggly Select Case...). End Select 문)을 사용하여 기능을 작동시키지만, 실제로 이러한 코드 옆에 제 이름이 있는 것이 다소 당황스럽습니다.그 외에도 미래의 유지보수 악몽이 될 수 있습니다.

오래된 p-code 문제일 수도 있다는 생각에 Project를 삭제하는 정도까지 진행했습니다.확장된 XLSM zip에서 bin 파일을 가져온 다음 모든 VBA 코드를 수동으로 다시 가져옵니다.거스름돈은 없습니다.저는 또한 iDetailSheet의 모든 용도에 프로젝트명을 추가하여 miFab으로 만들려고 했습니다.시트 상세 정보를 제공하지만 다시는 사용할 수 없습니다.(miFab이 프로젝트 이름입니다.)

CallByName을 사용하여 커닝할 수 있는 몇 가지 방법이 있습니다.어떻게 해서든 이 버그를 해결해야 합니다.

추잡한 예.

구현 라인으로 시작하는 모든 시트에는 공용 GetType 기능이 있어야 합니다.리본에 있는 버튼에 "TestSheet" 서브를 첨부했습니다.반환된 형식 이름을 셀 A1에 넣어 기능을 시연합니다.

모듈 1

'--- Start Module1 ---
Option Explicit

Public Sub TestSheet()
  Dim obj As Object
  Set obj = ActiveSheet
  ActiveSheet.[A1] = GetType(obj)
End Sub

Public Function GetType(obj As Object) As String
  Dim returnValue As String
  returnValue = TypeName(obj)
  On Error Resume Next
  returnValue = CallByName(obj, "GetType", VbMethod)
  Err.Clear
  On Error GoTo 0
  GetType = returnValue
End Function
'--- End Module1 ---

시트 1

'--- Start Sheet1 ---
Implements Class1
Option Explicit

Public Function Class1_TestFunction()
End Function

Public Function GetType() As String
    GetType = "Class1"
End Function
'--- End Sheet1 ---

TypeOf가 인터페이스를 구현하는 Excel 워크북의 ActiveSheet에서 작동하지 않음에 따라 유사한 문제를 게시한 후 이 질문을 발견했습니다.

확실한 설명은 없지만 해결책은 있다고 생각합니다.

[코드]가 Sheet1 또는 Chart1에 인터페이스를 구현하고 Sheet1/Chart1을 확장하고 있지만 Sheet1은 워크시트를 이미 확장하고 있습니다(Chart1은 이미 확장하고 있습니다).

테스트에서 VBA가 실제 값을 반환하도록 강제할 수 있습니다.TypeOf먼저 시트의 속성에 액세스함으로써.그 말은 추한 을 한다는 뜻입니다.

'Explicitly access ThisWorkbook.ActiveSheet.Name before using TypeOf
If TypeOf ThisWorkbook.Sheets(ThisWorkbook.ActiveSheet.Name) Is PublicInterface Then

만약 당신이 믿지 않는다면,TypeOf, 오류를 무시하고 계속 사용합니다.

Dim sht as EXCEL.WorkSheet
For Each sht in ActiveWorkbook.Worksheets
  'If TypeOf sht is IDetailSheet Then
  Dim DetailSheet As IDetailSheet
  On Error Resume Next
  Set DetailSheet = sht
  On Error GoTo 0
  If Not DetailSheet Is Nothing Then
    DetailSheets.Add DetailSheet, DetailSheet.Name
  End If
Next sht

이것이 작동하지 않으면 워크시트가 실제로 작동하지 않습니다.IDetailSheet적어도 그 때는

언급URL : https://stackoverflow.com/questions/18500674/why-would-vba-typeof-operator-fail

반응형