How to get rid of the first concatenation symbol - vb.net

I'm looping a table database to catch the first name of some rows
The code is like:
Try
While (readerFirstName.Read())
SearchedName = readerFirstName("parteA")
CombinatedNames = CombinatedNames & " & " & SearchedName
End While
Catch ex As Exception
MsgBox(ex.ToString())
End Try
And the desired result si something like
Mike & Eric & Tom
but I get
& Mike & Eric & Tom
I think I can get rid of the first " &" after the string formation using String.TrimStart
but there's a better way to cut the first "& "?

Try replacing your loop:
While (readerFirstName.Read())
SearchedName = readerFirstName("parteA")
CombinatedNames = CombinatedNames & " & " & SearchedName
End While
With this one:
Dim names As New List(Of String)()
While (readerFirstName.Read())
names.Add(readerFirstName("parteA"))
End While
CombinatedNames = String.Join(" & ", names)
The main idea here is to use the String.Join method to concatenate the single names in one single operation. That method acts on collections, so you will first have to read the single items into a collection names.
This method will take care to add the separator string " & " between items, never before the first or after the last, so you will not end up with a leading or trailing separator (unless you have an empty item in your list).
P.S.: If you happen to know beforehand how many names will be read from readerFirstNames, you could optimise memory usage of my suggested code by passing the name count to the List(Of T) constructor (as the capacity parameter).

You can check the contains in combine string before adding text in it
While (readerFirstName.Read())
SearchedName = readerFirstName("parteA")
If Not isNullOrEmpty(CombinatedNames) Then
CombinatedNames = CombinatedNames & " & " & SearchedName
Else
CombinatedNames = SearchedName
End If
End While

The other answers are the usual way to do it, but here are few lazier alternatives:
this will remove the first 3 characters:
CombinatedNames = Mid( CombinatedNames , 4 )
this will trim and & from the beginning of the string:
CombinatedNames = CombinatedNames.TrimStart(" "c, "&"c)

or you can just read the first record and then concatenate the rest:
CombinatedNames = If(readerFirstName.Read, readerFirstName!parteA.ToString, "")
While readerFirstName.Read
CombinatedNames &= " & " & readerFirstName!parteA.ToString
End While

Related

How to loop through a row in each column even the data is NULL or empty string?

