Question

Can't use Recordset Clone

Asked by: BobHavertyComh

I'm trying to use Recordset.Clone to populate a recordset obj on the before update event. Access doesn't seem to like that if I am entering in a new record and I guess because there's nothing to clone? Sow how would I populate a recordset obj with the data that the user has entered if it's a new record? Also note, I'm using Access 2007 multi value fields. This code works except that it doesn't perform Recordset.Clone, so it never even makes it to the point of populating the nested recordset with the values of the field. if it's a new record, so what should I replace it with if it IS a new record?

As far as fieldsArray(outerCount), that's just an array index containing string values of all of the field names on the form. I just use it to loop through all of the fields and then grabbing their values

Set objRSNew = Me.Recordset.Clone
Set objRSNew1 = objRSNew.Fields(fieldsArray(outerCount)).Value

                                  
1:
2:

Select allOpen in new window

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-06-09 at 06:17:20ID24475463
Topic

Microsoft Access Database

Participating Experts
2
Points
500
Comments
31

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. ADO Recordset Clone
    I need to maintain 1 hours worth of real-time data. This data is sourced from an SQL Server database table. Pseudo code is as follows :- Read last 1 hours data into ADO Recordset. Create local replica of recordset Then periodically Read data generated since last recordse...
  2. ADO RecordSet Cloning in MySQL
    I'm trying to clone an ADO Query's RecordSet to a Disconnected Dataset using the Clone command in the ADODataSet object. Does anybody know if MySQL supports cloning?

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: GRayLPosted on 2009-06-09 at 06:48:20ID: 24581072

In Access 2003, RecordsetClone is a single word.

 

by: BobHavertyComhPosted on 2009-06-09 at 06:55:51ID: 24581157

I think it is RecordsetClone according to the intellisense. However, it still bombs if it's a new record. I'm trying to use the info the user is submitting to write values to other tables, so when i use RecordsetClone on an update event, it seems to work, but I can't use it when it's a new record. Doesn't seem to have anything to clone I suppose, but I still need to find out the data the user has entered and make appropriate entries on other table whether it's a new record or an update. So what would be the equivalent of RecordsetClone in the situation of a new record?

 

by: GRayLPosted on 2009-06-09 at 07:01:31ID: 24581218

As it is a clone, I do not think you can edit it.  You can maniplulate/scroll it and select values, but not change or add.  What happens with:

Set objRSNew = Me.Recordset

 

by: BobHavertyComhPosted on 2009-06-09 at 07:07:02ID: 24581280

I don't need to edit it, I just need to get it's values into an object and then walk through those values to tell me which records on other tables need entries.

Set objRSNew = Me. Recordset bombs also. The debugger shows objRSNew to have a value of Nothing. So does this have to do with the fact that I'm entering a new record?

 

by: GRayLPosted on 2009-06-09 at 07:17:08ID: 24581386

This is how to get the values from unbound contros on a form into a table name myTable

strSQL = "INSERT INTO myTable (fld1, fld2, fld3) VALUES ( '" & Me!tbx1 & "','" & Me!tbx1 & "",'" & Me!tbx3 & "')"
DoCmd.RunSQL strSQL

this assumes text values in all three fields.  If any are numeric, omit the single quotes, if any are Date, replace the "'" with "#"

 

by: BobHavertyComhPosted on 2009-06-09 at 07:23:17ID: 24581447

GRayL, what I didn't say is that I can't use what you are suggesting because the field values are multi valued (Access 2007) and therefore I need to create one recordset for the field and then a nested one for the multiple values within the field, which are the values that I really want to get at..

 

by: LPurvisPosted on 2009-06-09 at 07:52:28ID: 24581771

Just a couple of quick comments.

RecordsetClone
and
Recordset.Clone

are both valid and describe different objects (which have effectively the same content and structure - baased as they are on the same core Recordset).

