How to keep a non-default form instance open without an external reference... (1 Viewer)

MarkK

bit cruncher
Local time
Today, 12:10
Joined
Mar 17, 2004
Messages
8,178
Using non-default instances of forms can be very powerful. See Allen Browne's discussion of non-default instances, and a technique to keep them open here: http://allenbrowne.com/ser-35.html

VBA keeps a class instance alive based on reference counts, so if there is one reference to an instance, garbage collection leaves it alone, but if that last reference goes out of scope the object is quickly gobbled up. Consider this code that creates a non-default instance of a form...
Code:
sub createform
   dim frm as form
   set frm = new form_form1
   frm.visible = true
end sub
This form will open for a second, become visible, but when frm goes out of scope the reference count to the Form_Form1 instance goes down to zero, and garbage collection destroys the object, reclaims the memory, and the form winks out of existence.

But the form can also maintain its own reference count with code like...
Code:
Private m_frm As Form

Private Sub Form_Load()
    Set m_frm = Me
End Sub
...so the form maintains an object reference to itself, VBA is fine with that, and the form stays open without any external references.

What I'm not sure of yet is whether this is a memory leak. If you close the form, it closes, but I don't have time to test if the object is released from memory or not.

Here's a sample Db too...
 

Attachments

  • ndTest.zip
    18 KB · Views: 56

static

Registered User.
Local time
Today, 19:10
Joined
Nov 2, 2015
Messages
823
set frm = new form_form1

creates a new form1, so you can display many form1s stored in a collection or array.

Set m_frm = Me

just sets a pointer to an already existing form.

Or am I missing something?


edit+

Ran your little test and yes it's quite interesting. I've no idea why it happens though.
 
Last edited:

MarkK

bit cruncher
Local time
Today, 12:10
Joined
Mar 17, 2004
Messages
8,178
You don't need to add the new object to a collection or array. In VBA, as long as there is one object variable pointing to the new instance, garbage collection leaves it alone, and in this case, the object variable pointing to the new instance is in the form itself. It's like a bootstrap method.

But what I bet you need to do on close is dereference it, like this...
Code:
private sub form_unload(cancel as integer)
   set m_frm = nothing
end sub
...otherwise I bet Access closes the form, but VBA garbage collection never reclaims the memory, because the object still has a live object variable pointing to it.

Here's how you can leak memory in VBA...
http://www.vbi.org/Items/article.asp?id=106
...nut no time to test it right now.
 

static

Registered User.
Local time
Today, 19:10
Joined
Nov 2, 2015
Messages
823
I don't think you've created a circular reference here.

The form stays open because something is pointing to it (itself).

As soon as you set the object variable to nothing the form closes because it no longer has an owner.

Closing the form would destroy the object variable so no need to even clear it.
 

Users who are viewing this thread

Top Bottom