excel vba: check negative number in inputbox - excel

I am using an inputbox the get a number from a user. I want to avoid not allowed input and am stuck with negative numbers. The only input which should be processed is an integer between 1 and 500. I don't understand why -1 is still triggered. Here is my code so far:
LBefore = InputBox("lines?", "", ">>> insert number <<<", 11660, 9540)
Select Case StrPtr(LBefore)
Case 0
'Cancel pressed
Exit Sub
Case Else
If (LBefore <> "") Then
'Check for numeretical value
If IsNumeric(LBefore) Then
cijfer = Abs(CByte(LBefore))
'Check to see if value is in allowed range
If (cijfer >= 1) And (cijfer <= 500) Then
'do stuff ...
end If
End If
End If
End Select

It's triggered because you use cijfer = Abs(CByte(LBefore)).
Abs is absolute function, so negative numbers become positive!
Try using cijfer = CInt(LBefore).

Related

If x <> Int(x) always true, even if x=Int(x). Can't find out why

I'm pretty amateur at coding, but I'm trying to develop some automated business sheets in excel to make my old man's life a little easier on the business.
The intent is to create a table with range based on a number in a userform.
Code looks like this: (textbox1 was renamed to nParc)
Private Sub Cmb1_Click()
Dim nP As Variant
nP = UserForm1.nParc.Value
If nP = "" Then
MsgBox "Error 0"
ElseIf Not IsNumeric(nP) Then
MsgBox "Error 1"
ElseIf Not nP > 0 Then
MsgBox "Error 2"
ElseIf nP <> Int(nP) Then
MsgBox "Error 3"
Else
ActiveSheet.ListObjects.Add(xlSrcRange, Range(Cells(1, 1).Address(), Cells(nP, 14).Address()), xlYes).Name = "Business"
End If
End Sub
I always get
Error 3
when I click the "Proceed" button, no matter what. If I remove the msgbox "error 3" and the else after, it works.
I have already tried using ElseIf Not nP = Int(nP), but the issue remains.
Any help would be deeply appreciated.
Let me elaborate on the answer #bigben has provided and explain what exactly is going on.
The Comparison
If you look at the value types of np and Int(np) using the VarType function, you will see that VarType(np) = 8, i.e. np is a String, and VarType(Int(np)) = 5, i.e. Int(np) is a Double. Since both are declared as a Variant---Int returns a Variant according to the paragraph 6.1.2.3.1.18 of the language specs---, the special case at the end of paragraph 5.6.9.5 of the language specs is triggered.
There is an exception to the rules in the preceding table when both operands have a declared type of Variant, with one operand originally having a value type of String, and the other operand originally having a numeric value type. In this case, the numeric operand is considered to be less than (and not equal to) the String operand, regardless of their values.
This is why the comparison returns False
The Numeric Check
You might wonder why IsNumeric(np) = True although np is a String. This is actually a bug in the VBA standard library. According to paragraph 6.1.2.7.1.8 of the language specs, IsNumeric should return False whenever the value type of the variable is String. However, in reality it seems to try to convert to Double and returns whether that was successful.
The Remediation
As #bigben already mentioned, you should cast the input from the TextBox to another type. It works, if you just declare np as String, although assigning to a Variable of type Double after the IsNumeric check would be more appropriate.
Your textbox is returning text, not a number. It is best to cast the value to a numeric type before attempting to do any sort of numeric comparison:
If Len(nP) = 0 Then
MsgBox "Error 0" ' blank string
Exit Sub
End If
If Not IsNumeric(nP) Then
MsgBox "Error 1" ' not numeric
Exit Sub
End If
' We've established it's numeric
Dim testValue As Double
testValue = CDbl(nP)
If testValue <> Int(testValue) Then
MsgBox "Error 3" ' has decimals
Exit Sub
End If
' You could also possibly check if it's a valid row number
' i.e. that it's not too big

Type mismatch when checking the value of a cell

I have this code hitting
error 13 :Type Mismatch
whenever I enter or change the value in C59, C59 contains this formula =ROUNDUP(D59/C57,0). I am guessing its because of the different variable but do not know how to solve it, any kind assistance is greatly appreciated!
If Range("C59").Value = "0" Then
Sheets("InvPL").Rows("78:79").EntireRow.Hidden = True
Else
Sheets("InvPL").Rows("78:79").EntireRow.Hidden = False
End If
You will want to make sure C57 is not 0 as you are dividing by it, in which case C59 will be #DIV/0! (an error)
You cannot check the .Value property of a cell if it contains an error.
Check cell C59 for the error first:
If IsError(Worksheets("InvPL").Range("C59")) Then
Msgbox "C59 contains an error. If C57=0 then it is a divide by zero error."
Else
If Range("C59").Value = "0" Then
Sheets("InvPL").Rows("78:79").EntireRow.Hidden = True
Else
Sheets("InvPL").Rows("78:79").EntireRow.Hidden = False
End If
End If
Or a cleaner version, using a With block, and using Worksheets instead of Sheets since sheets can refer to chart objects as well:
With Worksheets("InvPL")
If IsError(.Range("C59")) Then
Msgbox "C59 contains an error. If C57=0 then it is a divide by zero error."
Else
If .Range("C59").Value = "0" Then
.Rows("78:79").EntireRow.Hidden = True
Else
.Rows("78:79").EntireRow.Hidden = False
End If
End If
End With
You can change the logic a bit if you want to hide/un-hide those rows in the case of the error as well.
Another option would be to change the formula to return a zero instead of an error when C57 is 0:
=IF(C57=0,0,ROUNDUP(D59/C57,0))

Validate a TextBox before the _Change event is fired

