473,545 Members | 2,413 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Tip for dealing with circular reference issue

I just came up with a really tidy little solution to the VB/VBA circular
reference issue. It only works with Access 2000 or newer, but that's about
the only down-side.

The issue...
You need an object model that includes a container object, and the object in
the container need to interact with the container itself. The problem is
that, to access the container, each item needs a reference to the container,
and that constitutes a circular reference since the container also contains an
array or a collection that contains a reference to the contained object.
Unless extreme caution is used, this structure can hold itself in memory even
though all externalr references to it have gone out of scope, and memory will
gradually be swallowed up each time a new one is created.

As of Access 2000, there is a tool that seems to handle this which is the
ability to create and raise custom events to communicate with a referring
object, but this only works for single references, not arrays or collections.

The solution...
Create a generic proxy class that can be referenced by both a container and a
contained item that can be asked to raise an event to the container to ask for
a temporary reference to the container for use within a single function call.

clsContainerAcc essor
==========
Option Explicit
Option Compare Database

Event RequestReferenc e(ByRef objReference As Object)

Public Property Get Reference() As Object
Dim objReference As Object
RaiseEvent RequestReferenc e(objReference)
Set Reference = objReference
End Property
==========

In the contianer, add code like this...
==========
Private WithEvents mobjAccessor As clsContainerAcc essor

Private Sub mobjAccessor_Re questReference( objReference As Object)
Set objReference = Me
End Sub

Private Sub Class_Initializ e()
Set mobjAccessor = New clsContainerAcc essor
End Sub
==========

When the container creates a new contained item, it can supply the item with a
reference to mobjAccessor, and the item can obtain a temporary reference to
the container by accessing the Reference property of that object as needed.
Nov 12 '05 #1
11 9032
rkc

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:6k******** *************** *********@4ax.c om...
I just came up with a really tidy little solution to the VB/VBA circular
reference issue. It only works with Access 2000 or newer, but that's about the only down-side.

The issue...
You need an object model that includes a container object, and the object in the container need to interact with the container itself. The problem is
that, to access the container, each item needs a reference to the container, and that constitutes a circular reference since the container also contains an array or a collection that contains a reference to the contained object.
Unless extreme caution is used, this structure can hold itself in memory even though all externalr references to it have gone out of scope, and memory will gradually be swallowed up each time a new one is created.


How do you suppose Me.Parent works without swallowing up memory?

Nov 12 '05 #2
It does not cache an instance -- there is a weak ref to the parent and the
object is retrieved as needed.
--
MichKa [MS]
NLS Collation/Locale/Keyboard Development
Globalization Infrastructure and Font Technologies

This posting is provided "AS IS" with
no warranties, and confers no rights.
"rkc" <rk*@yabba.dabb a.do.rochester. rr.nope> wrote in message
news:Qt******** ***********@twi ster.nyroc.rr.c om...

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:6k******** *************** *********@4ax.c om...
I just came up with a really tidy little solution to the VB/VBA circular
reference issue. It only works with Access 2000 or newer, but that's about
the only down-side.

The issue...
You need an object model that includes a container object, and the object in
the container need to interact with the container itself. The problem

is that, to access the container, each item needs a reference to the

container,
and that constitutes a circular reference since the container also

contains an
array or a collection that contains a reference to the contained object.
Unless extreme caution is used, this structure can hold itself in memory

even
though all externalr references to it have gone out of scope, and memory

will
gradually be swallowed up each time a new one is created.


How do you suppose Me.Parent works without swallowing up memory?

Nov 12 '05 #3
rkc

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:6k******** *************** *********@4ax.c om...
I just came up with a really tidy little solution to the VB/VBA circular
reference issue. It only works with Access 2000 or newer, but that's about the only down-side.


<snip>

Your post and M.Kaplan's reply to my me.parent question caused me to
spend my hung-over morning reading up on this.

This was the most interesting article I found:
http://www.programmersheaven.com/art...y/article1.htm

Also
http://msdn.microsoft.com/library/de...references.asp

and
http://msdn.microsoft.com/library/de...ctlifetime.asp

This is how I implemented your solution.
Do I get it?

<Employee class>
Private Name_ As String
Private Department_ As Accessor

Public Property Let Name(n As String)
Name_ = n
End Property

Public Property Get Name() As String
Name = Name_
End Property

Public Property Set Department(acc As Accessor)
Set Department_ = acc
End Property

Public Property Get Department() As String
Department = Department_.Ref erence.Name
End Property
</Employee class>

<Department class>
Public Name As String
Public Employees As New Collection
Private WithEvents mobjAccessor As Accessor

Public Sub AddEmployee(ByV al strName As String)
Dim e As Employee

Set e = New Employee
e.Name = strName
Set e.Department = mobjAccessor
Employees.Add e

Set e = Nothing
End Sub

Private Sub mobjAccessor_Re questReference( objReference As Object)
Set objReference = Me
End Sub

Private Sub Class_Initializ e()
Set mobjAccessor = New Accessor
End Sub
</Department class>
Nov 12 '05 #4
It's not the style I would have used, but yes, you did it right, and you
appear to get it.

