delete duplicate records from query vba - ms-access

I have built a query for duplicate records. I need to run some VBA code to check if the record is already in the table (query). If so, I need to delete the last record.
My form consists of a button with a value so that when you click the button, the data is insert into table
Dim qry As QueryDef
Set qry = CurrentDb.QueryDefs("duplicate records")
'which method do i use to see if the query got duplicate record'
With rstCategories
.MoveLast 0
End With
With rstCategories
rstCategories.Delete
End With
MsgBox "The problem already reported before!"

What I would do is run a quick query on your table:
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset ("SELECT * FROM MyTable WHERE MyValue = '" & Me.MyValue & "'")
If rec.EOF = true then
'No match found, so the value isn't in the table. Add it.
Else
'Match found. This value is already in the table.
MsgBox "This value is already in the table"
End If

ok i solved it
i created a query using the find duplicates query wizard.
then i insert this code in "form close"
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = Application.CurrentDb
Set rs = db.OpenRecordset("qry_Duplicates")
Do Until rs.EOF
rs.MoveFirst
rs.delete
rs.Close
Set rs = Nothing
Set rs = db.OpenRecordset("qry_Duplicates")
Loop
this code delete the entire row

Related

How can I auto select items in a multiselect listbox related to values in a table?

So far I have accomplished the opposite of this - I have entered records into a table based on selections made in the multiselect listbox. The multiselect listbox was named "lstboxColor" and the table was named tblColors. This was accomplished with the following code:
Set rs = New ADODB.Recordset
Dim itm As Variant
cnnLocal.CursorLocation = adUseClient 'avoid error 3705
'SET UP A LOOP TO ADD A COLOR RECORD IN THE COLORS TABLE FOR EACH SELECTED COLOR
rs.Open "tblColors", cnnLocal, adOpenDynamic, adLockOptimistic
For Each itm In lstboxColor.ItemsSelected
rs.AddNew
rs!CrayonID = CrayonID_HOLD
rs!ColorID = lstboxColor.ItemData(itm)
rs.Update
Next
rs.Close
So, now I would like to do the reverse of this - I need to open a form with a listbox and have the items in the multiselect listbox automatically be pre-selected based on the values in the table. Just can't seem to figure out the method needed other than looping through the table and using an if statement and .Selected = true. Any ideas? Thank you in advance.
EDIT: Added current code that is almost working. Changed what I need to do - I am using 3 tables and having a combobox selection auto select rows in the listbox. The code is going in the combobox's AfterUpdate(). I added "Else: If rs.NoMatch Then .Selected(i) = False" - but that's not the problem. Thinking it may be the SQL query, but that same query pulls up the correct answer in a Subform, so I know the query works. Could it be the query that I am using for the listbox rows (which is only selecting EquipmentID and Equipment name from tblEquipment)? Please let me know what you think about the reason why it may only be highlighting one row in the listbox.
EDIT: This code is working for 3 tables. The selection in the combobox auto selects the correct rows in the listbox. Solution is marked for the 2 table version(or one table), but same concept.
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim i As Integer
Dim strSQL As String
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT tblMusicEquipment.EquipmentID, *
FROM tblMusic
INNER JOIN (tblEquipment INNER JOIN tblMusicEquipment
ON tblEquipment.EquipmentID = tblMusicEquipment.EquipmentID)
ON tblMusic.InstrumentID = tblMusicEquipment.InstrumentID
WHERE (((tblMusic.InstrumentID))) = " & [cboSelectInstrument])
With Me.LstEditEquip
For i = 0 To .ListCount - 1
rs.FindFirst "EquipmentID =" & .ItemData(i)
If Not rs.NoMatch Then
.Selected(i) = True
Else: If rs.NoMatch Then .Selected(i) = False
End If
Next
End With
Have to loop through listbox and compare to a value to determine selection. In your case, do a FindFirst on recordset. If match found then select item. Assuming value to match is a numeric key, consider:
Dim rs As DAO.Recordset, i As Integer
Set rs = CurrentDb.OpenRecordset("SELECT ColorID FROM tblColors WHERE CrayonID_HOLD=" & Me.CrayonID_HOLD)
With Me.lstboxColor
For i = 0 To .ListCount - 1
rs.FindFirst "ColorID = " & .ItemData(i)
.Selected(i) = Not rs.NoMatch
Next
End With

Access VBA: Scripting.Dictionary - Dump to Table?

