I need help with a little problem. I haven't been programming long and can't figure out how to fix this. I have a small project for school and I can't figure out why I'm getting this error when validating inputs.
For example, I'm checking if the input is valid and between a min and max range by creating a function to return a true or false value based on the values entered. The reason I'm using a function is because I'm doing multiple similar checks and I figured rather than rewriting it out again, this was the best way to do this task.
Do While inputValid(string, min, max)
This is my validation, below is the simple function to validate this.
Private Function inputValid(input As String, min As Integer, max As Integer)
If Not IsNumeric(input) Then
Return False
End If
If input > min Or input < max Then
Return False
Else
Return True
End If
End Function
For some reason, despite the fact it should make sure that the value is numeric before it checks whether it's within a numerical range. It still sends me an error when I type nothing or a string in because it's trying to convert it to a double yet if I'm not doing any between range checks, it checks just fine if it's only numeric with no errors.
Can anyone help me fix this? Thanks!
You could use CInt to convert the string to Integer
Private Function inputValid(input As String, min As Integer, max As Integer)
Dim v as Integer
If Not IsNumeric(input) Then
Return False
End If
v=CInt(input)
If v < min Or v > max Then
Return False
Else
Return True
End If
End Function
You might be better off served using a regular expression to do the numeric validation on the string
Private Function inputValid(input As String, min As Integer, max As Integer)
dim regex as new Regex("[\d]+")
If not regex.isMatch(input) OrElse cint(input) > min OrElse cint(input) < max Then
Return False
Else
Return True
End If
End Function
You can use the Integer.TryParse function to check if a string can be converted to an integer.
Also, you can return a boolean which is the result of a comparison: instead of something like If x > 4 Then Return True you can use Return x > 4.
So your function could look like
Private Function StringIsValidInteger(s As String, min As Integer, max As Integer) As Boolean
Dim tmp As Integer
If Integer.TryParse(s, tmp) Then
Return (tmp >= min AndAlso tmp <= max)
End If
Return False
End Function
Sorry, guys. I was returning true and false the wrong way around it appears because I needed to continue the loop it needed to be true where it would usually be false in regular validation.
By simply changing around in the inputValid function the true and false return types, it works fine.
Thanks for your help guys.
Related
I am writing a chess program and has to see whether certain value are empty. I tried
aPiece is an array of CommandButtons. cmdSquare is a control array of shapes.
Private aPiece(63) As CommandButton
...
For p = 0 To 63
If IsEmpty(aPiece(p)) Then
aPiece(p).Left = cmdSquare(p).Left
aPiece(p).Top = cmdSquare(p).Top
End If
Next p
All variable are declared and is seem to be IsEmpty function which is not working.
The IsEmpty method only returns meaningful information for variants. Since the array contains objects, you need to check like this:
If aPiece(p) Is Nothing Then
However, this seems like only part of the answer. The above logic is saying "If there is no piece in my array then update it's location". That doesn't make sense to me and will generate an error. You also need to add Not like below:
For p = 0 To 1
If Not aPiece(p) Is Nothing Then
aPiece(p).Left = cmdSquare(p).Left
aPiece(p).Top = cmdSquare(p).Top
End If
Next p
It depends on the datatype of aPiece. If it is a variant and you haven't assigned a value to it, IsEmpty will return true. However, if it is a String, Date, Integer, etc. those are automatically initialized (String will be an empty string, Integer will be 0) so IsEmpty will return false.
A pretty good reference is this page: IsEmpty Function - Visual Basic 6.0
In VB6, the function Mid(string, start, [length]) has an optional parameter length. If omitted, the whole characters after the start bound will be passed.
Say I want this default behaviour only in a certain condition:
s = Mid(s, i, IIf(condition, j, TheValue)) ' What could be TheValue?
Since length is of Variant type, I tried Empty. It didn't work. Neither did -1 and Nothing.
I didn't want to duplicate to Mid call in an If-Then-Else clause or somehow else. Is this possible?
Here is a working sample with OP's s = Mid(s, i, IIf(condition, j, TheValue)) line
Option Explicit
Property Get TheValue(Optional RetVal As Variant)
TheValue = RetVal
End Property
Private Sub Form_Load()
Dim s As String
Dim i As Long
Dim j As Long
Dim condition As Boolean
s = "test test test"
i = 6: j = 3
condition = False
s = Mid(s, i, IIf(condition, j, TheValue)) '<--- this works!
Debug.Print s
End Sub
Notice how TheValue returns a "missing" Variant i.e. one which tests positive for IsMissing and can be used in place of optional parameters instead of not passing actual argument.
No such value exists. When you omit the length parameter, the compiler chooses a different path through the VBRT -- it produces different code. If you want to emulate that, you need to do the same thing, using an If-Else or similar construct to handle the two cases, like #ÉtienneLaneville suggests
As an alternative to #Étienne's solution, VB provides the IsMissing method:
Public Function Mid(p_sString As String, p_iStart As Integer, Optional p_iLength As Integer) As String
If IsMissing(p_iLength) Then
Mid = VBA.Mid(p_sString, p_iStart)
Else
Mid = VBA.Mid(p_sString, p_iStart, p_iLength)
End If
End Function
And as this wrapper method returns a string, I suggest using the String verions of Mid, which is Mid$. The later is slightly faster than the Variant version (Mid)
This was nicely explained at this site, but at the time of this posting, the request times out. Not sure if gone forever or just a temporary problem.
You could define your own Mid function:
Public Function Mid(p_sString As String, p_iStart As Integer, Optional p_iLength As Integer = -1) As String
If p_iLength < 0 Then
Mid = VBA.Mid(p_sString, p_iStart)
Else
Mid = VBA.Mid(p_sString, p_iStart, p_iLength)
End If
End Function
This should work with the code from your question, using -1 (or any negative integer) as TheValue.
In c++, std::string these optional arguments are represented by either 0 when the default effect is zero position or length or std::string::npos when it is "infinite" length. You can explicitly supply that value and get the same behaviour.
I don't know what the equivalent constant is in m/s strings [In fact it is a different function definition, so there isn't one]. The alternative would be to pass in the string length, as that is the longest length currently possible.
The ?: ternary operator is an easy way to present 2 values with a condition to choose between them.
In Visual Basic, I need a way to clamp a number, preventing it from becoming too small or large. It has to fit one line, so should ideally look something like this clamp(x,min,max). I've tried finding a way to do this but could not find anything, any ideas on how to do this?
try this: (true if a change has been made, and false otherwise)
Function clamp(ByRef myNum as Integer, min as Integer, max as Integer) as Boolean
If myNum < min Then
myNum = min
Return True
End If
If myNum > max Then
myNum = max
Return True
End If
Return False
End Function
I am a noob to VB and I need to know how its done.
Haven't done VB in 3 years cannot remember much of it.
The textbox has a value in it (5.43), and it needs to be decreased by 0.34.
But this is the code:
TextBox3.Text = Val(TextBox3.Text) -0.34
How do I do this?
THIS IS VB 6 by the way
TextBox3.Text = CDbl(TextBox3.Text) - 0.34
Because your initial value has parenthesis (5.34) you must convert it to a specific number before operating on in.
Val does not recognize values in parens being negative. The Val() function in your original example is converting it to 0 in the same way that val("abcd") will also return 0 because it assumes both are strings.
You can test these conditions in the immediate window to quickly see the results.
Haven't tried it, but could be:
TextBox3.Text = Cdbl(TextBox3.Text) -0.34
The following code will do it:
TextBox3.Text = Cstr(CDbl(TextBox3.Text) - 0.34)
But you should be aware what is going on.
The TextBox does not store a double type, it stores a string type. The above code attempts to convert the string to a double, subtract your constant value from it, and convert it back to a string.
You should ask yourself what should happen if the string in the text box is not a valid number. In the above code, Double.Parse() will throw an exception. Double.TryParse() will return whether the conversion was successful.
Or is it impossible to enter a non-number into the text box? In which case, the safety check is unnecessary, though advisable.
You need to ask these questions when doing type conversions, or your program will behave unpredictably when a value is not convertible to the type you expected.
A safer way to decrement it would be:
Const DECREMENT_VALUE As Double = 0.34
Dim isDouble As Boolean
isDouble = IsNumeric(TextBox3.Text)
If isDouble Then
Dim newValue As Double
newValue = CDbl(TextBox3.Text)
newValue = newValue - DECREMENT_VALUE
TextBox3.Text = CStr(newValue)
Else
MsgBox "The Value was not a Double! Could not Decrement!"
End If
Try this.. It might just work
Dim TxtValue as Integer
TxtValue = TextBox3.Text
Since TxtValue is Integer, the decimal will be automatically dropped.
Like this??
TextBox3.Text=Double.Parse(TextBox3.Text)-0.43
This will work in C#
double number = Convert.ToDouble(textBox1.Text);
number = number - .34;
Is there any IsDouble() function in VB6? If I'm not mistaken, Double data type in VB6 is equivalent to float in SQL Server 2000.
Your advice would be much appreciated.
Actually you are much better off using the Vartype function.
Private Function IsDouble(ByVal value As Variant) As Boolean
IsDouble = (VarType(value) = vbDouble)
End Function
Function IsDouble(ByVal varValue As Variant) As Boolean
Dim dblTest As Double
On Error Resume Next
dblTest = CDbl(varValue)
IsDouble = Err.Number = 0
End Function
IsNumeric() is fine, it will only accept values that fit into Doubles. It is regionally aware, i.e. for French regional settings the decimal separator is a comma.
I just tried this in the Immediate window.
Debug.Print IsNumeric("4e308")
False
The definition of a VB6 Double in the manual is "VB6 Double variables are stored as IEEE 64-bit (8-byte) floating-point numbers ranging in value from -1.79769313486232E308 to -4.94065645841247E-324 for negative values and from 4.94065645841247E-324 to 1.79769313486232E308 for positive values".
I think that's the same as a SQL Server float, going by the online docs. "Floating precision number data with the following valid values: -1.79E + 308 through -2.23E - 308, 0 and 2.23E + 308 through 1.79E + 308."
There is no inbuilt IsDouble function available in VB6 instead you can use inbuilt IsNumeric Function. Otherwise you can use following User Defined Function to achieve the same:
Function IsDouble(ByVal value As Variant) As Boolean
Dim convertedValue As Double
On Error Goto EH
convertedValue = CDbl(value)
IsDouble = True
Exit Function
EH:
IsDouble = False
End Function
There's an IsNumeric() function that should work well enough. If that is inadequate for your needs can you also explain in what ways?