The main thing I would do differently is to never use underscore characters in
the names of anything in VB/VBA (except where it puts them, such as
mobjAccessor_Re questReference) . VB has its own meanings for underscores, and
you can mess yourself up if you use them yourself.

Specifically, Access uses underscores to identify event handlers and
implementations of interface members.

On Thu, 01 Jan 2004 17:37:24 GMT, "rkc" <rk*@yabba.dabb a.do.rochester. rr.nope>
wrote:

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:6k******* *************** **********@4ax. com...
I just came up with a really tidy little solution to the VB/VBA circular
reference issue. It only works with Access 2000 or newer, but that's

about
the only down-side.


<snip>

Your post and M.Kaplan's reply to my me.parent question caused me to
spend my hung-over morning reading up on this.

This was the most interesting article I found:
http://www.programmersheaven.com/art...y/article1.htm

Also
http://msdn.microsoft.com/library/de...references.asp

and
http://msdn.microsoft.com/library/de...ctlifetime.asp

This is how I implemented your solution.
Do I get it?

<Employee class>
Private Name_ As String
Private Department_ As Accessor

Public Property Let Name(n As String)
Name_ = n
End Property

Public Property Get Name() As String
Name = Name_
End Property

Public Property Set Department(acc As Accessor)
Set Department_ = acc
End Property

Public Property Get Department() As String
Department = Department_.Ref erence.Name
End Property
</Employee class>

<Department class>
Public Name As String
Public Employees As New Collection
Private WithEvents mobjAccessor As Accessor

Public Sub AddEmployee(ByV al strName As String)
Dim e As Employee

Set e = New Employee
e.Name = strName
Set e.Department = mobjAccessor
Employees.Add e

Set e = Nothing
End Sub

Private Sub mobjAccessor_Re questReference( objReference As Object)
Set objReference = Me
End Sub

Private Sub Class_Initializ e()
Set mobjAccessor = New Accessor
End Sub
</Department class>


Nov 12 '05 #5
rkc

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:gn******** *************** *********@4ax.c om...
It's not the style I would have used, but yes, you did it right, and you
appear to get it.

The main thing I would do differently is to never use underscore characters in the names of anything in VB/VBA (except where it puts them, such as
mobjAccessor_Re questReference) .


My naming conventions in throw away code change with the wind direction.
That's the first time I have ever used and underscore to indicate a member
variable. Just wanted to see how it looked.

I'll take your advice on it.


Nov 12 '05 #6
On Thu, 01 Jan 2004 23:30:01 GMT, "rkc" <rk*@yabba.dabb a.do.rochester. rr.nope>
wrote:

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:gn******* *************** **********@4ax. com...
It's not the style I would have used, but yes, you did it right, and you
appear to get it.

The main thing I would do differently is to never use underscore

characters in
the names of anything in VB/VBA (except where it puts them, such as
mobjAccessor_Re questReference) .


My naming conventions in throw away code change with the wind direction.
That's the first time I have ever used and underscore to indicate a member
variable. Just wanted to see how it looked.

I'll take your advice on it.


Incidenally, if anyone is interested, there is also a more complicated
solution that can work in Access 97 because it doesn't use custom events. I
prefer it to pointer-based weak references because it doesn' have to "look
under the hood" to work.

Basically, when you have a structure of interrelated objects that must "see"
each other, you wrap the whole structure in another object reference that can
properly tear down the structure it wraps when it gets terminated itself.

Here's a simplified example:

clsDepartment
==========
Option Compare Database
Option Explicit

Public Department As clsDepartmentDa ta
Public Employees As VBA.Collection

Private Sub Class_Initializ e()
Set Department = New clsDepartmentDa ta
Set Employees = New VBA.Collection
Department.Setu p Employees
End Sub

Private Sub Class_Terminate ()
While Employees.Count > 0
Employees.Remov e 1
Wend
End Sub

Public Function AddEmployee() As clsEmployeeData
Dim objNewEmployee As clsEmployeeData
Set objNewEmployee = New clsEmployeeData
objNewEmployee. Setup Department
Employees.Add objNewEmployee
Set AddEmployee = objNewEmployee
End Function
clsDepartmentDa ta
==========
Option Compare Database
Option Explicit

Private mcolEmployees As VBA.Collection

Public Sub Setup(colEmploy ees As VBA.Collection)
Set mcolEmployees = colEmployees
End Sub
clsEmployee
==========
Option Compare Database
Option Explicit

Private mobjDepartment As clsDepartmentDa ta

Public Sub Setup(objDepart ment As clsDepartmentDa ta)
Set mobjDepartment = objDepartment
End Sub
The circular reference occurs because the clsDepartmentDa ta object refers to a
Collection object which refers to 0 or more clsEmployeeData objects which each
refer to back to the clsDepartmentDa ta object. The trick that allows for
proper cleanup is that nothing in that reference loop references the
clsDepartment object, so that will be allowed to terminate properly, and when
it terminates, it removes all the clsEmployeeData entries from the collection,
so they are no longer referenced from anything and will then go out of scope.
Now, with the clsEmployeeData objects gone, only the clsDepartment object
refers to the clsDepartmentDa ta object, so it, too can go out of scope along
with the clsDepartment object.

