Access claiming duplicate record with no unique fields updated with Update Recordset/Addnew - vba

I'm trying to allow my client to add a bunch of dates in a row with the few fields copied. None of these fields are unique in the table but it keeps flagging them as duplicates records. When I got into the the table the new records are not added to the table despite there not being any duplicates.
This is the code (edited for silly mistakes)
Public Sub Create_Click()
Dim rsEventDayGroup As DAO.Recordset
Dim NextDate As Date
Set rsEventDayGroup = CurrentDb.OpenRecordset("Select * From tblEventDays")
NextDate = Me!Start.Value
While DateDiff("d", NextDate, Me!End.Value) >= 0
rsEventDayGroup.AddNew
rsEventDayGroup!Start.Value = NextDate
rsEventDayGroup!EventID.Value = Forms!frmEvents.Controls!ID.Value
rsEventDayGroup!DayType.Value = Me!DayType.Value
rsEventDayGroup!Period.Value = Me!Period.Value
rsEventDayGroup.Update
NextDate = NextDate + 1
Wend
rsEventDayGroup.Close
Set rsEventDayGroup = Nothing
End Sub
I'm trying to copy fields EventID, DayType, and Period and create records for each day someone inputs. tblEventDays has it's own unique ID, called just "ID" that is an autonumber. I suspect it's the code screwing up somewhere, but as it was working just yesterday and I haven't changed it, I'm not sure what it could be. When I go to debug it highlights "rsEventDayGroup.Update" I've also tried changing Select * from the table with no luck.

Related

Selectively deleting duplicates from table based on field value in Access

I have the following table (ID column exists but not shown below) :
Email
Course
DateComplete
1#1.com
Running
01/01/2021
1#1.com
Running
1#1.com
Running
2#2.com
Walking
2#2.com
Walking
2#2.com
Walking
I'd like to know if it is possible to delete all duplicate (of Email&Course) records from my table, but also ensuring that no records with a value in DateComplete are deleted.
So after running the query I would have :
Email
Course
DateComplete
1#1.com
Running
01/01/2021
2#2.com
Walking
You just need a query with an aggregation such as
SELECT Email, Course, MAX(DateComplete) AS DateComplete
INTO [dbo].[new_table]
FROM [dbo].[current_table]
GROUP BY Email, Course
Run a loop that deletes the dupes:
Public Function DeleteDupes()
Const Sql As String = "Select * From Course Order By Email, Course, DateComplete Desc"
Dim Records As DAO.Recordset
Dim Values As String
Set Records = CurrentDb.OpenRecordset(Sql)
While Not Records.EOF
If Values <> Records!Email.Value & Records!Course.Value Then
Values = Records!Email.Value & Records!Course.Value
Else
Records.Delete
End If
Records.MoveNext
Wend
Records.Close
End Function

How to insert every Single date into table [duplicate]

hoping someone can help? I'm fairly new to Access 2016 and have been tasked with building a very simple booking system for our school's breakfast and after school clubs.
I have a table with a list of Children (primary key is ChildID), another table (CLUBS) lists the 5 clubs available, and a third table (BOOKINGS) connects the children to the clubs (ChildID, ClubID, DateRequested)
I have a simple form that enables me to select a child's name from a drop down box, then from a list choose a club, then enter the date required. This saves the record to the Bookings table.
This works fine, however to make it easier to use...I've added unbound Start and End Date fields in the form with a view to being able to quickly book a child in over a term..i.e. rather than having to add each day individually, I enter the child's name, choose a club and then enter start and end dates. Multiple records are created in the booking table with the Child ID, Club ID identical, but the DateRequested field varies.
We do need to store a record in the Bookings table for the child on each date so we can print a register for each day..as well as for invoicing/reporting.
From looking at VBA...I think I need to use the INSERT INTO command? Is the best way to do it? Also I need to make sure that dates within the range that are Sat/Sunday are ignored.
I'd really appreciate any guidance on this and pointers to which commands would work best...
This is where DAO shines. It is so much faster to run a loop adding records than calling a Insert Into multiple times.
Here is how:
Public Function PopulateBokings()
Dim rsBookings As DAO.Recordset
Dim NextDate As Date
Set rsBookings = CurrentDb.OpenRecordset("Select Top 1 * From Bookings")
NextDate = Me!StartDate.Value
While DateDiff("d", NextDate, Me!EndDate.Value) >= 0
If Weekday(NextDate, vbMonday) > 5 Then
' Skip Weekend.
Else
rsBookings.AddNew
rsBookings!ChildrenId.Value = Me!ChildrenId.Value
rsBookings!ClubsId.Value = Me!ClubId.Value
rsBookings!DateRequested.Value = NextDate
rsBookings.Update
End If
NextDate = DateAdd("d", 1, NextDate)
Wend
rsBookings.Close
Set rsBookings = Nothing
End Function
Paste the code into the code module of the form, adjust the field and control names to those of yours, and call the function from the Click event of a button.
Consider populating a separate DateRange table that holds all possible dates, like all of 2017. You can build such a table iteratively with dynamic SQL query calls in VBA. And only run this once.
Then, create a stored query that cross joins Children, Club, and DateRange with filters for all by form parameters. This returns all possible date ranges repeating same Child and Club for table append.
VBA
Public Sub PopulateTime()
Dim i As Integer, StartDate As Date
CurrentDb.Execute "CREATE TABLE DateRange (" _
& " [ID] AUTOINCREMENT PRIMARY KEY," _
& " [BookDate] DATETIME)", dbFailOnError
StartDate = DateSerial(2017, 1, 1)
For i = 0 To 364
CurrentDb.Execute "INSERT INTO DateRange ([BookDate])" _
& " VALUES (#" & DateAdd("d", i, StartDate) & "#);", dbFailOnError
Next i
End Sub
SQL
INSERT INTO Bookings (ChildID, ClubID, DateRequested)
SELECT c.ChildID, b.ClubID, d.BookDate
FROM Children c, Clubs b, DateRange d
WHERE c.ChildID = Forms!myformname!ChildID
AND b.ClubID = Forms!myformname!ClubID
AND d.BookDate BETWEEN Forms!myformname!StartDate
AND Forms!myformname!EndDate
You can use a sequence generator query to repeatedly insert rows into a table between two parameters.
For this example, the maximum number of days inserted is 999, but this can easily be increased to 9999 or even more.
Inspired by this answer by Gustav:
PARAMETERS [StartDate] DateTime, [EndDate] DateTime;
INSERT INTO MyTable(MyDateField)
SELECT DISTINCT [StartDate] - 1+ 100*Abs([Hundreds].[id] Mod 10) + 10*Abs([Tens].[id] Mod 10)+Abs([Ones].[id] Mod 10)+1
FROM MSysObjects As Ones, MSysObjects As Tens, MSysObjects As Hundreds
WHERE [StartDate] - 1+ 100*Abs([Hundreds].[id] Mod 10) + 10*Abs([Tens].[id] Mod 10)+Abs([Ones].[id] Mod 10)+1 Between [StartDate]-1 And [EndDate]
Performance won't be good, but there are multiple advantages using a non-VBA solution.

