.text to .value without leaving field

E

Edward Reid

I want pressing Return in a text box to activate a nearby command. It
sounds so simple. I figured out that I have to use the KeyPress event.
That was easy, as was testing for a Return, and from there I called the
Click sub for the related command button. Then the fun began.

First, the Click sub was getting the .Value of the field I came from,
which hadn't been stored since the field was still active. So I tried
storing .Text into .Value before calling the Click sub. (It isn't
reasonable for the Click procedure to look at the .Text property. For
one thing, the real Click sub uses several text boxes to build its
query. Also, that would require moving the focus around to each text
box, or perhaps figuring out which one has the focus and using .Text
from that box and .Value for the others. Also, control validation rules
would be skipped.)

OK, so .Value = .Text mostly works. But that also appears to skip the
control validation. In fact, it looks like the unchecked string gets
permanently stored into .Value. For example, the field is formatted
"general date". If I type "3/21" (being in the US) and tab out, it's
changed to "03/21/2006". But if I press Return instead of Tab, I
execute the .Value = .Text code, and the field shows as "3/21" no
matter how often I move in and out, until I change it again.

I also had to add the check for empty string in addition to null,
though possibly I should have had that in the code anyway.

BTW, all of the fields in question are unbound. In fact, all the fields
on the form are unbound -- it's a sort of portal inquiry form.

All I want is to validate the current contents (.Text) and run some
code which ends up with a DoCmd.OpenForm, where the selector for the
new form is based in part on the content of the current field. Is there
an easier way? Should I do MyCmd.SetFocus and send it a click key?
Would that validate MyDateBox? Something else? I've done enough
experiments that I want to ask before continuing to grope around in the
dark.

At the moment my code looks very much like this:

Private Sub MyDateBox_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
MyDateBox.Value = MyDateBox.Text
MyCmd_Click
End If
End Sub

Private Sub MyCmd_Click()
If IsNull(MyDateBox) Or Len(MyDateBox) = 0 Then
MsgBox "Enter date"
Else
' build a LinkCriteria string involving MyDateBox
' call DoCmd.OpenForm
End If
End Sub

The above are repeated for 16 text boxes and 8 command buttons.

Edward
 
W

Wayne Morgan

If you set Tools|Options|Keyboard Tab|Move After Enter to Don't Move, the
cursor will stay in the textbox when you press Enter, but it will cause the
textbox to Update. This will trigger the textbox's AfterUpdate event. You
could then place code there to run what you want.

If you don't change the Options setting, pressing Enter will still cause the
update, but the textbox or record will lose the focus also.
 
E

Edward Reid

Wayne said:
If you set Tools|Options|Keyboard Tab|Move After Enter to Don't Move, the
cursor will stay in the textbox when you press Enter, but it will cause the
textbox to Update. This will trigger the textbox's AfterUpdate event.

