input左括号时,Excel崩溃
这是我不明白的一个。
鉴于这个类模块(剥离到最低限度重现崩溃):
VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END Attribute VB_Name = "TestCrashClass" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Option Explicit Public Function Init() As TestCrashClass Attribute Init.VB_UserMemId = 0 Dim tcc As New TestCrashClass Set Init = tcc End Function Public Property Get Data() As String Data = "test data" End Property
任何人都可以告诉我为什么当我input这个代码时,Excel为什么总是出来:
Sub MakeExcelCrash() With TestCrashClass(
在这一点上,我这个可爱的消息:
即使我input完整的程序而没有违规的括号,然后尝试稍后添加它们,我也会遇到相同的崩溃。
我可以让Excel不会崩溃的唯一方法是从其他位置复制/粘贴一组()
到这行代码。
Sub MakeExcelCrash() With TestCrashClass() Debug.Print .Data End With End Sub
如果Init()
方法有一个参数 – 即使是一个可选的参数 – 当打开paren时,它不会崩溃。
我更好奇为什么会发生这种事情,而不是周围的方式。 在我的代码中实际上并没有经常出现这种情况,当我可以通过改变方法来修复它时,我真的很沮丧,我不知道是什么导致了这些崩溃。 所以也许有人对VBA的内部工作有更多的了解可以向我解释一下?
你甚至不需要With
块。 任何types的尝试(
在类名称之后将Excel取下。
问题是你有VB_PredeclaredId
设置为true,并且默认成员试图返回自己。 当您将debugging器附加到垂死的Excel实例时,可以看到底层问题是堆栈溢出:
EXCEL.EXE中的0x0F06EC84(VBE7.DLL)未处理的exception:0xC00000FD:堆栈溢出(参数:0x00000001,0x00212FFC)。
当你键入With TestCrashClass(
,会发生什么是VBA开始寻找一个索引器的默认属性,因为Init()
没有任何属性,例如,考虑一个Collection
,你可以使用默认属性的( Item
)索引器喜欢这个:
Dim x As Collection Set x = New Collection x.Add 42 Debug.Print x(1) '<--indexed access via default member.
这完全等同于Debug.Print x.Items(1)
。 这是你开始遇到问题的地方。 Init()
没有参数,所以VBA开始向下钻取默认成员以find第一个具有索引器的参数,这样IntelliSense可以显示参数列表。 它开始这样做:
x.[default].[default].[default].[default].[default]...
在你的情况,这是创build一个无限循环,因为[default]
返回 x
。 同样的事情发生在上面的Collection
代码中(除了它find一个):
抛出事实,你有一个默认的实例,最终的结果是这样的:
Private Sub Class_Initialize() Class_Initialize End Sub
正如@TimWilliams所指出的那样,有一个默认成员返回一个相同类的实例(或者一个类循环,例如, ParentClass.ChildClass.ParentClass.ChildClass...
,其中ParentClass和ChildClass都有默认成员),并且当在某些语法情况(如With
块)将导致VBE尝试并parsing默认成员。
第一个括号使得VBE假设必须有一个方法,索引get
或数组索引,它将接受一个参数,所以它开始parsing最终的目标成员。
所以这个不完整的行,光标位于括号之后:
With TestCrashClass(
实际上是一样的:
With TestCrashClass.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init.Init '....You're inquisitive scrolling this far over, but you get the point.
在某个时候,你的系统或者VBE耗尽了资源,并且以一个热核团队的拥抱的优雅和平静而退出。
+1用于即兴表演与一对圆括号的复制/面食。
听起来像是某种腐败。 我曾经使用Excel的行为不像以前那样,通常在大型项目中,解决这个问题的唯一方法就是把所有的类拖放到一个新的项目中。
我怀疑这是因为Excel并没有真正删除已被删除的类,模块,工作表等。 你可以告诉这个,因为文件的大小。
据我所知,没有紧凑和修复function,就像在Access中一样