On 20 Jan 2004 18:42:27 -0800,
dr**********@hotmail.com (Terry Bell) wrote:
Steve Jorgensen <no****@nospam.nospam> wrote in message news:<tl********************************@4ax.com>. .. On 20 Jan 2004 03:35:05 -0800, dr**********@hotmail.com (Terry Bell) wrote:
Well that's interesting.
So is this what happens?
When you Dim y and do the For Each, on each iteration
it assigns to y a pointer to the recordset structure.
The Close works, because that's an operation on the
structure that's being pointed to.
But Set y = Nothing ... does nothing because y is not
explicitly associated with an object variable?
And thanks Lyle I tried your test with Steve's code
and confirmed it worked.
Terry
Close - very close, but not quite.
This following may benefit some future Google searchers...
OK, the recordset itself is an object instance located somewhere in memory as
you suggest. Technically, it is stored as a structure (with its own
references to other structures), but we don't think of them as mere
structures, because metaphorically, they have behaviors as well as data,
though technically, the behaviors are implemented by the inderlyng class code.
Anyway, the code that calls our function has a recordset variable which is
just little more than a pointer to the recordset instance. The little more
part is that the recordset also knows what references are pointing to it, and
will go out of scope only when all of those pointers go out of scope or are no
longer pointing to that object.
So, when you call the function, the parameters are passed by reference unless
you say otherwise, which means that when you manipulate the reference, you are
directly manipulating the variable passed to the reference by the calling
code. It turns out this works with paramarrays as well such that each element
in the array is actually a reference to the variable that was passed to it,
not a copy of its contents. In a way, you could say the parameter in the
function operates as a pointer to the Recordset variable in the calling
function, which in turn acts as a pointer to the Recordset instance somewhere
in memory. Note that there is actually only one thing pointing directly to
the Recordset instance, so the reference counter is 1.
Now, if I make a new Recordset variable (or variant that will hold a recordset
reference), and I copy the parameter to it, I now have 2 direct references to
the recordset, and on indirect reference. The reference count is 2. If I set
the second variable to Nothing, it reduces the reference count to 1 because
the second one no longer points to the recordset, but it has no effect on the
original reference which what accounts for the 1-count.
When you run the For Each loop, the item variable is being successively
assigned copies of the Recordset references just as if you manually assigned
them, so each Recordset's reference count goes briefly to 2, then back down to
1. The calling code's references all still point to the instance, so it does
not get released.
When we loop through, and directly assign the paramarray elements to Nothing,
these assignments apply to the variables passed to those parameters directly,
so the original reference is being released, and the Recordset can get
released.