422,023 Members | 1,035 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 422,023 IT Pros & Developers. It's quick & easy.

How to change a field in BeforeUpdate (runtime error 2115)

P: 3
I would like to do data validation in the BeforeUpdate procedure, but Access gives me a runtime error when I try to do this:

Runtime error 2115: The Macro of function set to the BeforeUpdate or ValidationRule property for this field is preventing MS Access from saving the date in the field.
An example of what I am trying to do is as follows:

Expand|Select|Wrap|Line Numbers
  1. Private Sub Option_BeforeUpdate(Cancel As Integer)
  2.   If Option = A Then
  3.     Answer=MsgBox("Don't you mean B?",vbYesNo)
  4.     If Answer = vbYes Then
  5.       Cancel = True
  6.       Option = B
  7.     End If
  8.   End If
  9. End Sub
The code breaks on Option=B. I have tried using Option.Value = B instead of Option = B, but it still gives the same error.

In plain english, what I'm trying to do is to check the value that a user supplies to a combo box, and under certain conditions, provide a message box to verify that the user has indeed made the correct selection. Based on the answer supplied by the user, the combo box should be changed to the correct value, or left as it is.

Does anyone know if this can be done?
Mar 9 '10 #1

✓ answered by NeoPa

No problem with that, but when the BeforeUpdate() event procedure is used properly there is no issue to worry about anyway.

See below an excerpt from the Help system about updating the control's value before completion of the BeforeUpdate()event procedure (including within the precedure itself of course) :
A run-time error will occur if you attempt to modify the data contained in the control that fired the BeforeUpdate event in the event's procedure.

Share this Question
Share on Google+
16 Replies


ADezii
Expert 5K+
P: 8,584
Setting Cancel = True will not allow the Form to be updated, and I don't think that this is what you're after. Depending on the User's Choice, either change the Entry or leave it along, then Save the Record.
Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_BeforeUpdate(Cancel As Integer)
  2.   If Me![cboOption] = "A" Then
  3.     Answer = MsgBox("Don't you mean B?", vbYesNo)
  4.       If Answer = vbYes Then
  5.         Me![cboOption] = "B"
  6.       End If
  7.   End If
  8. End Sub
P.S. - Setting the Name of a Control to Option is not a good idea.
Mar 9 '10 #2

P: 3
Thanks for your reply ADezii,

I misunderstood how Cancel = True setting works, thank you for clarifying that. Your code works if I attach it to a form (as you have it), but then the validation is only done if I move to the next record. Is there some way to make it work with the combo box BeforeUpdate event so that it validates when I click in another control? (something like the following, adapted from your code, which still gives runtime error 2115):

Expand|Select|Wrap|Line Numbers
  1. Private Sub cboOption_BeforeUpdate(Cancel As Integer)
  2.   If Me![cboOption] = "A" Then
  3.     Answer = MsgBox("Don't you mean B?", vbYesNo)
  4.       If Answer = vbYes Then
  5.         Me![cboOption] = "B"
  6.       End If
  7.   End If
  8. End Sub
  9.  
Mar 9 '10 #3

ADezii
Expert 5K+
P: 8,584
You may need to use the LostFocus() Event of the Combo Box in order to have the code work effectively:
Expand|Select|Wrap|Line Numbers
  1. Private Sub cboOption_LostFocus()
  2. If Me![cboOption].Text = "A" Then
  3.   Answer = MsgBox("Don't you mean B?", vbYesNo)
  4.     If Answer = vbYes Then
  5.       Me![cboOption].Text = "B"
  6.     End If
  7.   End If
  8. End Sub
Mar 9 '10 #4

P: 3
I got it working by putting the validation the AfterUpdate rather than the BeforeUpdate event. But that wouldn't let me undo the changes if I added a cancel option to undo changes (Undo only seems to work in BeforeUpdate):
Expand|Select|Wrap|Line Numbers
  1. Private Sub cboOption_BeforeUpdate(Cancel As Integer)
  2.   If Me![cboOption] = "A" or Me![cboOption] = "B" Then
  3.     Answer = MsgBox("Don't you mean C?", vbYesNoCancel)
  4.     If Answer = vbYes Then
  5.       Me![cboOption] = "C"
  6.     ElseIf Answer = vbCancel Then
  7.       Cancel = True
  8.       Me![cboOption].Undo
  9.     End If
  10.   End If
  11. End Sub
  12.  