The RecordsetClone is a persisted object during the instance of the form.
Recordset.Clone is a method which creates a new clone of the recordset - as many of these as required may be created but they're not persisted by default. Your object variable does that for you.
Neither is read only unless the underlying recordset is too.

Can you include more code that you're running (describing what actually works and where the problem lies)?

 

by: BobHavertyComhPosted on 2009-06-09 at 08:11:57ID: 24581969

Here's the code. These are the only events I'm coding for. I used to update tblItems in the after insert event, but since it looks like the before update code always runs whether it's a new record or not, then I just put the after insert code into the before update code and then put conditionals to check if it's a new record or an update of an existing one.

In the case of both a new record and an update of an existing one, on the before update, I am walking through a number of numeric multi valued fields and retrieving their values and using them to mark the corresponding record numbers on another table by making some entries to that record. Basically, if a boardmodule is used inside of a system, then I have to go back to that boardmudule's table and mark which system it is now inside of. This prevents this boardmodule's number from showing back up in the query combo for subsequent record entries and/or changes. because it is now marked as already used. This is also why you see the requery of the combos in the form's current event.

If it is an update, then i have to do one more step. I have to compare the record ready to be submitted after edits, to what it orginally was. So I create and RSOld by querying the database for the record's state right before the changes are inserted and an RS that contains the changed values and if an RSOld value does not show up anywhere in the new value, then I need to go back to the record number contained in RSOld and clear the values that were entered earlier relating to what system it's in (because it's no longer in that system), so that it will now show up in the combo query and be available for addition to a system again. I'm sorry that I can't seem to find an easy way to communicate this, which is why I lose people. The fact that I'm walking through multi valued fields makes this a particular pain in the ass.

Option Compare Database
Public SystemsSN

Private Sub Form_BeforeUpdate(Cancel As Integer)
    Dim tablesArray(7) As String
    Dim outerCount As Long
    outerCount = 0
    tablesArray(0) = "tblAirCooledModule"
    tablesArray(1) = "tblRFTMCCModule"
    tablesArray(2) = "tblBBTMCCModule"
    tablesArray(3) = "tblChassisModule"
    tablesArray(4) = "tblCPUNumbers"
    tablesArray(5) = "tblGPSNumbers"
    tablesArray(6) = "tblJ2BackplaneNumbers"
    Dim fieldsArray(7) As String
    fieldsArray(0) = "Air Cooled Modules"
    fieldsArray(1) = "RFTM CC Modules"
    fieldsArray(2) = "BBTM CC Modules"
    fieldsArray(3) = "Chassis Modules"
    fieldsArray(4) = "CPU Numbers"
    fieldsArray(5) = "GPS Numbers"
    fieldsArray(6) = "J2 Backplane Numbers"
   
    Dim bDimmed As Boolean
    Dim bflag As Boolean
    Dim objRSOld As Recordset
    Dim objRSNew As Recordset
    Dim objRSOld1 As Recordset
    Dim objRSNew1 As Recordset
        If Me.NewRecord Then
            Dim cnn As ADODB.Connection
            Dim strSQL As String
            Set cnn = CurrentProject.Connection
            strSQL = "INSERT INTO tblItems (SerialNumber,ItemType) VALUES (" & SystemsSN & ",'tblSystems')"
            cnn.Execute strSQL
            Set cnn = Nothing
        End If
        For outerCount = 0 To 6
        If Me.NewRecord Then
            Set objRSNew = Me.Recordset
        Else
            Set objRSNew = Me.RecordsetClone
        End If
        Set objRSNew1 = objRSNew.Fields(fieldsArray(outerCount)).Value
        If Not Me.NewRecord Then
            Set objRSOld = CurrentDb.OpenRecordset("select" & fieldsArray(outerCount) & " from" & tablesArray(outerCount) & "where SN =" & SN)
            Set objRSOld1 = objRSOld.Fields(fieldsArray(outerCount)).Value
            Do Until objRSOld1.EOF
                bflag = True
                Do Until objRSNew1.EOF
                    If objRSOld1.Fields(0).Value = objRSNew1.Fields(0).Value Then
                        bflag = False
                    End If
                objRSNew1.MoveNext
                Loop
                If bflag = True Then
                    strSQL = "UPDATE" & tablesArray(outerCount) & " SET [System Number] = NULL, [System Type] = '' WHERE SN = " & objRSOld1.Fields(0).Value
                    cnn.Execute strSQL
                End If
            objRSOld1.MoveNext
            Loop
        End If
        Do Until objRSNew1.EOF
            strSQL = "UPDATE" & tablesArray(outerCount) & " SET [System Number]=" & SN & ", [System Type] =" & tablesArray(outerCount) & "WHERE SN = " & objRSNew1.Fields(0).Value
            cnn.Execute strSQL
            objRSNew.MoveNext
        Loop
        Set objRSNew = Nothing
        Set objRSOld = Nothing
        Set objRSNew1 = Nothing
        Set objRSOld1 = Nothing
        Next outerCount
End Sub


Private Sub Form_Current()
    If Me.NewRecord Then
        SN = DMax("SerialNumber", "tblItems") + 1
    End If
    [Air Cooled Modules].Requery
    [RFTM CC Modules].Requery
    [BBTM CC Modules].Requery
    [Chassis Modules].Requery
    [CPU Numbers].Requery
    [GPS Numbers].Requery
    [J2 Backplane Numbers].Requery
    SystemsSN = SN
End Sub


 

by: BobHavertyComhPosted on 2009-06-09 at 08:14:09ID: 24581989

As far as what is not working? So far, objRSNew is not getting populated by either Me.Recordset (in the case that it's a new record nor Me.RecordsetClone. Note, i have not been able to update yet because I can't enter a new record because those statements above fail on the before update event

 

by: GRayLPosted on 2009-06-09 at 09:10:58ID: 24582563

In this line:

Set objRSOld1 = objRSOld.Fields(fieldsArray(outerCount)).Value

You have dimensioned objRSOld1 as a recordset yet the line provides a single value??

 

by: BobHavertyComhPosted on 2009-06-09 at 09:19:42ID: 24582672

Somebody told me that this would put all of the values from a multi valued field into this nested recordset. nobody seems to really know a lot about multi valued fields and i guess because it's only in Access 2007. But the first problem is that objRSNew isn't even getting populated by either Me.Recordset or Me.Recordset.Clone. The debugger tells me it's empty. How can a simple statement like this in the before update event fail? This is my immediate problem

If Me.NewRecord Then
            Set objRSNew = Me.Recordset
        Else
            Set objRSNew = Me.RecordsetClone
        End If
        Set objRSNew1 = objRSNew.Fields(fieldsArray(outerCount)).Value

 

by: BobHavertyComhPosted on 2009-06-09 at 09:22:40ID: 24582713

Since objRSNew comes up as empty or "Nothing", which it shouldn't, it bombs when trying to set objRSNew1 while using objRSNew.fields because objRSNew is empty or null "Nothing"

 

by: GRayLPosted on 2009-06-09 at 09:37:22ID: 24582884

Yes, but you are trying to set a recordset equal to the value of a field ??  That should blow a fuse when the compiler gets to it ;-)

 

by: BobHavertyComhPosted on 2009-06-09 at 10:03:48ID: 24583200

GRayL

Why does objRSNew = Me.RecordsetClone never populate objRSNew when a new record is being entered? That is my problem. The other stuff I'll deal with when i first get past this. As far as the compiler not blowing a fuse, it understands multi valued fields. Do you have an experience with Access 2007 multi value fields? I don't have much which is why I'm looki9ng for someone who does.

 

by: LPurvisPosted on 2009-06-09 at 12:25:49ID: 24584728

I see there's been some chatter on this. :-)
Right, so... what's been happening.

Well - even if there was type mismatch, the compiler wouldn't pick it up, it would be a runtime error at most.
However the code presented shouldn't be a problem. They key is that it's assigning the content of a field to a recordset object.
So we'd get a type mismatch (recordset <> field) if it were just
Set objRSNew1 = objRSNew.Fields(fieldsArray(outerCount))
However
Set objRSNew1 = objRSNew.Fields(fieldsArray(outerCount)).Value
is assigning a recordset object - as the field is multi-value.

It's not a new concept to DAO in 2007, ADO has been doing this with shaped recordsets for a long time.
Neither gets a lot of exposure in the light of day though ;-).

