Go Back one field using VB

J

John

From a numeric keypad where the only input will be numbers, I'd like to
capture an "/" keypress, and use that to trigger a goto previous field. The
same as a Shift-Tab from a full keyboard.
I'd prefer to not use SendKeys
With this code,
Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = 47 Then
' ** WhatVB code would cause a back one field?
End If
End Sub

Is there some way I can combine keycode constants to send the equivalent of
a Shift-Tab?
Thank you
John
 
A

Albert D.Kallal

I can FULL WELL agree that you should advoid the use of keypress in code...

Hwoever, this is one case where I would actualy use the keypress fucntion,
as it is a LOT less code.

However, for the sake of larning...we can write code to do this.

Furhter, for MOST key processing rouitnes, when you need to CHANGE the
behfours of the key (not just do somting with the keystroke), then use the
keydown event. This is impaornt, since we need not only to do womting with
the keystock, but ALSO KILL it. In other wrds, we want NO part of anything
to process what this key is supposed to do.! So, grab the key i the
keydown..sice not only do we want the "/" key to go back, we also don't want
the field to even "see", or ever receive the "/" key... (if we don't do
this, then the file with the focus would actually ahve a "/" key placed in
the text!!).

So, use keydown..and set the keycode = 0 to flush the key into a black hole.
Note that to use the forms keydown event, you also must set the form
keypreview = yes.

The follwign code would thus simulat the shift-tab key. As mtneoned, could
write the whole thing in likey 2, or 3 lines of code if you are willinhg to
use the keypress fucntion.

Anyway, here is some code that will work...

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

Dim intTpos As Integer
Dim c As Control

If KeyCode = 191 Then

KeyCode = 0 ' kill keystroke into black hole

intTpos = Me.ActiveControl.TabIndex
intTpos = intTpos - 1

GoSub JumpToIndex


End If

Exit Sub

JumpToIndex:

On Error Resume Next

Do While intTpos >= 0

For Each c In Me.Controls
If c.TabIndex = intTpos Then

Select Case c.ControlType
Case acTextBox, acCheckBox, acListBox, acComboBox
c.SetFocus
Exit Sub

Case Else
' skip labels, sub-form etc
End Select

End If
Next c
' if we get here..then
' requested tab stop not found..but, could have been a label etc.
' try looking for the next lower
intTpos = intTpos - 1

Loop

Return

End Sub
 
J

John

Barry,
Thanks for the reply.
However, I should have mentioned that the user might have to back up several
fields. This code would only go back one field, then return to the starting
field on the next "/" press. These are users on a production line, so
finger checks may occur quite often.
The Screen.PreviousControl.SetFocus is good to know about in the future
though.
I appreciate the help.
John
 
A

Albert D.Kallal

You are very wellcome...

By the way, sorry about missing the spell check...that post is somewhat
embarrassing...but, I was using a laptop..and it was on my lap..and I bumped
the "touch pad".....
 
T

Terry Kreft

Albert,
I think that' the first time I've seen the use GoSub in VB (of course it was
used all the time in Basic). Now I'm trying to decide whether I like it or
not.

I can see the advantages of breaking the main work code out into a separate
block but I think my prejudices against spaghetti code are getting in the
way at the moment.
 
A

Albert D.Kallal

Terry Kreft said:
Albert,
I think that' the first time I've seen the use GoSub in VB (of course it
was
used all the time in Basic). Now I'm trying to decide whether I like it
or
not.

Yes. You bring up a rather interesting point.

Two things:

1) For any error handling in the vb code, we do have to use a goto. I
don't like it..but, it is part of the landscape that we use.

2) in my example, it is a gosub, not a goto. So, that gosub is really not
MUCH different then if I broke out the code into another separate sub, and
used Call, such as:

Call JumpToIndex(intPos)

So, I am not using a goto, and the syntax is not really much different then
above? So, then why write the code as I did?

The problem here is that of what we call "scope". I made a judgment call
that I wanted to "share" those variables with two routines. I FURTHER wanted
that code to belong ONLY to that one sub.

I have to say that Pascal was really nice in this regards, since one could
write subs inside of subs. The results was that these additional subs would
be LOCAL to the top most routine. This allowed you to "naturally" group a
few functions together (very much like when we place similar groups of code
into a new separate module. And, another example is the difference between
defining variables at the beginning of module, or in each routine (you
choose the appropriate place based on the scope of the variables).

So, that coding example was really a cross over habit of mine from when I
coded in Pascal. However, my "decision" process did come into play..and it
was not a blind shot in the dark. The choice for this was one of scope, and
simply that both bits of code operated on the save variable (intPos). It is
a nice coding technique, since my variables are still ALL local to that one
"main" sub (in this case, the keydown event).

If later on, I need that code for another form, I will NOT have to hunt for
any related routines.

To fair, I certainly could have moved out the local sub JumpToIndex code to
a complete separate sub, and called it. However, my example does show a
"natural" grouping here, and that the sub used *belongs* to the keypress
routine (and, it belongs to NO OTHER CODE).

A developer looking at that code will *instantly* know that this is a local
sub, and is ONLY to be used by the keypress routine. There is NO confusing
as to what routine will use, or call than sub (it is LOCAL to the key down,
and in fact NO other routine can even call it). Further, it actually made
the code easier to read (at least for me!!), and also easier to code. I
wrote the first part "if keycode = 191 then" in my head..and then had to
"think" about the ugly loop part I wrote!!).

You seem to point out that you likely would have moved the code to a
separate routine. In fact, for the most part I would have to agree that your
suggestion is a good idea (in fact, a really good idea). Since that code is
in fact using a BUILT-IN event routine (keydown event), then in fact this
supports even MORE that one should have moved the code out to a separate
routine.

I suppose I can come up with a few more ideas such as:

I also kept the code together in a attempted to reduce the poster having
to deal with more then one routine!!

Looking at the example, there is really not much being shared between the
two routines, so, breaking it out to a separate sub likely would make more
sense here.

However, don't overlook this "natural" grouping of one, or two related subs
inside of a module. It is a natural grouping of code that can help you as a
developer.

If you give me a poker face look, I would have to blink, and concede it
would have been better to written that local sub as a separate sub
routine....
 
T

Terry Kreft

I've got an inbuilt abhorrence for spaghetti code as one of the legacy
pieces of software I support was written (in VB) by a 4gl programmer and it
is littered with GoTo instead of loops and ifs.

Hmm, I was debating the separate sub-routine (which is probably how I would
have written it) and also moving the gosub unit of code back into where you
make the call.

The thing I like about how you've written it is that there is some level of
encapsulation, which always makes it easier to write and debug, but it is
tightly linked to the (only) code calling it.

To a great extent I agree with your other comments.

My concluding thoughts are this is a useful technique, but I don't think I
would want to break out to more than 1 GoSub in a procedure as it would
probably confuse me (se para 1 <g>).
 

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