Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Is It Possible to Reference Multiple Text Boxes With a Single Function

Status
Not open for further replies.

wisgro

Technical User
Mar 5, 2008
25
US
I have to validate numeric entry and the enter key press in 8 text boxes. After a number is entered and/or the enter or tab key is pressed, focus is set to the next text box. I wrote a KeyPress sub routine and validation works fine. I'd like to call the KeyPress sub routine as a function instead of copying and pasting it into 8 text box KeyPress sub routines. The challenge is that the next text box name is used to set the focus such that after validation, the Sub Text1_Keypress routine sets the focus to Text2 then the Sub Text2_Keypress routine sets the focus to Text3... etc. I'd like to name it Sub Validate_Entry_KeyPress and call it in each text box Sub Keypress routine instead of pasting the code 8 times but I've painted myself into the corner or text box 1. Any advice greatly appreciated.
Code:
Option Explicit

Sub Text1_KeyPress(KeyAscii as integer)
	If KeyAscii = 13 Then
		Text2.SetFocus
	ElseIf KeyAscii < 48 or KeyAscii > 57 Then
		Msgbox “Enter a number greater than zero”, , “”
		KeyAscii = 0
	End If
End Sub
 
Look into setting the Forms keypreview to true and then in the
Form_KeyPress(KeyAscii As Integer)
check ActiveControl
 
Thanks for responding so quickly. I understand the first part... set Forms keypreview to true but part two, "... in the Form_KeyPress(KeyAscii as Integer) check ActiveControl." Could you be a little more specific? Do you mean I should write a sub routine in the form named Form_Keypress(KeyAscii as Integer)? How do I check "ActiveControl"? I'm sure you know what you mean but I don't understand part two of your suggestion.
 
8 text box

I think I would be tempted to create these text boxes as a control array. With a control array, each text box is named the same. You differentiate between them based on an index value.

When you have a control array, all of the events have another parameter.

To see what I mean, do this:

