How to avoid duplicate entries in database access - vb.net

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

Related

Conditional increasing ID in ms access formular

i have a ms access formular where there are given several Information. For "Status" Combobox there are several options like "1","2","3","4". If "4" is selected in "cbx_Status" then I want to add in Textbox "txt_ID_Order" an automatically increased ID and give an Order Time in textbox "txt_OrderTime". That's why I wrote this and works well:
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Me.cbx_Status.Value = "4" Then
Me.txt_OrderTime = Now()
Me.txt_ID_Order = DMax("[ID_Order]", "tblX") + 1
Else:
Me.txt_ID_Order=""
Me.txt_OrderTime = ""
End If
End Sub
However, if Status "4" is for some reason changed and again selected , I want to keep that old ID. But right know wenn i do that, it's still increasing ID.
How can I fix it?
Thanks
Check for a value:
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Me!cbx_Status.Value = "4" Then
If IsNull(Me!txt_OrderTime.Value) Then
Me!txt_OrderTime.Value = Now()
Me!txt_ID_Order.Value = DMax("[ID_Order]", "tblX") + 1
End If
Else
Me!txt_ID_Order.Value = Null
Me!txt_OrderTime.Value = Null
End If
End Sub
Not sure about the logic though; if you select anything else than 4, the textboxes will be cleared.

Take list box selection, add value to other list box without allowing duplicates

I have two list boxes on a form I am making. The first list box is linked to a table with various company names. The goal I am after is after double clicking a companies name, the value is inserted in the second list box.
It worked fine until I tried to add code to prevent duplicates from appearing in the second list box, so you couldn't accidentally insert the same company twice. I have tried several different iterations, but with no luck. Anyone able to help with this one? My end goal would be for a msgbox to pop up alerting the user that duplicates are not allowed.
Private Sub ContractorLstbx_DblClick(Cancel As Integer)
Dim found As Boolean
found = False
Dim ID As Long
Dim Contractor As String
For Each newItem In Me.ContractorLstbx.ItemsSelected
For j = 0 To Me.SelectedContractorLst.ListCount - 1
If (Me!ContractorLstbx.ItemData(newItem).Column(1) = Me.SelectedContractorLst.ItemData(j).Column(1)) Then
found = True
Exit For
End If
Next j
If found = False Then
ID = Me.ContractorLstbx.ItemData(newItem)
Me.SelectedContractorLst.AddItem ContractorLstbx!.ItemData(newItem).Column(0) & ";" & Me!ContractorLstbx.ItemData(newItem).Column(1)
End If
found = False
Next newItem
End Sub
This is the full code for your solution. I tried it on test sample and working fine. just copy and paste the code. If you need your comparison to be case sensitive (I mean A <> a) then use Option Compare Binary as in my code below. If it is required to be case insensitive (A = a) just leave the default Option Compare Database or better force it using Option Compare Text
Option Compare Binary
Private Sub ContractorLstbx_DblClick(Cancel As Integer)
Dim found As Boolean
found = False
Dim ID As Long
Dim Contractor As String
For i = 0 To Me.ContractorLstbx.ItemsSelected.Count - 1
For j = 0 To Me.SelectedContractorLst.ListCount - 1
If (Me.ContractorLstbx.Column(1, Me.ContractorLstbx.ItemsSelected(i)) = Me.SelectedContractorLst.Column(1, j)) Then
found = True
Exit For
End If
Next j
If found = False Then
ID = Me.ContractorLstbx.ItemData(Me.ContractorLstbx.ItemsSelected(i))
Me.SelectedContractorLst.AddItem (ContractorLstbx.Column(0, Me.ContractorLstbx.ItemsSelected(i)) & ";" & Me.ContractorLstbx.Column(1, Me.ContractorLstbx.ItemsSelected(i)))
End If
found = False
Next i
End Sub

Listbox.List(i) error - Method or Data Member not Found

