I have a Userform in Excel. It has 6 Textboxes, they are the only controls on the Userform with TabStop set to True.
I can tab and move through the textboxes. I cannot get SetFocus to work on Events fired when moving between the Textboxes. I can put a CommandButton on the userform with Userform16.Textbox1.Setfocus and it works as expected to move the focus to Textbox1.
I set up a simple test event (see below) to move the textbox focus back up to TextBox1 when Textbox2 is entered. It moves focus to Textbox3 when I tab out of TextBox1.
Private Sub TextBox2_Enter()
Cancel = True
UserForm16.TextBox1.SetFocus
End Sub
By putting a Stop in the above, I can see that the event is firing as expected, but it will not allow me to control the focus the next control.
I get the same results with or without the Cancel = True statement in the sub.
I set up a simple test event (see below) to move the textbox focus back up to TextBox1 when Textbox2 is entered, it actually moves focus to Textbox3 when I tab out of TextBox1.
You can't set focus to another control in the _Enter() event. If you try to then the code will move focus to control which has the next TabIndex
For example
Let's say you have 5 textboxes with the following TabIndex
TextBox1 (TabIndex 0)
TextBox2 (TabIndex 1)
TextBox3 (TabIndex 3)
TextBox4 (TabIndex 4)
TextBox5 (TabIndex 2)
Now if you have this code
Private Sub TextBox2_Enter()
TextBox3.SetFocus
End Sub
The moment you press TAB from TextBox1, the focus will move to TextBox5 (and not TextBox3) as it has the next TabIndex.
Also Cancel = True will not have any effect because it is not an argument of _Enter() like it is of say Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Edit
BTW, the only time the focus will come back to Textbox1 in your scenario is when there are only two TextBoxes in the form.
I know this is old but this answered my question and I can't comment. However, Stan in reference to your comment on June 8, 2017 I believe you were looking for something like the code below which will highlight the text in the text box when you use it with Cancel = True. I use it in the textbox exit event. This will be the indication to the user that the text box is selected.
With Me.TextBox1
.Value = "Full Name"
.SelStart = 0
.SelLength = Len(.Text)
.SetFocus
End With
Cancel = True
While it is true that _Enter() event can not handle .SetFocus, the _KeyDown() event can! And thats a pretty good workaround, you just need to monitor if the TAB key was pressed.
So the code would look like something similar where TextBox1 is the one you leave and TB2 is the one you enter;
Private Sub TextBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 9 Then TextBox1.SetFocus 'where 9 is the KeyCode for the TAB button
End Sub
Related
I have created a userform and included a combobox populated with numbers 1 to x in userform.initialize and then added .setfocus and .dropdown commands. For some strange reason the combobox (with dropdown) appears on my lefthand screen outside the userform. The combobox also appears on the userform, but without the dropdown displayed. The screen combobox is active and if I click a number in the dropdown list the code accepts this input.
I have tried deleting the combobox and inserting another one with a different name, but the behaviour persists. If I remove the .dropdown command, the combobox appears correctly on the userform without the screen copy and I can click the userform box and display and use the dropdown list.
On reading an unrelated post, I tried adding .visible=false, followed by .visible=true before the .dropdown command, but that didn't stop the behaviour.
I have tried exporting, deleting and re-importing the userform, but the behaviour persists.
The code I am using (in userform_initialize sub) is:
With cbxGroup 'combobox
.Clear
For i = 1 To PlayGroups
.AddItem i
Next
.ListIndex = -1
.Visible = False
.Visible = True
.SetFocus
.DropDown
End With
Has anyone come across such behaviour before and can explain what has happened, and maybe how to fix it. I can just recreate the userform, but it seems a lot of unnecessary work. I am using Office 365
I can confirm the behaviour.
I strongly assume that this is related to the fact that you are using the Initialize-Trigger. When this trigger is executed, the form is still in the creation-process and some internal properties (eg the exact screen position) are likely not calculated. As a consequence, when calling DropDown, the Combobox is painted on the screen but not at the right position.
You can keep the code to fill the combobox in the Initialize-Trigger, but you should move the SetFocus and DropDown-commands to the Activate-Trigger
Private Sub UserForm_Initialize()
fillCombo
End Sub
Private Sub UserForm_Activate()
showCombo
End Sub
Sub fillCombo()
With Me.cbxGroup
.Clear
Dim i
For i = 1 To PlayGroups
.AddItem i
Next
.ListIndex = -1
End With
End Sub
Sub showCombo()
With Me.cbxGroup
.SetFocus
.DropDown
End With
End Sub
Hopefully this is a simple one for somebody out there. I have an Excel VBA UserForm with a number of text boxes for the entry of parameters. In addition, there is an image on the userform. As the user clicks into a textbox, the image on the UserForm is changed by triggering the _Enter() event to show an image of the parameter in question. This works fine and is not a problem. However, as the user exits the textbox, I want the image to revert back to the original image. I've tried the Events for _Exit() and _AfterUpdate() to make this work and although it works fine if I update the parameter, it doesn't work if I don't update the parameter. In essence, the image changes as I enter the text box but doesn't change as I leave unless I update the value in the text box.
Does anybody have any ideas why this is so and what I might be able to do about it?
Update (with code as requested). I've now figured out that the textbox Exit event is not being triggered because I have more than one frame on my UserForm and I am clicking on a control in a different frame. I've made the following example.
and the following code;
Option Explicit
Dim TextBox1Data As Variant, TextBox2Data As Variant
Private Sub TextBox1_AfterUpdate()
TextBox1Data = TextBox1.Value
Debug.Print "AfterUpdate Textbox 1"
End Sub
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Debug.Print "Exit Textbox 1"
End Sub
Private Sub TextBox2_AfterUpdate()
TextBox2Data = TextBox2.Value
Debug.Print "AfterUpdate Textbox 2"
End Sub
Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Debug.Print "Exit Textbox 2"
End Sub
Private Sub UserForm_Initialize()
ComboBox1.List = Array("Item 1", "Item 2", "Item 3", "Item 4")
ComboBox1.Text = ComboBox1.List(1)
End Sub
If I click into TextBox1 and then click into either ComboBox1 or CheckBox1, the Exit event for TextBox1 is triggered. However, if I click into TextBox1 and then click into either CheckBox2 or CheckBox3, the event is not triggered. I assume that this is because the CheckBoxes are in a different frame. Is this the case? Is there a way of triggering an Exit event for a TextBox when moving from one frame to another?
It seems like this is a known problem - see Microsoft Q210734. Rather than use the Set Focus method suggested by MS, I've now added an Event for exiting the Frame where the textboxes are located, e.g. using my example code, I added the following;
Private Sub Frame1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Debug.Print "Exiting Frame"
End Sub
What happens now is that when moving from one control to another within Frame1, the normal Exit event for the control works as expected and when moving from Frame1 to Frame2, the Exit event for the frame works.
Hope this helps someone in the same predicament.
I'm after some help that has had me stumped for a while. Excuse the long explanation.
I have a combobox that populates from a range when the userform initializes. When I type into the combobox the preemptive text appears as it is supposed to. I then have a Change event for a textbox which populates based on what gets typed into the combobox. That part all works fine (I got that code from another site).
I have two ways to enter the data into the combobox, one is by typing, and the other is when the text in another text box changes, it also populates the combobox. I do this by "combobox1 = textbox1.value". Now here is the part when I am stumped. When using the combobox1 = textbox1 method, it doesn't work properly (or more so, how I want it to work). It enters the text that is contained in textbox1, but it doesn't show the full line of preemptive text like how it does when typing in the combobox, nor does it then populate the textbox that changes when the combobox changes. If I then click in the combo box and hit the space bar the change event fires and the rest of the preemptive text from the range appears. I tried putting a space " " command at the end combobox1 = textbox1 & " " in the hope it would think there is more text to come but that didn't work. Is there any way to get VBA do do this, or am I asking too much of it?
Hopefully this makes sense.
cheers
paul
seems like ComboBox AutoCompletion feature is triggered by UI input only
you can work around it as follows:
Private Sub TextBox1_Change()
Dim iList As Long
With Me.ComboBox1
For iList = 0 To .ListCount - 1
If Left(.List(iList), Len(Me.TextBox1.Value)) = Me.TextBox1.Value Then
.ListIndex = iList ' if any combobox1 value matches textbox1 value then select it
Exit Sub
End If
Next
.ListIndex = -1 ' if no combobox1 value matches textbox1 value then "deselect" combobox1
End With
End Sub
Let's say I had a combobox1, 2, 3 and a textbox1 on a userform. After update event was associated to combobox1. When Tab key was pressed after update event was fired (filling comboboxes 2 and 3). In the code of this event, just before exit sub there was textbox1.setfocus to skip entering other coboboxes in the tab order (combobox 1,2,3, textbox1). It worked just fine.
When I added another combobox that is now combobox2, the tab order was changed to 1,2,3,4.
After update is still associated to combobox1 and textbox1.setfocus is last line before exit sub. Unfortunately when exit sub line for after update is executed, it fires combobox3 enter event and moves focus to combobox3. It's more incomprehensible because tab order is combobox1,2,3,4 so it skips the tab order as well.
When I debuged code, the focus to textbox1 was set as it should but still just when exit sub is executed, code line is moved to combobox3 enter event...
Any tips appreciated.
in your userform code pane act as follows:
a userform scoped Boolean variable
hence, place this before any Sub/Function code
Dim SetTextBox1Focus As Boolean
in your ComboBox1_AfterUpdate() event handler place:
Private Sub ComboBox1_AfterUpdate()
If (condition that checks if the data entered in combobox1 exists in the database) is True Then
...
your code to fill comboboxes 2, 3 ad 4
...
Me.TextBox1.SetFocus
SetTextBox1Focus = True '<--| "flag" TextBox1 to receive the focus
End If
End Sub
add an Enter event handler for all userform controls whose tab index is in between ComboBox1 and TexBox1
for instance, assuming those are ComboBox2, ComboBox3 and ComboBox4
Private Sub ComboBox2_Enter()
CheckSetTextBox1Focus
End Sub
Private Sub ComboBox3_Enter()
CheckSetTextBox1Focus
End Sub
Private Sub ComboBox4_Enter()
CheckSetTextBox1Focus
End Sub
add the following CheckSetTextBox1Focus() Sub
Sub CheckSetTextBox1Focus()
If SetTextBox1Focus Then
Me.TextBox1.SetFocus
SetTextBox1Focus = False
End If
End Sub
I have a button that is on an excel spreadsheet (not in a userform) and I have a userfrom that has a textbox on and would like it to, when I enter a name in the textbox on my userform for it to then set the Caption of my button that is on my excel sheet to what ever is entered in the textbox. I would like to know what code I need to use and where to insert that code?
Hope that make sense, please keep in mind I'm a newbie to this so this is why I am asking where to insert the code
Many thanks in advance
Code in your userform, assuming a textbox named TextBox1, could be like this:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Len(Me.Textbox1.text) > 0 then
ActiveSheet.Buttons("Button 1").Caption = Me.Textbox1.text
End If
End Sub
or if you want the caption to update as you type:
Private Sub TextBox1_Change()
If Len(Me.TextBox1.Text) > 0 Then _
ActiveSheet.Buttons("Button 1").Caption = Me.TextBox1.Text
End Sub
As you have used "CommandButton" (which is an ActiveX control) yet seemingly heading towards a Form control, I have gone with the 2 methods you will need:
ActiveX:
ActiveSheet.Shapes("YourButton").OLEFormat.Object.Object.Caption = "YourText"
Forms:
ActiveSheet.Shapes("YourButton").TextFrame.Characters.Text = "YourText"