I have a VB.NET program which runs as a Windows Service. All it does is connect to a table in SQL Server 2016 and reads data (if any exist) and does some transaction posting to an ERP System. Now in that table (ALL_LABOR_DETAILS) I have 29 columns and some of them could be 'NULL' or empty string value per given row. You can see I've used IsDBNull function for those columns only in my code.
Following is my code which I'm moving through the rows and columns in the dataset but I've noticed whenever it comes to a row with a 'NULL' value for operationComplete or strDefaultBin or strLotNo column it does not read is as a Empty String, instead it tries to move to another row with no NULL record and read that row instead.
Also it throws me this error in my log file whenever it encounters a NULL value in
operationComplete
Error: Conversion from type 'DBNull' to type 'String' is not valid.
Code:
Dim postCount3 As SqlDataReader
Dim newServer3 As String = ConfigurationManager.AppSettings("newServer")
Try
Using cn3 As New SqlConnection(newServer3),
cmd3 As New SqlCommand(Sql3, cn3)
cn3.Open()
postCount3 = cmd3.ExecuteReader()
If postCount3.HasRows Then
While postCount3.Read()
Try
SourceID = Trim(postCount3.Item(0))
strSourceName = Trim(postCount3.Item(1))
strOrderNumber = Trim(postCount3.Item(4))
strItemNumber = Trim(postCount3.Item(11))
strOperationNumber = Trim(postCount3.Item(7))
strCurrentStatus = Trim(postCount3.Item(2))
strDepartment = Trim(postCount3.Item(5))
strWorkCenter = Trim(postCount3.Item(6))
strOperator = Trim(postCount3.Item(8))
strTrxDate = Trim(postCount3.Item(3))
strPosted = Trim(postCount3.Item(14))
totalLaborHrs = Trim(postCount3.Item(9))
laborFeetProduced = Trim(postCount3.Item(10))
If Not IsDBNull(Trim(postCount3.Item(22))) Then
operationComplete = Trim(postCount3.Item(22))
Else
operationComplete = Trim(postCount3.Item(22)).ToString()
End If
If Not IsDBNull(Trim(postCount3.Item(13))) Then
strDefaultBin = Trim(postCount3.Item(13))
Else
strDefaultBin = Trim(postCount3.Item(13)).ToString()
End If
If Not IsDBNull(Trim(postCount3.Item(12))) Then
strLotNo = Trim(postCount3.Item(12))
Else
strLotNo = Trim(postCount3.Item(12)).ToString()
End If
FileIO.WriteLog("")
'Print Source ID
FileIO.WriteLog(SourceID)
'Print Source Name
FileIO.WriteLog(strOrderNumber & " Source Name = " & strSourceName)
'Print Order Number
FileIO.WriteLog(strOrderNumber & " Order Number = " & strOrderNumber)
'Print Item Number
FileIO.WriteLog(strOrderNumber & " Item Number = " & strItemNumber)
'Print Operation Number
FileIO.WriteLog(strOrderNumber & " Operation Number = " & strOperationNumber)
'Print Department
FileIO.WriteLog(strOrderNumber & " Department = " & strDepartment)
'Print Work Center
FileIO.WriteLog(strOrderNumber & " Work Center = " & strWorkCenter)
'Print Operator
FileIO.WriteLog(strOrderNumber & " Operator = " & strOperator)
'Print Current Status
FileIO.WriteLog(strOrderNumber & " Current Status = " & strCurrentStatus)
'Print Total Labor Hours
FileIO.WriteLog(strOrderNumber & " Total Labor Hours = " & totalLaborHrs)
'Print Labor Feet Produced
FileIO.WriteLog(strOrderNumber & " Labor Feet Produced = " & laborFeetProduced)
'Print Operation Complete
FileIO.WriteLog(strOrderNumber & " Operation Complete = " & operationComplete)
'Print Default Bin
FileIO.WriteLog(strOrderNumber & " Default Bin = " & strDefaultBin)
'Print Lot No
FileIO.WriteLog(strOrderNumber & " Lot No = " & strLotNo)
Catch ex As Exception
FileIO.WriteLog("Error : " & ex.Message)
End Try
Continue While
End While
postCount3.Close()
cn3.Close()
End Using
Catch ex As Exception
FileIO.WriteLog(strOrderNumber & " There was an error getting the laborDetails FROM ALL_LABOR_DETAILS table WHERE posted = '' AND work_order IS NOT NULL ORDER BY SOURCE_ID. Error Message : " & ex.Message)
End Try
You are trying to Trim DBNull. Try changing this(the Else)
operationComplete = Trim(postCount3.Item(22)).ToString()
to
operationComplete = postCount3.Item(22).ToString()
Same for the others.
You cannot implicitly cast dbnull to a string which is what youa redoing with the trim command. It accepts a string parameter and vb tries to cast. If null is an option, I would recommend tryParse.
Y organization uses a wrapper class to parse the value of return a nothing for these sorts of calls. The class structure is simple enough and looks something like the below though with a string we return string.empty.
Public Module Parsers
Function ParseString(value as object) as String
Dim result as string
If String.TryParse(value, result) then
Return result
End if
Return string.empty
End function
End module
And then call it like
strSourceName = Trim(Parsers.ParseString(postCount3.Item(1)))

Removing first character from a column if it starts with 0

I have an oracle table, a_abc that have three columns (name, ID and address). The data for this table will be extracted from a txt file. How to remove the first character in ID column if it starts with number '0'. I need a VB solution. This is what Ive done so far now
Private Sub ReadData()
Dim rowvalue As String
Dim cellvalue(20) As String
Dim header As String = "ID"
Dim streamReader As IO.StreamReader = New IO.StreamReader("D:\local_costctr.txt")
'Reading CSV file content
While streamReader.Peek() <> -1
rowvalue = streamReader.ReadLine()
cellvalue = rowvalue.Split("|") 'check what is ur separator
ConnectOracle()
mySQLcmd.Connection = myConn
If SQL.Length > 0 Then
SQL.Replace(SQL.ToString, "")
End If
SQL.Append("insert into a_abc (name ,ID ,address) ")
SQL.Append(" values ('" & cellvalue(0) & "' ,'" & cellvalue(1) & "','" & cellvalue(2) & "') ")
Console.WriteLine(header)
Console.WriteLine(header.Trim({"0"c}))
Try
mySQLcmd.CommandText = SQL.ToString
mySQLcmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Error " & ex.Message.ToString)
End Try
End While
End Sub
If there is more than one leading zero, I want all of them removed.
The ltrim function should do the trick:
SELECT name, LTRIM(id, '0'), address
FROM a_abc
EDIT:
Now that the question was edited, I see you refer inserting the data, not querying it. The same solution could be applied on an insert too though:
SQL.Append("insert into a_abc (name ,ID ,address) ")
SQL.Append(" values ('" & cellvalue(0) & "', LTRIM(" & cellvalue(1) & ", '0'), '" & cellvalue(2) & "') ")
While you are extracting the data from the txt-file and you come across the ID-field:
For Each line As String In IO.File.ReadAllLines("yourpath")
If "myID".Substring(0, 1) = "0" Then
'take the "myID" without the leading 0
"myID".Substring(1)
End if
Next
Depending on your case you might need Null-checks etc...
Edited for your code:
Replace cellvalue(1) in the SQL.append by:
IIF(cellvalue(1).Substring(0, 1) = "0",cellvalue(1).Substring(1),cellvalue(1))

