VB.NET not deleting records from SQL DB - sql

I'm having some rather annoying issues with an app I'm trying to write.
I have a DB with a small table ("main") that i entered data into manually when i created the table. I can delete one of the 3 rows that I manually inputted, no problem, but if I add a row from the app it doesn't save to the database and I can't delete it.
Additionally, none of the values that I've edited save to the DB. I suspect that these two issues are related and was hoping you could help me figure out what's wrong.
here's the code for the "delete" button:
Private Sub btnSearchDelete_Click(sender As Object, e As EventArgs) Handles btnSearchDelete.Click
Try
Me.MainTableAdapter.Delete(searchIP.Text, searchSubnet.Text, searchVLAN.Text, searchAlive.Checked, searchReserved.Checked, searchUser.Text, searchDate.Text, searchFail.Text)
' updates system message bar for 1 second
Dim tmCurTime As DateTime = Date.Now
Dim wait As Int16 = 1 ' Time in seconds
Do
sysmsg.Text = "Deleted record."
sysmsg.ForeColor = Color.Red
Application.DoEvents()
Loop Until DateDiff(DateInterval.Second, tmCurTime, Date.Now) = wait
sysmsg.Text = ""
Catch ex As Exception
MsgBox("Delete failed!" - ex.Message)
End Try
Ds.AcceptChanges()
Me.MainTableAdapter.Update(Me.Ds.main)
'clears search filter
Me.MainBindingSource.Filter = Nothing
Me.MainTableAdapter.Fill(Me.Ds.main)
grid.Refresh()
End Sub
(grid is referring to the datagridview on the main app page)
i realize my code is probably, um, extremely messy -- I'm super new the development side of things and this is only the 3rd app I've worked on so far.
Any help you could give would be appreciated.
::EDIT::
ok, so this is what MainTableAdapter.Delete() is calling in SQL-speak:
DELETE FROM [dbo].[main] WHERE (([IP] = #Original_IP) AND ((#IsNull_SUBNET = 1 AND [SUBNET] IS NULL) OR ([SUBNET] = #Original_SUBNET)) AND ((#IsNull_VLAN = 1 AND [VLAN] IS NULL) OR ([VLAN] = #Original_VLAN)) AND ((#IsNull_ALIVE = 1 AND [ALIVE] IS NULL) OR ([ALIVE] = #Original_ALIVE)) AND ((#IsNull_RESERVED = 1 AND [RESERVED] IS NULL) OR ([RESERVED] = #Original_RESERVED)) AND ((#IsNull_USR = 1 AND [USR] IS NULL) OR ([USR] = #Original_USR)) AND ((#IsNull_DATE = 1 AND [DATE] IS NULL) OR ([DATE] = #Original_DATE)) AND ((#IsNull_FAIL = 1 AND [FAIL] IS NULL) OR ([FAIL] = #Original_FAIL)))

Related

How to avoid duplicate entries in database access

I'm creating a Registration form
How can i Prevent a data from duplicating when i save a data to my Ms access Database , something like Error handling for duplicate data or same First Name/Last Name and a message box that says there's a duplicated data.
As for now this is the code that i saw someone uses.
For i As Integer = 0 To DataGridView1.Rows.Count - 1
If Fname.Text = DataGridView1.Rows(i).Cells(0).Value.ToString() Then
MessageBox.Show("Duplicate Info")
Return
End If
Next
Do you guys have any suggestion , Thanks in Advance
This might be useful for what you asked, but personally I would check if Data matches the one in DB instead of DataGridView, because Users can edit them if you don't set ReadOnly property to true.
Private Sub DuplicatePrevention(datagridview As DataGridView, name As String)
Dim duplicateCount As Integer = 0
For i As Integer = 0 To datagridview.Rows.Count - 1
If datagridview.Rows(i).Cells(0).Value.ToString = name Then
duplicateCount += 1
End If
Next
If duplicateCount = 0 Then
'fire your Query
Else
MsgBox(name & " exist already", MsgBoxStyle.Information)
End If
End Sub

How to display my data from a text-file determined by a combo box?

I am trying to retrieve a surfer from a list on a textfile, the user selects the surfer from the combo box which then displays that surfers data in a bunch of labels. My code requires each surfer to have an ID for it to be able to know which record to retrieve from the database. However when I try to put my ID from my loop together with each surfers name, I receive an error saying "Conversion from string to type 'Long' is not valid." I have tried different methods of getting around this, none of which have worked. Here is my code:
Private Sub Lookup_Load(sender As Object, e As EventArgs) Handles MyBase.Load
madelabel = False
For i = 1 To maxrecJudge
FileGet(2, ajudge, i)
recnoJudge = i
judgename = recnoJudge And " " And ajudge.name
cmbJudge.Items.Add(judgename)
Next i
For i = 1 To maxrecSurfer
FileGet(1, asurfer, i)
recnoSurfer = i
surfername = recnoSurfer And " " And asurfer.name
cmbSurfer.Items.Add(surfername)
Next i
End Sub
Private Sub cmbSurfer_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbSurfer.SelectedIndexChanged
recnoSurfer = CInt(Val(New Text.StringBuilder((From ch In cmbSurfer.Text.ToCharArray Where IsNumeric(ch)).ToArray).ToString))
FileGet(1, asurfer, recnoSurfer)
If madelabel = False Then
lblName = New Label
lblName.Top = 160
lblName.Left = 253
lblName.Autosize = True
lblName.Text = asurfer.name
Me.Controls.Add(lblName)
End Sub
For simplicity I have only included one label creation above, but there are several labels spawned each with data of the surfer.
Am I on the right track with this? In the second sub my code extracts the integer (ID) from the combo box which then is used as a record number to find the rest of the data. The error relates to these lines:
surfername = recnoSurfer And " " And asurfer.name
cmbSurfer.Items.Add(surfername)
It won't let me concatenate the ID and the surfers name. Any help?
If you are doing a lot of concatenation, use a StringBuilder. It is far quicker. Every time you concatenation strings, a new string is created. Over a large amount of iterations, StringBuilder is the better choice.

Adding new row to unbound datagridview

I have an unbound datagridview. Because of the various things I am doing with the data in the grid I do not want to bind it. The columns are predefined in the settings (Edit Columns) of the datagridview.
I want to create a new row and then populate the grid row with data. I am trying to use the .Add.Rows method but it is failing with
{"Index was out of range. Must be non-negative and less than the size of the collection." & vbCrLf & "Parameter name: index"}
The following SQL retrieves data:
USE CCAP
declare #ScheduleName as varchar(30) = 'Walk-In Center April Wk 1 2019'
Select ShiftName, ScheduleStart, ScheduleEnd, Position, ADP_ID1,
Name1,ADP_ID2, Name2, ADP_ID3, Name3, ADP_ID4, Name4, ADP_ID5,
Name5, ADP_ID6, Name6, ADP_ID7, Name7
from FormattedSchedules
where ScheduleName = #ScheduleName;
and the rowcount is greater than 0 so it is getting results.
I do not understand what index is out of range or why the collection is 0
Code is below:
Tried .Rows.Add(1) and .Rows.Add() and .Rows.Add("")
Dim FSchedCmd As SqlCommand
Dim FSchedSQL As String
Dim FSchedConn As New SqlConnection()
Dim FSchedadapter As New SqlDataAdapter()
Dim i As Integer = 0
Dim rowIndex As Integer
Dim row As DataGridViewRow
AddedNewRow = 1
Dim dsFSched As New DataSet()
FSchedSQL = "Select ShiftName, ScheduleStart, ScheduleEnd, Position, ADP_ID1, Name1, ADP_ID2, Name2, ADP_ID3, Name3, ADP_ID4, Name4, ADP_ID5, Name5, ADP_ID6, Name6, ADP_ID7, Name7 from FormattedSchedules where ScheduleName = #ScheduleName;"
Try
If GlobalVariables.logProd = 1 Then
GlobalVariables.strConnection = "CCAPProdConnectionString"
Else
GlobalVariables.strConnection = "CCAPTestConnectionString"
End If
FSchedConn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings(GlobalVariables.strConnection).ConnectionString
FSchedConn.Open()
FSchedCmd = New SqlCommand(FSchedSQL, FSchedConn)
FSchedCmd.Parameters.Add("#ScheduleName", SqlDbType.VarChar).Value = cboCreateScheduleName.Text
FSchedadapter.SelectCommand = FSchedCmd
FSchedadapter.Fill(dsFSched)
FSchedadapter.Dispose()
FSchedCmd.Dispose()
FSchedConn.Close()
'dgvCreateSchedule.DataSource = dsFSched.Tables(0)
dgvCreateSchedule.Rows.Clear()
With dgvCreateSchedule
Dim RowNo As Long = 0
'.RowCount = 0
While RowNo <= dsFSched.Tables(0).Rows.Count - 1
.Rows.Add(1)
.Rows(RowNo).Cells(0).Value = dsFSched.Tables(0).Rows(RowNo).Item(0) 'ShiftName
'.Rows(RowNo).Cells(1).Value = dsFSched.Tables(0).Rows(RowNo).Item(1) 'Start Time
.Rows(RowNo).Cells(1).Value = Convert.ToDateTime(dsFSched.Tables(0).Rows(RowNo).Item(1)).TimeOfDay
'.Rows(RowNo).Cells(2).Value = dsFSched.Tables(0).Rows(RowNo).Item(2) 'End Time
.Rows(RowNo).Cells(2).Value = Convert.ToDateTime(dsFSched.Tables(0).Rows(RowNo).Item(2)).TimeOfDay 'End Time
.Rows(RowNo).Cells(3).Value = dsFSched.Tables(0).Rows(RowNo).Item(3) 'Position
.Rows(RowNo).Cells(4).Value = dsFSched.Tables(0).Rows(RowNo).Item(4) 'ADP_ID1
.Rows(RowNo).Cells(5).Value = dsFSched.Tables(0).Rows(RowNo).Item(5) 'Name1
.Rows(RowNo).Cells(6).Value = dsFSched.Tables(0).Rows(RowNo).Item(6) 'ADP_ID2
.Rows(RowNo).Cells(7).Value = dsFSched.Tables(0).Rows(RowNo).Item(7) 'Name2
.Rows(RowNo).Cells(8).Value = dsFSched.Tables(0).Rows(RowNo).Item(8) 'ADP_ID3
.Rows(RowNo).Cells(9).Value = dsFSched.Tables(0).Rows(RowNo).Item(9) 'Name3
.Rows(RowNo).Cells(10).Value = dsFSched.Tables(0).Rows(RowNo).Item(10) 'ADP_ID4
.Rows(RowNo).Cells(11).Value = dsFSched.Tables(0).Rows(RowNo).Item(11) 'Name4
.Rows(RowNo).Cells(12).Value = dsFSched.Tables(0).Rows(RowNo).Item(12) 'ADP_ID5
.Rows(RowNo).Cells(13).Value = dsFSched.Tables(0).Rows(RowNo).Item(13) 'Name5
.Rows(RowNo).Cells(14).Value = dsFSched.Tables(0).Rows(RowNo).Item(14) 'ADP_ID6
.Rows(RowNo).Cells(15).Value = dsFSched.Tables(0).Rows(RowNo).Item(15) 'Name6
.Rows(RowNo).Cells(16).Value = dsFSched.Tables(0).Rows(RowNo).Item(16) 'ADP_ID7
.Rows(RowNo).Cells(17).Value = dsFSched.Tables(0).Rows(RowNo).Item(17) 'Name7
RowNo = RowNo + 1
End While
End With
If dgvCreateSchedule.RowCount > 0 Then
dgvCreateSchedule.Rows(0).Selected = True
dgvCreateSchedule.CurrentCell = dgvCreateSchedule.Rows(0).Cells(0)
'dgvCreateSchedule.FirstDisplayedScrollingRowIndex = dgvCreateSchedule.CurrentRow.Index
End If
Catch ex As Exception
MessageBox.Show("Cannot open FormattedSchedules to load grid")
End Try
AddedNewRow = 0
Error message from line: .Rows.Add(1)
Index was out of range. Must be non-negative and less than the size of the collection." & vbCrLf & "Parameter name: index
This should be the fastest option:
dgvCreateSchedule.Rows.Clear()
For Each xrow As DataRow In TempDataTable.dsFSched.Tables(0).Rows
dgvCreateSchedule.Rows.Add(xrow.ItemArray)
Next
What it does adds all "Cells" along with row.
And when editing cells, I prefer to use
dgvCreateSchedule(y,x).Value = somevalue
'Though it's a little bit strange, as it's column first then row for location hence y then x axis , opposed to usual row then column thats x then y axis
Add it like this, assuming there is the same column count/order
.Rows.Add(dsFSched.Tables(0).Rows(RowNo).ItemArray)
I changed the name of the DGV to DataGridView1 because that is what I happened to have in my test project.
You can use conditional compile statements to chose the correct connection string. Not necessary to keep a Boolean variable somewhere to determine correct string. I know I would forget to change it for the release version.
You did a good job closing and disposing of database objects but if there is an error all that good work will be for naught. A Using...End Using block will accomplish the close, dispose even if there is an error.
Pass the connection string directly to the constructor of the connection and pass the Sql statement and the connection directly to the constructor of the command.
Don't open your connection until the last minute. In the case of a DataAdapter.Fill, the connection is opened and closed for you however, if the adapter finds and open connection it leaves it open. In this case there is no need for an adapter or a DataSet.
I do not see anything wrong with your line .Rows.Add(1). The problem comes on the next line. The index of DataGridView.Rows is an Int32, Integer in vb.net, and you have declared RowNo as Long. Of course you will want to use the code suggested by #CruleD answer.
Private Sub OPCode()
Dim dt As New DataTable
Dim FSchedSQL = "Select ShiftName, ScheduleStart, ScheduleEnd, Position, ADP_ID1, Name1, ADP_ID2, Name2, ADP_ID3, Name3, ADP_ID4, Name4, ADP_ID5, Name5, ADP_ID6, Name6, ADP_ID7, Name7 from FormattedSchedules where ScheduleName = #ScheduleName;"
Try
#If Not DEBUG Then
GlobalVariables.strConnection = "CCAPProdConnectionString"
#Else
GlobalVariables.strConnection = "CCAPTestConnectionString"
#End If
Using FSchedConn As New SqlConnection(ConfigurationManager.ConnectionStrings(GlobalVariables.strConnection).ConnectionString)
Using FSchedCmd As New SqlCommand(FSchedSQL, FSchedConn)
FSchedCmd.Parameters.Add("#ScheduleName", SqlDbType.VarChar).Value = cboCreateScheduleName.Text
FSchedConn.Open()
dt.Load(FSchedCmd.ExecuteReader)
End Using
End Using
DataGridView1.Rows.Clear()
For Each xrow As DataRow In dt.Rows
DataGridView1.Rows.Add(xrow.ItemArray)
Next
If DataGridView1.RowCount > 0 Then
DataGridView1.Rows(0).Selected = True
DataGridView1.CurrentCell = DataGridView1.Rows(0).Cells(0)
End If
Catch ex As Exception
MessageBox.Show("Error loading grid")
End Try
End Sub

VB.NET - Unable to retrieve the first ID on a table using SELECT query

Good day everyone! After 3 years without using VB.NET I decided to use again for my project that not require web development.
this is my code (Reference: link)
cmdOLEDB.CommandText = "SELECT Price FROM tblPrice"
cmdOLEDB.Connection = cnnOLEDB
Dim rdrOLEDB As OleDbDataReader = cmdOLEDB.ExecuteReader
Dim priceList(18) As String
Dim i As Integer = 0
If rdrOLEDB.Read = True Then
While rdrOLEDB.Read()
priceList(i) = rdrOLEDB.GetValue(0)
i += 1
End While
txtPrice1.Text = priceList(0).ToString
cnnOLEDB.Close()
Else
MsgBox("Record not found.")
cnnOLEDB.Close()
End If
when I put this code in a MsgBox
MsgBox(rdrOLEDB.GetValue(0))
the result is "2" but I have 1 more data before that. It means the query retrieve the ID # 2 not the ID # 1. Here's the screenshot on my Access database
and when I use this code:
txtPrice1.Text = priceList(17).ToString
the result is 35.
You are skipping the first record because you call two times the Read method.
The first call reads the first record and returns true, then you enter the while loop extracting the info, but at this point you are on the second record.
If you want to check if there are rows then call HasRows
If rdrOLEDB.HasRows Then
While rdrOLEDB.Read()
priceList(i) = rdrOLEDB.GetValue(0)
i += 1
End While
txtPrice1.Text = priceList(0).ToString
cnnOLEDB.Close()
Else
MsgBox("Record not found.")
cnnOLEDB.Close()
End If
Please check with If condition , replace rdrOLEDB.Read with rdrOLEDB.hasrows
If rdrOLEDB.Hasrows= True Then
and check it again.

How to count Maximum rows in Visual Basic

I have the code for the next button. The data in the database show up normally.
The problem is when I click next button, the data will be repeated again as --> data1 > data2 > data3 > data1 > data2...
I've to been told that I should count the maximum rows but I didn't know how to do it; I've search for the coding as well, but nothing that I understand came out.
Please help me~~~ (I am not very good with English, sorry)
Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnNext.Click
btnBack.Enabled = True
da.Fill(dt)
If position >= 0 Then
position = position + 1
Me.lblID.Text = dt.Rows(position).Item("RefNo")
Me.txtboxName.Text = dt.Rows(position).Item("Name")
Me.rtxtboxAddress.Text = dt.Rows(position).Item("Address")
Me.txtboxContactNo.Text = dt.Rows(position).Item("ContNo")
Me.txtboxFaxNo.Text = dt.Rows(position).Item("FaxNo")
Me.txtboxBrand.Text = dt.Rows(position).Item("Brand")
Me.txtboxModel.Text = dt.Rows(position).Item("Model")
Me.txtboxSN.Text = dt.Rows(position).Item("SN")
Me.rtxtboxProblems.Text = dt.Rows(position).Item("Problems")
Me.rtxtboxTechRemark.Text = dt.Rows(position).Item("TechRemark")
Me.rtxtboxServChange.Text = dt.Rows(position).Item("ServiceChange")
Me.rtxtboxPartChange.Text = dt.Rows(position).Item("PartsChange")
Me.txtboxTotal.Text = dt.Rows(position).Item("TotalPrice")
End If
End Sub
I don't know if this is also need to be told, but... there is two different class
1) database.vb - sql coding
2) forms.vb - coding for my visual basic form
Please help me!!
THANKS EVERYONE WHO HELO ME WITH THE ANSWERS!! I HAVE FOUND THE SOLUTION OF THE QUESTION AFTER RE-FIGURED THE CODING.
I didn't figure out the position value and the row value is same. My value of position = 0 and dt.Rows.Count = 4, since I have 4 data; so when the position = 0, the row = 1. I get confused about that; I thought both value is starting with 0.
A bit more code... this is bad code... don't rely on it for production since I'm sure there are plenty of corner cases it doesn't handle, but I wanted to give you a picture of how you could handle it and at least a glimpse of stuff you might need to worry about (e.g. 0 rows in the data table). Please work through this and try to understand the code... don't simply copy/paste.
Private Sub btnNext_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnNext.Click
If position >= dt.Rows.Count Then
// No more rows to show after this one, so disable the next button
btnNext.Enabled = False
End If
// Put check for zero in btnBack.Click to make sure it doesn't go below 0
// I'm assuming position starts off at 0, and that you're showing the very
// first row by default
position += 1
// This is to handle a condition like having 0 rows in the data table,
// in which case don't want to do the next part...
If position > dt.Rows.Count Then Exit Sub
// Only necessary once really, but we'll do it each time anyway...
btnBack.Enabled = True
da.Fill(dt)
position += 1
// Update various textboxes and labels...
End Sub
dt.Rows.Count is the number of rows in the Rows collection. Anytime you want to check the whether you've reached the maximum number of rows compare the row count to dt.Rows.Count
da, dt, and position should be declared outside your sub above. The Fill statement should also be executed outside the sub.
In the sub:
If position >= 0 and position < dr.rows.count then
do stuff above
else
Beep ' out of range
end if