Clear Value of a TextBox - excel

I've got an excel UserForm with two TextBox and a Button. How can I delete the value of the TextBox without using TextBox1.Value = "" or TextBox1.Text = "" ?
I can't use these two operations because then the instruction: TextBox2.Value = TextBox1.value*2
give me back an error. (The error is Runtime error 13)
Thanks.

Try looking at the problem a different way. If box1 is empty then why would you want to multiply it by 2? In this case you should error check the value of box1 before you multiply it by box2. The code below checks if Textbox1 is a number and is not empty before multiplying it.
Private Sub CommandButton1_Click()
'Error check: does textbox1 have a number and is not null
If IsNumeric(TextBox1.Value) And TextBox1.Value <> vbNullString Then
TextBox2.Value = TextBox1.Value * 2
Else
TextBox2.Value = "Box1 is empty or invalid"
End If
End Sub
Valid Number:
Invalid or empty:

Related

Mismatch Type in vba

I am trying to create a search mask in Excel, where a search field is popped up (which matches with a column of the sheet), but having only written the first part of the code and wanting to try I ran and ... gives me an error.
Here's the error:
Here's the mask:
I’m translating the error: "Build error... Mismatch type."
Private Sub CommandButton1_Click()
Dim UltimaRiga As Long
If CheckBox1.Value = True And TextBox1.Value Is Not "" Then
UltimaRiga = Range("D1").End(xlDown).Row + 1
If Range("D2").Value Is Not "" And Range("D2").Value = TextBox1.Value Then
TextBox2.Value = "Presente"
If Range("J2").Value = "Disponibile" Then
TextBox3.Value = "Disponibile"
End If
End If
End If
End Sub

How to click out of Combobox?