In other words, if the current option is A, and the user selects B, a YesNoCancel message box should come up. If the user then clicks on Yes, the option should be set to C, if the user clicks No, the option should be set to B, and if the user clicks Cancel, then the option should remain A.

The code above still gives error 2115. I did get it working using AfterUpdate and the OldValue property as follows:
Expand|Select|Wrap|Line Numbers
  1. Private Sub cboOption_AfterUpdate()
  2.   If Me![cboOption] = "A" or Me![cboOption] = "B" Then
  3.     Answer = MsgBox("Don't you mean C?", vbYesNoCancel)
  4.     If Answer = vbYes Then
  5.       Me![cboOption] = "C"
  6.     ElseIf Answer = vbCancel Then
  7.       Me![cboOption] = Me![cboOption].OldValue
  8.     End If
  9.   End If
  10. End Sub
I'm a bit hesitant to use OldValue rather than Undo, but I can't think how else to do it?
Mar 9 '10 #5

P: 6
While this is an "old" nugget, some observations here as I've had to solve this recently.


For the event, rather than an "beforeupdate" select "change". Then I could reset the code.
May 25 '10 #6

NeoPa
Expert Mod 15k+
P: 30,549
Using the BeforeUpdate() event procedure is certainly the correct approach. When I've tried to use it, it works perfectly. I suspect where you're hitting problems is that after you cancel the update (or technichally slightly before even) you are attempting to change the value again. This doesn't make much sense logically. Do you want to cancel the update, or do you rather want to overwrite the selection of the operator to set it to a value of your choosing? Only one of these can be true. When you decide which it is then you are more than half way to resolving your problem. Of course we can still help if you need, but this must be the first step.
May 25 '10 #7

P: 6
My experience was that setting "Cancel = True" doesn't reset the field to its earlier state; so instead, with the OnCurrent event I'm capturing the original value and in the OnChange, of the user wants to cancel, I'm resetting it.
May 25 '10 #8

NeoPa
Expert Mod 15k+
P: 30,549
That's interesting, as that's exactly what it's supposed to do (as well as to clear the .Dirty flag if it's the only item otherwise changed). Do you have a repeatable example of this strange behaviour?
May 25 '10 #9

P: 6
This was just one of several incarnations that didn't work...

Expand|Select|Wrap|Line Numbers
  1. Private Sub idRealID_BeforeUpdate(Cancel As Integer)
  2.  
  3. Dim txMsg
  4. Dim ct As Long
  5.  
  6.     ct = DLookup("count(*)", "customer", _
  7.         "idCustomer<> " & Nz(Me.idCustomer, 0) & " AND idRealID='" & Me.idRealID & "'")
  8.  
  9.     txMsg = IIf(ct = 0, _
  10.       "MUSTERININ KODUNU ""{1}"" DEYISMEK ISTEDIYINIZDEN EMINSINIZ?", _
  11.       "MUSTERININ KODUNU ""{1}"" DEYISMEK ISTEDIYINIZDEN EMINSINIZ? YENI KOD {2} DIGER MUSTERI TEREFINDEN ISTIFADE OLUNUR!")
  12.  
  13. 'TRUE re you sure you want to change the customer code from {1}.  The new code is used by {2} others customers."
  14.  
  15.     Cancel = MsgBox(Replace(Replace(txMsg, "{1}", Nz(m_idRealID, "")), "{2}", ct), vbOKCancel + vbCritical + vbDefaultButton2, "Change of Customer Code") = vbCancel
  16.  
  17.  
  18. End Sub
  19.  
  20.  
May 26 '10 #10

NeoPa
Expert Mod 15k+
P: 30,549
For it to be considered repeatable, I'd need a database to try out.

