which textbox was entered ?

erik.van.geit

MrExcel MVP
Joined
Feb 1, 2003
Messages
17,832
intresting solution posted by Jaafar here:Which commandbutton was clicked ?

Didn't want to interfer in the original thread...

Can this be done with textboxes?
I would like to do some operations when a textbox is entered. There are 80 boxes, so this would spare me a lot of lines of code

at the moment I'm using
Code:
Private Sub TextBox1_Enter()
macro1 (Mid(ActiveControl.Name, 8))
End Sub
...
Private Sub TextBox80_Enter()
macro1 (Mid(ActiveControl.Name, 8))
End Sub
same code 80 times !!

kind regards,
Erik
 

Excel Facts

Using Function Arguments with nested formulas
If writing INDEX in Func. Arguments, type MATCH(. Use the mouse to click inside MATCH in the formula bar. Dialog switches to MATCH.
I think something like below may work for you but i havnt checked my code so I assume theres errors there somewhere but will give you the idea

Private Sub CommandButton1_Click()

Dim i As Integer

For i = 1 To 80
UserForm1.Controls("TextBox" & i).select
macro1 (Mid(ActiveControl.Name, 8))
Next i
End Sub
 
Upvote 0
Gibbo,
thanks for trying

the original thread is titled: which button was pressed?
the code provided returns the caption of the button when you press a button, you could return the Name or other properties

this thread is titled: which textbox is entered
the code I'm searching for would
- "know" what textbox was entered
- do some operations when a (single) textbox is ENTERED

in comparison with the original thread the result would be a MsgBox with "TEXTBOX1" when the user would enter TEXTBOX1

kind regards,
Erik
 
Upvote 0
You need a class module. Enter and Exit events for TextBoxes are not reliable in a class module environment. Because your textboxes are on a userform, they do not support the GotFocus event as an embedded activex textbox would.

For a workaround and as an example of class modules, in the VBE, insert a new class module and acept its default name of New Class 1. Paste this code into it:

Option Explicit
Public WithEvents TxtGroup As MSForms.TextBox

Private Sub TxtGroup_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
MsgBox "You clicked the text box named " & TxtGroup.Name
End Sub

Private Sub TxtGroup_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
MsgBox "You used the keyboard to exit from the text box named " & TxtGroup.Name
End Sub

Private Sub TxtGroup_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
On Error Resume Next
With TxtGroup
Select Case KeyAscii
Case 46, 48 To 57
Case Else
KeyAscii = 0
MsgBox "Only numbers are allowed.", 48, "That character is not allowed."
End Select
End With
End Sub





In the userform module, paste in this code:

Option Explicit
Dim txtBoxes(1 To 80) As New Class1

Private Sub UserForm_Initialize()
Dim i As Integer
For i = 1 To 80
Set txtBoxes(i).TxtGroup = Me.Controls("TextBox" & i)
Next i
End Sub




Now return to the worksheet and call your userform. The code as is will be somewhat annoying practically, remember, these are just examples of events. The MouseDown event will make a message box pop up when you click on the textbox but that will not select it. With the KeyDown event, you can select a textbox using the tab key, and when you do, it will make a message box pop up telling you what the name of that text box is you just exited. The KeyPress event is an example of what I use in my clients' apps for textboxes where only numbers are allowed, and I have a lot of textboxes, hence a class module like this.

Note, the "80" in code is there because you said 80. Modify as needed, depending on naming syntax of your textboxes if they are not named as "TextBox" & number .

Also note as I said, practically, these events would not all be in place, they are just examples. As is, if you enter a non-didgit character, you will get two message boxes. Therefore, add or delete events from the class module for that TxtGroup class as are appropriate for your app.
 
Upvote 0
Thank you very much, Tom, for taking the time to respond.

This fixes the problem. I knew about this "classmodule-trick" and I've got something of the kind on my machine here, but your syntax is much less complicated.
Just what I needed !

kind regards,
Erik
 
Upvote 0
Hi, again!
Tom,

this would avoid the need of entering the number of textboxes.
do you think it's OK ?
for me it's working
Code:
Option Explicit

Dim txtBoxes() As New Class1

Private Sub UserForm_Initialize()
Dim i As Integer
Dim ctrl As Control

For Each ctrl In Me.Controls
    If TypeName(ctrl) = "TextBox" Then
    i = i + 1
    ReDim Preserve txtBoxes(i)
    Set txtBoxes(i).TxtGroup = ctrl
    End If
Next ctrl

End Sub

kind regards,
Erik
 
Upvote 0
If you use redim preserve to capture all textboxes, just make sure there are no textboxes in the userform that you do not want involved in the class, because by design that syntax will involve all textboxes (read on for exception).

In my actual workbook example for textbox class modules, I have 8 textboxes in a userform, and onlt the first 5 are to be involved in the class, so really my userform's event code looked like this:

Option Explicit
Dim txtBoxes(1 To 5) As New Class1

Private Sub UserForm_Initialize()
Dim i As Integer
For i = 1 To 5
Set txtBoxes(i).TxtGroup = Me.Controls("TextBox" & i)
Next i
End Sub



This made the point in my example (among others that will be on a training disk I am developing) that the other 3 textboxes are not affected.

As a minor (and I do mean minor) point because I normally don't get into the trivialities of differences in nanoseconds with code compilation, redim presents a slightly greater burden when compiling than the loop. It all goes back to design. If you know you have 80 and will keep it at 80, or maybe you will add or delete textboxes from the userform and will remember to modify the code, then the loop is fine if you don't want to worry about textboxes that are not meant to be included in the class.

Now someone may say, why not just stick an If structure in the redim to ferret out textboxes of a certain naming syntax or in a certain control group such as a frame. But, as long as that will take place, just think ahead of time how to name the textboxes. That's what workbook design is all about. In that case, the loop I suggested would be fine for only involving textboxes with that naming syntax.

Bottom line, it depends on design and likely evolution of the application depending on eventual client needs.
 
Upvote 0
Tom,

The only thing to say is:
I completely agree with every part of your post here!

kind regards,
Erik
 
Upvote 0
in comparison with the original thread the result would be a MsgBox with "TEXTBOX1" when the user would enter TEXTBOX1

As Tom rightly said, the Enter\Exit Events cannot be trapped in Class modules.

Below is a Demo of a work-round .It uses an API Timer .. I have tested it and seems to work with no appearant side effects for any number of TextBoxes on a UserForm and the code responds to the Tab Key as well as the Mouse.



Place this code in the UserForm Module:

Code:
Option Explicit

Private Sub UserForm_Activate()
    lngTimerID = SetTimer(0, 0, 1, AddressOf TimerProc)
End Sub


Private Sub UserForm_Terminate()
    killtimerAPI 0, lngTimerID
    strPreviousTextBox = ""
End Sub


Place this in a Standard Module :

Code:
Option Explicit

Declare Function SetTimer Lib "user32" _
(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long

Declare Function killtimerAPI Lib "user32" Alias "KillTimer" _
(ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

Public lngTimerID As Long
Public strPreviousTextBox As String


Public Sub TimerProc()

    With UserForm1
        If TypeName(.ActiveControl) = "TextBox" Then
            If strPreviousTextBox <> .ActiveControl.Name Then
                killtimerAPI 0, lngTimerID
                Call TextBox_Enter_Event
                .ActiveControl.SetFocus
                lngTimerID = SetTimer(0, 0, 1, AddressOf TimerProc)
                strPreviousTextBox = .ActiveControl.Name
            End If
        Else
            strPreviousTextBox = ""
        End If
    End With
    
End Sub


Sub TextBox_Enter_Event()

    Dim strMsg As String
    With UserForm1.ActiveControl
       strMsg = "* Name :  " & .Name & vbCrLf
        strMsg = strMsg & "* Text :  " & .Object.Text & vbCrLf
       strMsg = strMsg & "* Tab index :  " & .TabIndex
    End With
    MsgBox "You entered TextBox : " & vbCrLf & vbCrLf & strMsg
    
End Sub


This hack will mimic the effect of the missing Enter Event in a Class Module.

Regards.
 
Upvote 0
Jaafar,

Thank you for this intresting workaround :)
I will need to study how you did this...

One problem: activating the userform, you get a first popup from "TextBox_Enter_Event"
Couldn't stop this using something like

Private Sub UserForm_Activate()
flag = True
lngTimerID = SetTimer(0, 0, 1, AddressOf TimerProc)

normal module
Public flag As Boolean

in the TextBox_Enter_Event
If flag = True Then Exit Sub

Jaafar, do you get the popup? Can you avoid it ?

kind regards,
Erik

PS: this is for sport as Toms soluton is already operational
 
Upvote 0

Forum statistics

Threads
1,215,906
Messages
6,127,660
Members
449,395
Latest member
Perdi

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top