Conversion From String to Boolean Vb.net - vb.net

I want to evaluate a String with Boolean Values and Binary Logical Operators (And/Or).
When i write Dim Expression = ((True And False) Or True) then the value of "Expression" Will be true.
However, when i write Dim Expression = "((True And False) Or True)" and try to convert the string to Boolean using Convert.ToBoolean() like MsgBox(Convert.ToBoolean(Expression)) then i got an error stating: String was not recognized as a valid Boolean. as in the picture.
All previous posts deals with strings containing only "True" or "False". but rarely i found a post dealing with an Expression containing brackets and more than one operator as "((True Or False) And True)" or much more complicated expressions. is this supported in the convert.ToBoolean function and if yes why i am getting this error?

There is a round-about way of evaluating an expression using Microsoft script control ..
Right click on your project and choose Add
In the sub menu, choose Reference
In the window that appears, on the left click on COM
Scroll down until you see MicrosoftScriptControl 1.0 and double click it.
Then click Ok on the lower right of the window
This function takes a string and using VBScript, evaluates the string expression. You can of course tweak it to your needs.
Private Function EvaluateBoolean(formula As String) As Boolean
Dim sc As New MSScriptControl.ScriptControl
'SET LANGUAGE TO VBSCRIPT
sc.Language = "VBSCRIPT"
'ATTEMPT MATH
Try
Return Convert.ToBoolean(sc.Eval(formula))
Catch ex As Exception
'SHOW THAT IT WAS INVALID
MessageBox.Show("Invalid Boolean expression")
End Try
End Function

Related

Return string after timeout in VB.NET

I use the following function to send commands to an instrument and receive the query results back and it works fine.
Public Function InstrSndRcv(cmd2Send As String) As String
MyInstrument.WriteLine(cmd2Send)
' if myTimeout(desierdtime) then
'Return "my string"
'else
Dim qryRetrn As String = MyInstrument.ReadLine()
Return qryRetrn
'End if
End Function
I have commented out the conditional functionality I need in terms of a subroutine myTimeout(desiredtime). How to implement it in VB.NET?
The idea is to return "my string" in case the instrument does not respond to a query command. May be there is a better way to do this...

I am using a method with a stored procedure, but it's always returning false