I see that your problem in this thread is just one of aquiring the parent recordset on a new record.
This isn't a peculiar to multi-value fields.
If you're on a new record then the record isn't yet committed and isn't accessible from the clones (as you've clearly found and hence the decision to use the actual form Recordset).

This is going to be messy at best, and at worst just fail (as you're finding).
It's where the discontinuity between the Recordset object and the actual form data differ.
You can't use the Recordset entirely as a standard recordset object. (For example navigating to a new record using recordset methods is fine - but try committing it and advancing like that and it fails).

For my money - if you're performing some function (subsequent additions of data based on entries in the currently displayed record) then it's worth committing that data before continuing.
Once committed you're free to navigate, access and rely upon that record's data.

Obviously committing the New Record's data is as easy as
Me.Dirty = False

Remember to hold the previously displayed PK value in a variable just as you have been doing as this commital won't necessarily see the recordset agree with what you perceive the current position to be. Then you can navigate to the recently added record and iterate through it's values as you would otherwise.
Something like:
objRSNew.FindFirst "PKField = " & lngPKField

If there's a reason why you don't want to commit the new record before acting upon its data then by all means offer it. I can't see how it would be a good idea as yet though.

Cheers.

 

by: BobHavertyComhPosted on 2009-06-09 at 13:45:39ID: 24585600

LPurvis, it would certainly appear that you understand the issues. I'm getting pulled away at work and will need some time to digest what you're saying. Thanks

 

by: BobHavertyComhPosted on 2009-06-09 at 14:12:15ID: 24585867

"If you're on a new record then the record isn't yet committed and isn't accessible from the clones (as you've clearly found and hence the decision to use the actual form Recordset)."

I did this, for that very possibility, but it does not work when entering a new record, and that's where it bombs on objRSNew=Me.Recordset, even though that's not the actual line where it really bombs as explained above.. Can't comment about updates until new ones can be added except to say that I moved my new record code that was in the after insert event to the before update section when i found out that before update code will execute prior to before insert or after insert events whether it';s a new record or not, so why not put it there at that point is the way I began to see it.

"For my money - if you're performing some function (subsequent additions of data based on entries in the currently displayed record) then it's worth committing that data before continuing.
Once committed you're free to navigate, access and rely upon that record's data."

I considered this. I can use the just added record and query it and use it as the new record. But I need to compare it to the old record on updates.

 

by: BobHavertyComhPosted on 2009-06-09 at 14:21:01ID: 24585944

Would i have to create a recordset to save the original record during it's form current event? Seems kind of hokey, wouldn't it? I can't be the first person who's run into this problem and there has to be a completely proper solution.

 

by: BobHavertyComhPosted on 2009-06-09 at 14:22:35ID: 24585955

But again, the problem is how to get the current record's data during the before update event and populate a new recordset

 

by: BobHavertyComhPosted on 2009-06-09 at 14:36:14ID: 24586076

"If there's a reason why you don't want to commit the new record before acting upon its data then by all means offer it. I can't see how it would be a good idea as yet though."

If the data is already committed, then it's my understanding that the data has been lost according to my event script and then i would have to use the global variable to query for the just entered or updated record. That would mean i would have to grab the current values of the record during the current event (seems like a lot of unnecessary, repeated processing given how Access allows you to browse records through it's forms), and put them into a global or public recordset, and then also, grab the SN (PK) val and put that into a global variable and then, in the after update event rather than the before update event, I would query the database based on the criteria of the global variable's value to grab the record just entered and use that as the new values, so that i can compare the values of the old global recordset with the values of the new, properly queried recodset

