Excel VBA Userform If Focus Changes Trigger - vba

I have a couple user forms in VBA, id like to add a feature that when a user first clicks on a textbox (changes the focus to it), any text inside gets selected. I've seen this feature in some accounting applications and in your web browser when you first click the URL bar. Its essentially meant so that users can immediately overwrite a text field. Was wondering how I might do the same in VBA, but I'm still a novice. I looked through a couple sub triggers(dont know the correct term) but haven't seen any. I found one for when you click the text box but I don't want the text constantly being selected every time I click the field.
Thanks.

put this in your textbox event
Dim checked As Boolean
Private Sub TextBox1_Change()
If checked = True Then
TextBox1.SelStart = 0
TextBox1.SelLength = 0
checked = True
End If
End Sub
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
checked = False
End Sub
Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If checked = False Then
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1)
checked = True
End If
End Sub
once you click your textbox, it will hightlight the text, if you click the text, it will unhightlight and allow you to modified the text. if you click outside that textbox and click back inside that will rehighlight the whole text.

Related

How to set tab order by a macro in MS Word?

I have a MS Word form with ActiveX control (not the form control). Suppose I have two textboxes and two option button as follows:
Name: [textBox1]
Address: [textBox2]
Gender: [opt1] Male [opt2] Female
Now if I want a tab order, I have to add following macro:
Private Sub textBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 9 Then
textBox2.Activate
End If
End Sub
Private Sub textBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 9 Then
opt1.Activate
End If
End Sub
Private Sub opt1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 9 Then
opt2.Activate
End If
End Sub
Now in my real form there are 20 text boxes and 12 option buttons, so it is quite boring to write down keydown event for each form field. How can I write a macro so that it will first get the name of current form field on keydown (and validating it as tab keydown) and then go to next form field?
For the sake of tab order, I will then rename all form field chronologically such as field1, field2, field3......... etc, so that with an increment the code can move the tab to next form field.
Here is the screen shot of ActiveX tools those I used in forms:
I have cross-posted this topic to VbaExpress forum also.
You aren't going to be any happier with this answer than you were with my last...
The problem is that the keypress, or KeyDown, is only triggered by the fact that the focus is in an ActiveX control, and will be specific to that control. So you have no choice than a KeyDown event for every control. You can keep the code in the event to a minimum, but...
There's no way to identify controls on a document surface directly by name as a string. ThisDocument.ControlName is possible, but there's nothing like ThisDocument.Controls("ControlName") available that would let you substitute names, nor allow you to identify the name of the current control.
There is a way to do it, but it's convoluted. Since these are in-line with the text (no text wrapping) they belong to the document's InlineShapes collection. Their programming interface can only be addressed through the InlineShape's OLEFormat.Object property. This means the code needs to loop the InlineShapes collection twice: once to identify the ActiveX control where the key was pressed, once to identify the control which should be next.
The following code illustrates the principle. What it does not do is
work for more than 9 controls - that would require code that checks, from the right of the name, how many characters are numerical
go back to the first control if focus is in the last
Note that it might be possible to get around event code for each control. It would involve using the Windows API, which means it would fire every time the user presses Tab. But I have no idea whether the key presses would be captured when focus is inside a control. And you would have to test each time if this is the case - and you'd still have to be able to identify which control the focus is in.
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
GoToNextControl KeyCode, ThisDocument.TextBox1.Name
End Sub
Private Sub TextBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
GoToNextControl KeyCode, ThisDocument.TextBox2.Name
End Sub
Sub GoToNextControl(KeyCode As MSForms.ReturnInteger, controlName As String)
Dim ils As Word.InlineShape, ils2 As Word.InlineShape
Dim c As MSForms.Control
Dim baseName As String, nextName
Dim nameCounter As Long
baseName = Mid(controlName, 1, Len(controlName) - 1)
nameCounter = Right(controlName, 1)
If KeyCode = 9 Then
For Each ils In ThisDocument.InlineShapes
If ils.Type = wdInlineShapeOLEControlObject Then
If ils.OLEFormat.Object.Name = controlName Then
nextName = baseName & nameCounter + 1
For Each ils2 In ThisDocument.InlineShapes
If ils2.Type = wdInlineShapeOLEControlObject Then
If ils2.OLEFormat.Object.Name = nextName Then
ils2.Select
Exit Sub
End If
End If
Next
End If
End If
Next
End If
End Sub
All-in-all it might make more sense to stick to the legacy form fields or to content controls, or move this to a UserForm that then writes to the document.

Send keystroke to caret