Thanks, Wayne ... two problems with that method. First, if the user
tabs out of a field, that will also trigger AfterUpdate, which is a
problem because the user may want to fill in multiple fields, so I only
want to trigger on Enter/Return. (And some of the fields are optional,
so I can't even check for "all filled".)

Second, if the user tabs to, or clicks in, a field and then hits Enter
without changing anything, AfterUpdate does not get triggered.

Both of these behaviors are contrary to what Windows users are
accustomed to. I could probably fix the first problem by setting a
module variable when I see a return keypress and using that to
determine what triggered the update. But I haven't figured out a way
around the second problem. Hmm, perhaps when Enter is pressed, I could
compare .Text to .Value, and if they're the same, go ahead and take
action. I'm still surprised that it's so hard to make a Microsoft
application use standard Windows conventions ...
If you don't change the Options setting, pressing Enter will still cause the
update, but the textbox or record will lose the focus also.

I did a little experimenting. Actually, either "don't move" or "next
field" will trigger AfterUpdate. I didn't check on focus, since I'm
going to open a new form anyway and so don't care. "New record" does
not appear to trigger AfterUpdate (though perhaps I'm missing somethng
there). I also see that if this were useful, I could easily check the
option on startup and offer to change it for the user.

Edward
 
W

Wayne Morgan

I understand your concerns. The problem is that if you have the Return key
do something more than what it would normally do, you may confuse the users.
It may be better to use the DoubleClick event of the textbox or a button
next to the textbox to actually run your routine so that the user knows that
they are explicitly running the routine. Another option would be a special
key sequence, such as Ctrl+Alt+R for run.
 
E

Edward Reid

Wayne said:
I understand your concerns. The problem is that if you have the Return key
do something more than what it would normally do, you may confuse the users.

I totally agree. I'm trying to make Return/Enter work like it normally
does in Windows applications. If I can't accomplish that, then I'll
make it do nothing and the user will have to either click the command
button or tab to the command button and then hit Return. The Windows UI
is a long way from perfect, but violating user expectations just makes
it worse.
It may be better to use the DoubleClick event of the textbox or a button
next to the textbox to actually run your routine so that the user knows that
they are explicitly running the routine. Another option would be a special
key sequence, such as Ctrl+Alt+R for run.

Yeah, but the user (even though in this case the user is a programmer),
isn't thinking "run a routine", and shouldn't. The user is just
thinking "do the inquiry", do what the nearby button says. That's what
Return does in Windows (when a new line isn't valid in the context of
course). And I wouldn't ever use double-click on a text box or command
button; that's totally against user expectations.

In my situation, the choice is between giving Return normal Windows
behavior, or nothing. I still have the keyboard-only, Windows-standard
option of tabbing to the command button.

Edward
 
W

Wayne Morgan

Well then, since the main problem seems to be that the control's validation
routine gets skipped when you manually update the control (you're correct,
it does), then you'll need to run the validation in the routine you are
running. Another option would be, as you say, move the focus around. You
could create a control that is very small, colored so that it is hidden, and
removed from the tab order to set the focus to. To find out which control
was active, you can use Screen.ActiveControl or Screen.PreviousControl.
These will give the value active control of the active form or the
previously active control of the active form. You can use
Screen.ActiveControl.Name or Screen.PreviousControl.Name if you prefer to
get the name of the control. Once you have the name, you could move the
focus right back to that control so that the user doesn't realize that
you've moved the focus. If necessary, you could turn Echo off while you do
the move then turn it back on again to prevent the user from seeing
anything.
 
W

Wayne Morgan

PS,

As far as "normal Windows behavior when pressing the Enter key", that
depends on the application. A text editor or word processor won't normally
update, it will go to the next line on the Enter key. The behavior you
mention would be common for a web page.
 
E

Edward Reid

Thanks for the tips -- no time to try them out this morning, will do
later. I take it there's no way to run the standard validation
explicitly? I looked through all the properties for textbox and didn't
see a method that looked even remotely likely, but that's a long list
....

Wayne said:
As far as "normal Windows behavior when pressing the Enter key", that
depends on the application. A text editor or word processor won't normally
update, it will go to the next line on the Enter key. The behavior you
mention would be common for a web page.

Oh, absolutely. I added some qualification about "where a return is not
valid in the context". Wasn't very clear; what you say is what I meant.
Anywhere multi-line text is valid, the Enter key should put a newline
in the text. This is very often the case in applications where text is
the main focus. It's very seldom true in dialog boxes. Web pages are a
mixed bag as you say -- sometimes newline is valid, but more often not.
In an Access form textbox, if I have EnterKeyBehavior set to New Line
in Field, then I should not override that in the KeyPress sub.

Edward
 
E

Edward Reid

Where do you currently have this "standard validation"?

I was hoping someone could tell me ... ;-)

I have no validation code. All I've done is set the (unbound) textbox's
Format property to "general date" -- and in the property sheet, not in
code. This appears to be all that is needed so that the user can enter, for
example, "6/29" in the textbox and have Access automatically convert it to
"6/29/2006". That's the "control validation" I referred to originally. I
haven't tried, but I assume similar things happen for other kinds of
formats, such as numbers.

This step is skipped when I do ".Value = .Text" in the KeyPress event
procedure; then the string "6/29" gets stored into the Value. But I've been
through various parts of the help files and have not figured out just where
this "control validation" (based solely on the Format property) fits in
with all the events related to the textbox, nor in particular have I
figured out how I can force it to happen from within an event procedure.

Edward
 
W

Wayne Morgan

Ok, what you are mentioning is built-in. Excel does the same thing. To do
the same thing when you do ".Value = .Text", you would do the following:

Dim dteTemp As Date
dteTemp = Me.ControlName.Text
Me.ControlName.Value = dteTemp

When you assign the value to a date variable, the current year will be
appended if all you have is the month and date. You could also do this on
one line as follows:

Me.ControlName.Value = Format(Me.ControlName.Text, "Short Date")
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top