The down-side of this approach is that, when structures become more
complicated than a simple 1-M, the logic can get hairy really fast, and that
means it can be easy to overlook a circular reference case that will not be
torn down properly. On the plus-side, this code may perform better than the
Event proxy approach in many cases (not all cases as it might appear, but many
cases).
Nov 12 '05 #7
rkc

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:ic******** *************** *********@4ax.c om...
Incidenally, if anyone is interested, there is also a more complicated
solution that can work in Access 97 because it doesn't use custom events. I prefer it to pointer-based weak references because it doesn' have to "look
under the hood" to work.


There's also keeping a collection of Container objects and simply
storing the key as a member of the Contained object.
Nov 12 '05 #8
On Sat, 03 Jan 2004 00:54:59 GMT, "rkc" <rk*@yabba.dabb a.do.rochester. rr.nope>
wrote:

"Steve Jorgensen" <no****@nospam. nospam> wrote in message
news:ic******* *************** **********@4ax. com...
Incidenally, if anyone is interested, there is also a more complicated
solution that can work in Access 97 because it doesn't use custom events.

I
prefer it to pointer-based weak references because it doesn' have to "look
under the hood" to work.


There's also keeping a collection of Container objects and simply
storing the key as a member of the Contained object.


Yes, I've used that one, but it proves to be pretty hairy, too. Basically,
you have a global Collection variable, and dynamically generate unique keys
for the items in it. Objects in relationship keep collections of the keys of
their relatives, and look them up dynamically when needed.

I decided this seemed unattractive because you need another standard module
that does nothing more than hold the global collection, and you also need an
extra step to generate a session-wide unique key for each item in the
collection. The best I was able to come up with is concatenating a looping
counter value to the address of the object (ObjPtr). The ObjPtr alone is not
enough because it does nto distinguish between an item no longer held in the
colleciton and a new one that happens to have been allocated in the same
memory location. Technically, the cylcing pointer doesn't totally solve the
problem either, but the odds of a duplicate are astronomically small.
Nov 12 '05 #9
tom
Steve,

This all looks very sexy, and I'm eager to try it out. Is it all
still holding up as far as you are concerned? How did you determine
that the objects are terminating properly?

I realize that there may be a circular reference or two in the
behemoth we have here. It would be very good to use this to clean that
up.

Thanks,
-Tom

I just came up with a really tidy little solution to the VB/VBA circular
reference issue. It only works with Access 2000 or newer, but that's about
the only down-side.

Nov 12 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1910
by: John E. | last post by:
How can I compile two projects with a circular reference while giving them a strong name? There is a project that we have that has two components that reference each other e.g. A<->B thus creating A.dll and B.dll. I have a project (e.g. R with an assembly name of Com.MyCompany.R.dll) that has to use this mess and access A. So, R->A. ...
1
484
by: ChrisB | last post by:
Hello: I have created several components that have the following dependency relationships: Assembly1 references assemblies A, B, and C. Assembly2 references assemblies A, B When attempting to allow Assembly 2 to reference Assembly1, the following message is returned: "A reference to Assembly1.Library could not be added. Adding this...
16
3963
by: Dave S | last post by:
Anyone know how to get round the problem of circular references in VB.NET (sorry I'm a .NET newbie). I create one project which has 2 classes in it, MyHandler and MyObject. MyHandler just needs to call another class in a different project and pass a parameter of type MyObject to it. So the class in the different project needs to import the...
6
5063
by: Stephen Robertson | last post by:
We are currently in a dead end with a circular reference issue using vb.net, and are hoping someone might help us resolve it. Idea... We have frmmain calling frmperson (dim f as new frmperson) in search (no record) mode. When the search is executed, frmperson calls frmsearchresult (dim f as new frmsearchresult) which is a listing of...
3
4387
by: Richard Lewis Haggard | last post by:
We are having a lot of trouble with problems relating to failures relating to 'The located assembly's manifest definition with name 'xxx' does not match the assembly reference" but none of us here really understand how this could be an issue. The assemblies that the system is complaining about are ones that we build here and we're not changing...
2
2590
by: ChrisB | last post by:
Hello, I was wondering what options are available for resolving the following (simplified) scenario. Two project exist and each contains a class: ProjectA - Class1 ProjectB - Class2 Additionally, Class2 needs to accept Class1 as a parameter:
8
4123
by: nyhetsgrupper | last post by:
I have written a windows service and want to expose a web based user interface for this service. I then wrote a class library containing a ..net remoting server. The class library have a method named StartRemotingServer(). To be able to call this method from the windows service I need to reference the remoting class library, but for the class...
3
3740
by: =?Utf-8?B?c2lwcHl1Y29ubg==?= | last post by:
Hi I Have a solution with about 50 projects and each project have References to 1 to n of the projects in the solution. I try go to a project and try to add a reference to another project and I get a Circular Reference" error and cannot reference the project. Is there any way to find out the what Method or Project is causing the problem...
0
7487
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7420
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
1
7446
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7778
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5349
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
4966
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3476
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
1908
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
731
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.