How to re-write Redundant Assignment? - vb.net

I have this code:
If SalaryCbx.Checked = True Then
fundSalary = "S" <- Throws an error
Else
fundSalary = "N" <- Throws an error
End If
SonarQube throws a "Critical" error:
Assignment is not used
(Category: Redundancies in Code)
resharper-vbnet RedundantAssignment
Value assigned is not used in any execution path
Is there a better way to write this kind of logic?
I tried a Select Case statement but it also threw the error.
I also use this same code except for different variables/checkboxes and it works fine - no errors.
Update: Here's where I am using it.
Dim insertQry As String = "INSERT INTO FUND (FUND_ID, FUND_NM, FUND_TICKER_NM, FUND_SALARY_IND, FUND_BONUS_IND, FUND_ALCTN_IND, BEG_DT, END_DT) "
insertQry &= " VALUES(#FundID, #fndName, #fndTicker, #fndSalary, #fndBonus, #fndAllocation, #fndBeg, #fndEnd) "
'Code omitted
'Declare Connection String
Using sqlConnection As New SqlConnection(myConn)
'Declare variable for SQL command
Using cmd As New SqlCommand(insertQry)
With cmd
.Connection = sqlConnection
.CommandType = CommandType.Text
.Parameters.AddWithValue("#FundID", id)
.Parameters.AddWithValue("#fndName", fundName)
.Parameters.AddWithValue("#fndTicker", fundTicker)
.Parameters.AddWithValue("#fndSalary", fundSalary)

The message is saying that you're not reading the assigned value in any other part of your code. Possible reasons:
You made an mistake (like a copy-and-paste error) and are accidentally reading a different variable where you intend to read this one.
The reading code has shadowed the written variable with an identically-named variable in a narrower scope.
Old code that no longer needs to be present because nothing is meant to read the variable.
False positive in the checker.

Related

VB.net connection string works, then doesn't, then does - why?

Using VB.NET, VS 19 v16.10.4
I have a small application which asks a user to provide database server, database name and then builds a connection string. Then, using a data access layer DLL I've written it runs a check to see if a connection can be made to the database.
The problem is unusual:
If I write the connection string direct to the data access layer into a variable it connects;
If I use a string builder to build the string then pass it to the data access layer it fails;
If I write the connection string into a variable then pass it to the data access layer it fails;
If I use the first step again it works.
With DAL
MessageBox.Show("Using hard-coded string")
.ConnectionString = "data source=THEWINELIBRARY\MSSQLSERVER01;initial catalog=TrialDatabase;trusted_connection=true"
.DoConnectionCheck() 'THIS WORKS
MessageBox.Show("Using string builder string")
.ConnectionString = SBConnString.ToString.Trim
.DoConnectionCheck() 'THIS FAILS
MessageBox.Show("Using CS string")
.ConnectionString = CS.Trim
.DoConnectionCheck() 'THIS FAILS
MessageBox.Show("Using hard-coded string")
.ConnectionString = "data source=THEWINELIBRARY\MSSQLSERVER01;initial catalog=TrialDatabase;trusted_connection=true"
.DoConnectionCheck() 'THIS WORKS
End With
The data access layer does the following in the DoConnectionCheck method:
Public Sub DoConnectionCheck()
OpenConnection()
With AppConnection
If (.State = ConnectionState.Open) Then
RaiseEvent ConnectionOpened()
CloseConnection()
End If
End With
End Sub
and the OpenConnection method:
Private Sub OpenConnection()
With AppConnection
'Is the conenction currently closed?
If (.State = ConnectionState.Closed) Then
Try
'Set connection string to POS
.ConnectionString = ConnectionString
'Try opening the connection
.Open()
'Otherwise raise an event.
Catch E As Exception
RaiseEvent ConnectionFailed()
End Try
End If
End With
End Sub
And the connection string is a simple property:
Public ConnectionString As String
So, what I don't understand is why the connection fails with the string builder string and the variable string, but not with the hard-coded string?
If there is any other code you need please let me know, I posted what i think is enough to explain the problem without putting in too much that makes the question unreadable.
here is the code which constructs the connection string from entries in a form:
Dim CS As String = "datasource=" & .TextServer.Text.Trim & ";initial catalog=" & .TextDatabase.Text.Trim & ";trusted_connection=true"
SBConnString = New StringBuilder
With SBConnString
.Clear()
.Append("datasource=")
.Append(Me.TextServer.Text.Trim)
.Append(";initial catalog=")
.Append(Me.TextDatabase.Text.Trim)
.Append(";trusted_connection=true")
End With
When these strings are compared to the hard coded string
DAL.ConnectionString = "data source=THEWINELIBRARY\MSSQLSERVER01;initial catalog=TrialDatabase;trusted_connection=true"
the function returns a value 1, "The first substring follows the second substring in the sort order." according to the documentation.
As far as I can see, these strings are identical but somewhere an additional character must be getting inserted in the form textbox.
Again, any suggestions gratefully received.
All the best,
Dermot
Mea culpa - I had a very simple mistake which I could not see - in the two strings causing the problem I had datasource rather than date source...