SQL Variable in Where Clause

Dim varCity As String
varCity = Me.txtDestinationCity
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE" & Me.txtDestinationCity & "= [TDestinationType].[tPreTravelDestinationCity]"
I am trying to select the states for the selected city. There is a drop down box with a list of cities. That box is titled txtDestinationCity.
It says I have an error in my FROM clause.
Thank you
You miss a space and some quotes. How about:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE '" & Me.txtDestinationCity & "' = [TDestinationType].[tPreTravelDestinationCity]"
Copy that next to your original to see the difference.
And for reasons SQL, PLEASE reverse the comparison. Always mention the column left and the value right:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = '" & Me.txtDestinationCity & "'"
Since the quotes are annoying and easy to miss, i suggest defining a function like this:
Public Function q(ByVal s As String) As String
q = "'" & s & "'"
End Function
and then write the SQL string like that:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(Me.txtDestinationCity)
This makes sure you ALWAYS get both quotes at the right places and not get confused by double-single-double quote sequences.
If you care about SQL-injection (yes, look that up), please use the minimum
Public Function escapeSQL(sql As String) As String
escapeSQL = Replace(sql, "'", "''")
End Function
and use it in all places where you concatenate user-input to SQL-clauses, like this:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(escapeSQL(Me.txtDestinationCity))
Lastly, breakt it for readability. I doubt your editor shows 200 characters wide:
Me.txtDestinationState.RowSource = _
"SELECT tPreTravelDestinationState " & _
"FROM [TDestinationType] " & _
"WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(escapeSQL(Me.txtDestinationCity))
Note the trailing spaces in each line! Without them, the concatenation will not work.
It can be easier to troubleshoot your query construction if you set it to a variable (e.g., strSQL) first. Then you can put a breakpoint and see it right before it executes.
You need a space after WHERE. Change WHERE" to WHERE<space>"
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE " & Me.txtDestinationCity & "= [TDestinationType].[tPreTravelDestinationCity]"

SQL/VB.NET Search-Function looking for at least one correct input