I have an onscreen number pad 0-9, I'm trying to send a keystroke to a checkbox when a user clicks the button of that number (essentially a touchscreen keyboard). There are several textbox's and I want to send it to the one that currently has the caret in it. I've tried SendKeys.Send("1") but that doesn't send it. What is the best way of doing this?
The issue you are encountering is because when the user clicks on any of your buttons, the button takes focus and the textbox loses focus, and therefore any keystrokes are sent to the control with focus, i.e. the button.
One possible way around this might be to use a global variable to store a reference to the last textbox to have lost focus on the form (via the On Exit or On Lost Focus events of each textbox), and then populate the content of this stored textbox with an appropriate value as part of the On Click event of each button.
A very simple example of this might be something along the lines of:
Dim LastTextBox As TextBox
Private Sub TextBox1_Exit(Cancel As Integer)
Set LastTextBox = TextBox1
End Sub
Private Sub TextBox2_Exit(Cancel As Integer)
Set LastTextBox = TextBox2
End Sub
Private Sub Button1_Click()
If Not LastTextBox Is Nothing Then LastTextBox = "1"
End Sub
Private Sub Button2_Click()
If Not LastTextBox Is Nothing Then LastTextBox = "2"
End Sub

How to dynamically edit a excel vba form label and tab label?

I have an excel vba form which has some tabs(pages).What I need is, if I double click on label, it should be editable. same is the case for the tabs.
I tried to add some things into the double click function, but not showing any change.
Labels are not editable by the end user
you may adopt this workaround
'change "Label1" occurrences to your actual label name
Private Sub Label1_DblClick()
Me.Label1.Caption = Application.InputBox("enter label text", "label editing", "")
End Sub
You can have a TextBox and disable it. The side effect is you will have textbox edit cursor over the label.
Have two subroutines, one called Labelize and another Textboxize. The former locks the textbox, makes it tranparent, and sets the 3D effect to flat. The latter unlocks it, makes it opaque, and sets the 3D to sunken (the default).
' Makes a textbox look like a label
Private Sub Labelize(txtbox As MSForms.TextBox)
txtbox.Locked = True
txtbox.BackStyle = fmBackStyleTransparent
txtbox.SpecialEffect = fmSpecialEffectFlat
End Sub
' Makes a textbox look like a textbox
Private Sub Textboxize(txtbox As MSForms.TextBox)
txtbox.Locked = False
txtbox.BackStyle = fmBackStyleOpaque
txtbox.SpecialEffect = fmSpecialEffectSunken
End Sub
In the form initialize event set call the Labelize method passing in your textboxes.
Private Sub UserForm_Initialize()
Labelize Me.txtExample
End Sub
In the double-click event per textbox, call the Textboxize method passing in your textbox again.
Private Sub txtExample_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Textboxize Me.txtExample
End Sub
Then in each KeyDown event, check if the key pressed was enter then call the Labelize method.
Private Sub txtExample_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 13 Then Labelize Me.txtExample
End Sub

Trapping right-click in worksheet textbox

I'd like to be able to trap the right-click event when a user right-clicks in a worksheet textbox not ActiveX.
I know it can be done easily for userform textboxes, that's not what I'm after.
In the worksheet event Worksheet_BeforeRightClick I have the following:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
mRightClick.RightClickOnMoMList rngTarget:=Target, boolCancel:=Cancel
End Sub
However it doesn't even enter it when I right click on the textbox (but a cell of the same worksheet does work). I suspect that it is due to the Target argument being a Range.
Is there a way to make that event trap right clicks on shapes like textboxes as well?
I've just done this:
- opened Excel and entered Design Mode
- added a text box to a worksheet
- double-clicked the text box, which took me to the Change event for that control
- I selected the MouseUp event
What you're after is Button = 2 for the right button (left button is 1).
So...
Private Sub TextBox1_MouseUp(ByVal Button As Integer, _
ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
If Button = 1 Then
MsgBox "Left-click"
ElseIf Button = 2 Then
MsgBox "Right-click"
End If
End Sub

When I double click on a cell to open a form, a checkbox on the form behind my cursor is checked/unchecked. How can I prevent this from happening?

I have a form that appears on a double click event of a specific cell.
The form contains a list box with a bunch of checkboxes in it and in my _Activate() sub, the checkboxes are set to true or false based on values on the active sheet.
The trouble is that when the form opens up behind the cursor, the second click of the double click that opens the form is also checking/unchecking a checkbox in the form.
I've tried sticking "DoEvents" in the activate sub before the code sets the checkbox values but it hasn't made a difference - The checkbox behind my cursor where the form opens will be checked/unchecked.
I don't expect that the code will help much but it is essentially as below:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target = Range("aParticularRangeName") Then
frmSelectStuff.Show
End If
End Sub
Public Sub UserForm_Activate()
Dim iRegions As Integer
Dim sRecheck As Variant
Dim sRecheckList() As String
sRecheckList = Split(ActiveCell.Value, "; ")
For Each sRecheck In sRecheckList
For iRegions = 0 To lbRegionsTemp.ListCount - 1
If sRecheck = lbRegionsTemp.List(iRegions) Then lbRegionsTemp.Selected(iRegions) = True
Next
Next
End Sub
What about using Cancel = True?
If Target = Range("aParticularRangeName") Then
Cancel = True
frmSelectStuff.Show
End If