text box exit event in multipage userform - vba

I have multipage user form which has sub multipage. the text box exit event is not working it is working when userform exits. So I have tried the after update event. It works fine but I am not able to set focus the textbox if the entered value is not numeric. the code is working fine. userform doesnt show the previos page text box.
below is the screen shot and code
At page no 4 I have text box and once the details entered,I click the page2 to proceed. before that I need to check whether the entered detaisl is numeric or not. If its not numeric I have to show the page4 and focus on text box1 to re-enter the details that is not working. please help me guys.
Private Sub TextBox3_AfterUpdate()
If Len(UserForm1.TextBox3.Value) <> 0 And _
IsNumeric(UserForm1.TextBox3.Value) = False Then
UserForm1.MultiPage1.Value = 0
userform1.multipage2.value = 1
UserForm1.TextBox3.SetFocus
MsgBox "Only Numbers are Allowed!!"
End If
End Sub
the code didnot show error but Its not focusing on the text box still showing the page2.

Messagebox interrupts set Focus
Displaying a messagebox (window) interrupts your SetFocus code. In order to work around this issue just redisplay the userform after hiding via
Me.Hide: Me.Show
Another approach would be to display the error message by a Label caption message.
Modified example using your original code:
Private Sub TextBox3_AfterUpdate()
If Len(Me.TextBox3.Value) <> 0 And _
IsNumeric(Me.TextBox3.Value) = False Then
Me.MultiPage1.Value = 0
MsgBox "Only Numbers are allowed!!"
Me.MultiPage2.Value = 1
Me.TextBox3.SetFocus
Me.Hide: Me.Show ' << work around by redisplaying userform
End If
End Sub
Hint
It's better to use the Me. prefix than UserForm1. within the userform code module itself to identify controls (and allow IntelliSense).

You could consider using keydown events to prevent non numeric input all together with something like this
'' allows checking numlock
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Private Const ksCapital As Long = 20
Private Const ksNumLock As Long = 144
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case vbKeyBack, vbKeyDelete, vbKeyLeft, vbKeyRight, vbKeyInsert, vbKeyNumlock
'' allow deleting, moving, changing numlock
Case Asc(0) To Asc(9)
'' if input is a number, not a symbol let it remain
If Shift Eqv Not GetKeyState(ksNumLock) Then KeyCode = 0
Case Asc("-")
'' allow negatives
If InStr(1, Me.TextBox1.Text, "-") > 0 Or Me.TextBox1.SelStart > 0 Then Let KeyCode = 0
Case Asc(".")
'' allow decimals
If InStr(1, Me.TextBox1.Text, ".") > 0 Then Let KeyCode = 0
Case Else
'' allow nothing else
Let KeyCode = 0
End Select
End Sub

Related

Moving the cursor to another textbox after Enter Event - VBA

