热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

当输入展开括号时,Excel崩溃-Excelcrashwhentypingopenparenthesis

HeresoneIdontunderstand.有一个我不明白。Giventhisclassmodule(strippeddowntothebareminimum

Here's one I don't understand.

有一个我不明白。

Given this class module (stripped down to the bare minimum necessary to reproduce the crash):

给定这个类模块(简化为再现崩溃所需的最小值):

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

Can anyone tell me why Excel totally craps out when I type in this code:

有谁能告诉我为什么我输入这段代码时Excel会完全崩溃?

Sub MakeExcelCrash()
    With TestCrashClass(

At this point, I this lovely message:

此时此刻,我要传达一个可爱的信息:

Excel crash - oops!

Even if I type in a full procedure without the offending parentheses and then try to add them later, I get the same crash.

即使我输入了一个完整的过程而没有出现问题的括号,然后再尝试添加它们,我也会得到相同的崩溃。

The only way I can get Excel not to crash is to copy/paste a set of () from somewhere else to this line of code.

使Excel不崩溃的唯一方法是将一组()从其他地方复制/粘贴到这一行代码。

 Sub MakeExcelCrash()
     With TestCrashClass()
         Debug.Print .Data
     End With
 End Sub

If the Init() method has a parameter—even an optional one—it won't crash when the opening paren is typed.

如果Init()方法有一个参数—甚至是可选的-它在打开paren的时候不会崩溃。

I'm more curious about why this happens than ways around it; it doesn't actually come up that often in my code and when it does I can fix it with a change in approach, but I'm really frustrated that I don't know what's causing these crashes. So maybe someone who knows more about the inner working of VBA can explain it to me?

我更好奇的是为什么会发生这种情况,而不是围绕它;它在我的代码中并不经常出现,当它出现时,我可以通过改变方法来修复它,但是我真的很沮丧,因为我不知道是什么原因导致了这些崩溃。所以,也许有人对VBA的内部工作有更多的了解,可以给我解释一下吗?

3 个解决方案

#1


10  

You don't even need the With block. Any attempt to type ( after the class name takes Excel down.

你甚至不需要带块。任何输入尝试(在类名取出Excel后)。

The problem is that you have the VB_PredeclaredId set to true and the default member is trying to return itself. When you attach a debugger to the dying Excel instance, you can see that the underlying issue is a stack overflow:

问题是,您将VB_PredeclaredId设置为true,并且默认成员正在尝试返回自己。当您将调试器附加到垂死的Excel实例时,您可以看到底层问题是堆栈溢出:

Unhandled exception at 0x0F06EC84 (VBE7.DLL) in EXCEL.EXE: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00212FFC).

EXCEL中0x0F06EC84 (VBE7.DLL)处未处理的异常。EXE: 0xC00000FD:栈溢出(参数:0x00000001, 0x00212FFC)。

When you type With TestCrashClass(, what happens is that VBA starts looking for an indexer on the default property, because Init() doesn't have any properties. For example, consider a Collection. You can use the default property's (Item) indexer like this:

当您键入TestCrashClass时(发生的情况是VBA开始寻找默认属性的索引器,因为Init()没有任何属性。例如,考虑一个集合。您可以使用默认属性的(项目)索引器,如下所示:

Dim x As Collection
Set x = New Collection
x.Add 42
Debug.Print x(1)   '<--indexed access via default member.

This is exactly equivalent to Debug.Print x.Items(1). This is where you start running into problems. Init() doesn't have parameters, so VBA starts drilling down through the default members to find the first one that has an indexer so IntelliSense can display the parameter list. It starts doing this:

这完全等同于调试。打印x.Items(1)。这就是你开始遇到问题的地方。Init()没有参数,因此VBA开始通过默认成员查找第一个具有索引器的成员,以便IntelliSense可以显示参数列表。它开始这样做:

x.[default].[default].[default].[default].[default]...

x。(默认)。(默认)。(默认)。(默认)。(默认)……

In your case, it's creating an infinite loop because [default] returns x. The same thing happens in the Collection code above (except it finds one):

在您的例子中,它正在创建一个无限循环,因为[default]返回x。

IntelliSense on open parens

Throw in the fact that you have a default instance, and the end result is something like this:

假设你有一个默认实例,最终结果是这样的:

Private Sub Class_Initialize()
    Class_Initialize
End Sub

#2


8  

As @TimWilliams points out, having a default member that returns an instance of the same class (or a class loop eg. ParentClass.ChildClass.ParentClass.ChildClass... where ParentClass and ChildClass both have default members), and when used in certain syntax cases, such as a With block, will cause VBE to try and resolve the default member.

正如@TimWilliams指出的,有一个默认的成员返回同一个类的实例(或者一个类循环eg)。ParentClass.ChildClass.ParentClass.ChildClass……ParentClass和子类都有默认成员的地方),以及在某些语法情况下(如With block)使用时,会导致VBE尝试并解析默认成员。

The first parenthesis makes VBE assume there must be a method, indexed get or array index that will take an argument, so it sets off to resolve the ultimate target member.

第一个括号使VBE假设必须有一个方法,索引get或数组索引来获取一个参数,因此它开始解析最终目标成员。

So the incomplete line, with a cursor located after the parenthesis:

所以不完整的行,在括号后面有一个光标:

With TestCrashClass(

Is effectively the same as:

有效地等于:

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.

At some point, your system or VBE runs out of resources and exits with the grace and poise of a thermonuclear group-hug.

在某些时候,您的系统或VBE会耗尽资源,以热核群体拥抱的优雅姿态退出。

+1 for improvising with a copy/pasta of a parentheses pair.

使用圆括号对的拷贝/意大利面进行即兴创作。

#3


-4  

Sounds like some sort of corruption. I've had Excel behave irrationally like this before, normally in large projects, and the only way to get around it is to drag all of your classes etc into a new project.

听起来像是某种腐败。我以前有过Excel不合理的行为,通常在大型项目中,唯一的解决方法是将所有的类拖到一个新的项目中。

I suspect it happens because Excel doesn't truly delete classes, modules, worksheets etc that have been removed. You can tell this because of the file size.

我怀疑这是因为Excel并没有真正删除已经删除的类、模块、工作表等。由于文件的大小,您可以看出这一点。

There is no Compact and Repair functionality, as in Access, as far as i'm aware

就我所知,在访问方面没有紧凑和修复功能


推荐阅读
author-avatar
我hi7娘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有