Thanks to the helpful hand provided earlier, I have a functional approach to compute Word Frequency among strings in a recordset. The following code produces the desired result.
Last step will be to dump the dictionary structure into an Access table in the currentDB. I can step thru each key as commented out below and append to a table via SQL - but it is very slow w/24K terms.
UPDATED >> w/Solution <<
Private Sub Command0_Click()
Dim counts As New Scripting.Dictionary
Dim word As Variant
Dim desc As String
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset '<< solution
Dim strSQL As String
Dim db As Database
Set db = CurrentDb
strSQL = "SELECT DISTINCT Items.Description FROM Items ;"
Set rs1 = db.OpenRecordset(strSQL, dbOpenDynaset)
Do While Not rs1.EOF
For Each word In Split(rs1!Description, " ")
If Not counts.Exists(word) Then
counts.Add word, 1
Else
counts.Item(word) = counts.Item(word) + 1
End If
Next
rs1.MoveNext
Loop
'>> .AddNew Solution inserted as suggested below <<
rs2 = db.OpenRecordset("Freq", dbOpenTable)
For Each word In counts.Keys
With rs2
.AddNew ' Add new record
.Fields!Term = word
.Fields!Freq = counts(word)
.Update
.Bookmark = .LastModified
End With
Next
rs2.Close
'>> End Solution <<
Set rs1 = Nothing
Set rs2 = Nothing
MsgBox "Done"
End Sub
Question:
Can I dump the Dictionary into a table in BULK, vs stepping thru the Keys one-by-one?
Rationale: Easier (for me) to perform downstream presentation & manipulation using a table structure.
Thanks!
Your code doesn't show how you tried to insert the rows - with separate INSERT INTO (...) VALUES (...) statements for each row, I assume?
For multiple inserts in a loop, don't use SQL INSERT statements. Instead use a DAO.Recordset with .AddNew, it will be much faster.
See this answer: https://stackoverflow.com/a/33025620/3820271
And here for an example: https://stackoverflow.com/a/36842264/3820271

RecordSet and Ms Access 2007

I have a query that has CustID with mutiple Business affiliated with the CustID. I can't use Dlookup because it only returns one variable. I want to show on a form that for this custID, here are all the businesses it's affiliated it. I want the Businesses to show up into a field (business) in another table on the form.
I started out by this
Public Sub OpenRecordset()
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("Q:businesses")
Do While Not rs.EOF
T:Custinfo!business = NAME (I am lost in between on how to identify the custid and place the businesses into the table field as a Dlookup)
rs.movenext
Loop
rs.Close
Set rs = Nothing
db.Close
End Sub
I keep looking at other examples but can't seem to tie together where the dlookup replacement will take place and how will you have to put this on a form as a datasheet?
You don't need a DLookup. You could do one of two things:
1) Use a listbox and set the recordsource equal to your query (assuming Q:businesses has been appropriately defined to give the businesses as a result)
2) Still need your query to be appropriate, but you could create a string with all of the businesses in it:
Public Sub OpenRecordset()
Dim db As Database
Dim rs As Recordset
Dim StrBusinesses As String
Set db = CurrentDb
Set rs = db.OpenRecordset("qryBusinesses")
If rs.EOF and rs.BOF Then
MsgBox("No businesses exist for this Customer")
Exit Sub 'Or do whatever else you want if there are no matches
Else
rs.MoveFirst
End If
StrBusinesses = ""
Do While Not rs.EOF
StrBusinesses = StrBusinesses & rs!Business & ", "
rs.movenext
Loop
rs.Close
StrBusinesses = Left(StrBusinesses, Len(StrBusinesses) - 2)
Forms!MyForm.MyField = StrBusinesses 'Set the field equal to the string here
Set rs = Nothing
db.Close
End Sub
Of course this assumes that the query "Q:Business" is defined to get the appropriate info such as:
SELECT custID, business FROM tblBusinesses WHERE custID = X
where "X" is the custID you are looking for.
If you need to set the query dynamically, you will need to set a querydef.
EDIT to include querydef code***********************
Also changed the name of the query to "qryBusinesses" in the code above and below as I'm not sure whether you can make a query with a colon in it.
To set the querydef, put this at the beginning of the code:
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("qryBusinesses")
qdf.SQL = "SELECT custID, business FROM tblBusinesses" _
& " WHERE custID = " & Forms!MyForm.CustID 'replace with actual form and field
This assumes that i) qryBusinesses exists already,
ii) custID is a number field
EDIT**************
If you define the query to look at the form itself, you would not need to set the sql, so if the query were defined (either in VBA or through the query wizard) as:
qdf.sql = "SELECT custID, business FROM tblBusinesses" _
& " WHERE custID = Forms!MyForm.CustID"
then you would not need to redefine the sql. However, it is a bit more dynamic to put the custID into the qdf itself as it is easier to debug any issues as you can see the exact sql that is being run in the original method.

