I am searching a database and pulling results from it. Before displaying it in WPF I am checking the contents of the text in a field called PrimarySponsor which can be (1) blank/null (2) number at 3rd character (3) persons name. I am currently using Char.IsNumber to check option 2 if there is a number at position 4.
If reader("PrimarySponsor") Is DBNull.Value Then
resultxPrimSpon = ""
ElseIf Char.IsNumber(reader("PrimarySponsor"), 3) Then
resultxPrimSpon = "Terminated"
Else
resultxPrimSpon = reader("PrimarySponsor")
End If
Before I put the Char.IsNumber check in I was getting 4 results displaying. When i add the Char.IsNumber code I only get 2 results along with the error;
Error while connecting to SQLServer.Sepcified argument was out of the range of valid values. Parameter name: index.
Anyone have any ideas about why this is happening or how to work around it?
It's not clear where you get that error because Char.IsNumber is not a sql-server method. So i assume that it's a custom message from you. However, the "Specified argument was out of the range" is documented:
ArgumentOutOfRangeException: index is less than zero or greater than
the last position in s.
So it seems that at least one of the strings is shorter than 4 characters. In general you should store the reader values in a variable of the correct type if you have to access it more than once. In this case in a String-variable.
But it's also a good idea to create a custom type that has all properties. Then you can add all to a List(Of T). Here's an example:
Public Class Sponsor
Public Property PrimarySponsor As String
End Class
Of course you could also fill a List(Of String) instead of a List(Of Sponsor). Then you don't need to create a new type. But i assume that you have more than one column in the table. Using a custom type increases readability and maintainability much.
....
Dim allSponsors As New List(Of Sponsor)
Using reader = command.ExecuteReader()
If reader.HasRows Then
Dim primSponsorColumnIndex = reader.GetOrdinal("PrimarySponsor")
While reader.Read
Dim sponsor As New Sponsor()
If reader.IsDBNull(primSponsorColumnIndex) Then
sponsor.PrimarySponsor = ""
Else
sponsor.PrimarySponsor = reader.GetString(primSponsorColumnIndex)
If sponsor.PrimarySponsor.Length >= 4 AndAlso _
Char.IsDigit(sponsor.PrimarySponsor(3)) Then
sponsor.PrimarySponsor = "Terminated"
End If
End If
allSponsors.Add(sponsor)
End While
End If
End Using
First use DataReader.IsDBNull to check if the value is Null. Then check if Length >= 4 before you use Char.IsDigit(sponsor.PrimarySponsor(3)) to avoid the ArgumentOutOfRangeException.
Difference between Char.IsDigit() and Char.IsNumber() in C#
Using VB.Net
I want to check whether the table row is null or 0
Code
sCmd = New SqlCommand("SELECT * from table1)", conObjects.myConnection)
dReader = sCmd.ExecuteReader
While dReader.Read()
If dReader.Item(11) <> "0" And dReader.Item(11) IsNot Nothing Then
msgbox ("Not NUll or 0")
End if
End while
Showing Error as "Operator '<>' is not defined for type 'DBNull' and string "0""
Why i am getting this error, How to solve this problem.
Need VB.Net Code Help
You should always use AndAlso and OrElse instead of And and Or.
With AndAlso the latter expression is only evaluted if the former returned true. On this way you can avoid exceptions and make your code more efficient.
But apart from that, you should use reader.IsDBNull(index):
If Not dReader.IsDBNull(11) AndAlso dReader.GetString(11) <> "0" Then
End If
There are two problems here: one is that you use And instead of AndAlso: the former will cause your whole line to be evaluated, where the latter will only evaluate the second argument if its first argument is already True.
Your second problem is that you check for "not zero" before you check for "Nothing", and so your first part can fail before the second part is evaluated.
Try this instead:
If dReader.Item(11) IsNot Nothing AndAlso dReader.Item(11) <> "0" Then
Also, it's been a while since I did ADO, but shouldn't you be checking IsDbNull instead of comparing to Nothing? Perhaps VB takes care of that for you, I'm not sure.
Try using AndAlso
If (dReader.Item(11) IsNot Nothing) AndAlso (cint(dReader.Item(11)) <> 0) Then
msgbox ("Not NUll or 0")
End if
basically what it does is, when the first expression is already true, the second expression is not evaluated.
If Convert.ToString(dReader.Item(11)) <> "0" AndAlso dReader.IsDBNull(11)=False
i have this line of code to catch an exception if a letter is inputed, or if it is out of rang as a number, but I have added WHEN to avoid catching numberical data. Now how can I use an exception error to use it before my case statement in order to avoid running the code twice, cause once the case codes has been through it will run a clear txtbox which is already taken care by the try catch, don`t if thats clear for you but i understand it. here is the code in parts...
Try
'Integer Levels: intLvls is egual to the assigned text box, the first one from
'the top, this line of code allow the user input to be captured into a variable.
intLvls = txtBoxLvl.Text
Catch ex As Exception When IsNumeric(intLvls)
ErrTypeLetterFeild1()
Finally
analysingvalues1()
End Try
WHAT I WOULD LIKE TO DO: Use loop until refencing the exception error to avoid running this following part of the code:
Private Sub analysingvalues1()
Do Until IsNumeric (ex As Exception)<------how do i do this???
Loop
the case part of the code:
Select Case intLvls
'User is prompt with the following label: lblLvl "Level of salespersons 1 - 4"
'to make a choice from 1 to 4 as available values.
Case 1 To 4
'This line regulates the range of acceptable values, first textbox: must be egual
'or higher than 1 and lower or egual to 4. Upon such rules a validation becomes
'correct and is directed to the isValidCalculation sub.
isValidCalculation()
Case Is < 1
ErrType1NumberRangeFeild()
Case Is > 4
ErrType1NumberRangeFeild()
Case Else
If txtBoxLvl.Text = "" Then
ErrTypeClear1()
Else
If Not IsNumeric(txtBoxLvl.Text) Then
ErrType1NumberRangeFeild()
Else
ErrTypeLetterFeild1()
ErrTypeClear1()
End If
End If
End Select 'Ending choices.
End Sub
Tks for your help!
If you turn on Option Strict this:
intLvls = txtBoxLvl.Text
Will no longer compile. This should tell you that your doing something smelly.
Turn on Option Strict
The correct solution is not to blindly allow the runtime to cast string to int for you, and catch the exceptions.
When you are converting string user input to an integer, bad input is not an exceptional condition, it is something you should expect and code defensively for.
I would rewrite it to something like this:
'Integer Levels: intLvls is egual to the assigned text box, the first one from
'the top, this line of code allow the user input to be captured into a variable.
if integer.TryParse( txtBoxLvl.Text, intLvls )
analysingvalues1()
else
ErrTypeLetterFeild1()
Edit - As pointed out by Chris below, I meant Option Strict. I recommend using but Explicit and Strict, and Infer if available.
This has got to be one of the most frustratingly stupid bugs I have ever encountered, and I just want to see if anybody else has run into this before.
Here's the deal. I have a TextBox in a Windows Forms application in VB 2008 (.NET 3.5) where a user can key an estimate amount. I am allowing them to key dollars and cents, and I want to round to the nearest dollar. The original code had the rounding down when the data was written back to a table, and that worked fine - I have this code in a "Save" routine that fires when the user moves to a different screen or record:
Dim est As Decimal : Decimal.TryParse(txtEstimateAmount.Text.Trim, est)
Dim estimatedAmount As Integer = Math.Round(est)
I decided that it might be nice to actually do the rounding as soon as they leave the field instead, so they're not surprised when they reload the screen and find that 1822.60 is now 1823. So I took the exact same code and added it to the TextBox.Leave event handler. And the weirdest thing happened: instead of the variable est being populated with 1822.60 after the parse, it gets set to -1! What the...?
Debugging the handler shows that the value goes into the parser correctly, and if I do the parsing manually via the Immediate window, it parses correctly, but when I let the code do it, it invariably gets set to -1. What's even weirder is that any number gets parsed as -1, not just decimals, and any non-number gets parsed as 0 (which is correct).
Has anybody else ever run into this before? I tried moving the code to the TextBox.LostFocus event instead, but with the same results. I have no idea what in the heck is going on, and obviously there are workarounds galore for this, but it just makes no sense whatsoever.
EDIT: Here's the full event handler (current behavior for which is to put -1 in the TextBox):
Private Sub txtEstimateAmount_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtEstimateAmount.Leave
' Take any dollars-and-cents amount and round to the nearest dollar
Dim est As Decimal
est = Decimal.TryParse(txtEstimateAmount.Text.Trim, est)
txtEstimateAmount.Text = If(est <> 0, Math.Round(est).ToString(), String.Empty)
End Sub
First off, you really need to do this with a Validating event handler so that you can catch junk and avoid ignoring the return value of TryParse. Like this:
Private Sub TextBox1_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
Dim est As Decimal
If TextBox1.Text.Length = 0 then Exit Sub '' optional
If Not Decimal.TryParse(TextBox1.Text.Trim, est) Then
e.Cancel = True
TextBox1.SelectAll()
Else
TextBox1.Text = est.ToString("N0")
End If
End Sub
Explaining -1 is difficult. TryParse normally writes 0 if it cannot parse the text. Watch out for changing the UI thread's CurrentCulture property. And any changes made to the format settings in Control Panel + Region and Language applet.
I don't think the code you've posted is the code you're running. What is happening is:
Dim est As Decimal = Decimal.TryParse(txtEstimateAmount.Text.Trim, est)
Dim estimatedAmount As Integer = Math.Round(est)
I would do a clean and a rebuild or try rewriting it in a different format, maybe with a boolean to get the result of the tryparse.
EDIT now that I've seen your actual code. You are indeed putting the true/false from the tryparse result into the est decimal. Delete the est=. Est gets loaded because it is passed by reference into tryparse.
In VB.NET, what is the difference between And and AndAlso? Which should I use?
The And operator evaluates both sides, where AndAlso evaluates the right side if and only if the left side is true.
An example:
If mystring IsNot Nothing And mystring.Contains("Foo") Then
' bla bla
End If
The above throws an exception if mystring = Nothing
If mystring IsNot Nothing AndAlso mystring.Contains("Foo") Then
' bla bla
End If
This one does not throw an exception.
So if you come from the C# world, you should use AndAlso like you would use &&.
More info here: http://www.panopticoncentral.net/2003/08/18/the-ballad-of-andalso-and-orelse/
The And operator will check all conditions in the statement before continuing, whereas the Andalso operator will stop if it knows the condition is false. For example:
if x = 5 And y = 7
Checks if x is equal to 5, and if y is equal to 7, then continues if both are true.
if x = 5 AndAlso y = 7
Checks if x is equal to 5. If it's not, it doesn't check if y is 7, because it knows that the condition is false already. (This is called short-circuiting.)
Generally people use the short-circuiting method if there's a reason to explicitly not check the second part if the first part is not true, such as if it would throw an exception if checked. For example:
If Not Object Is Nothing AndAlso Object.Load()
If that used And instead of AndAlso, it would still try to Object.Load() even if it were nothing, which would throw an exception.
Interestingly none of the answers mentioned that And and Or in VB.NET are bit operators whereas OrElse and AndAlso are strictly Boolean operators.
Dim a = 3 OR 5 ' Will set a to the value 7, 011 or 101 = 111
Dim a = 3 And 5 ' Will set a to the value 1, 011 and 101 = 001
Dim b = 3 OrElse 5 ' Will set b to the value true and not evaluate the 5
Dim b = 3 AndAlso 5 ' Will set b to the value true after evaluating the 5
Dim c = 0 AndAlso 5 ' Will set c to the value false and not evaluate the 5
Note: a non zero integer is considered true; Dim e = not 0 will set e to -1 demonstrating Not is also a bit operator.
|| and && (the C# versions of OrElse and AndAlso) return the last evaluated expression which would be 3 and 5 respectively. This lets you use the idiom v || 5 in C# to give 5 as the value of the expression when v is null or (0 and an integer) and the value of v otherwise. The difference in semantics can catch a C# programmer dabbling in VB.NET off guard as this "default value idiom" doesn't work in VB.NET.
So, to answer the question: Use Or and And for bit operations (integer or Boolean). Use OrElse and AndAlso to "short circuit" an operation to save time, or test the validity of an evaluation prior to evaluating it. If valid(evaluation) andalso evaluation then or if not (unsafe(evaluation) orelse (not evaluation)) then
Bonus: What is the value of the following?
Dim e = Not 0 And 3
If Bool1 And Bool2 Then
Evaluates both Bool1 and Bool2
If Bool1 AndAlso Bool2 Then
Evaluates Bool2 if and only if Bool1 is true.
Just for all those people who say side effects are evil: a place where having two side effects in one condition is good would be reading two file objects in tandem.
While File1.Seek_Next_Row() And File2.Seek_Next_Row()
Str1 = File1.GetRow()
Str2 = File2.GetRow()
End While
Using the And ensures that a row is consumed every time the condition is checked. Whereas AndAlso might read the last line of File1 and leave File2 without a consumed line.
Of course the code above wouldn't work, but I use side effects like this all the time and wouldn't consider it "bad" or "evil" code as some would lead you to believe. It's easy to read and efficient.
AndAlso is much like And, except it works like && in C#, C++, etc.
The difference is that if the first clause (the one before AndAlso) is true, the second clause is never evaluated - the compound logical expression is "short circuited".
This is sometimes very useful, e.g. in an expression such as:
If Not IsNull(myObj) AndAlso myObj.SomeProperty = 3 Then
...
End If
Using the old And in the above expression would throw a NullReferenceException if myObj were null.
A simple way to think about it is using even plainer English
If Bool1 And Bool2 Then
If [both are true] Then
If Bool1 AndAlso Bool2 Then
If [first is true then evaluate the second] Then
Also see Stack Overflow question: Should I always use the AndAlso and OrElse operators?.
Also: A comment for those who mentioned using And if the right side of the expression has a side-effect you need:
If the right side has a side effect you need, just move it to the left side rather than using "And". You only really need "And" if both sides have side effects. And if you have that many side effects going on you're probably doing something else wrong. In general, you really should prefer AndAlso.
In addition to the answers above, AndAlso provides a conditioning process known as short circuiting. Many programming languages have this functionality built in like vb.net does, and can provide substantial performance increases in long condition statements by cutting out evaluations that are unneccessary.
Another similar condition is the OrElse condition which would only check the right condition if the left condition is false, thus cutting out unneccessary condition checks after a true condition is found.
I would advise you to always use short circuiting processes and structure your conditional statements in ways that can benefit the most by this. For example, test your most efficient and fastest conditions first so that you only run your long conditions when you absolutely have to and short circuit the other times.
For majority of us OrElse and AndAlso will do the trick except for a few confusing exceptions (less than 1% where we may have to use Or and And).
Try not to get carried away by people showing off their boolean logics and making it look like a rocket science.
It's quite simple and straight forward and occasionally your system may not work as expected because it doesn't like your logic in the first place. And yet your brain keeps telling you that his logic is 100% tested and proven and it should work. At that very moment stop trusting your brain and ask him to think again or (not OrElse or maybe OrElse) you force yourself to look for another job that doesn't require much logic.
Use And and Or for logical bit operations, e.g. x% = y% Or 3
AndAlso and OrElse are for If statements:
If x > 3 AndAlso x <= 5 Then
is same as
If (x > 3) And (x <= 5) Then
The way I see it...
Also it's worth noting that it's recommended (by me) that you enclose equations with logical operators in If statements, so they don't get misinterpreted by the compiler, for example:
If x = (y And 3) AndAlso ...
To understand with words not cods:
Use Case:With “And” the compiler will check all conditions so if you are checking that an object could be “Nothing” and then you are checking one of it’s properties you will have a run time error.
But with AndAlso with the first “false” in the conditions it will checking the next one so you will not have an error.
The And / AndAlso Or / OrElse are actually quite useful. Consider this code, where the function DoSomethingWihtAandB may not set A and/or B if it returns False:
Dim A,B,C,D As Object
If DoSomethingWithAandB(A,B)=True And A=1 And B=2 Then C=3
It will crash if DoSomethingWithAandB returns False, because it will continue to evaluate after the And and A and B will equal Nothing
Dim A,B,C,D As Object
If DoSomethingWithAandB(A,B)=True AndAlso A=1 AndAlso B=2 Then C=3
This won't crash if DoSomethingWithAandB returns False because it will stop evaluating at DoSomethingWithAandB(A,B)=True, because False is returned. The AndAlso prevents any further evaluation of the conditions (as the first condition failed). OrElse works the same way. The first True evaluated in the logic chain will stop any further evaluation.