2017-02-06 44 views
9

İşte anlamadığım bir tane. (Kilitlenmeyi yeniden gerekli minimumda soyunmuş) Bu sınıf modülü Verilen Açık parantez yazarken Excel çökmesi

:

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 

ben bu kodu yazdığınızda, Excel tamamen dışarı kreps neden kimse bana söyleyebilir:

Sub MakeExcelCrash() 
    With TestCrashClass(
Bu noktada

, ben bu güzel mesajı:

Excel crash - oops!

Hatalı parantezler olmadan tam bir yordam yazıp daha sonra bunları eklemeyi denesem de, aynı çökme olur.

Excel'i çökmesine izin vermemin tek yolu, başka bir yerden bu kod satırına () kümesini kopyalamak/yapıştırmaktır.

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

Init() yöntem varsa parametreyi bile opsiyonel tek o açılış parantez yazdığınız zaman kilitlenmez.

neden daha çok merak ediyorum; bunun etrafından daha fazla şey; Aslında bu benim kodumda sık sık ortaya çıkmaz ve ne zaman olduğu zaman bunu bir yaklaşım değişikliği ile çözebilirim, ama bu çökmelere neyin sebep olduğunu bilmediğim için gerçekten hüsrana uğruyorum. Yani belki de VBA'nın iç işleyişi hakkında daha fazla bilgi sahibi olan biri bunu bana açıklayabilir mi?

+0

Excel, siz yazarken bir çeşit otomatik tamamlama sunuyor mu? – Carcigenicate

+0

Sınıfınızın bir örneğini oluşturan bir yöntemi varsayılan yöntemde sonsuz bir döngü oluşturduğunu tahmin ediyorum. Muhtemelen bu satırı yazarken, sınıfın kodunun bir değerlendirmesi var ... Bu yöntemin amacı nedir? –

+2

İnit'i varsayılan üyeye yaptığınızdan bu yana, VBE size bunun üzerinden bir Intellisense açılanması vermeye çalışacaktır - bunu yapmaya çalıştığında sonsuz döngüye girer girmez (çünkü dönüş değeri Init', aynı sınıfın başka bir örneğidir, aynı varsayılan üye ile ve benzerleri ... ve Excel çöküyor. –

cevap

9

With bloğuna bile ihtiyacınız yoktur. Herhangi bir, sınıf adının Excel'i almasından sonra ( yazmayı dener.

Sorun şu ki, VB_PredeclaredId true değerine ayarlanmış ve varsayılan üye kendini döndürmeye çalışıyor.

0x0F06EC84 EXCEL.EXE (VBE7.DLL) de

işlenmeyen özel durum: 0xC00000FD: Yığın taşması (parametreler ölmekten Excel örneğine bir hata ayklayc zaman, altta yatan sorun yığın taşması olduğunu görebiliriz : 0x00000001, 0x00212FFC). Init() herhangi özelliklere sahip olmadığından

Eğer With TestCrashClass( tip

, ne olur, VBA bir dizinleyicideki varsayılan mülkiyet aramaya başlar olmasıdır. Örneğin, Collection'u düşünün. Böyle varsayılan tesisin ( Item) dizinleyici kullanabilirsiniz: Bu Debug.Print x.Items(1) ile tamamen aynıdır

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

. Sorun yaşadığın yer burası. Init() parametresine sahip değildir, bu nedenle VBA, bir indeksleyiciye sahip olanı bulmak için varsayılan üyeler arasında aşağı açılır. Böylece IntelliSense, parametre listesini görüntüleyebilir. Bunu yaparken başlar: Senin durumunda

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

, bu sonsuz döngü yaratıyor çünkü [default]dönerx. (Bir bulursa hariç) aynı şey yukarıda Collection kodunda olur:

Private Sub Class_Initialize() 
    Class_Initialize 
End Sub 
: Varsayılan bir örneği var ve sonuç böyle bir şey olduğunu aslında

IntelliSense on open parens

Throw

+0

Tamam, bu mantıklı. Detaylar için teşekkürler. –

-4

Bir çeşit yolsuzluk gibi görünüyor. Excel'in normalde büyük projelerde böyle mantıksız davrandığını gördüm ve etrafta dolaşmanın tek yolu tüm sınıflarınızı vb. Yeni bir projeye sürüklemektir.

Bunun nedeni, Excel'in kaldırılmış sınıfları, modülleri, çalışma sayfalarını vb. Dosya boyutu nedeniyle bunu söyleyebilirsin.

hiçbir Kompakt ve Onarım işlevselliği kadarıyla ben

+0

Aynı şey tamamen yeni bir proje ile de olur. –

7

olarak @TimWilliams aynı sınıfının bir örneğini döndürür varsayılan üye olan işaret farkındayım olarak, Access'te olarak vardır (ya da Örneğin, ParentClass ve ChildClass öğelerinin her ikisi de varsayılan üyelere sahip olan sınıf döngüsü gibi ParentClass.ChildClass.ParentClass.ChildClass... ve With bloğu gibi belirli sözdizimi durumlarda kullanıldığında, VBE'nin varsayılan üyeyi denemesine ve çözmesine neden olur.

İlk parantez, VBE'nin bir yöntem olması gerektiğine, get dizinine veya bir argüman alacak dizi dizisine sahip olduğunu varsayar, böylece nihai hedef öğeyi çözmek için yola çıkar.

Bir noktada
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. 

, sistem veya VBE biterse:

Yani parantez sonra bulunan bir imleç ile eksik hattı,: olarak

With TestCrashClass(

etkili aynı mı Bir termonükleer grup-sarılmanın zarafeti ve poiti ile kaynakları ve çıkışları.Bir parantez çiftinin kopyası/makarnası ile doğaçlama için

+1.

+2

thermonuclear grup-sarısı benim +1 –

+2

alır Benim itiraf etmeliyim Ne kadar ilerlediğini görmek için, sağa doğru kaydırma yaptım. Teşekkürler! –