Using access vba to check if table column has null values

I'm trying to find if the specified column has null values or no data.if null values are present in the column then gives the message box to user saying column contain nulls.
My vba
Dim sqlid As String
Dim rst As Recordset
Dim cdb As Database
Set cdb = CurrentDb
SQLEID = "SELECT * " & _
"FROM table_1 ;"
'
Set rst = cdb.OpenRecordset(sqlid , dbOpenSnapshot)
Do While Not rst.EOF
If IsNull(rst.Fields("column1").Value) Then
MsgBox "Has nulls"
End If
Loop
rst.Close
Set rst = Nothing
Set cdb = Nothing
But when i'm running this my access goes not responding. How do i check if the column has any nulls using vba
It hangs as your recordset is not being incremented, you need a MoveNext
Do While Not rst.EOF
If IsNull(rst.Fields("column1").Value) Then
MsgBox "Has nulls"
End If
rst.MoveNext
Loop
Simoco had a better suggestion for accomplishing this,
If DCount(1, "table_1", "IsNull([column1])")>0 Then
MsgBox "Has nulls"
End If

How to search a field in a table in Access

Using VBA, how can I search for a text string, for example "CHIR", in a table called "ServiceYES", in the field "Service".
After that, I would like to save the neighboring field for all the rows that "CHIR" exists in the table "ServicesYES". The "ServiceYES" table is below:
I basically, want to find all the "CHIR" in "Service" column and then save the names which are on the left of the CHIR, eg "FRANKL_L", "SANTIA_D" as an array.
Thanks for all your help in advance.
Start by creating a SELECT query.
SELECT Code_Perso
FROM ServicesYES
WHERE Service = 'CHIR';
Use SELECT DISTINCT Code_Perso if you want only the unique values.
Add ORDER BY Code_Perso if you care to have them sorted alphabetically.
Once you have a satisfactory query, open a DAO recordset based on that query, and loop through the Code_Perso values it returns.
You don't need to load them directly into your final array. It might be easier to add them to a comma-separated string. Afterward you can use the Split() function (assuming you have Access version >= 2000) to create your array.
Here's sample code to get you started. It's mostly standard boiler-plate, but it might actually work ... once you give it "yourquery".
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strItems As String
Dim varItems As Variant
Set db = CurrentDb
Set rs = db.OpenRecordset("yourquery", dbOpenSnapshot)
With rs
Do While Not .EOF
strItems = strItems & "," & !Code_Perso
.MoveNext
Loop
.Close
End With
If Len(strItems) > 0 Then
' discard leading comma '
strItems = Mid(strItems, 2)
varItems = Split(strItems, ",")
Else
MsgBox "Oops. No matching rows found."
End If
Set rs = Nothing
Set db = Nothing
I tested this and it seems to work. This function will pull all records where ServiceYes='CHIR' and dump the Code_Person value into an array which it will return:
Function x() As String()
Dim rst As Recordset
Set rst = CurrentDb.OpenRecordset( _
"Select * from ServiceYES where Service='CHIR'")
Dim Arr() As String
Dim i As Integer
While rst.EOF = False
ReDim Preserve Arr(i)
Arr(i) = rst.Fields("Code_Person")
i = i + 1
rst.MoveNext
Wend
x = Arr
End Function
Sample Usage:
Debug.Print x()(0)
Paolo,
Here is something I threw together in a few minutes. You can add it to the VBA editor in a module. It uses a trick to get the RecordCount property to behave properly. As for returing the array, you can update the function and create a calling routine. If you need that bit of code, just post a comment.
Thanks!
Option Compare Database
Function QueryServiceYES()
Dim db As Database
Dim saveItems() As String
Set db = CurrentDb
Dim rs As DAO.Recordset
Set rs = db.OpenRecordset("SELECT Code_Perso, Service, Favorites " & _
"FROM ServiceYES " & _
"WHERE Service = 'CHIR'")
'bug in recordset, MoveFirst, then MoveLast forces correct invalid "RecordCount"
rs.MoveLast
rs.MoveFirst
ReDim Preserve saveItems(rs.RecordCount) As String
For i = 0 To rs.RecordCount - 1
saveItems(i) = rs.Fields("Code_Perso")
rs.MoveNext
Next i
'print them out
For i = 0 To UBound(saveItems) - 1
Debug.Print saveItems(i)
Next i
rs.Close
Set rs = Nothing
db.Close
Set db = Nothing
End Function