I've got a form that has 3 TextBox controls on it: stock code, quantity, certificate number. The stock code TextBox is set to focus automatically when the form is loaded.
I've also attached a bar code scanner to my PC, as the user wants to be able to either scan a bar code to populate the TextBox, or manually type the data in.
The labels being scanned contain two bar codes. One is a certificate number and the other a stock code.
The stock bar code has a prefix of "SBC/", whilst a certificate bar code is prefixed with "C/".
When the user scans a bar code, if the TextBox in focus is the stock code TextBox, then I want to run a check as below.
Private Sub txtStockCode_Change()
On Error GoTo errError1
If Len(txtStockCode.Text) >= 5 Then
If bChangeCode Then
If Left(txtStockCode.Text, 2) = "C/" Then
msgbox "You have scanned the certificate barcode; please scan the stock barcode."
txtStockCode.Text = ""
Else
bChangeCode = False
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End If
End If
Exit Sub
Let's say the focus is currently on the stock code TextBox.
If the stock bar code is scanned, the following should happen:
Stock code length is greater than 5
Left 5 characters do not = "C/", so correct code has been scanned
TextBox text value is updated to remove all * and the prefix of "SBC/"
E.g. "SBC/A12-TR0*" becomes "A12-TRO"
and
Certificate number length is greater than 5
Left 5 characters do = "C/", so incorrect code has been scanned
MsgBox to user
TextBox value is reset to ""
However, no matter which code is scanned into the stock code TextBox, the value is never validated.
E.g. "SBC/A12-TR0*" remains as "SBC/A12-TR0*" and "C/29760" remains as "C/29760"
As the validation code is the same in the certificate TextBox, the same pattern is repeated vice versa.
Why are my values not updating, or how can I validate the input before the _Change is fired?
EDIT
I've now changed my code to
Private Sub txtStockCode_Change
If txtStockCode.Text <> "" Then
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End Sub
But it still displays the prefix of SBC/, yet is removing the two * characters (at the start and end of the barcode as is required for the scanner to read it as a barcode)
You could try to set the barcode reader to return Enter key at the end of the scanned barcode and then use the Keypress event to check it and make your changes.
Sub txtStockCode_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
If Len(txtStockCode.Text) >= 5 Then
If bChangeCode Then
If Left(txtStockCode.Text, 2) = "C/" Then
msgbox "You have scanned the certificate barcode; please scan the stock barcode."
txtStockCode.Text = ""
Else
bChangeCode = False
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End If
End If
End If
End Sub

Error 91 on Frame Control upon Start Up

I have a Microsoft Form 2.0 Frame Control with three option buttons. The name of the Frame Control is Side, three option button captions are X, O, and Random with names xOption, oOption, and randomSide respectively.
The code runs fine, except upon startup, if I open Excel and run the program immediately, it will give me an Error 91, note that one of the options (X, O, or Random) is already selected. In order to get rid of this error, I need to explicitly select another option, then the error goes away. I don't know why this happens. Here is the sub for the Frame Control
Public Sub Side_Click()
sideLetter = Side.ActiveControl.Caption
If StrComp(sideLetter, "Random") = 0 Then
Randomize
tempRand = Int((Rnd() * 2 + 1))
If tempRand = 1 Then
sideLetter = "X"
Else
sideLetter = "O"
End If
End If
End Sub
The Line sideLetter = Side.ActiveControl.Caption Is the one causing the issue. I have not explicitly declared Side as a frame control in case that's some helpful information because I'm thinking that the object is already declared just by making the Frame Control. Thanks in advance!
You need to check that Side.ActiveControl is actually an object, before you read it's Caption:
Public Sub Side_Click()
If Not Side.ActiveControl Is Nothing Then
sideLetter = Side.ActiveControl.Caption
If StrComp(sideLetter, "Random") = 0 Then
Randomize
tempRand = Int((Rnd() * 2 + 1))
If tempRand = 1 Then
sideLetter = "X"
Else
sideLetter = "O"
End If
End If
End If
End Sub

cancel or hide input box in vba

I have a code which asks for an input between 1-3 using an InputBox which then runs a code depending on what input it is given. The problem i have is that i don't need that InputBox anymore, as the work i intend to do only uses one input which is 3.I tried removing the input box and just inserting 3 there but then the code doesnt do anything. I then tried to insert a default value in the box, but it still appears and needs me to click enter which is what i am trying to avoid. Pls how should i go about this problem.
My Code
Function GetTypeFile() As Integer
Dim strInput As String, strMsg As String
Dim Default
choice = 0
While (choice < 1 Or choice > 3)
Default = "3"
strMsg = "Type in the kind of entities to create (1 for points, 2 for points and splines, 3 for points, splines and loft):"
strInput = InputBox(Prompt:=strMsg, _
Title:="User Info", Default:=3, XPos:=2000, YPos:=2000)
'Validation of the choice
choice = CInt(strInput)
If (choice < 1 Or choice > 3) Then
MsgBox "Invalid value: must be 1, 2 or 3"
End If
Wend
GetTypeFile = choice
End Function
Your function returns the value to wherever it's called, so you could just use:
Function GetTypeFile() As Integer
GetTypeFile = 3
End Function
or just replace any calls to the function with the number 3.
So rather than something like:
Sub Test()
ThisWorkbook.SaveAs "MyFileName", GetTypeFile
End Sub
You'd have:
Sub Test()
ThisWorkbook.SaveAs "MyFileName", 3
End
Thank you all for your reply. I just understood what to do, by setting the variable which is dependent on the value in the inputbox to 3 instead of it being TypeDocument=GetTypeFile it is now TypeDocument=3 directly..I think that is what you all had been trying to say all the while. Thank you again.

Resources