It sounds like it will work, but do you think it's the only or best solution? Seems like you would know.

 

by: BobHavertyComhPosted on 2009-06-09 at 14:50:23ID: 24586204

The main oddity or redundancy would be continually repopulating a recordset every time each record is the current one, whether the user is going to enter data or not. That's what seems to be not right to me, although maybe that's the answer if it's cheap in terms of memory, processing (etc....) to do anyway.

 

by: LPurvisPosted on 2009-06-09 at 16:57:12ID: 24587030

OK, I haven't really got time to sift through all your comments just now.
Can you summarise the actual intent of your process in a couple of lines?
I think that might be instructive in an overall solution suggestion rather than spending time pouring over the code (and not being familiar with your data objects anyway - for example I can't know if a recordset you open as the same source as the form you've been working on etc).

Cheers.

 

by: BobHavertyComhPosted on 2009-06-10 at 05:14:25ID: 24590415

We have system and different types of subsystems. Both have numeric PKs that they are identified by Subsystems are  FK's of a system and their numeric SN values are accessed via multi value lookup. On entry or update of a system, user selects from a pool of available subsystem numbers and adds them. Each field on a system form represents a type of subsystem to be entered. In each there can be more than one subsystem of that type, hence the use of multi valued fields. Any subsystems used for any system must be marked as used and marked with the SN of the system using it, so that it does not continue to show up as an available subsytem for future systems entries or even edits. So when a subsystem number is used, i have to go to it's table, find that record number and mark it as used and then, if the subsystem number gets removed from a system upon edits, then i need to clear the system number entries from it's record, so that it will now be availble again in the lookup vals for future system entries.