Syntax Error in INSERT INTO statement vb.net and an access database

The program I'm writing (in vb.net) is supposed to be loading values from text boxes into a database.
However, when I click "Save", at first nothing at all happened. No error, no notification, nothing. So I traced it using breakpoints, and it got to:
daTraining.Update(dsTraining, "Training")
and just stopped.
So I put in a try/catch, and now when I hit save I get
System.Data.OleDB.OledgException (0x80040E14): Syntax error in INSERT INTO statement.
I'm confused on how to troubleshoot this or what the issue might be.
The Code
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Try
Dim cb As New OleDb.OleDbCommandBuilder(daTraining)
Dim dsNewRow As DataRow
dsNewRow = dsTraining.Tables("Training").NewRow
dsNewRow.Item("ID") = txtTrainingID.Text
dsNewRow.Item("Ranch") = cbRanches.Text
dsNewRow.Item("Location") = txtLocation.Text
dsNewRow.Item("Date") = mtbDate.Text
dsNewRow.Item("StartTime") = mtbStartTime.Text
dsNewRow.Item("FinishTime") = mtbFinishTime.Text
dsNewRow.Item("Crew") = txtCrews.Text
dsNewRow.Item("Supervisor") = txtSupervisor.Text
dsNewRow.Item("Foreperson") = txtForeperson.Text
dsNewRow.Item("Activity") = txtActivity.Text
dsNewRow.Item("Trainer") = txtTrainer.Text
dsNewRow.Item("Topics") = txtTopics.Text
dsTraining.Tables("Training").Rows.Add(dsNewRow)
daTraining.Update(dsTraining, "Training")
MsgBox("Training Recorded")
cb.Dispose()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
This is a common issue when using a data adapter with a wildcard in the query and a command builder. If one or more of your columns names is a reserved word or contains spaces or other special characters then the auto-generated INSERT and UPDATE statements will generate syntax errors.
The preferred solution is to change the offending column name(s) but, if that's not an option, you can set the QuotePrefix and QuoteSuffix properties of your command builder so that it escapes all column names in the generated action commands. The appropriate values will vary depending on your database but for Microsoft databases, use "[" and "]" respectively.
As indicated in comments, the issue was in
dsNewRow.Item("Date") = mtbDate.Text
with Date being a reserved word.

Constructor in VBA - Runtime error 91 "Object variable not set"