Date format problems when passing information from Access to Excel

just for documentation and future readers, the problem was solved and the answer is in the discussion between me and #varocarbas
My Application is reading a few columns from access data base and joining those columns into an existing datatable. one of the columns in the database has dates, the column is configured as date and time column in the database and in the data column of the datatable. the problem is when i am extrcting it into excel ,some of the dates are behaving in the oposite direction (i think the term is "english date"). what that i mean by "behaving", is that excel recognize the monthes as the days and the days as the months, for example a date that should be 11 in september 2015 the excel formula month(11/09/2015) is showing that the month is november and not september.
also, the date values in the access column are from sharepoint list that is also configured as dateandtime.. i have a filling that this behaving maybe belongs to excel(?),
here is the importent parts of my code:
' declaring the dateandtime column
Dim colString As DataColumn = New DataColumn("changed")
colString.DataType = System.Type.GetType("System.DateTime")
UnitedTable.Columns.Add(colString)
Storing it from the database:
If Not (IsDBNull(UnitedTable.Rows(i).Item("spcall"))) Then
spcall = UnitedTable.Rows(i).Item("spacll")
rowNum = Searchbinary(spcall) ' check that spcall exist in Projects table via binary search
If rowNum > -1 Then
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("PmUserName").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("OpertionalStatus").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("CrmCallNum").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("OperationStart").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("Approved").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("GeneralStatus").ToString
UnitedTable.Rows(i).Item("changed") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("Changed")
Else
' the spcall not exist add it to arraylist
SpCalls_NotExist.Add(spcall)
'UnitedTable.Rows(i).Delete()
End If
Then I am populating it to excel with nested loop.

Access SQL Randomizer Not working as intended

