What is a recordset clone?

D

Dirk Goldgar

Robert said:


A recordsetclone is a "clone" of a recordset -- that is, a recordset object
that is created by copying an existing one. The Recordset object, in both
the DAO and the ADO object libraries, has a Clone method to create such an
object. An Access form has a RecordsetClone proeprty, which returns a clone
of the form's recordset -- not the form's recordset itself, but a copy of
it.

The handy thing about the recordset clone is that its Bookmark proeprty is
compatible with that of its parent recordet, so you can synchronize the two
by matching bookmarks. Most commonly this is used to find a record in the
form's RecordsetClone, and then position the form to that record by setting
the form's Bookmark property to the recordsetclone's Bookmark.
 
R

Robert

Thank you.
Dirk Goldgar said:
A recordsetclone is a "clone" of a recordset -- that is, a recordset
object that is created by copying an existing one. The Recordset object,
in both the DAO and the ADO object libraries, has a Clone method to create
such an object. An Access form has a RecordsetClone proeprty, which
returns a clone of the form's recordset -- not the form's recordset
itself, but a copy of it.

The handy thing about the recordset clone is that its Bookmark proeprty is
compatible with that of its parent recordet, so you can synchronize the
two by matching bookmarks. Most commonly this is used to find a record in
the form's RecordsetClone, and then position the form to that record by
setting the form's Bookmark property to the recordsetclone's Bookmark.

--
Dirk Goldgar, MS Access MVP
www.datagnostics.com

(please reply to the newsgroup)
 
D

David W. Fenton

An Access form has a RecordsetClone proeprty, which returns a
clone of the form's recordset -- not the form's recordset itself,
but a copy of it.