I have a combobox with the properties MatchEntry 1-fmMatchEntryCompleteand MatchRequired True.
I need it true to prevent any invalid entry in the combobox. I dont want to make this a Style 2-fmStyleDropDownList but rather keep it a Style 0-fmStyleDropDownCombo because I have about 1000 items to choose from.
This setup works, except if you accidentally click in the combobox, and try to click out of it. You keep getting
Invalid Property Value
Is there anyway I could code the invalid entries so I don't have to assign the property to True?
Figured it out if anyone has this problem in the future. All I did was keep the properties above, and add this code to my userform for the combobox1.
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value = "" Then
'Match not required if zero lenght string
Me.ComboBox1.MatchRequired = False
Else
'Match is required if other than zero length string
Me.ComboBox1.MatchRequired = True
End If
End Sub
You can use the combo LostFocus event. It will check if the value matches one of the combo entries, send a message in case of not, and delete the combo value. Or it can do something else, if my suggestion is not good enough:
Private Sub ComboBox1_LostFocus()
If ComboBox1.Value = "" Then Exit Sub
Dim cbVal As Variant, boolFound As Boolean, i As Long
cbVal = ComboBox1.Value
For i = 0 To ComboBox1.ListCount - 1
If cbVal = ComboBox1.list(i) Then boolFound = True: Exit For
Next i
If Not boolFound Then _
MsgBox "The value """ & cbVal & """ does not exist between the combo items" & vbCrLf & _
"It will be deleted", vbInformation, "Illegal entry": ComboBox1.Value = ""
End Sub
MatchRequired should remain False (default)...

BeforeUpdate event validation control

Dears,
I want to make a simple userform to record some serial numbers into excel, it contains a textbox_serialNo., a command button “enter” and another command button “cancel”.
I made a validation control in that serialNo textbox so that only number can be entered. However, when I run the program and input some numbers into the textbox, both command buttons (the "enter" button named as label_enter,the "cancel" button named as label_cancel) have no reactions (e.g. the "cancel" button doesn't unload the form when press) , how should I correct the program? Below are the relevant codes, Thanks.
Private Sub TextBox_SerialNo_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
If Not IsNumeric(TextBox_SerialNo.Value) Then
TextBox_SerialNo.BackColor = rgbYellow
End If
Cancel = True
End Sub
Private Sub TextBox_SerialNo_AfterUpdate()
If TextBox_SerialNo.Value <> "" Then
TextBox_SerialNo.BackColor = rgbWhite
End If
End Sub
Private sub label_enter_click()
sheet1.Select
Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Select
ActiveCell.Value = ActiveCell.Offset(-1, 0).Value + 1
ActiveCell.Offset(0, 1) = TextBox_SerialNo.Value
TextBox_SerialNo.Value = ""
End Sub
Private Sub Label_Cancel_Click()
Unload Me
End Sub
Sorry to be posting as an answer, not enough rep.
Shouldn't Cancel=True be inside the if statement? You are locking it up regardless of entry being numeric or not as is.
Edit:
Actually upon further testing still not working proper. However, change event works better and you can get instant feedback for any non numerics.
Updated code would look like this, control names differ. I am used to working with .Text, same thing as .Value. Also, since I am not sure what you would do with an empty string, assumed it to be yellow background as well.
One concern would be, can you allow comma or period in there? Depending on locale settings, a decimal would also be considered a numeric.
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdEnter_Click()
If TextBox1.BackColor = rgbYellow Then Exit Sub
test4.Range("A1").Value = TextBox1.Text
End Sub
Private Sub TextBox1_Change()
If Not IsNumeric(TextBox1.Text) Or TextBox1.Text = "" Then
TextBox1.BackColor = rgbYellow
Else
If TextBox1.Text <> "" Then
TextBox1.BackColor = rgbWhite
End If
End If
End Sub
Edit 2: I use this piece of code to check for only numbers (assuming number Ascii codes are standard). Maybe it can help.
Public Function isnumber(ByVal strValue As Variant) As Boolean
On Error Resume Next
Dim i As Long
isnumber = True
If Not strValue = "" Then
For i = 1 To Len(CStr(strValue))
If Asc(Mid(strValue, i, 1)) > 57 Or Asc(Mid(strValue, i, 1)) < 48 Then
isnumber = False
Exit For
End If
Next i
Else
isnumber = False
End If
On Error GoTo 0
Err.Clear
End Function
Edit 3: I have revised the TextBox1_Change event code so all invalid characters are stripped right away. However, in this state if you copy paste a serial no with a non-allowed char, it will strip them leaving only the numbers. Not sure if it is acceptable.
Private Sub TextBox1_Change()
If Not isnumber(TextBox1.Text) Or TextBox1.Text = "" Then
TextBox1.BackColor = rgbYellow
Dim i As Long
Dim strValue As String
strValue = ""
If Not TextBox1.Text = "" Then
For i = 1 To Len(CStr(TextBox1.Text))
If Not (Asc(Mid(TextBox1.Text, i, 1)) > 57 Or Asc(Mid(TextBox1.Text, i, 1)) < 48) Then
strValue = strValue & Mid(TextBox1.Text, i, 1)
End If
Next i
End If
TextBox1.Text = strValue
Else
If TextBox1.Text <> "" Then
TextBox1.BackColor = rgbWhite
End If
End If
End Sub

Restrict Userform Textbox input to [H]:MM

I have multiple textboxes on multiple userforms that are for time allocations. For simplicity say userform1 & userform2, with textbox1 & textbox2 on each.
Userform1 is for user input, which places values into a table and userform2 pulls the values from this table and displays in the relevant textbox. I need to restrict both the input of these boxes and the display to the [H]:mm format where minutes cannot exceed 59 but hours can be 25+ i.e 125:59 but not 4:67
I tried a combination of code from both of these threads as well as others but can't seem to get it to work.
Excel VBA Textbox time validation to [h]:mm
Time format of text box in excel user form
eventually i just tried to manipulate user input with message boxes but this still leaves entries open to error
Sub FormatHHMM(textbox As Object)
Dim timeStr As String
With textbox
'Check if user put in a colon or not
If InStr(1, .Value, ":", vbTextCompare) = 0 And Len(.Value) > 1 Then
MsgBox "Please use HH:mm Format"
textbox.Value = ""
textbox.SetFocus
Else
If Right(.Value, 2) > 60 Then
MsgBox "Minutes cannot be more than 59"
textbox.Value = ""
textbox.SetFocus
End If
End If
End With
End Sub
this allows users put alpha characters in and even if correctly input when called from the table is shows as a value instead i.e 5.234... instead of 125:59
How about you split hours and minutes into two seperate input fields on the same inputbox.
So the user has to type in hours and in the next field minutes. This way you can check the input for isnumeric and >60 for seconds.
I know this is not ideal, but it would be a way to evade the given problems.
Have you tried using the Like operator? That allows checking for numeric values in each character-position. I would do it like this:
Function FormatCheck(ByVal strEntered As String)
Dim correctformat As Boolean
If strEntered Like "*#:##" And IsNumeric(Mid(strEntered, 1, InStr(1, strEntered, ":", 1) - 1)) Then
If Mid(strEntered, InStr(1, strEntered, ":", 1) + 1, 999) <= 59 Then
correctformat = True
End If
End If
If Not correctformat Then FormatCheck = "Incorrect format"
End Function
This requires at least one number before the ":"
Edit: Below is a Sub version instead of using a Function. This will pop up a MsgBox like you were using originally. You could probably replace your whole FormatHHMM sub with this without any adverse effect.
Sub FormatCheck(ByVal strEntered As String)
Dim correctformat As Boolean
If strEntered Like "*#:##" And IsNumeric(Mid(strEntered, 1, InStr(1, strEntered, ":", 1) - 1)) Then
If Mid(strEntered, InStr(1, strEntered, ":", 1) + 1, 999) <= 59 Then
correctformat = True
End If
End If
If Not correctformat Then MsgBox "Incorrect format"
End Sub
i think this may be helpful:
Option Explicit
Sub test()
Dim str As String
str = TextBox.Value
'Test string lenght. Maximun lenght number 4
If Len(str) <> 4 Then
MsgBox "Enter a valid time. Proper number of digits are 4."
Exit Sub
End If
'Test if string includes only one ":"
If (Len(str) - Len(Replace(str, ":", ""))) / Len(":") <> 1 Then
MsgBox "Use only one "":"" to separate time."
Exit Sub
End If
'Test how many digits are before and after ":"
If InStr(1, str, ":") <> 2 Then
MsgBox """:"" position should be place 2."
Exit Sub
End If
'Test if number 1,3 & 4 are number
If IsNumeric(Mid(str, 1, 1)) = False Or IsNumeric(Mid(str, 1, 1)) = False Or IsNumeric(Mid(str, 1, 1)) = False Then
MsgBox "Enter number in position 1,3 and 4."
Exit Sub
End If
'Test 2 last to digits
If Right(str, 2) <= 60 Then
MsgBox "Second limit is 60."
Exit Sub
End If
End Sub
You could use regular expressions :
Sub inputTimeFormat()
Dim userInput As String
Dim strPattern As String
Dim msgBoxText As String
Dim regEx As New RegExp
Dim objRegex As Object
strPattern = "(^[0-9]+):([0-5])([0-9])$"
msgBoxText = "Insert time in HH:mm, or hit Cancel to escape"
Set objRegex = CreateObject("vbscript.regexp")
With regEx
.ignorecase = True
.Pattern = strPattern
Do
If userInput <> vbNullString Then msgBoxText = "PLEASE RETRY" & Chr(13) & msgBoxText
userInput = Application.InputBox(msgBoxText, Default:="17:01")
If userInput = "False" Then
MsgBox "User hit cancel, exiting code", vbCritical
Exit Sub
End If
Loop Until .Test(userInput)
End With
MsgBox "Format OK"
End Sub
(you need to activate regular expressions : in VBA, "Tools" > "References" > Check the box "Microsoft VBScript Regular Expressions 5.5" > "OK")
More details on How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops

Excel VBA Textbox resets to 0 when i press a button

i have a userform with 2 textboxes, 2 labels and a log in button.
On my excel sheet i have a sort of database with id, name, pin and balance.
the problem is whenever i click the login button my ID textbox resets its value to 0, but my pin textbox works fine!
i will paste my complete code:
Dim ID As Integer
Dim PIN As Integer
Dim PINField As String
Dim Balance As Double
Dim Attempts As Integer
Dim BalanceField As String
Private Sub btnLogin_Click()
txtID.Text = ID
Call SetId
Call Authenticate
End Sub
Sub Authenticate()
If txtPin.Text = PIN Then
Call Welcome
ElseIf Attempts > 3 Then
Call Bye
Else
lblWelcome.Caption = "Wrong Pin"
lblWelcome.ForeColor = RGB(255, 0, 0)
Attempts = Attempts + 1
End If
End Sub
Sub SetId()
PINField = "C" & Str(ID)
PINField = Replace(PINField, " ", "")
MsgBox (PINField)
BalanceField = "D" & Str(ID)
BalanceField = Replace(BalanceField, " ", "")
MsgBox (BalanceField)
End Sub
Sub Welcome()
MsgBox ("Login Successful. Welcome")
End Sub
Sub Bye()
MsgBox ("Max Pin Attempts reached. Contact Your Bank")
Unload frmLogin
End Sub
The reason it does this is because you are using a variable which has no value. Since it is an Integer it returns 0.
I'm guessing you probably actually want to have ID = txtID.Text - that is, take the value of the txtID textbox and store the value in the ID variable.
This will probably error though because the Text property of a textbox is a String. You will need to use ID = CInt(txtID.Text). You should also do some checking to make sure that txtID.Text evaluates to an Integer before assignment.
Please make sure there's no reset for the txtID anywhere in the code that you have not shown here. Looking at your code, it doesn't say anything how you are setting values to either ID or PIN... You said it's working fine for PIN, so it makes me very curious...
It could be the case Nick pointed out given this is a Form with textboxes allowing people to enter ID and PIN.. And then you are comparing it against PIN. But what are you comparing against? As you said you have a database kind of a structure in the sheet. You need to assing ID and PIN using it.
Here is the visualization I have for your Sheet, which is my best blind guess:
User needs to enter a value via the Form into txtID. That number is infact the cell number for column C which contains the relevant PIN. Then you compare that PIN with the txtPIN value. Next return the balance from column D based on that PIN.
Try this:
Private Sub btnLogin_Click()
If txtID.Text <> "" Or txtID.value > 0 or txtPIN.Text <> "" Then
ID = CInt(txtID.Text)
Call SetID
Call Authentication
Else
MsgBox "ID and PIN" can't be empty!"
End If
End Sub
Sub Authenticate()
If CInt(txtPin.Text) = PIN Then '-- here
Call Welcome
'-- idealy Blance can be shown at this point...
ElseIf Attempts > 3 Then
Call Bye
Else
lblWelcome.Caption = "Wrong Pin"
lblWelcome.ForeColor = RGB(255, 0, 0)
Attempts = Attempts + 1
End If
End Sub
Sub SetId()
PIN = CInt(Trim(Sheets(1).Range("C" & ID).value))
'-- NOT sure why you are showing this PIN here since you want to authenticate...?
MsgBox PIN
BalanceField = Sheets(1).Range("D" & ID).value
BalanceField = Trim(BalanceField) '--here
'-- doesn't make sense to show Balance before authentication...
MsgBox BalanceField
End Sub
Trim is clearner and faster than Replace..

Resources