I am having problems coming up with a solution to the following problem:
I have a booking form, but when the user adds details I want to check my database to see if the exact vehicle has been booked out for those dates already. If it has, an error message would appear.
Your vehicles should have ID Numbers. So, when a user tries to book a vehicle, you check the ID against the table of booked vehicles. Something like this (aircode) should work:
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset ("SELECT CarID FROM tblBookedCars WHERE CarID = " & Me.cboCarsToBook.Selected & "")
If rec.EOF Then
'Your car isn't booked, so process your booking
Else
Msgbox "That car is already booked"
End If
Assuming that booked out cars have a start and end date, then a booking collision occurs when:
RequestStartDate <= EndDate
and
RequestEndDate >= StartDate
The above is thus a rather simply query, but if any collision occurs, the above will return records, and you simply don’t allow the booking. And this means you don’t have to maintain some huge “messy” table of cars and each date that the car is book. You ONLY need simple row attached to a given vehicle with the start and end date (and thus it easy to change dates - you only update the one booking reocrd.
Air code to build such a query will look much like this:
dim strWhere as string
dim dtRequeestStartDate as date
dim dtRequestEndDate as date
dim lngCarID as long
dtRequestStartDate = inputbox("Enter start Date")
dtRequestEndDate = inputbox("Enter end date")
lngCarID = inputbox("What car id")
strWhere="#" & format(dtRequestStartDate,"mm/dd/yyyy") & "# <= EndDate" & _
" and #" & format(dtRequestEndDate,"mm/dd/yyyy") & "# >= StartDate and CarID = " & lngCarID
if dcount("*","tableBooking",strWhere) > 0 then
msgbox "sorry, you cant book
...bla bla bla....
The above is just an example, and I am sure you would build a nice form that prompts the user for the booking dates. However, what is nice here is that the above simple query will return ANY collision.
Related
I am creating a database to manage the flow of people in and out of an incident system. My idea is to use the DLookup function to allow me to identify a null value in the checkout date. This would allow me to prevent someone from jumping incidents without signing out first.
If it is possible I would like to get the EVENT ID and the COMMAND POST ID so I can create an error message to tell me the incident that is member is still attached to.
'***Section 1 - Ensure member is Checked out and DEMOBed from previous incidents
'******Variables
'*********Variable to hold the Member ID
Dim id As Integer
'*********Variable to hold the checkout status
Dim checkout As String
'*********Variable to hold the Event ID
Dim eventID As Integer
'******Code Block 1 - Check for Null Values
id = Me.Text18
Forms![frm_ics238Table].Refresh
If Not IsNull(DLookup("[eventID]", "[frm_ics238Table]", "[checkoutDate] is Null And employeeID = '" & Me.Text18 & "'")) Then
MsgBox "y"
End If
End Sub
From your original question which right now it doesn't look like you've edited it to indicate the updated code and errors, you had:
id = Me.Text18
Forms![frm_ics238Table].Refresh
If Not IsNull(DLookup("[eventID]", "[frm_ics238Table]", "[checkoutDate] is Null And employeeID = '" & Me.Text18 & "'")) Then
MsgBox "y"
End If
I think these might help:
"[frm_ics238Table]" should be table:"[tbl_ics238Table]"
ID appears to be declared as an integer yet you're using it as a
string. If employeeID is actually a numeric field remove the quotes
around employeeID = '" & Me.Text18 & "'" It should look like this employeeID = " & ID & "
You can also try using IsNull([checkoutDate]) instead of
[checkoutDate] is Null
SO it might look like:
If Not IsNull(DLookup("[eventID]", "[tbl_ics238Table]", "IsNull([checkoutDate]) And (employeeID = " & ID & ")")) Then
MsgBox "y"
End If
Even better would be to put the criteria into a string variable so you could debug and test it first
Dim strCriteria as String
strCriteria = "IsNull([checkoutDate]) And (employeeID = " & ID & ")"
Debug.Print strCriteria
If Not IsNull(DLookup("[eventID]", "[tbl_ics238Table]", strCriteria)) Then
MsgBox "y"
End If
EDIT: PROOF OF WORKING CODE:
Not that I don't believe you but I don't believe that it doesn't work if what you've described matches my assumptions.
I tested successfully using assumptions that:
eventID - number field
checkoutDate - date/time field
employeeID - number field
My sample data table
Then I put a command button on a form to test the code:
Private Sub Command8_Click()
Dim strCriteria As String
Dim ID As Integer
ID = 4
strCriteria = "IsNull([checkoutDate]) And (employeeID = " & ID & ")"
Debug.Print strCriteria
If Not IsNull(DLookup("[eventID]", "[tbl_ics238Table]", strCriteria)) Then
MsgBox "y"
End If
End Sub
Finally - testing the button click resulted in:
In conclusion - if you're still getting an error then you can update
your question with BOTH your code AND your table design.
I am currently creating a database for our company and I would need to add a Customer ID to each new record.
I designed a data entry form and have the following Module running on it to create the ID:
Option Compare Database
Function NewCustomerIDCode() As Long
Dim db As Database
Dim LSQL As String
Dim LUpdate As String
Dim Lrs As DAO.Recordset
Dim LNewCustomerIDCode As Long
On Error GoTo Err_Execute
Set db = CurrentDb()
'Retrieve last number assigned for Customer ID Code
LSQL = "Select Last_Nbr_Assigned from CustomerIDCode"
LSQL = LSQL & " where Code_Desc = 'Customer ID Code'"
Set Lrs = db.OpenRecordset(LSQL)
'If no records were found, return an error
If Lrs.EOF = True Then
LNewCustomerIDCode = 0
MsgBox "There was no entry found in the Codes table for Customer ID Code."
Else
'Determine new Customer ID Code
LNewCustomerIDCode = Lrs("Last_Nbr_Assigned") + 1
'Increment Customer ID Code in CustomerIDCode table by 1
LUpdate = "Update CustomerIDCode"
LUpdate = LUpdate & " set Last_Nbr_Assigned = " & LNewCustomerIDCode
LUpdate = LUpdate & " where Code_Desc = 'Customer ID Code'"
db.Execute LUpdate, dbFailOnError
End If
Lrs.Close
Set Lrs = Nothing
Set db = Nothing
NewCustomerIDCode = LNewCustomerIDCode
Exit Function
Err_Execute:
'An error occurred, return 0
NewCustomerIDCode = 0
MsgBox "An error occurred while trying to determine the next Customer ID Code to assign."
End Function
The problem is, if for example someone starts entering data in this form an ID is assigned (example: 1023). If for any reason they decide not to finsh the entry and delete the record, the next entry will get number (example: 1024). But I would need 1023 to be reused because it is not linked to a record. For accounting reasons I cannot have this number skip.
On the other hand if the new record is created and for whatever reason is deleted in a year, it's number cannot be reused. For example we delete record 1023 but our last entered record is 1145 the next record should get 1146 and not the deleted n° 1023.
Just for some background info I have a separate Autonumber for the primary key. This is not visible to users and has no meaning to the record except for Access to have a unique number for each record.
Can someone help? I've been searching the net for a day and the only stuff I can find is about autonumbers which does not apply here.
I have a system with a subscription method. A user will get notified that his subscription is about to run out 3 days in advance.
The message works, but every time a user presses OK, and browse, a new sql insert will be sent.
What I want is that the user gets the message only ONCE a day.
Dim themsg = "Your subscription is about to end bla bla"
Set almost = ObjConn.execute("Select * from users where expire <= '"& DateAdd("d", -3, Date()) &"'")
If almost.eof then
Response.write "No users about to finish"
Else
dim sql
sql = "insert into events(uid, event, msg, sended, need_confirm, eventtime)"
sql = sql & " VALUES "
sql = sql & "('"& almost("id") &"', "
sql = sql & "'send_msg', "
sql = sql & "'"& themsg &"', "
sql = sql & "'1', "
sql = sql & "'1', "
sql = sql & "'"& Now() &"')"
on error resume next
ObjConn.execute sql,recaffected
End if
So as you can see everytime you enter this page, a new insert will be sent. Can I restrict it so it only send to this uid/user only ONCE a day, until the expiry date?
Add the what ever your unique identifier from your users table to the events table. That way you can do a quick SELECT from the events table for user and eventtime to determine if an INSERT should occur.
Thanks to #jradich1234 gave me idea on how to do it
added new column in events ´checkday´
Then added
Set kollar = ObjConn.execute ("Select * from events where uid='"& slut("id") &"' AND checkday='"& Date() &"'")
If kollar.eof Then
<<THE SQL INSERTION HERE >>
Else
Response.write "Already sent"
End if
So with this it check if the row with same ID & todays date found, if not insert.
I’m trying to prefill a template for teachers to enter student grades.
The teacher will identify the Class, and/or Section and I will retrieve every student in those classes and/or sections. Each student will appear on a row in the template and the teacher will then fill in the grades.
I plan to retrieve the student info from the existing Student table and write this data into the EnterGrades table. After the teacher fills in the grades I will write these records from the EnterGrades table into the master grades table.
I’m having a problem figuring best method – query, form, what type. I tried to add some sql code to a form, but I couldn’t get it to work in VBA. It seems relatively straight forward, I just can’t quite see the solution. I’m first time Access user.
Using a form based on as you said Temp table is how I tend to do enter data. In the properties of the form under DATA Tab look for RECORD SOURCE. Then the fields can be set by Data Tab again Control Source.
Form Wizard should actually work well for you.
What do you mean by Pre-filled? As in has Default text? I use a lot of Combo Boxes with options and make sure that none of them are empty then have a button to submit. Run a query to update the master table and then empty the table.
If you are using .mdb
Create a module and add the following code. (Might have to add Tools>Reference. Microsoft DAO Library.)
It will run any query for you. [Param1],[Param2]... in the query where you want to fill in criteria dynamically. Call it by simply
fncQueryRun "QueryName", 0
or
fncQueryRun "QueryName", 1, "John Smith"
I copy this code to every new database I make if it has a form.
My favorite module code is:
Public dbTemp As Database, rstTemp As Recordset, tblTemp As TableDef
Public qryTemp As QueryDef, prmTemp As Parameter
Public bQueryError As Boolean, bError3271 As Boolean
Public Function fncQueryRun(ByVal stQueryName As String, ByVal intParamCnt As Integer, _
ParamArray Param() As Variant)
On Error GoTo Err_fncQueryRun
bQueryError = False
Set dbTemp = CurrentDb
DoCmd.SetWarnings False
If intParamCnt = 0 Then DoCmd.OpenQuery stQueryName 'Runs Query
'Parameter Count 0 = Just Runs the Query
If intParamCnt >= 1 Then Set qryTemp = dbTemp.QueryDefs(stQueryName)
If intParamCnt >= 1 Then qryTemp.Parameters![Param1] = Param(0)
If intParamCnt >= 2 Then qryTemp.Parameters![Param2] = Param(1)
If intParamCnt >= 3 Then qryTemp.Parameters![Param3] = Param(2)
If intParamCnt >= 4 Then qryTemp.Parameters![Param4] = Param(3)
If intParamCnt >= 5 Then qryTemp.Parameters![Param5] = Param(4)
If intParamCnt >= 6 Then qryTemp.Parameters![Param6] = Param(5)
If intParamCnt >= 7 Then qryTemp.Parameters![Param7] = Param(6)
If intParamCnt >= 8 Then qryTemp.Parameters![Param8] = Param(7)
If intParamCnt >= 9 Then qryTemp.Parameters![Param9] = Param(8)
If intParamCnt >= 10 Then qryTemp.Parameters![Param10] = Param(9)
If intParamCnt >= 1 Then qryTemp.Execute dbSeeChanges
DoCmd.SetWarnings True
Exit_fncQueryRun:
Set qryTemp = Nothing
dbTemp.Close
Exit Function
Err_fncQueryRun:
bQueryError = True
If Err.Number = 3271 Then
bError3271 = True
Resume Exit_fncQueryRun
ElseIf Err.Number = 3070 Then
Resume Exit_fncQueryRun
Else
MsgBox "Query named " & stQueryName & " - Had error number: " & Err.Number & Chr(10) & Chr(10) _
& Err.Description, , "Query - " & stQueryName & " - Error: " & Err.Number
Resume Exit_fncQueryRun
End If
End Function
I am trying to have a msgbox popup when clicking on a command button within a form in Access 2003.
The msgbox should be triggered by the current date, when compared to dates referenced within a table that is in the database. It would look like this:
If Date() is < [Date in table?], THEN "Msgbox" = "It is now Quarter 2"
once it is beyond the date for quarter 3, the msg box would read "It is now Quarter 3"
Thanks if you can help
Access has a set of functions called Domain Functions for looking up a single piece of information stored in a table. Some of the most common ones are DCount(), DLookup(), DSum(), DAvg(), DMax(), and DMin().
You need to use the DLookup function for this. Basically, it needs a field name and a table name to lookup a value. And in many cases you want to include a criteria statement (or WHERE clause) as the third argument to make sure that the DLookup function is actually retrieving the value from the correct row. If you don't pass in a criteria statment, the Domain functions will simply return the first match.
If Date() <= DLookup("SomeDateField", "tblYourTableName") Then
MsgBox "The date in stored in the table is today or else is in the future."
Else
MsgBox "The date stored in the table is in the past."
End If
Here's an alternate way to write this:
If Date() < DLookup("SomeDateField", "tblYourTableName") Then
MsgBox "The date in stored in the table is in the future."
Else
MsgBox "The date stored in the table is today or is in the past."
End If
And here's how you do it if you have multiple records/rows in the table. You then need to some kind of criteria statement to narrow it down to retrieving the value you want to from the very row you want.
If Date() < DLookup("SomeDateField", "tblYourTableName", "UserID = 1") Then
MsgBox "The date in stored in the table is in the future."
Else
MsgBox "The date stored in the table is today or is in the past."
End If
While it's not really what you are asking, I think it's important to realize what's really going on behind the scenes with this function (and other domain functions). Basically, you are choosing to retrieve one single value from one single table with the option to specify which record/row you want the value retrieved from using a criteria statement, known as a WHERE clause in SQL. So let's take a look at how you would write a function like this, and at how Microsoft likely did write their DLookup function.
Public Function MyLookup(ByVal strField As String, _
ByVal strTable As String, _
Optional ByVal strCriteria As String) As Variant
'Error handling intentionally omitted
'Proper error handling is very critical in
'production code in a function such as this
If strField <> "" And strTable <> "" Then
Dim sSQL as string
sSQL = "SELECT TOP 1 " & strField & " FROM " & strTable
If strCriteria <> "" Then
sSQL = sSQL & " WHERE " & strCriteria
End If
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset(sSQL, dbOpenSnapshot)
If Not (rst.EOF and rst.BOF) Then
MyLookup = rst(strField).Value
End If
rst.Close
Set rst = Nothing
End If
End Function
Now let's suppose you want to find the birthdate of someone in your contacts table:
Dim dteBirthDate as Date
dteBirthDate = MyLookup("BirthDate", "tblContacts", "ContactID = " & 12345)
If you didn't have a DLookup function, (or if you didn't write your own), you'd end up writing all that code in the "MyLookup" function up above for every time you needed to lookup a single value in a table.
I think what you're looking for is the following:
'Dates to be retrieved from the db (quarter start dates)
Dim q1 As Date
Dim q2 As Date
Dim q3 As Date
Dim q4 As Date
'Today's date
Dim today As Date
Dim quarter As Integer
Set today = Date()
Set q1 = DLookup("FieldContainingDate", "tableContainingDates", "quarter=1")
Set q2 = DLookup("FieldContainingDate", "tableContainingDates", "quarter=2")
Set q3 = DLookup("FieldContainingDate", "tableContainingDates", "quarter=3")
Set q4 = DLookup("FieldContainingDate", "tableContainingDates", "quarter=4")
Set quarter = 1 'Base case.
If (today > q1) Then quarter = 2
If (today > q2) Then quarter = 3
If (today > q3) Then quarter = 4
MsgBox "It is quarter " & quarter 'Display which quarter it is in a msgbox
You may have to fiddle with the date formatting depending on how you have it stored in the database, etc. It would also be much more efficient to write it in another way (for instance remove the intermediary q# variables) but I wrote it out in a lengthy way to make it more clear.