Er, to be more precise, the RecordsetClone *is* a clone of the
recordset and can be operated on directly, like any other recordset
or recordset clone. It can also be used as a FUNCTION that returns a
pointer to itself (not a new clone of the form's RecordsetClone).

It sounds to me as though you code like this:

Dim rs As DAO.Recordset

Set rs = Me.RecordsetClone
[do something with the rs variable you've just created]
Set rs = Nothing

Instead, it's *much* easier and cleaner to do this:

With Me.RecordsetClone
[do something with the actual RecordsetClone]
End With

No cleanup, no variable declaration, not SET operations, no extra
memory allocated for the pointer to an object that already exists in
memory and has an object that already exists for using.
 
D

Dirk Goldgar

David W. Fenton said:
Er, to be more precise, the RecordsetClone *is* a clone of the
recordset and can be operated on directly, like any other recordset
or recordset clone.

Uh, that's pretty much what I said.
It can also be used as a FUNCTION that returns a
pointer to itself (not a new clone of the form's RecordsetClone).

I don't think that's true any more. In earlier versions of Access, as I
recall, a single clone of the form's recordset would be created the first
time the RecordsetClone property was interrogated, and then that same clone
would be supplied to all future requests for the property until the form was
closed. However, in more recent versions, a new clone of the form's
recordset is taken each time the RecordsetClone property is asked for. This
has meant that code like this:

Me.RecordsetClone.FindFirst "ID = " & varIDWanted
Me.Bookmark = Me.RecordsetClone.Bookmark

.... which used to work fine, no longer gives the desired result, because the
second RecordsetClone is not positioned at the same record as the first.
Instead, we have to write:

With Me.RecordsetClone
.FindFirst "ID = " & varIDWanted
Me.Bookmark = .Bookmark
End With
It sounds to me as though you code like this:

Dim rs As DAO.Recordset

Set rs = Me.RecordsetClone
[do something with the rs variable you've just created]
Set rs = Nothing

I haven't the faintest idea what would make you think that. You're jumping
to a conclusion that is not supported by any evidence.
Instead, it's *much* easier and cleaner to do this:

With Me.RecordsetClone
[do something with the actual RecordsetClone]
End With

I agree. See any of umpty-zillion code snippets I've posted.
No cleanup, no variable declaration, not SET operations, no extra
memory allocated for the pointer to an object that already exists in
memory and has an object that already exists for using.

However, I think you're overstating the case a bit. If I write ...

With Me.RecordsetClone
' Do stuff
End With

An object reference still has to be retrieved, stashed in a local memory
location, and then freed up when the block exits. I don't see any reason
that what goes on behind the scenes would be significantly different from
what goes on if I write:

Dim rs As Recordset
Set rs = Me.RecordsetClone
' Do stuff
Set rs = Nothing ' or just wait for procedure clean-up

Oh, I suppose there's initialization and cleanup code involved when you use
a local variable that may not be when you use the With block, but I think
local memory is still going to be allocated for the object pointer either
way.
 
P

Pat Hartman

I would point out that the RecordSet clone of a form or report is a DAO
object in all versions of Access, even in 2K and XP where the default
library was ADO. This caused great confusion as you might imagine.
 
D

David W. Fenton

Uh, that's pretty much what I said.

No, it's not at all the same thing. You said the property returns a
clone, just as Me.Recordset.Clone would. But instead,
..RecordsetClone is a clone that already exists, and is created when
the form's recordset is populated.
I don't think that's true any more. In earlier versions of
Access, as I recall, a single clone of the form's recordset would
be created the first time the RecordsetClone property was
interrogated,

I think it's created when the form's recordset is created.
and then that same clone
would be supplied to all future requests for the property until
the form was closed. However, in more recent versions, a new
clone of the form's recordset is taken each time the
RecordsetClone property is asked for.

No, that's the case only in ADPs, according to Michael Kaplan:

In an ADP file, every time you retrieve the RecordsetClone of a
form, you will be given a new instance of a cloned recordset.
This is not the case in an .MDB file, where you always have in
the past and continue in the present day to use the same
recordset and cursor.
-- http://trigeminal.com/usenet/usenet022.asp?1033
This
has meant that code like this:

Me.RecordsetClone.FindFirst "ID = " & varIDWanted
Me.Bookmark = Me.RecordsetClone.Bookmark

... which used to work fine, no longer gives the desired result,
because the second RecordsetClone is not positioned at the same
record as the first. Instead, we have to write:

With Me.RecordsetClone
.FindFirst "ID = " & varIDWanted
Me.Bookmark = .Bookmark
End With

According to MichKa, both should work in an MDB. As I don't use ADPs
(except for SQL Server administration), that issue is irrelevant to
me. And, it's equally irrelvant because I always use the With block
for accessing the form's RecordsetClone.
It sounds to me as though you code like this:

Dim rs As DAO.Recordset

Set rs = Me.RecordsetClone
[do something with the rs variable you've just created]
Set rs = Nothing

I haven't the faintest idea what would make you think that.
You're jumping to a conclusion that is not supported by any
evidence.

Well, I didn't know you were applying ADP issues to MDBs.
Instead, it's *much* easier and cleaner to do this:

With Me.RecordsetClone
[do something with the actual RecordsetClone]
End With

I agree. See any of umpty-zillion code snippets I've posted.
No cleanup, no variable declaration, not SET operations, no extra
memory allocated for the pointer to an object that already exists
in memory and has an object that already exists for using.

However, I think you're overstating the case a bit. If I write
...

With Me.RecordsetClone
' Do stuff
End With

An object reference still has to be retrieved, stashed in a local
memory location, and then freed up when the block exits. I don't
see any reason that what goes on behind the scenes would be
significantly different from what goes on if I write:

Dim rs As Recordset
Set rs = Me.RecordsetClone
' Do stuff
Set rs = Nothing ' or just wait for procedure clean-up

Oh, I suppose there's initialization and cleanup code involved
when you use a local variable that may not be when you use the
With block, but I think local memory is still going to be
allocated for the object pointer either way.

But you don't have to code it. That's a good thing, no?

And actually, I'm not so sure there's anything new allocated, except
whatever memory the WITH block takes (it has a pointer to the
RecordsetClone, I guess, or to whatever object you use it on).

I think your description of a RecordsetClone is misleading as it
*does* exists before you call it. At least, according to MichKa.
 
D

Dirk Goldgar

David W. Fenton said:
No, it's not at all the same thing. You said the property returns a
clone, just as Me.Recordset.Clone would. But instead,
.RecordsetClone is a clone that already exists, and is created when
the form's recordset is populated.

I didn't say it returns a *fresh* clone, just that it returns a clone, which
we both agree it does. So my original statement is true as written.

However, I did in fact think that, in recent versions, the RecordsetClone
property returned a new clone each time. I've tested that now and found
that I was wrong:

Set rs1 = Me.RecordsetClone
Set rs2 = Me.RecordsetClone

Debug.Print rs1 Is rs2 ' prints True

If ADPs behave differently, perhaps that's where my incorrect understanding
came from (though I've never done more than dabble with ADPs).
I think it's created when the form's recordset is created.

That could be, but is there any reason to think that it's not created the
first time the property is interrogated? To my mind, that would be more
efficient. Why create the clone if it's not going to be used?
But you don't have to code it. That's a good thing, no?

It is as far as I am concerned. But then, I've always advocated the use of
With blocks. You're preaching to the choir here.
I think your description of a RecordsetClone is misleading as it
*does* exists before you call it. At least, according to MichKa.

That question -- whether it exists before the first time you call it -- is a
separate one from whether a new clone is created each time. That's really
only of academic interest, but I don't see in the article you linked to
where MichKa actually says anything about that.

Anyway, you're right about not getting a fresh clone each time you call for
RecordsetClone in an MDB. Thanks for correcting my misunderstanding.
 
D

David W. Fenton

I didn't say it returns a *fresh* clone, just that it returns a
clone, which we both agree it does.

Not, it returns not "a" clone, but *the* clone that is created with
the form's recordset.
So my original statement is true as written.

What you wrote seemed to imply to me that what was returned was a
fresh clone, sort of the way CurrentDB() works as both function and
object.
However, I did in fact think that, in recent versions, the
RecordsetClone property returned a new clone each time. I've
tested that now and found that I was wrong:

Set rs1 = Me.RecordsetClone
Set rs2 = Me.RecordsetClone

Debug.Print rs1 Is rs2 ' prints True

If ADPs behave differently, perhaps that's where my incorrect
understanding came from (though I've never done more than dabble
with ADPs).

I assumed that was where you were getting that.
That could be, but is there any reason to think that it's not
created the first time the property is interrogated?

I don't think of it as a property. Is a control a property of a
form? Not to my way of thinking (even though it's treated that why
by the behind-the-scenes properties that are created and accessible
with the . operator). To me, it's an object that is a child of the
form.
To my mind, that would be more
efficient. Why create the clone if it's not going to be used?

Well, I'm not certain it makes much difference whether it's created
only when requested or exists already whether it's not used of not,
as it's only a pointer structure, in any case.

Anyway, if Helen Keller falls over in the forest, is there a sound?
 
Top