I have an **unbound** textbox control. The user enters some valid text and leaves the control. The user then returns to the control and enters some invalid text. I want to show the user a message then **rollback the value of the control to its previous state** and **keep the focus in that control**.

I've tried the following approaches, none of which gets me exactly what I am looking for:

---

**OPTION A**: SendKeys

```
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
    Cancel = DataIsInvalid(Me.MyTextBox.Value)
    If Cancel Then SendKeys "{Esc}"
End Sub    

```

This does exactly what I want, but I really want to avoid using `SendKeys`. There are many problems that come with using SendKeys: [Vista+ compatibility](http://vb.mvps.org/samples/SendInput/), keys being sent to a different application, etc.

---

**OPTION B**: Undo method of control

```
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
    Cancel = DataIsInvalid(Me.MyTextBox.Value)
    If Cancel Then Me.MyTextBox.Undo
End Sub    

```

This is simply broken for unbound controls (at least as of MS Access 2002/XP). This method does not restore the value of MyTextBox to the valid input. However, it does allow the user to change the focus to a new control while leaving the invalid input in place in Me.MyTextBox! Unbelievable!!!

---

**OPTION C**: Undo method of form

```
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
    Cancel = DataIsInvalid(Me.MyTextBox.Value)
    If Cancel Then Me.Form.Undo
End Sub    

```

The `Undo` here does absolutely nothing. But at least it doesn't break the BeforeUpdate Cancel=True code and allow the invalid data to stand.

---

**OPTION D**: Explicitly restore old value in BeforeUpdate event

```
Private mPrevMyTextBoxValue As Variant

Private Sub MyTextBox_AfterUpdate()
    mPrevMyTextBoxValue = Me.MyTextBox.Value
End Sub
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
    Cancel = DataIsInvalid(Me.MyTextBox.Value)
    If Cancel Then Me.MyTextBox.Value = mPrevMyTextBoxValue
    'If Cancel Then Me.MyTextBox.Text = mPrevMyTextBoxValue
End Sub    

```

Attempts to assign the previous value to either the `.Value` or `.Text` property of the textbox result in the same error message:

> 
> The macro or function set to the BeforeUpdate or ValidationRule property for this field is preventing {Program Name} from saving the data in the field.
> 
> 
> 

---

**OPTION E**: Explicitly restore old value in AfterUpdate event

```
Private mPrevMyTextBoxValue As Variant

Private Sub MyTextBox_AfterUpdate()
    If DataIsInvalid(Me.MyTextBox.Value) Then
        Me.MyTextBox.Value = mPrevMyTextBoxValue
        Me.MyTextBox.SetFocus
    Else
        mPrevMyTextBoxValue = Me.MyTextBox.Value
    End If
End Sub

```

This is really close to the desired behavior. Unfortunately, it's impossible to keep the focus on the control because the AfterUpdate event runs *before* the Tab/Enter keypress or mouse-click events are processed. So even if we try to force the focus to the proper control (via the `.SetFocus` statement above), the program will immediately shift the focus to the control the user selected.

---

It seems to me that the "right" way to do this is to use the `.Undo` method of the control. That does not work for unbound controls, though. This is an inexplicable shortcoming, especially given the fact that an Escape key-press performs this functionality for an unbound field.

Is there a better way to do this or should I just stick to using `SendKeys`?