I'm writing a program in Visual Basic about Databases. Now I have a Sub/Function who searches the database for correct inputs. I have five text boxes where the user can put in something for each data field.
If txtBox1.Text <> "" Or txtBox2.Text <> "" Or txtBox3.Text <> "" Or txtBox4.Text <> "" Or txtBox5.Text <> "" Then
Try
connection.Open()
command.CommandText = "SELECT * from lager WHERE (lager_waren_id LIKE '" & txtBox1.Text & "' OR lager_warenanzahl LIKE '" & txtBox2.Text & "' OR lager_warenname LIKE '%" & txtBox3.Text & "%' OR lager_warengewicht LIKE '" & txtBox4.Text & "%' OR lager_waren_verkaufspreis LIKE '" & txtBox5.Text & "%');"
reader = command.ExecuteReader()
FormKunde.Enabled = True
FormKunde.lstViewKundeStore.Items.Clear()
Do While reader.Read()
Dim lstViewItem As New ListViewItem(reader("lager_waren_id").ToString())
lstViewItem.SubItems.Add(reader("lager_warenanzahl").ToString())
lstViewItem.SubItems.Add(reader("lager_warenname").ToString())
lstViewItem.SubItems.Add(reader("lager_warengewicht").ToString())
lstViewItem.SubItems.Add(reader("lager_waren_verkaufspreis").ToString())
FormKunde.lstViewKundeStore.Items.Add(lstViewItem)
Loop
reader.Close()
FormKunde.Enabled = False
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
connection.Close()
Else
MessageBox.Show("Please fill in something in the text fields")
Exit Sub
End If
I'm aksing the database if at least one text field has some input that matches to the data field it belongs to. But when I put something in, doesn't matter how much, nothing happens in my list view. It just loads all data back in the list view. When I try to do "AND" instead of "OR", it works only if i fill all text fields with the correct datas for one data set. But I want, that it finds all data sets.
An example:
I have two data sets where the names are "App" and "Apple". When i just fill in "Ap" in the field for names (nothing in the others) it shows me both. I think it should work with "OR", but it just does nothing.
I'm really confused how to solve this, I hope anyone has a guess. Thank you!
Your problem is that your query always uses all the conditions also when there is no input in the relevant textboxes. In this way your LIKEs become LIKE '%%' and, of course, this matches every record.
You need to add the conditions only if the textboxes are not empty or null.
So you need to build your query in parts after checking if the textbox contains any value to search for.
connection.Open()
Dim sql = "SELECT * from lager WHERE "
if Not string.IsNullOrWhiteSpace(textBox1.Text) Then
sql = sql & "lager_waren_id LIKE #p1 OR "
command.Parameters.AddWithValue("#p1", textBox1.Text)
End If
if Not string.IsNullOrWhiteSpace(textBox2.Text) Then
sql = sql & "lager_warenanzahl LIKE #p2 OR "
command.Parameters.AddWithValue("#p2", textBox2.Text)
End If
if Not string.IsNullOrWhiteSpace(textBox3.Text) Then
sql = sql & "lager_warenname LIKE #p3 OR "
command.Parameters.AddWithValue("#p3", "%" & textBox3.Text & "%")
End If
if Not string.IsNullOrWhiteSpace(textBox4.Text) Then
sql = sql & "lager_warengewicht LIKE #p4 OR "
command.Parameters.AddWithValue("#p4", textBox4.Text & "%")
End If
if Not string.IsNullOrWhiteSpace(textBox5.Text) Then
sql = sql & "lager_waren_verkaufspreis LIKE #p5 OR "
command.Parameters.AddWithValue("#p5", textBox5.Text & "%")
End If
' Remove the last OR if any ....'
if sql.EndsWith(" OR ") then
sql = sql.Substring(0, sql.Length - 4)
End If
' Remove the WHERE if no textbox has been filled....'
if sql.EndsWith(" WHERE ") then
sql = sql.Substring(0, sql.Length - 7)
End If
command.CommandText = sql
reader = command.ExecuteReader()
Notice also that you should ALWAYS use a parameterized query to avoid Sql Injection particularly when you get your inputs directly from your user. (Not to mention the problems with typed texts that contain a single quote)
I hope I understand your problem correctly. I am sure there are better ways to do this and my VB is rusty but something like this may work
Dim query As String = "SELECT * FROM lager"
Function addField (ByVal query As String, ByVal value as String, ByVal field as String) As String
addField = query
If value <> "" Then
If query.IndexOf("where", 0, StringComparison.CurrentCultureIgnoreCase) > -1 Then
addField = query & " AND " & field & " LIKE '%" & value & "%'"
Else
addField = query & " WHERE " & field & " LIKE '%" & value & "%'"
End If
End If
End Function
query = addField(query, txtBox1.Text, "lager_waren_id")
query = addField(query, txtBox2.Text, "lager_warenanzahl")
'...continue adding fields...'
command.CommandText = query
This should make it so your query string only includes the populated fields

number of query values and destination fields not the same

hello I'm looking to just do a simple reason for what this is not working ... i have tried adding the same column twice, taking out the TextBox2 i just cant get it to work. all that works is if i take the last value out and the last column otherwise it will not work at all and i have now idea why.what i want is it to place a check mark in there to along with the name.
code:
Dim SqlText As String = "INSERT INTO tblEmployeeNames ([EmployeeName],
[UseForDropDown]) VALUES ('" & Trim(TextBox1.Text) & " " &
Trim(TextBox2.Text) & " " & (CheckBox1.Checked) & "')"
You have included the checkbox-state with the first value, you need to separate them with a comma.
Dim SqlText As String = "INSERT INTO tblEmployeeNames ([EmployeeName], [UseForDropDown]) VALUES ('" & Trim(TextBox1.Text) & " " & Trim(TextBox2.Text) & "', " & (CheckBox1.Checked))"
Notice the Checked state doesn't require apostrophes around it.
See SLaks comment as well, you should be using parameterized queries.