I'm using the below mentioned code to select a record ID from an Access Database that wasn't already selected in the last day and add it to an array.
The general goal is that a record that matches the initial "Difficulty" criteria will be retrieved so long as either the record was never selected before OR the record wasn't chosen in the last 2 days. After the loop is done, I should have x amount of unique record ID's and add those onto an array for processing elsewhere.
Private Function RetrieveQuestionID(questionCount As Integer)
' We're using this retrieve the question id's from the database that fit our arrangements.
Dim intQuestArray(0 To questionCount) As Integer
Dim QuestionConnection As New OleDb.OleDbConnection("PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source = |DataDirectory|\Database\MillionaireDB.accdb;")
QuestionConnection.Open()
For i As Integer = 1 To intNoOfQuestions
'TODO: If there are no valid questions, pull up any of them that meets the difficulty requirement....
Dim QuestionConnectionQuery As New OleDb.OleDbCommand("SELECT Questions.QuestionID FROM Questions WHERE (((Questions.QuestionDifficulty)=[?])) AND (((Questions.LastDateRevealed) Is Null)) OR (Questions.LastDateRevealed >= DateAdd('d',-2,Date())) ORDER BY Rnd((Questions.QuestionID) * Time());", QuestionConnection)
QuestionConnectionQuery.Parameters.AddWithValue("?", intQuestionDifficulty(i - 1).ToString)
Dim QuestionDataAdapter As New OleDb.OleDbDataAdapter(QuestionConnectionQuery)
Dim QuestionDataSet As New DataSet
QuestionDataAdapter.Fill(QuestionDataSet, "Questions")
intQuestArray(i - 1) = QuestionDataSet.Tables("Questions").Rows(0).Item(0)
Dim QuestionConnectionUpdateQuery As New OleDb.OleDbCommand("UPDATE Questions SET Questions.LastDateRevealed = NOW() WHERE Questions.QuestionID = [?]", QuestionConnection)
QuestionConnectionUpdateQuery.Parameters.AddWithValue("?", intQuestArray(i - 1).ToString)
QuestionConnectionUpdateQuery.ExecuteNonQuery()
Next
QuestionConnection.Close()
Return intQuestArray
End Function
However, looping through the array will show that there are records are somehow being repeated even though the record updates during the loop.
Is there another way to loop through the database and pull up these records? I even attempted to move the .Open() and .Close() statements to within the For...Next loop and I'm given worse results than before.
As Steve wrote, the >= should be a < .
In addition, your WHERE clause is missing parentheses around the OR part.
It should be (without all unnecessary parentheses):
SELECT Questions.QuestionID
FROM Questions
WHERE Questions.QuestionDifficulty=[?]
AND ( Questions.LastDateRevealed Is Null
OR Questions.LastDateRevealed < DateAdd('d',-2,Date()) )
ORDER BY Rnd(Questions.QuestionID * Time());
Also have a look at How to get random record from MS Access database - it is suggested to use a negative value as parameter for Rnd().

populate array list from For loop using entire database table row

I am trying check my Events table for DateTime overlaps in each of the events. I have written code that will allow a user to input a Module_code. This Module_code is checked against the entries in the Events table. If Start_Date_Time or End_Date_Time for any of the events overlap with the Start_Date_Time or End_Date_Time of any other event in the table, for that module only, then I want to put the event row into an array list and later populate a gridview with the results. I have the following code, which I think achieves most of my goals. However when I run it the gridview there is no data in it. Debug shows that nothing was sent to it. I presume it is a problem with how I am trying to pass my values to the arrayList.
'return all relevant tables from the Modules database, based on the module code entered by the user.
Dim eventTime = (From mods In db.Modules
Join evnt In db.Events On mods.Module_code Equals evnt.Module_code
Join rm In db.Rooms On rm.Room_ID Equals evnt.Room_ID
Join build In db.Buildings On build.Building_code Equals rm.Building_code
Where ((mods.Module_code = initialModCode) And (evnt.Room_ID = rm.Room_ID))
Select evnt.Event_ID, evnt.Module_code, evnt.Event_type, evnt.Start_Date_Time, evnt.End_Date_Time, build.Building_code, rm.Room_Number)
Dim listClashes As New ArrayList()
For i As Integer = 0 To eventTime.Count - 1
For j As Integer = i + 1 To eventTime.Count - 1
If (eventTime.ToList(i).Start_Date_Time < eventTime.ToList(j).End_Date_Time) And (eventTime.ToList(i).End_Date_Time > eventTime.ToList(j).Start_Date_Time) Then
'MsgBox("Clash", MsgBoxStyle.MsgBoxSetForeground, "")
listClashes.Add(eventTime)
Else
'MsgBox("No Clash", MsgBoxStyle.MsgBoxSetForeground, "")
End If
Next
Next
gdvClashes.DataSource = listClashes
gdvClashes.DataBind()
EDIT..Code changed to
If (eventTime(i).Start_Date_Time <= eventTime(j).End_Date_Time) And (eventTime(i).End_Date_Time >= eventTime(j).Start_Date_Time) Then
'MsgBox("Clash", MsgBoxStyle.MsgBoxSetForeground, "")
listClashes.Add(eventTime.ToList)
Else
This edit has not worked. It is throwing an exception to say that The query operator 'ElementAtOrDefault' is not supported. Am I going in the totally wrong direction here?
EDIT..
New code suggestion
Dim listClashes = From e1 In eventTime
From e2 In eventTime
Where (e2.Start_Date_Time >= e1.Start_Date_Time) And (e2.Start_Date_Time <= e1.End_Date_Time)
Select eventTime
gdvClashes.DataSource = listClashes
gdvClashes.DataBind()
Should this be enclosed in a for loop or referencing an arrayList or something?
Your nested loop is only confusing. You can do everything in one query:
Dim listClashes =
From e1 in eventTime
From e2 in eventTime
Where e2.Start_Date > e1.Start_Date && e2.Start_Date < e1.End_Date
Select (...)
Which is: you find events that have their start date between the startdate and enddate of other events.
Since eventTime is an IQueryable the whole statement listClashes is translated to one SQL query and in the end the database engine does all the hard work and your client code only receives the results.