2013-10-29 41 views
4

我一直在追蹤這個問題好幾天,所以我想我會在這裏發佈它來幫助其他人解決同樣的問題,以及學習更多關於原因。我已經簡化了這篇文章結尾處的兩個類模塊的問題代碼。「TypeOf ... Is Child」from Parent導致破損的Excel文件

基本上,簡化的場景是這樣的:兩個類模塊,父和子,其中子實現父。 Parent中的某處是行TypeOf Me Is Child,其中Me可以是任何對象。

從我的理解,當TypeOf...Is行被編譯爲P代碼(調試>編譯或調用方法)並保存到文件(.xlsm或.xlsb)時,它會導致文件無法正常打開。代碼可以正常運行,但是當文件保存,關閉並重新打開時,它會在打開(或打開VBE)時提示錯誤,說Invalid data formatError accessing file. Network connection may have been lost,並且父模塊不能再打開,也不能打開任何VBA運行(在立即窗口中嘗試?1=1,它會給出相同的錯誤)。

如果使用TypeName()而不是TypeOf...Is檢查類型,則不會出現此問題(這是我在項目中使用的解決方案)。

任何人都可以更清楚地知道究竟是哪裏出了問題,或者至少證明我是在正確的軌道上引發問題(P代碼)?

PS是的,我知道父母對孩子的認識是糟糕的設計,但我接近一次性項目的結束,這是不值得花時間重新設計的。

相關鏈接:

類模塊:

家長:

Option Explicit 
' Class: Parent 

' The problem (so far as I can tell): 
' When the compiled version of the method below is saved to the file, the file 
' will no longer load properly. Upon saving and reopening the file, I get a 
' "Invalid data format" error, and the code for this class module can no longer be 
' accessed. Furthermore, no VBA code will run after this happens. Try typing "?1=1" 
' into the Immediate Window - you'll get another "Invalid data format" window. 
' Alternatively, the error will be "Error accessing file. Network connection may 
' have been lost." if the code is changed from using "Me" to "tmp" as noted in the 
' comments in DoSomething(). 

' Steps to replicate: 
' 1. Debug > Compile VBAProject. 
' 2. Save file. 
' 3. Close Excel. 
' 4. Reopen file (and may need to open VBE). 

Public Sub DoSomething() 
    ' The TypeOf...Is statement seems to be what causes the problem. 
    ' Note that checking "Me" isn't the cause of the problem (merely makes 
    ' for shorter demo code); making a "Dim tmp as Object; set tmp = new Collection" 
    ' and checking "TypeOf tmp Is Child" will cause the same problem. 
    ' Also note, changing this to use TypeName() resolves the issue. 
    ' Another note, moving the TypeOf...Is to a "Private Sub DoSomethingElse()" has 
    ' no effect on the issue. Moving it to a new, unrelated class, however, does 
    ' not cause the issue to occur. 
    If TypeOf Me Is Child Then 
     Debug.Print "Parent" 
    End If 
End Sub 

兒童:

Option Explicit 
' Class: Child 

Implements Parent 

Private Sub Parent_DoSomething() 
    Debug.Print "Child" 
End Sub 

回答

1

VBA並不支持類的多態性。

我想你是誤解了關鍵字Implements的目的。

當你想一個類來實現的接口它使用 - 沒有其它類(好吧,至少不是真的,因爲接口在VBA是另一個類模塊對象)

this answer for better understanding of theImplementskeyword in VBA

另請參閱this有關VBA多態性的信息

+0

我明白我濫用'Implements',雖然我的問題(和設計)可能不會顯示它(所以鏈接仍然讚賞)。在項目結束時,這只是一個快速又髒兮兮的補充,如果我意識到當我第一次添加它時導致了這個問題,我會花時間在適當的實現上而不是追蹤問題。在這一點上,我更加好奇這是如何導致Excel文件在保存並重新打開後中斷的。 – aplum

+0

@aplum也許可以考慮使用'VarType(Me),TypeName(Me)'。我真的不能深入探究錯誤的原因。 – 2013-10-29 17:53:16

+0

是的,一旦我找到了違規行 - 我已經完全從項目中刪除了,因爲在我發佈之前,我會轉而使用'TypeName(Me)',但好奇心讓我在這裏問。不過謝謝你。 – aplum

相關問題