Solved NewEnum Crashes Access

Local time
Today, 06:13
Joined
Aug 10, 2024
Messages
39
The NewEnum get property is causing trouble in some of my Collection wrapper classes I'm trying to write. It seems to work for me in some projects/classes but not in others. I think there's some serious bug here. If I step (F8) through the For-Next loop (in the places where it doesn't work for me) it then works, but when I run through it normally its causes Access to crash.

I've been trying to pinpoint for hours to find out what is triggering this but to no avail. Does anybody else have experienced this problem?

BTW: I know of and tried the /decompile /repair /compact switches.

I'm using Access v16.0 (64 bit).

Attached is a copy of the database. And here's the code. There's not much to see and as simple as possible.

Even if I create a fresh database project and import those files it crashes for me. Perhaps I'm doing something wrong and can't see i, but again it works when stepping (F8) through the loop which tells me this is an Access bug.

Code:
Attribute VB_Name = "Module1"
Option Compare Database
Option Explicit

Dim Coll As New Class2

' This crashes when run (F5). However, when
' stepped (F8) through, it doesn't.
Sub Dump()
    Dim o As Object
    For Each o In Coll
        Debug.Print ObjPtr(o)
    Next
End Sub

' Add some object to the collection.
Sub AddSome()
    Coll.Add New Class1
End Sub

Some dummy class to add to the collection.

Code:
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "Class1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Compare Database
Option Explicit

' Empty dummy, to keep it simple.

And here's the minimal custom collection.

Code:
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "Class2"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Compare Database
Option Explicit

Private Coll As New Collection

Sub Add(ByVal Class2 As Class1)
    Coll.Add Class2
End Sub

Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
  Set NewEnum = Coll.[_NewEnum]
End Property
 

Attachments

Last edited:
Share the code or a db where it both works and where it doesn't.

Explain in detail what is happening.

You are then much more likely to have folk here be able to help you pinpoint any issues
Ok, attached the database and posted code.
 
Did you try the suggestion in the last answer?
This is just a superset of my posted example, so yes this is what I'm doing. However, I'll have to try to use the Dictionary instead of the Collection.

Keep in mind that it works for me when I single step the code but not when I run it normally.

Update: Dictionary does not support enumeration.
 
Last edited:
Did you try the suggestion in the last answer?
Oh, you are referring to this solution in the thread?

Code:
Public Function NewEnum() As Collection
        Set NewEnum = m_ObjectCollection
End Function

Well, this just returns a reference to the inner collection by a function called NewEnum but not an enumerator. Then you could just make your inner collection public and achieve the same thing.
 
Your example is so poor and not flushed out it is not worth trying to answer why it does not work.
Here is a real example of a fully flushed out custom collection class supporting enumeration and default methods in the class and collection class.
Well, I deleted all the noise around it because it is irrelevant to my question and your readers time. My question simply was why NewEnum crashes and not how to make a complete collection wrapper class with everything included which doesn't answer my question at all. The issue is not that it is incomplete (from your viewpoint) but simply that the enumerator crashes when I run it but works when I single step (F8) through it.

Anyways thanks for your example as a reference. So, when I look at your code, the NewEnum is like mine besides the attribute with the value 40 which, I think, is ignored by VBA (so I read). This tells me that NewEnum is correct.

Anyways I figured out why my example crashes Access (at least for me on my system). It might interest you that it crashes your Pet project as well. Here's a code module that demonstrates it. If you run (F5) First_AddSomePets and then run (F5) Second_IterateAndCrahit crashes Access on my system. If I single step it (F8), the last step works for me.

Now, if I was copying the content of First_AddSomePets into Second_IterateAndCrash, like it is in your test functions, then it works. However, this is a rather theoretical use case as the instantiation of a collection object and adding to it typically happens in different contextes over time, like shown by my example.

Code:
Attribute VB_Name = "CRASH"
Option Compare Database
Option Explicit

Dim myPets As New Pets

' Run this first (F5)
Sub First_AddSomePets()
  myPets.Add "Toto", 5, "Dog", "Bow wow"
  myPets.Add "Flipper", 8, "Dolphin", "Squeak whistle"
End Sub

' Run this second (F5) which crashes on me.
' Althought it won't crash when stepped (F8) through.
Sub Second_IterateAndCrash()
    Dim myPet As Pet
    For Each myPet In myPets
        Debug.Print myPet.Name
    Next
End Sub
 
The NewEnum get property is causing trouble in some of my Collection wrapper classes I'm trying to write. It seems to work for me in some projects/classes but not in others. I think there's some serious bug here. If I step (F8) through the For-Next loop (in the places where it doesn't work for me) it then works, but when I run through it normally its causes Access to crash.
Further looking into this with more examples:
Code:
' Crashes
Sub Crash()
    AddSome
    AddSome
    Dump
End Sub

No crash here:
Code:
Sub NoCrash()
    AddSome
    AddSome

    Dim o As Object
    For Each o In Coll
        Debug.Print ObjPtr(o)
    Next
End Sub

Again no crash:
Code:
Sub Dummy()
End Sub

' No crash triggered.
Sub Dump2()
    Dummy
    
    Dim o As Object
    For Each o In Coll
        Debug.Print ObjPtr(o)
    Next
End Sub

While experimenting I sometimes could get an error message telling me that the automation object has disconnected from the client. Given all this it looks to me this is a bug.
 
I have never had a crash when used with 100s of collection classes.
 
Last edited:
The NewEnum get property is causing trouble in some of my Collection wrapper classes I'm trying to write. It seems to work for me in some projects/classes but not in others. I think there's some serious bug here. If I step (F8) through the For-Next loop (in the places where it doesn't work for me) it then works, but when I run through it normally its causes Access to crash.
I updated Access to Build 2406 17726.20206 and the problem went away.

I think I was on 2405.
 

Users who are viewing this thread

Back
Top Bottom