I am using bool method with Visual Studio 2015 and SQL Server 2005.
When I am passing correct details and click loginButton, the code always returns false from the stored procedure.
This is my stored procedure in SQL Server 2005:
ALTER PROCEDURE [dbo].[UserCheckLoginDetails]
(#IsLoginIdCorrect BIT OUTPUT,
#IsPasswordCorrect BIT OUTPUT,
#LoginID NVARCHAR(200),
#Password NVARCHAR(20)
)
AS
BEGIN
SET #IsLoginIdCorrect = 0
SET #IsPasswordCorrect = 0
IF EXISTS (SELECT * FROM UserInfo
WHERE loginid = #LoginID AND password = #Password)
BEGIN
SET #IsLoginIdCorrect = 1
SET #IsPasswordCorrect = 1
END
ELSE
IF EXISTS (SELECT * FROM UserInfo WHERE loginid = #LoginID)
BEGIN
SET #IsLoginIdCorrect = 1
END
END
This is my method returning True or False:
Private Sub GetIsUserLoginCorrect(IsLoginIdCorrect As Boolean, IsPasswordCorrect As Boolean)
Using Conn As New SqlConnection(_SqlCon)
Using cmd As New SqlCommand("UserCheckLoginDetails", Conn)
cmd.CommandType = CommandType.StoredProcedure
Conn.Open()
'OutPut Parameters
cmd.Parameters.Add("#IsLoginIdCorrect", SqlDbType.Bit).Direction = ParameterDirection.Output
cmd.Parameters.Add("#IsPasswordCorrect", SqlDbType.Bit).Direction = ParameterDirection.Output
'InPut Parameters
cmd.Parameters.AddWithValue("#LoginID", LoginIDTextBox.Text)
cmd.Parameters.AddWithValue("#Password", PasswordTextBox.Text)
cmd.ExecuteNonQuery()
' Assign Parameters
IsLoginIdCorrect = Convert.ToBoolean(cmd.Parameters("#IsLoginIdCorrect").Value)
IsPasswordCorrect = Convert.ToBoolean(cmd.Parameters("#IsPasswordCorrect").Value)
End Using
End Using
End Sub
This is the Login button click event handler, even when I provide the correct values, it still always returns false:
Private Sub LoginButton_Click(sender As Object, e As EventArgs) Handles LoginButton.Click
Try
Dim IsLoginIdCorrect, IsPasswordCorrect As Boolean
GetIsUserLoginCorrect(IsLoginIdCorrect, IsPasswordCorrect)
If IsLoginIdCorrect And IsPasswordCorrect = True Then
Me.Hide()
' User Information
DeshBoard.MainUserIdLabel.Text = Me.MainUserIdLabel.Text
DeshBoard.UserNameLabel.Text = Me.UserNameLabel.Text
DeshBoard.UserLoginIdLabel.Text = Me.UserLoginIdLabel.Text
DeshBoard.UserLevelLabel.Text = Me.UserLevelLabel.Text
'Organanization Information
DeshBoard.MainOrgIDLabel.Text = Me.MainOrgIDLabel.Text
DeshBoard.OrgNameLabel.Text = Me.OrgNameLabel.Text
DeshBoard.OrgTelLabel.Text = Me.OrgTelLabel.Text
DeshBoard.OrgEmailLabel.Text = Me.OrgEmailLabel.Text
DeshBoard.OrgAddressLabel.Text = Me.OrgAddressLabel.Text
DeshBoard.Show()
Else
If IsLoginIdCorrect = False Then
MessageBox.Show("Login ID is not correct...!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
LoginIDTextBox.Clear()
PasswordTextBox.Clear()
LoginIDTextBox.Focus()
Else
MessageBox.Show("Password ID is not correct...!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
PasswordTextBox.Clear()
PasswordTextBox.Focus()
End If
End If
Catch ex As ApplicationException
MessageBox.Show("Error: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Thank you very much.
You need to add ByRef to both arguments in Sub GetIsUserLoginCorrect().
To demonstrate, try the following with and without ByRef.
Private Sub ChangeBoolean(ByRef TorF As Boolean)
TorF = True
End Sub
Private Sub OPCode2()
Dim TorF As Boolean
ChangeBoolean(TorF)
Debug.Print(TorF.ToString) ' Result False without ByRef in ChangeBoolean
'When ByRef is added result is True
End Sub
First off, a method can refer to either a sub or a function. A sub is a method that performs an action. A function is a method that calculates or retrieves one or more values.
A sub should not be called Getxxx, because its primary purpose should not be returning a value.
A function should be used to return values. Since you are trying to retrieve multiple values, if you were using 2017 I would suggest returning a named tuple with your two values, since you aren’t I would create an object that has the values and return that.
On a totally different note, you really can’t tell the difference between right user wrong password and wrong user right password and wrong user wrong password - so you shouldn’t tell someone you can. You just say login unsuccessful login, or invalid username/password combination.
There's a lot wrong with your code.
Firstly, why are you using so much of SQL code ? Correct me if i am wrong : You are trying to build a log in system. So much of SQL code or even the stored procedure is worthless here. You can simply write the SQL statements in your code by using the SqlCommand class. Even though you are using the ALTER PROCEDURE statement, i can surely say that things can be simplified here.
You are also using the Me keyword. It's not C# where the use of this(same as Me in VB.Net) becomes compulsory. I assume it's a Windows Forms Application and if that's so, then using Me keyword to access it's child elements wouldn't result in any different if it's not used at all.
The next worth mentioning issues is your Name Conventions. Most or should i say all of your variables have the same name. For example : IsLoginIdCorrect - used both as a parameter of a method and also a variable inside a method.
The next issues is in these two lies :
Dim IsLoginIdCorrect, IsPasswordCorrect As Boolean
GetIsUserLoginCorrect(IsLoginIdCorrect, IsPasswordCorrect)
You are passing the boolean variables before they have been assigned any value. You are lucky it's not C# or this wouldn't even compile. Passing the boolean variables without assigning any value will, by default, set their values to False. So, literally, you are always passing the same value in which case, the outcome will always be the same.
The next issue is in your If statement inside your LoginButton_Click method aka LoginButton's click event handler's method :
If IsLoginIdCorrect And IsPasswordCorrect = True Then
The if statements, if described in simple words, means : If IsLoginIdCorrect and IsPasswordCorrect are true, then proceed.... So, in this case, IsPasswordCorrect = True doesn't affect much. However, this is not the best practice too. You should better follow the following coding rule while using If statements:
If (IsLoginIdCorrect = True AndAlso IsPasswordCorrect = True) Then
AndAlso operators evaluates each side just like the And operator. The difference is that it would return False if the left side(IsLoginIdCorrect, in this case) returns False.
The next issues is the usage of ApplicationException. I don't understand why, in this era, you are using that class! This class is usually used to derive from and create exceptions. You can simply use Exception instead of ApplicationException.
Your Try-Catch block seems not useful as well. All of your codes inside the LoginButton_Click are in If conditions and they perform very basic operation. It is unlikely to ever throw any exception at all.
Your logics, for most part, are illogical(sorry to put it this way). In your GetIsUserLoginCorrect method, you are setting IsLoginIdCorrect and IsPasswordCorrect to either true or false but it wouldn't matter because they are parameters of the method itself. So even if you set their values, they will be reset when you call the method again. The reason why ByRef (according to Mary's answer) works is because ByRef, in short, means that you are pointing to original variable that you passed(not it's copy).
And finally, the solution you are looking for....
Even though i see you have marked Mary's answer as the answer, i would like to help you out a bit as-well.
Firstly, get rid of the stored procedure if possible and also if you are not using it anywhere else. I see you are using the If Exist condition inside your SQL queries. This is actually a nice move because according to performance reports, checking if data exists in a database/table using IF EXISTS yields the fastest output. So bravo for that one. But if you follow my advice and want to ditch the stored procedure, then you need to get rid of the IF EXISTS statement as well. Rather, you can simply use the SELECT statement itself, use the ExecuteScalar method of the SqlCommand class, convert it's value to Integer and check if the value of the Integer is 1 or not.
Example :
Dim cmd = New SqlCommand("SELECT COUNT(*) FROM UserInfo
WHERE loginid = #LoginID AND password = #Password")
Dim Exists = Convert.ToInt32(cmd.ExecuteScalar)
If Exists = 1 Then
''Code if data exists
End if
Note that i have used Convert.ToInt32 here. This will prevent null-reference exception as when ExecuteScalar returns Null, it will be converted to 0 integer value.
Also, why are you using GetIsUserLoginCorrect as method ? You can simply use it as a function and return required values. As you are returning multiple values, you can easily use the Tuple type as your function's type:
Private Function GetIsUserLoginCorrect(IsLoginIdCorrect As Boolean, IsPasswordCorrect As Boolean) As Tuple(of Boolean, Boolean)
....
....
return Tuple.Create(IsLoginIdCorrect, IsPasswordCorrect)
End Sub
Usage
Dim IsLoginCorrect = GetIsUserLoginCorrect(first_boolean_variable,second_boolean_variable).Item1
Dim IsPasswordCorrect = GetIsUserLoginCorrect(first_boolean_variable,second_boolean_variable).Item2
One last thing. As you are showing DeshBoard form after hiding the main form, make sure to call MainForm.Close on the Dashboard form's Closing/Closed event. This will ensure the application's exit(unless you have other plans for the main form, of course).
Hope this answer helps you.

Conditional guard IF Not (x = Empty) Then

I have the following
Public Sub BreakAllLinks(ByRef aWkBook As Excel.Workbook)
Dim Link As Variant
Dim myLinks As Variant
myLinks = aWkBook.LinkSources(Type:=Excel.xlLinkTypeExcelLinks)
If Not (myLinks = Empty) Then
For Each Link In myLinks
aWkBook.BreakLink Name:=Link, Type:=Excel.xlLinkTypeExcelLinks
Next Link
End If
End Sub 'BreakAllLinks
If myLinks is empty then it works well and avoids the For Each loop but if myLinks contains some links then I get the following error
Runtime error '13'
What is wrong with If Not (myLinks = Empty) Then?
LinkSources returns either Empty or an array.
You cannot compare an array with Empty using the equality operator.
The documentation shows you the right way of checking the result - using the IsEmpty function.
The function succeeds regardless of the value type stored in your Variant.
If e.g. you had a Nothing in there, you would get error 91.
Or, if you had an object reference in there, your comparison would try to fetch the default property of the stored object and compare that to Empty.
Which is why you should never check for = Empty really, and only use IsEmpty.

WP use string as name of control

Please, can anyone help me with this problem:
I have a name(s) of control(s) in string format (str) and I want to set property (in code) of that controls using that string-name.
I try something like this but it doesn't work. Actually, I have a problem with expression. When I put exactly the name it works but when i use variable in string format it doesn't.
Dim str as String
str="k3"
Dim g As Image = CType(str, Image)
g.Source = New BitmapImage(New Uri("/APP;component/Icons/hero.png", UriKind.Relative))
This works:
Dim g As Image = CType(k3, Image)
While this does not:
Dim g As Image = CType(str, Image)
I think I understand what you are trying to do, to declare an object by a string...
Essentially for this to work you will need a custom function that returns the Object Type that you are seeking...
You will need to loop through each control and check the name of the control as a comparison, e.g. If oControl.Name.ToString = sString then Return oControl
Example
' A function to return a Control by the Control's name...
Public Function GetControlByName(ByVal oForm As Form, ByVal sName As String) As Control
Dim cReturn As New Control
Dim ctrl As Control
For Each ctrl In oForm.Controls
cReturn = ctrl
If ctrl.Name.ToString = sName Then
Return ctrl ' this is what we want!
End If
Next
Return cReturn
End Function
' Example Usage
Dim oButton As Button = GetControlByName(Me, "Button44")
If oButton.Name.ToString = "Button44" Then
MessageBox.Show("I have found your Button!")
Else
MessageBox.Show("Your button was NOT Found!")
End If
Obviously there is room for error with this function, because if sName is NOT found, then it will return the last ctrl found, therefore, you will need to ensure that the control you seek is indeed found, via the If statement as provided in the example above...
Furthermore, it may not loop through controls inside of containers, menus, etc, but I'm not sure on that, so you will need to check to ensure it's not having that problem...
(The Me in the statement will most likely be used more often than not, though Me could be the name of the form you are searching if you are running the code outside of the form you are searching the form with the function.)
FINALLY, to answer your question, you will need to change Control to Image, and Set CReturn as a New Image, and then use Return ctrl.BackgroundImage (etc) to return the image..

VB.NET: short cuts in code

Why is the following VB.NET code setting str to Nothing in my VS2005 IDE:
If Trim(str = New StreamReader(OpenFile).ReadToEnd) <> "" Then
Button2.Enabled = True
TextBox1.Text = fname
End If
OpenFile is a Function that returns a FileStream
EDIT: If the above line containing Trim is not correct, is there a way to achieve the intended result in only one line?
The code is never setting str at all:
If Trim(str = New StreamReader(OpenFile).ReadToEnd) <> "" Then
This line doesn’t set str, it compares it to the result of reading the file.
In VB, the = operator has two meanings, depending on context. If used in a statement, it assigns the right-hand expression to the left-hand expression. If used in any other context (i.e. in an expression), it performs an equality comparison, not an assignment.
Thus, in VB you must write the following:
str = New StreamReader(OpenFile()).ReadToEnd()
If str.Trim() <> "" Then …
Notice that I’ve replaced the free function Trim by a method call to make the code more consistent with common .NET coding practices.
The first thing to do when starting any VB.Net project is to make sure that Option Explicit and Option Strict are both set to true in the project settings. Only ever disable either of them if you have a specific reason (you need late binding or are taking over some old horrible code).
This would have stopped that code from even compiling and would have shown you the error right away.
Because you're not setting str, you're comparing it, then trimming the result of the comparison (basically trimming either "True" or "False"
If Trim(str = New StreamReader(OpenFile).ReadToEnd) <> "" Then
This doesn't actually set str, this breaks down to the following code
Dim str as string ' Defaults to nothing/""
Dim boolValue as bool = (str = New StreamReader(OpenFile).ReadToEnd)
If Trim(boolValue) <> "" Then
' This is always true, as "True" and "False" will never = ""'
...
End If