Could you please help me?
With the code below, I can "Setfocus" and change the "Backcolor" of "Me.txtFT".
But, when I am trying to move the cursor to "Me.txtFT" after an "Enter" event on "txtPT", the cursor is not moving, it keeps on the "txtPT".
I am using the code below.
Private Sub txtPT_Enter()
If Trim(Me.txtPT.Value & vbNullString) = 0 Then
MsgBox """FT field"" must contain a value before continue. Please try again": _
Me.txtFT.SetFocus: _
Me.txtFT.BackColor = &H80FFFF: _
Exit Sub
End If
End Sub
Could you please help me?
The condition is testing the length of txtPT but the message is warning about txtFT, so it's unclear from the code what the intent might be.
Instead of handling the entry into control B to validate the value of control A, consider handling the exit from control A - and cancel it losing the focus with an invalid value in the first place:
Private Sub txtFT_Exit(ByVal Cancel As MSForms.ReturnBoolean)
With txtFT
If Len(Trim(.Text & vbNullString)) = 0 Then
Cancel.Value = True
.BackColor = &H80FFFF
MsgBox "[FT] cannot be empty!"
End If
End With
End Sub

Number only text box not working on one of two text boxes in a userform

I have two text boxes on a userform that I would like to be numeric only. The first one works fine based on this( Link), however the second one, which I have implemented in exactly the same way as the first is not working, and I don't know why. Any idea why?
The first textbox is call TextBoxMainVal
The second is called perHour
Code:
'If the Main Value box does not recieve a number send a message to make them change it
Private Sub TextBoxMainVal_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If TextBoxMainVal.Value = "" Then
ElseIf Not IsNumeric(TextBoxMainVal.Value) Then
MsgBox "Enter numbers only"
Cancel = True
TextBoxMainVal.Value = vbNullString
End If
End Sub
'I DONT KNOW WHY THIS ONE ISNT WORKING!
Private Sub perHour_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If perHour.Value = "" Then
ElseIf Not IsNumeric(perHour.Value) Then
MsgBox "Enter numbers only"
Cancel = True
perHour.Value = vbNullString
End If
End Sub
I thought there could be a naming error conflict, so I changed the textbox name, but that did not resolve it.
I cant understand why it is not working. What am I overlooking?
For those who are interested why this may happen there is an answer here. The reason, it appears, the textbox exit handler is not occurring is because it is outside of a frame. For the exit handler to work you need to stay inside the frame.

What property will return the caret (or cursor type bar) to the designated textbox in VBA Excel UserForms? [duplicate]

I have a textbox on a userform. If the user fails to enter anything in this textbox, I need to trap that to force an entry. I can do this easily enough, but after notifying the user tht they need to make an entry, I want the focus to return to the textbox. Right now, it doesn't do that. Here is my code:
Private Sub txtAnswer_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 13:
If Me.txtAnswer.Value = "" Then
temp = MsgBox("You need to enter an answer!", vbCritical + vbOKOnly, "No Answer Found!")
Me.txtAnswer.SetFocus
Else
recordAnswer
End If
End Select
End Sub
This code works fine in that the message box pops up if the textbox is left blank. After clearing the message box, if I hit enter immediately again, the message box reappears, suggesting that the focus is on the textbox. However, if I try to enter a character (like the number '1' for example) nothing appears in the textbox.
Can anybody suggest how I can get the focus back on this textbox in a way that will allow the user to enter data? Thank you!
Why are you not using an 'ok' button to complete the action?
You should not bother users with messages while they are typing in a form. Do it at the end.
Private Sub OK_Click()
'// Validate form
If txtAnswer.Text = vbNullString Then
MsgBox "You need to enter an answer!", vbExclamation, "No Answer Found!"
txtAnswer.SetFocus
Exit Sub
End If
'// You have reached here so form is correct carry on
recordAnswer
End Sub
If you really want to use the behaviour you asked for then try this:
Private Sub txtAnswer_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 13:
If Me.txtAnswer.Value = "" Then
temp = MsgBox("You need to enter an answer!", vbCritical + vbOKOnly, "No Answer Found!")
KeyCode = 0
Else
recordAnswer
End If
End Select
End Sub
The problem is that in your code you are setting focus but the enter key is firing afterwards. You don't need to set focus because the textbox already has the focus you just need to cancel the enter key.
The other answers seem really complicated. I had a similar problem and really wanted a text warning. It seemed easier for me to just make an invisible label on the form that would show up if the input was incorrect. I also made the background of the label red so that the user would notice something was wrong. Doing it this way kept the cursor visible and right where they left off.
Public Function amount(ByRef cont As MSForms.TextBox) As Integer
'makes sure that a number is used
'could change to account for decimals if necessary
Dim i As Long
On Error Resume Next
i = 0
If (cont.Value = "") Then Exit Function
Do While i < 1000000
If (cont.Value = i) Then
UserForm1.Label257.Visible = False
Exit Function
End If
i = i + 1
Loop
UserForm1.Label257.Visible = True
amount = 1
End Function
Public Sub qty_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
If amount(UserForm1.qty) = 1 Then
Cancel = True
End If
End Sub
I hope this helps other who run into this problem later on.
Looking at the above code, I assume the i counter is to keep it going? Sorry a bit rusty, been a few years since I've done code.
At any rate, if thats the case you could always run it while i=0, do (or while true).
Sorry, first time posting here, hope that made sense.

Detecting when data is added to a document, eg. a character or white space

Is there a way to detect when a user presses a key in Microsoft Word using VBA. I have searched for a method which does this. I have also searched for methods which create a way around this, such as detecting when the insertion point moves or it detects when a new character is placed in the word document, but I have had no look. I am currently using appWord_WindowSelectionChange(ByVal Sel As Selection) but this does not detect as you type.
I would appreciate anyone showing me how to either detect a keypress or would be able to show me a workaround which will accomplish the same goal.
Edit
I apologise if the summary of what I want above is not clear. What I have is a sub which fires using appWord_WindowSelectionChange(ByVal Sel As Selection). However what I want is this sub to fire whenever any data is entered into the word document, eg. a letter or a white space character. For example, if there was a character count in the footer of the word document and this sub which I have updates this character count, the character count field should update as the user types in the document.
Not my Code but HTH.
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Sub KeyStrokeLogger()
Dim i As Integer
Dim KeyAsciiValue As Integer
StartLogging
Do While True
For i = 1 To 255
If GetAsyncKeyState(i) = -32767 Then
If CapsLockIsOn() Then
If ShiftIsPressed() = True Then
KeyAsciiValue = Asc(LCase(Chr(i)))
Else
KeyAsciiValue = Asc(UCase(Chr(i)))
End If
Else
If ShiftIsPressed() = True Then
KeyAsciiValue = Asc(UCase(Chr(i)))
Else
KeyAsciiValue = Asc(LCase(Chr(i)))
End If
End If
LogKeyStroke KeyAsciiValue
End If
Next i
DoEvents
Loop
End Sub
Private Function CapsLockIsOn() As Boolean
CapsLockIsOn = CBool(GetKeyState(20))
End Function
Private Function ShiftIsPressed() As Boolean
ShiftIsPressed = CBool(GetAsyncKeyState(16))
End Function
Private Sub StartLogging()
Open "C:\keylog.txt" For Binary As #1
Seek #1, LOF(1) + 1
End Sub
Private Sub LogKeyStroke(KeyAsciiValue As Integer)
Dim c As String * 1
c = Chr(KeyAsciiValue)
Select Case KeyAsciiValue
Case 8
Put #1, , "{BACKSPACE}"
Case 9
Put #1, , "{TAB}"
Case 13
Put #1, , "{ENTER}"
Case 32 To 126
Put #1, , c
Case Else
Put #1, , "{" & KeyAsciiValue & "}"
End Select
End Sub
*"How to use the above code:
Step 1
Create a new document in MS-Word.
Step 2
Go to Tools, Macro, Visual Basic Editor
Step 3
Double click on ThisDocument Object under Project(Document1) in the Project Window.
Step 4
Copy the above code and paste it into the Visual Basic Editor.
Step 5
Close the Visual Basic Editor and save the document.
Step 6
Ensure that macros are enabled. To start logging keystrokes at any time click on Tools, Macro, Macros. Select KeyStrokeLogger and click Run. All the keystrokes will be stored in C:\keylog.txt.
"*
LinkBack to Post
Use keybindings to bind characters to the function you want. For example, the following code (when run) fires a message box when the user enters 0 in the word document.
Put this in module 1
Sub AddKeyBinding()
With Application
.CustomizationContext = ThisDocument
.KeyBindings.Add KeyCode:=BuildKeyCode(wdKey0), _
KeyCategory:=wdKeyCategoryCommand, _
Command:="userpressedzero"
End With
End Sub
Put this in module 2
Sub userpressedzero()
Dim MyText As String
Selection.TypeText ("0")
MsgBox ("user pressed 0")
End Sub
Now run module 1 and press 0 in your word document.

How to Select All Text in TextBox After textBox.Setfocus Using Access VBA

I need to select all the text in a textbox of an Access form when I click (or double click) into it. i tried the following code, unsuccessfully:
Me.txt_CompraPreco.SelStart = 0
Me.txt_CompraPreco.SelLength = Len(Me.txt_CompraPreco)
thanks in advance.
You can use the code shown below. If it doesn't work, place a breakpoint at the first line of code. If it doesn't stop on your breakpoint, then your event is not recognized.
Option Compare Database
Option Explicit
Private Sub txt_CompraPreco_Click()
If Len(Me.txt_CompraPreco & "") = 0 Then Exit Sub
Me.txt_CompraPreco.SelStart = 0
Me.txt_CompraPreco.SelLength = Len(Me.txt_CompraPreco)
End Sub
I was looking for a solution regarding this problem, I have the same issue, however, I have a solution to it, I'm not sure if it's efficient, but here's my code:
'Declare a flag
Public flagDblClick As Boolean
'Double click event
Private Sub txtbox_DblClick (Cancel As Integer)
flagDblClick = True
End Sub
'Mouse up Event
Private Sub txtbox_MouseUp(Button As Integer, Shift As Integer, X as Single, Y as Single)
If flagDblClick Then
flagDblClick = False
txtBox.SelStart = 0
txtBox.SelLength = Len(txtBox.Value)
End If
End Sub
This code will resolve your problem (use with userform).
txt_CompraPreco.SetFocus
Me.txt_CompraPreco.SelStart = 0
Me.txt_CompraPreco.SelLength = Len(Me.txt_CompraPreco)
My trial and error found this.
If your textfield is formatted as a Standard Number and you have set the decimal places to a certain length, you will run into trouble when you enter a single digit. For example if your decimal places in the field properties is set to 2 and you enter "1", you will display "1.00". To get the entire field (1.00) selected, you must specify the .Text property when you determine the .SelLength (not the default .Value property)
Me.txtYourFieldname_GotFocus
Me.txtYourFieldName.SelStart = 0
Me.txtYourFieldName.SelLength = Len(Me.txtYourFieldName.Text)
End Sub
This works for me:
Dim bSelect As Boolean
Private Sub fieldX_Click()
If bSelect Then
'Select text only at first mouse click then user can click again
'and is able to put mouse pointer where he prefers
Me.fieldX.SelStart = 0
Me.fieldX.SelLength = Len(Me.fieldX)
bSelect = False
End If
End Sub
Private Sub fieldX_GotFocus()
bSelect = True
'Select text if field got focus via keyboard, Enter or TAB
'this is not enough if field got focus via mouse click
Me.fieldX.SelStart = 0
Me.fieldX.SelLength = Len(Me.fieldX)
End Sub