I am trying to write some code in excel VBA using the Object Oriented Concept. Therefore I wanted to initialize my objects with constructors, like we usually do in Java. However I discovered that the default Class_Initialize() Sub that is offered in VBA does not take arguments. After searching a bit, I found that the answer for this Question proposed a pretty good alternative.
Here is a sample of my Factory Module (I Named it Creator):
Public Function CreateTool(ToolID As Integer) As cTool
Set CreateTool = New cTool
CreateTool.InitiateProperties (ToolID) '<= runtime error 91 here
End Function
The class cTool:
Private pToolID As Integer
Private pAttributes As ADODB.Recordset
Private pCnn As ADODB.Connection
Public Sub InitiateProperties(ToolID As Integer)
Dim sSQL As String
Set pCnn = connectToDB() 'A function that returns a connection to the main DB
pToolID = ToolID
sSQL = "SELECT Tool_ID, Status, Type, Tool_Number " _
& "FROM Tool WHERE Tool_ID = " & pToolID
pAttributes.Open sSQL, pCnn, adOpenKeyset, adLockOptimistic, adCmdText
End Sub
This is how I call the constructor:
Dim tool As cTool
Set tool = Creator.CreateTool(id)
My issue is that when I run the code, I get the following error:
Run-Time error '91' : Object Variable or With Block Variable not Set
The debug highlights the CreateTool.InitiateProperties (ToolID) line of my CreateTool Function.
I know that this usually happens when someone is setting a value to an object without using the keyword Set but it does not seem to be my case.
Any help, advice to resolve this issue would be greatly appreciated!
Thanks.
Might not be the cause of your error, but this:
Public Function CreateTool(ToolID As Integer) As cTool
Set CreateTool = New cTool
CreateTool.InitiateProperties (ToolID) '<= runtime error 91 here
End Function
Is problematic for a number of reasons. Consider:
Public Function CreateTool(ByVal ToolID As Integer) As cTool
Dim result As cTool
Set result = New cTool
result.InitiateProperties ToolID
Set CreateTool = result
End Function
Now, looking at the rest of your code, you're doing the VBA equivalent of doing work in the constructor, i.e. accessing database and other side-effects to constructing your object.
As #Jules correctly identified, you're accessing the unitialized object pAttributes inside InitiateProperties - that's very likely the cause of your problem.
I'd strongly recommend another approach - if you come from Java you know doing work inside a constructor is bad design... the same applies to VBA.
Get your code working, and post it all up on Code Review Stack Exchange for a full peer review.

VB SQL CommandText property has not been initialized