Here are some basic points to consider when attaching databases :
When attaching your work please follow the following steps first :
  1. Remove anything not relevant to the problem. This is not necessary in all circumstances but some databases can be very bulky and some things do not effect the actual problem at all.
  2. Likewise, not entirely necessary in all cases, but consider saving your database in a version not later than 2003 as many of our experts don't use Access 2007. Largely they don't want to, but some also don't have access to it. Personally I will wait until I'm forced to before using it.
  3. If the process depends on any linked tables then make local copies in your database to replace the linked tables.
  4. If you've done anything in steps 1 to 3 then make sure that the problem you're experiencing is still evident in the updated version.
  5. Compile the database (From the Visual Basic Editor select Debug / Compile {Project Name}).
  6. Compact the database (Tools / Database Utilities / Compact and Repair Database...).
  7. Compress the database into a ZIP file.
  8. When posting, scroll down the page and select Manage Attachments (Pressing on that leads you to a page where you can add or remove your attachments. It also lists the maximum file sizes for each of the allowed file types.) and add this new ZIP file.
It's also a good idea to include some instructions that enable us to find the issue you'd like help with. Maybe some instructions of what to select, click on, enter etc that ensures we'll see what you see and have the same problems.
May 26 '10 #11

P: 6
This isn't a problem for me. As I wrote before, I found a solution (which I suggested here as it might help others).
May 26 '10 #12

NeoPa
Expert Mod 15k+
P: 30,549
No problem with that, but when the BeforeUpdate() event procedure is used properly there is no issue to worry about anyway.

See below an excerpt from the Help system about updating the control's value before completion of the BeforeUpdate()event procedure (including within the precedure itself of course) :
A run-time error will occur if you attempt to modify the data contained in the control that fired the BeforeUpdate event in the event's procedure.
May 27 '10 #13

P: 1
Believe it or not you it will all work nicely if you just add on error resume next at the top of the subroutine. If you change a bound form control (ie control.text for example) the form control will change but then because it is bound to the underlying database field the field cannot be changed in the before_update event no matter what value cancel is set to.

However, the on error resume next clears the 2115 error but the value of the form control is now set to the value you are trying to change it to in your code. Setting the cancel to true will then prevent the cursor exiting the control. Took me hours to work this one out so thought I would share. Not sure why Microsoft have to make it so difficult!
Oct 13 '16 #14

NeoPa
Expert Mod 15k+
P: 30,549
Hi Roddy. Thanks for posting.

I wonder though, have you considered the ramifications of using such an approach with regards to the maintainability of the code?

It's often possible to shoe-horn things into code that work, but are not very intuitive. One also needs to bear in mind that many problems people have working with restrictions are more down to their less than full appreciation of what's happening than to badly designed implementation from Microsoft.

Don't get me wrong. They exist too, but not every case where people scratch their heads wondering why it works a particular way is an example of that. I would contend this is one such instance. I believe it makes good sense for such code to be discouraged as it's normally a sign of limited understanding by the developer.

Of course, it's possible to get a messy loop going even when you place the update in the more logically appropriate place in the AfterUpdate event but MS can only do so much on that score.
Oct 19 '16 #15

P: 1
Hi roddyBenson your ansewer is the right one, thanks for spending so much time figuring it out helped me a lot.
Nov 7 '16 #16

NeoPa
Expert Mod 15k+
P: 30,549
It's frustarting to see comments like that Diego. Without wanting to be insulting to another member who's taken their time and energy to post to the best of their understanding, that's a very poor answer. Many things can be made to work without their making good sense. This is one such example. That suggestion is a simplistic and counter-intuitive approach that will get no-one very far. There are better ones in this thread that don't come along with the same problems.

I'm afraid your assessment of the situation lacks any evidence of understanding and I'd be doing a great disservice to those millions of members, of this site and the general public, who rely on the experts here to help and guide them in a direction that makes sense if I were simply to let that comment stand unopposed.
Nov 17 '16 #17

Post your reply

Sign in to post your reply or Sign up for a free account.