Open a new VB6 project.
On the form, put a text box.
In the properties window, change the name to txtName
Add another text box to the form
Change the name for the 2nd text box to txtName (the same name as the previous text box.

You'll get a popup box saying, "You already have a control named 'txtName'. Do you want to create a control array.

Click Yes.

Now, when you create the KeyPress event for either one of the text boxes, the code will look like this:

Code:
Private Sub txtName_KeyPress(Index As Integer, KeyAscii As Integer)

End Sub

Notice that there is a new parameter for this function. Index as integer. This one key press event will fire for both text boxes. If you need to know which text box it is, then you can use the Index parameter to tell the difference.

Your combined key press event would look something like this:

Code:
Private Sub txtName_KeyPress(Index As Integer, KeyAscii As Integer)

    If KeyAscii = 13 Then
        If Index = 0 Then
            txtName.Item(1).SetFocus
        ElseIf Index = 1 Then
            txtName.Item(2).SetFocus
        End If

    ElseIf KeyAscii < 48 Or KeyAscii > 57 Then
        MsgBox "Enter a number greater than zero", , ""
        KeyAscii = 0
        Exit Sub
    End If

End Sub

-George
Microsoft SQL Server MVP
My Blogs
SQLCop
"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Thanks for the detailed explanation George. I really appreciate it. I have printed the info and will read it until I get it. I have also looked up help for ActiveControl in VB6 and was surprised to find pertinent info. I hope your info and the help info will turn the light on. I consider myself to be the world's worst programmer but I refuse to give up trying.
 
Control arrays, as discussed here, are the most suitable solution. I would like to make a few changes to George's code, to make it even more simple and efficient.
[tt]
Private Sub txtName_KeyPress(Index As Integer, KeyAscii As Integer)
Select Case KeyAscii
Case vbKeyReturn
txtName((Index + 1) Mod 8).SetFocus
Case vbeky1 To vbKey9
Case Else
MsgBox "Enter a number greater than zero."
KeyAscii = 0
End If
End Sub
[/tt]
Here, assuming that the text box indices range from 0 to 7, the SetFocus method makes sure that the focus is pushed forward to the next text box automatically, and then back to the first one, in a close loop.
 
Err...
The "End If" above should be read as "End Select".
 
There is a reason why VB6 does not include events for "validation by keystroke" and promotes "validation by field."

Unless your program is meant for use by rank novices who only use it rarely keystroke validation is tedious and frustrating. Most typists can get ahead of it the result can be a mess if keystroke A triggers a MsgBox that keystroke B dismisses - or worse yet triggers an undesired action.

In general don't do this.

It is also absurd to write code treating the Enter key as the Tab key. These two keys have a predefined meaning in Windows user interfaces. By subverting this you break the whole "learn it once" model of Windows UI interaction.


Lots of time and money was spent on studying the issues when Microsoft set these rules in place. By subverting them you just increase the training requirements to use your applications and make Windows more confusing for users.
 
Thank you all for the great help. I've learned a lot in a short time.
 

I would definitely go with the strongm and gmmastros’ answer, but to answer your original question (kind of) you can use a function or sub like that to be called from text boxes. Let’s say you want to position a calendar control next to a text box, you can pass the text box to the procedure ByRef and use it there:
Code:
Option Explicit

Private Sub Text1_Click()
    Call PositionMyCalNextTo(Text1)
End Sub
Private Sub Text2_Click()
    Call PositionMyCalNextTo(Text2)
End Sub
Private Sub Text3_Click()
    Call PositionMyCalNextTo(Text3)
End Sub

Private Sub PositionMyCalNextTo(ByRef txtBox As TextBox)

With MyCalendar
    .Top = txtBox.Top
    .Left = txtBox.Left + txtBox.Width
End With

End Sub

Have fun.

---- Andy
 
Hypetia... Can't get your example to work. I placed two text boxes on a form and placed your code but I can type any non numeric character without getting the error message and the enter key doesn't work. ???
 
The two textboxes need to have the same name in properties...


Mark

"You guys pair up in groups of three, then line up in a circle."
- Bill Peterson, a Florida State football coach
 

I placed two text boxes on a form
What are the names and indexes of the 2 text boxes on your Form? Like Mark said, the names have to be the same, indexes will be different.

If the text boxes' name is [tt]txtName[/tt], try this little modification of Hypetia's code
Code:
Private Sub txtName_KeyPress(Index As Integer, _
    KeyAscii As Integer)
Select Case KeyAscii
    Case vbKeyReturn
        If Index < txtName.UBound Then
            txtName(Index + 1).SetFocus
        End If
    Case vbKey1 To vbKey9, 8 [green]'8 is Backspace[/green]
    Case Else
        MsgBox "Enter a number greater than zero."
        KeyAscii = 0
End Select
End Sub

Have fun.

---- Andy
 
Yep. I forgot to set the form keypreview to true and create a text box array. Everything works now. Thanks again folks.
 
Code:
        txtName((Index + 1) Mod 8).SetFocus
Elegant stuff, Hypetia...

Wisgro, it looks like you don't quite understand the use of the form's keypreview event. I'll see if I can explain. Any event that has something to do with a key (keypress, keyup, keydown) will be tied to a control. So each textbox will have its own set of these events, and so will other types of controls that allow keyboard input. Now, what if, say, you want the F3 key to always bring up some sort of menu? You'd have to write the code once for each control that the user could be in when they pressed the F3 key. You don't want that. So, you set the Form's KeyPreview property to true, and you create a Form_KeyUp event in which you handle the F3 key.

So, KeyPreview means that you will first look for any Form_Keywhatever events before looking for any WhateverTheCurrentControlIs_KeyWhatever events. It's useful when you have some sort of behavior with the keys that you want to be the same no matter where you are on the form.

In this case, therefore, you don't need KeyPreview to be set to true, because you're using control arrays instead. (I would also recommend the use of control arrays here over KeyPreview/ActiveControl. All due respect to waytech, the resulting code is more efficient.)
 
I always have every text box and Command button on a form with the same name but with a different index.
After you lay down the first one just make a copy of it and when you paste it a different index is automatically applied.

That way you do such things as easily identify where the mouse is by having each control change color or have a outer border appear when you hover the mouse over it.

For the various buttons, instead of having lots of subs, I simply have one sub for each type of control such as -
Sub cmdMyText_Click(Index as integer)
Select Case Index
Case 0
'Stop code

Case 1
'Pause code

Case 2
'Go code

etc
End Select
End Sub

Any common validation goes outside the Select Case loop
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top