我已经追踪这个问题好几天了,所以我想我会在这里发布它以帮助其他有同样问题的人,并了解更多关于原因的信息。我已将问题代码简化为本文末尾的两个类模块。
基本上,简化的场景是这样的:两个类模块,Parent 和 Child,其中 Child 实现 Parent。Parent 中的某处是 line TypeOf Me Is Child
,其中Me
可能是任何 Object。
据我了解,当该TypeOf...Is
行编译为 P 代码(调试 > 编译,或调用方法)并保存到文件(.xlsm 或 .xlsb)时,会导致文件无法正确打开。代码可以正常运行,但是当文件被保存、关闭和重新打开时,在打开(或打开 VBE)时会报错Invalid data format
or Error accessing file. Network connection may have been lost
,并且父模块无法再打开,也无法运行任何 VBA (?1=1
在立即窗口中尝试,它会给出相同的错误)。
如果使用TypeName()
而不是检查类型TypeOf...Is
,则不会出现此问题(这是我在项目中使用的解决方案)。
任何人都可以进一步了解这里到底出了什么问题,或者至少确认我在导致问题的原因(P代码)方面处于正确的轨道上吗?
PS 是的,我知道父母对孩子的了解是糟糕的设计,但我已经接近一次性项目的尾声,不值得花时间重新设计。
有用的链接:
- 解释 VBA 的代码状态,以及保存到文件中的内容。 http://orlando.mvps.org/VBADecompilerMore.asp?IdC=OrlMoreWin#WhatItIs
类模块:
家长:
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