views:

321

answers:

2

I am really new to programming access. I converted an old 97 access db to access 2007 and it has been working fine for awhile. Today I go into it and was snooping around in design view and looking at the code. I didn't change anything. Just looked. When I went to run the code I kept getting the "Not a valid bookmark" error. Just to be sure I opened up the old program I converted and all the code is the same the line that is giving me the problem is the

Me.Bookmark = pos

The following is the whole routine.

Thanks in advance.

Private Sub ProductID_AfterUpdate()
    Dim pos As Variant
    Me![UnitPrice] = Me![ProductID].Column(2)
    Me![ProductName] = Me![ProductID].Column(1)
    Me![GLAcct] = Me![ProductID].Column(3)
    DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
    pos = Me.Bookmark
    Me.Requery
    Me.Bookmark = pos
End Sub

Edit: I already tried compact and repair.

A: 

You will need to change this code as it is out of date for quite some time. I am not sure why it worked in the first place, because the bookmarks will have changed after updating, saving and requerying. I have commented the requery line, because it does not seem to serve a useful purpose, if you wish to update the combo, requery that. If you wish to find a record after an action, save the unique ID to a variable and find it. DoMenuItem is deprecated, you can use RunCommand instead, in this case, however, Me.Dirty=false will save.

Private Sub ProductID_AfterUpdate()
    Dim pos As Variant
    Me![UnitPrice] = Me![ProductID].Column(2)
    Me![ProductName] = Me![ProductID].Column(1)
    Me![GLAcct] = Me![ProductID].Column(3)
    Me.Dirty=False
    'pos = Me.Bookmark
    'Me.Requery 
    'Me.Bookmark = pos
End Sub
Remou
The reason it doesn't work is that a requery invalidates all bookmarks.
David-W-Fenton
I am very very new to access 97 and 2007 programing. What exactly does the .Bookmark do?
Bruno43
A bookmark is similar to a physical bookmark in that it marks a "page" (record), however, re-querying and inserting records shifts the "pages" around, so the bookmark is no longer valid. You can save the unique id before re-quering and find it again afterwards. If this is what you want to do, please add another comment.
Remou
So is it safe to go through this program and find all the places that use Bookmarks and requerys and replace them with Me.Dirty = False ?
Bruno43
By no means. Me.Dirty = False only saves the current record, it all depends on what the rest of the code is doing, bookmarks can be very useful.
Remou
Basically, any time a bookmark is being saved for later use, you're in danger, because bookmarks are volatile data and valid only in the context in which they were created (which is destroyed with a requery). I've never in 14 years of Access programming saved a bookmark, since the only thing I ever use them for is navigation via the Recordsetclone of a form, where you set the form's bookmark to the Recordsetclone's bookmark, all on one line.
David-W-Fenton
Okay thanks. So it only screws up with the requery. Thanks for all the help both you guys.
Bruno43
Well, it may be that only the requery messes it up, but I would have to question any code that is storing bookmark values. That's just not what they are for and they are too volatile to be trusted even without an explicit requery (what if the user hits SHIFT-F9 on the keyboard, i.e., manually requerying the form with the focus).
David-W-Fenton
Please define 'store'. I only use bookmarks to match to a recordsetclone, too, in which case they are very useful, and I can't quite see how a short piece of code in a starter app could get messed up by F9, surely the code would have completed?
Remou
Thanks for your continued information. If you want I can create a new question: I am new to coding Access. I can't seem to find how or where the form actually inserts data? I inherited this project and its ALL greek to me. Also its a 95 Access database that I converted to 2007. Also any good tutorials on the internet would be appreciated.
Bruno43
By "store" I mean storing a bookmark value in a variable, as in the line of code in the original question, "pos = Me.Bookmark". The value stored in that variable is invalidated by the requery. If you instead store the PK value, you can use that to navigate back to the record after the requery (assuming there's an actual justification for the requery).
David-W-Fenton
@Bruno43: there doesn't seem to be any reason for the requery in the code you posted. If you remove it (as @Remou suggested), does the app continue to behave appropriately?
David-W-Fenton
A: 

To requery a form and return to the same record, do this:

  Dim lngPKValue As Long

  With Me.RecordsetClone
    lngPKValue = Me!ID
    ' Me.Dirty = False is unnecessary, as the Requery saves the data
    Me.Requery
    .FindFirst "[ID]=" & lngPKValue
    If Not .NoMatch Then
       Me.Bookmark = .Bookmark
    End If
  End With

Now, where you put this code depents. I don't quite see in the original code why there's a need to requery, as the updates have been done to the record you're already on, so you're not really accomplishing anything by requerying and returning to the record you started on. But there are circumstances in which you'd want to do that (e.g., in an ordered recordset where you've edited values that will change the place of this particular record in the sorted result), and the above is the way to do it.

If it's necessary, you'd probably want to turn off painting of the form (Me.Painting = False, the Me.Painting = True once you've set the bookmark) or of the application (Application.Echo = False/True) so the screen doesn't flicker and you don't see the requerying and navigating. But be sure you add an error handler, since if an error happens while screen painting is turned off, your user may end up stuck and unable to continue.

David-W-Fenton
But why requery? The data is being written to the form as far as I can see (Me![UnitPrice] = Me![ProductID].Column(2)), so a requery should not be necessary.
Remou
A save is possibly necessary when the form is not being requeried.
Remou
Yes, I said that I didn't see a need for the requery, but did provide one justification for it (sort order).
David-W-Fenton
Whether or not a save is required without the requery will entirely depend on the context in which the code is called, and we don't know anything about that.
David-W-Fenton