I'm new to working with background workers, and I'm trying to run the following code. But I recieve a run-time error on the m._Value_CreatedDate = m._MyCMD.ExecuteScalar() line. The error is:
Additional information: ExecuteScalar: CommandText property has not
been initialized
Try
Dim m As MyParameters = DirectCast(e.Argument, MyParameters)
m._Con.Open()
m._QueryStr = "SELECT TOP 1 CONVERT(varchar(10),aCreated,103) FROM Account WHERE aMember_ID = " & m._Selected_MemberID & ""
m._MyCMD.CommandType = CommandType.Text
m._Value_CreatedDate = m._MyCMD.ExecuteScalar()
Catch ex As Exception
m._Value_CreatedDate = "N/A"
End Try
Here's the Parameter's I'm using:
Class MyParameters
Friend _QueryStr As String
Friend _Value_CreatedDate As Object
Friend _AccountID As Object
Friend _Selected_MemberID As String = Committee_Database.GridView1.GetFocusedRowCellValue("Unique ID").ToString
Friend _Con As New SqlConnection('Connection string ommitted)
Friend _MyCMD As New SqlCommand(_QueryStr, _Con)
End Class
Please forgive me if I'm doing something extremely wrong, I'm self taught and experimenting with the backgroundworker. It's worth noting that _QueryStr will change multiple times as the background worker runs multiple queries against the same database and (as I understand it) stores each of the returned values from the queries into variables - _Value_CreatedDate is the variable I am using in this code. I've included an example of how I'm recycling the _QueryStr variable below and storing the returned value into a diffent Variable each time.
Try
m._QueryStr = "SELECT TOP 1 aAccount_ID FROM Account WHERE aUser_Name='" & _Selected_AccountID & "'"
m._MyCMD.CommandType = CommandType.Text
m._AccountID = m._MyCMD.ExecuteScalar()
Catch ex As Exception
End Try
Am I doing something wrong?
In the implementation of your class MyParameters you initialize the SqlCommand directly with the declaration using the value of the variable _QueryStr. At that point in time the variable _QueryStr is not yet initialized, so it is an empty string.
After the initialization of an instance of MyParameters, you change the value of _QueryStr (many times according to you) but these changes are not automatically passed to the CommandText of your SqlCommand. It still contains the empty initial value.
You could fix this problem building appropriate getter and setter for a new QueryStr property. When someone tries to set the property the code below change the value of the internal field _QueryStr (now private) and reinitializes the CommandText property of your SqlCommand.
Class MyParameters
Private _QueryStr As String
Public Property QueryStr() As String
Get
Return _QueryStr
End Get
Set(ByVal value As String)
_QueryStr = value
_MyCMD.CommandText = _QueryStr
End Set
End Property
..... other properties
Friend _MyCMD As New SqlCommand(_QueryStr, _Con)
End Class
Now when you write
Try
m.QueryStr = "SELECT ...."
....
the new command text is correctly assigned to your command.
As a side note: I suggest to use plain ADO.NET objects (or learn how to use an ORM tool). Do not try to encapsulate them in custom classes unless you have a very deep understanding on how these ADO.NET objects works. You gain nothing and expose your code to many problems. For example your code is very easy to exploit with Sql Injection because the MyParameters class has no provision to use a parameterized query. Your code has no method to close and dispose the SqlConnection embedded in your class thus leading to resource leaks.

Vb.net: Calling a Function That Does not Match Prototype Passes Compiler Check

I have encountered something I would like explained. I have a function InitializeValues() that sets up a combobox, and sets the datasource to a datatable. The datatable is retrievedfrom an instance of the class DGVMain_Functions using the public method GetFileSourceData which takes no parameters.
The issue is that a call to GetFileSourceData(MyConnectionString) will actually compile and run. A run time error occurs when the datatable is returned and attempted to set to the datasource of the cbo. The normal call GetFileSourceData() works properly.
I had asked another developer about this, and he thought I had some stale reference, so I cleaned the project, then deleted everything in my debug folder, and rebuilt, but it still had the same behavior.
My question is this, Why does the compiler accept this and not throw a syntax error, and furthermore why does it even get to the point where you can actually step into this function that should not exist, and have it fail on return?
EDIT: Putting Option Strict On, does make the compiler catch this. "Option Strict On disallows implicit conversions from 'String' to 'Integer'. But that is still not the error I want to see. I would like to know why it does not display something along the lines of "No such overload/definition of that function exists".
The error is this:
An error occurred creating the form. See Exception.InnerException for details. The error is: ERROR: ERROR: Conversion from string "user id=XXXX;data source=XXXXX" to type 'Integer' is not valid.Microsoft.VisualBasicFileProcessor.
"InnerException = {"Input string was not in a correct format."}"
Private Sub InitializeValues()
cboFileSource.DisplayMember = "filesource"
cboFileSource.ValueMember = "filesource"
'first call works fine since it matches
cboFileSource.DataSource = DgvMain_functs.GetFileSourceData()
'below is the call that gets through the complier and actually runs, fails on return
cboFileSource.DataSource = DgvMain_functs.GetFileSourceData(MyConnectionString)
End Sub
Public Function GetFileSourceData() As DataTable
Try
Dim dt As DataTable
Dim strSQL As String = "select distinct filesource from FileUpload_FolderPath"
dt = SqlHelper.ExecuteDataset(MyConnectionString, CommandType.Text, strSQL).Tables(0)
Return dt
Catch ex As Exception
Throw New Exception("Error in DGVMain_Functions: " & ex.Message & ex.Source)
End Try
End Function
As you've hinted in your comment, surely Option Explicit On would solve this issue.