I'm trying to use a multi-select listbox so users can select cleaning tasks they have completed and mark them as done. While looping through the list I want to see if the item is selected and create a record if so. When I try to use the .List method to return the data from a specific row, I keep getting the method not found error.
I originally did not have the forms 2.0 library loaded so I thought that was the issue, but that did not resolve the problem. I've also compacted and repaired thinking it might just be an odd fluke, but that did not help either.
'loop through values in listbox since its a multi-select
For i = 0 To listCleaningTasks.ListCount - 1
If listCleaningTasks.Selected(i) Then
'add entry to cleaning log
Set rsCleaning = CurrentDb.OpenRecordset("SELECT * FROM cleaning_log;")
With rsCleaning
.AddNew
.Fields("cleaning_task_id") = Form_frmCleaning.listCleaningTasks.List(i)
.Fields("employee_id") = Me.cmbUser
.Fields("cleanroom_id") = Me.cmbCleanroom
.Fields("cleaning_time") = Now()
.Update
.Close
End With
End If
Next i
Any ideas?
Use .listCleaningTasks.ItemData(r) to pull bound column value from row specified by index.
Use .listCleaningTasks.Column(c, r) to pull value specified by column and row indices.
Open and close recordset only one time, outside loop.
Really just need to loop through selected items, not the entire list.
Dim varItem As Variant
If Me.listCleaningTasks.ItemsSelected.Count <> 0 Then
Set rsCleaning = CurrentDb.OpenRecordset("SELECT * FROM cleaning_log")
With rsCleaning
For Each varItem In Me.listCleaningTasks.ItemsSelected
`your code to create record
...
.Fields("cleaning_task_ID") = Me.listCleaningTasks.ItemData(varItem)
...
Next
.Close
End With
Else
MsgBox "No items selected.", vbInformation
End If
Of course the solution of June7 is correct. If you need to store the selected items and then later recall and re-select the list box items, consider to get the selected items comma delimited using this function
Public Function GetSelectedItems(combo As ListBox) As String
Dim result As String, varItem As Variant
For Each varItem In combo.ItemsSelected
result = result & "," & combo.ItemData(varItem)
Next
GetSelectedItems = Mid(result, 2)
End Function
Store it into one column of a table and after reading it back pass it to this sub:
Public Sub CreateComboBoxSelections(combo As ListBox, selections As String)
Dim N As Integer, i As Integer
Dim selectionsArray() As String
selectionsArray = Split(selections, ",")
For i = LBound(selectionsArray) To UBound(selectionsArray)
With combo
For N = .ListCount - 1 To 0 Step -1
If .ItemData(N) = selectionsArray(i) Then
.Selected(N) = True
Exit For
End If
Next N
End With
Next i
End Sub
This will select items in your ListBox as they were before.

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.

For loop for bowling score array

I am trying to create a bowling program that will display the scores given in a multi-line text box. I've manage to get the program giving an output, but when it runs it skips asking for new inputs and just gives 5 0s on seperate lines and nothing else. I'm completely lost, any help is very much appreciated
EDIT: Sorry should have changed errors to reflect the programs changes, it looks like this now. It gives 0's instead of using the value I gave it, but it does ask for each input now.
For gameNumber As Integer = 1 To 5 Step 1
lblEnterScore.Text = "Enter Score for game #" & gameNumber
Dim Testint As Integer ' define an Integer for testing
Try
Testint = CInt(txtScoreInput.Text) ' try to convert whatever they entered to Int
Catch
MessageBox.Show("Entry is not an Integer") ' If you are here then the CInt failed for some reason, send a message
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End Try
If txtScoreInput.Text.Contains(".") Then
MsgBox("Bowling Score must be a whole number.")
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End If
If txtScoreInput.Text > MAXIMUM_SCORE Or txtScoreInput.Text < MINIMUM_SCORE Then
MsgBox("Bowling Score must be between 1 and 300.")
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End If
scoreInput(gameNumber) = CInt(txtScoreInput.Text)
' and store it in the array
' and increment the gamecounter for the next time through the loop
Next
'btnEnterScore.Enabled = False
' place the good score into the multi-line textbox
txtScoreOutputs.Text = gameScore & vbCrLf & txtScoreOutputs.Text
End Sub
If it was me, here's what I would do... Just a suggestion; I also cut out over half of your code and stopped it from throwing exceptions as well... You can put this in a click event or where ever you need it as well. You can modify this as well to take as many as you want from user input as well not just limit them from entering score's. Your user also has the option to get out of that loop when they choose to do so as well, not keeping them inside the loop...
Private ScoreLists As New List(Of Integer) 'Hold your inputted values
Private Const MAXIMUM_SCORE As Integer = 300 'Max score
Private Const MINIMUM_SCORE As Integer = 1 'Min score
Private blnStop As Boolean = False
Try
For gameNumber As Integer = 1 To 5
Dim intScore As Integer = 0
Do Until (intScore >= MINIMUM_SCORE And intScore <= MAXIMUM_SCORE) OrElse blnStop
If Not Integer.TryParse(InputBox("Please enter a score for game # " & gameNumber.ToString), intScore) Then
If MsgBox("Bowling Score must be a whole number. Stop getting scores?.", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
blnStop = True
Exit For
End If
End If
Loop
ScoreLists.Add(intScore)
Next
'Display the results...
For i As Integer = 0 To ScoreLists.Count - 1
txtScoreOutputs.Text &= ScoreLists.Item(i.ToString)
Next
ScoreLists.Clear()
Catch ex As Exception
End Try
Construct your logic like this (pseudo):
Loop
{
AskUserForInput()
ProcessUserInput()
}
The loop part will control how many scores the user is prompted to enter. The AskUserForInput() function will prompt the user to type in a new score, and the ProcessUserInput() function will get the value and store it in an array or print it to the screen, etc.
Your current logic is not waiting for any new user input before trying to add to the scores. You are also getting zeros because you're setting the txtScoreOutputs with gameScore, which doesn't look like it's been set to the user's input.