I don't think what I'm trying to do is all that complex, heroic or hard to understand, and in fact, it's really necessary, but I can't seem to get across what I'm trying to do for the life of me to other people. It's really rather simple, conceptually. Maybe people see text and just don't even read it and go right to any code I have, get confused, and give up.

 

by: LPurvisPosted on 2009-06-10 at 06:21:08ID: 24591088

And the point of asking you for your description there was to explain what you're doing.
Not that it's hard to understand - but that you'd not done so previously.
(When the bigger picture is looked at it's usually easier to place the smaller puzzle piece - a little jigsaw analogy for you there :-).

I have to say though, if you'd place yourself at a reasonably advanced level I'm surprised you've chosen to go with MVF's.
The underlying structure is relational (we're assured as much by MS) but the access to that is programatic only.
For me - if there's an entity to be modelled, then model it. (i.e. in your table design schema).
MVFs can be a handy tool for the uninitiated to begin to think relationally but, unless you're planning on moving to Sharepoint, they don't have an external platform equivalent. i.e. to my mind they're a dead end.
However - I say again that this isn't the crux of your issue here, it's to do with Recordset access to the new record in a bound form.
None the less, that you need to perform this action entirely programatically is, again, a result of having implemented MVF's.

For example...
>> "So when a subsystem number is used, i have to go to it's table, find that record number and mark it as used "
Assigned entries in a table being unavailable for subsequent selection is a common action performed through SQL. There's no programatic requirement on updates for tagging items as used. (Such operations should really be wrapped up within a transaction even). A simple query would then always show you the subsystem numbers that haven't yet been selected.

Anyway - I dare say you're not about to abandon MVF's now.
So to your issue.
Accessing the data on a new record.
Don't.
It's in a buffer - the Recordset object can scarsely access it at best.
Commit those changes and navigate back.
You say there's no problem when operating from existing records - you'd then be in that exact position.

Each row on your form must have some primary key to uniquely identify that record.
Grabbing that value and returning to that row.
You then voice concerns about comparins against old values.
If that is something you need to do then I don't, for one second, feel that the memory overhead of a few variables to hold those values is excessive overhead.

For example consider your comment:
>> "Would i have to create a recordset to save the original record during it's form current event? Seems kind of hokey, wouldn't it? I can't be the first person who's run into this problem and there has to be a completely proper solution."

You're certainly not the first person wanting to compare updated values with those that existed previously.
However as part of that requirement, holding the previously entered values somewhere is not an unreasonable expectation.
I'd say you've implemented things the way you've implemented them.
That you're now having to jump through a hoop or two, well that's just a consequence of your design. Nobody made you design it that way.
If you're comparins all records loaded into the form - then you could even maintain a recordset in memory of all records on that form as it was when loaded. That's perhaps not ideal from a memory usage perspective - but if your requirements demand a comparison then relying on the values displayed in the BeforeUpdate event before commital, to me, isn't any more robust. Ordinarily I'd think - a disconnected ADO recordset held open for comparison, but your MVF implementation negates that as a possibility. So a Snapshot DAO recordset instead it is.

If your comparisons aren't form-wide but merely for the one specific record upon which you're located (and your use of the BeforeUpdate event certainly implies this is intended for each individual record only) then the process is simple. Either a single row recordset (established before the record commits) or, as you say, a set of variables.
To my mind, the recordset is easier, due to your MVF implementation (you'd need an array or collection to hold the MVF values if implementing variables). And a single row recordset in memory, honestly, is surely nothing compared to the manipulation you're performing otherwise here (to handle the scenario you're left with).

And in a new record it's surely trivial though - there were no previously entered values! A simple flag to indicate as much (that you were on a new record) should relieve you of any checking duties on that front.

Thoughts?

 

by: BobHavertyComhPosted on 2009-06-10 at 06:32:54ID: 24591232

"For me - if there's an entity to be modelled, then model it. (i.e. in your table design schema)."

Does SharePoint understand data modeling and child tables? It understand MVFs very well. We want this to be al least partially viewable in Sharepoint lists. If you think i can do that with data modeling, then I might change everything

 

by: LPurvisPosted on 2009-06-10 at 06:42:31ID: 24591352

I have to say I'm not (thus far) a convert to the joys of using Sharepoint as a data repository.
MVF's do indeed exist (to one extent or another) to help service integration with Sharepoint (FWIW complex data types have also given us Attachment data types by necessesity, so it's great in that respect too).

AFAIK you can model what you want using different lists - though it would be up to your Access FE to then bind these together.
FWIW I wouldn't expect query performance to be blisteringly fast though using distinct lists through the Access FE. (Quite the reverse).
For a general example of selecting from lists and only making available unselected items have a look in the List Select demo in the examples page linked to in my profile.

(By the way - that Sharepoint is a big factor in this might have been worth mentioning earlier in the thread? ;-)

Either way, I don't think you're in a hard place. The suggestions presented to you require a bit of work, but not much.
(Consider the amount of code you've already written above to accomplish your current task).

Despite your previous explanation I can't offer much on suggested schema without being very much more familiar with the data objects in play (for example all those tables listed).

Cheers.

 

by: BobHavertyComhPosted on 2009-06-10 at 06:53:23ID: 24591471

"Assigned entries in a table being unavailable for subsequent selection is a common action performed through SQL. There's no programatic requirement on updates for tagging items as used. (Such operations should really be wrapped up within a transaction even). A simple query would then always show you the subsystem numbers that haven't yet been selected."

So how would I do that in Access 2007?

"So to your issue.
Accessing the data on a new record.
Don't.
It's in a buffer - the Recordset object can scarsely access it at best.
Commit those changes and navigate back."

How do i know what values record had before editing? I can certainly query the record that I just entered and do so on the after update event rather than the before event and use that as the new recordset values, but how do I populate and another recordset with the original values before they were edited so that I can compare the two and make the appropriate entries when i find out what's been entered and what's been deleted.

As far as new records go, where I just need to mark records, not compare old and new values, are you saying that I merely submit the record and then query for that record it on the after insert event in order to get the values I need to look at and then take my actions in the after insert event?

"That you're now having to jump through a hoop or two, well that's just a consequence of your design. Nobody made you design it that way."

SharePoint?

"So a Snapshot DAO recordset instead it is."

So what exactly does that mean in terms of code?

"Either a single row recordset (established before the record commits) or, as you say, a set of variables."

I did the following and it bombs on a new record, so i can't even tell you about updates yet

And how to I establish that? That's mostly what my problem and question is. Me.Recordset or Me.RecordsetClone refuses to populate the object with anything

"To my mind, the recordset is easier, due to your MVF implementation (you'd need an array or collection to hold the MVF values if implementing variables). And a single row recordset in memory, honestly, is surely nothing compared to the manipulation you're performing otherwise here (to handle the scenario you're left with)."

If I could just figure out a way to get an old and new recordset, I wouldn't have to bother with global arrays, and also, Access forces them to be private rather than public. i don't know if that means it won't work or not, but arrays were the first thing I thought of, but loping through nested recordsets is far more elegant and less klunky, if, again, i could just find a way to get two recordsets. I think, for the time being, for new records, I'm going to mark a global variable on the current event as to the record form's pre populate SN and then use that to query the record I just entered on the after insert event. then, if i could get past the new Record entry, the Me.RecordsetClone might then start populating the recordset

 

by: LPurvisPosted on 2009-06-10 at 17:18:39ID: 24597766

>> "So how would I do that in Access 2007?"
You mean in a table schema design only?
Have you looked at the example I suggested? That's the "select from a list" which includes only "unselected" items for selection.
The old "Two Listboxes Demo".

>> "SharePoint?"
Well up until then I had no way of telling that Sharepoint was a factor in your situation. (You'd not mentioned it).
Still though, AFAIK there's no requirement that you use MVFs just because you're working in Sharepoint. Just the potential / liklihood of them.

>> Snapshot DAO recordset instead it is.
>> So what exactly does that mean in terms of code?

Well, thinking about it, a snapshot recordset is still connected to the database. Not a problem for main record data - as the data it contains is fixed until requeried. However the child records in the MVF would be a potential problem. (Since they're implemented relationally). Deleted records therein would be a problem.

I presume you're wanting to make note of the MVF values that have been changed for the given record?
Even a snapshot lacks the true discontinuity from the updated data that an ADO disconnected recordset could have offered if only the provider supported it :-s
You may have to then rely on an array or other variable to maintain the "previous" set of data prior to update through the form.

As a general functionality point though - you could open a recordset (and/or fill an array for the MVF data) in the form's Dirty event (whereby the form record commences editing) and then compare in the AfterUpdate when the changes have been committed.

>> and it bombs on a new record
There we come back to the "commit the record before attempting to access it" solution.
For example, consider just displaying the data to the immediate window...

Private Sub Form_AfterUpdate()

   Dim rstSub As DAO.Recordset
   Dim lngID As Long
   
   lngID = Me.ID  'Whatever your PK ID field is.

   With Me.RecordsetClone
       .FindFirst "ID = " & lngID  'Get to that row
       Debug.Print "New value: " & .Fields("WhateverNameField")
       Set rstSub = .Fields("YourMultiField").Value
       Do Until rstSub.EOF
           Debug.Print "  " & rstSub.Fields(0).Value
           rstSub.MoveNext
       Loop
   End With

End Sub

As I say though - the MVF is perhaps the problem in using recordsets only and not variables.
But there's little harm in a single, simple array for comparing the MVF data. (Since you're already this far into it, it doesn't seem a bigger leap to me). In for a penny, in for a pound - and all that.

Cheers.

 

by: BobHavertyComhPosted on 2009-06-11 at 11:48:06ID: 24605481

>>>"Still though, AFAIK there's no requirement that you use MVFs just because you're working in Sharepoint. Just the potential / liklihood of them."

I don't think sharepoint is going to understand data modeling, but since it's a microsoft product, it understands MVFs.

Also, Here's another complexity that I haven't been able to get across which could be another reason to use MVFs. There are three types of BoardModules that can be entered into a System (BoardModule FK lookup multivalue). Call them Module A, B and C.  A system will always get at least one of each type of Module, so i have three columns in my System table and three fields on it's form, each representing one of the three types of Modules. However, there is an undetermined amount of Modules of each type that can be added. So suppose we can enter anywhere between 1 and 20 BoardModule ID values of module typeA. We never know how many. So the way I see it, and I could be naive, is that I would have to make 20 child tables, each with a varying amount of columns ranging from one to 20,  or create one child table with the maximum amount of fields and have many null values and wasted space in the records. Each option seems strange or hokey, so maybe there's another option?

>>>"I presume you're wanting to make note of the MVF values that have been changed for the given record?"

Absolutely, and this is where I have to do a little dancing. I didn't even need recordsets or anything in other situations, i would just walk through the .Fields and grab the field value

>>>"You may have to then rely on an array or other variable to maintain the "previous" set of data prior to update through the form."

Can one have global recordsets? Also, when i tried to create a public array, Access didn't like it and made me name it private. Can it still be used globally?


There we come back to the "commit the record before attempting to access it" solution.
For example, consider just displaying the data to the immediate window...

>>With Me.RecordsetClone

This is the problem and always has been, I cannot get this to work in the after insert event when I enter a new record, so i can't even tell whether it would work in the after update event. For new records, I use the global variable to find the record just entered, and fill a recordset to record which other tables need entries and then walk through it and do it. So untill I can get something like this to work during any other event besides the form's current event, i can't even say with recordset clones work after the after update event. My query is correct according to then debugger and the global variable is the correct one, but if fails to populate the recordset with anything almost as though the record hasn't been added yet, but when i stop it in the debugger and manually check that table to see if that record was added, it was.

So here's the plain and simple question. What events can you use RecordsetClone on? Otherwise, i can't figure out why this simple little statment returns nothing and then causes the statement that calls this supposedly populated recordset bombs.

Dim myDB As DAO.Database
    Dim objRSNew As DAO.Recordset
    Set myDB = CurrentDb
    Dim strRS
    strRS = "SELECT * FROM tblSystems WHERE SN=" & SystemsSN
    Set objRSNew = myDB.OpenRecordset(strRS)
    For outerCount = 0 To 6
        Set objRSNew1 = objRSNew.Fields(" & fieldsArray(outerCount) & ").Value

 

by: LPurvisPosted on 2009-06-11 at 14:03:39ID: 24606854

It would be up to Access to understand the data modelling as such (in as much as the way you handled it via your UI).
But as for MVFs, I would say it's actually the reverse of Sharepoint understanding Access' recent addition :-)

>> "Can one have global recordsets?
Absolutely, they're just held in variables (object variables) like any other. THe scope of those variables is determined by how and the location of their declaration.

>> "Also, when i tried to create a public array, Access didn't like it and made me name it private. Can it still be used globally?"
Hmmm - now that sounds like you're using a class module. (Which applies to Form's and Reports of course.)
If you're talking about wanting to expose an array to the entire application, then you do need public declaration.
In a class module you could still provide that through a property of method of the form.
(Or hiding your array inside a variant).
However if you only need to access that one array from procedures in that same module then there's no need to it to be public. Declared at the module level will allow any procedure in that module to reference it.

>> "What events can you use RecordsetClone on?"
Basically any (though I'd avoid the Open event as a matter of course).
It's more to do with what that recordset contains and when it contains it, that you're finding problems with, i.e. record commital and database updates.
(Is this form you're working with empty apart from the new record - in which case your RecordsetClone would be empty, and not very useful to you).

As for your structure issue, it's hard to offer much without knowing how your schema really fits together.
It sounds like you're designing horizontally as opposed to vertically though.

Must dash for now.

 

by: BobHavertyComhPosted on 2009-07-01 at 06:23:12ID: 31590402

Thanks

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...