How to get date name in MS-Access - ms-access

I have 3 record:
day_birth of type Number (1-31);
month_birth of type Short Text ("January");
year_birth of type Number.
How to get in calculated field, full birthday day name from this day?
I tried this one expression:
WeekdayName(Weekday(DateSerial(2003;1;1);2))
But it doesn't work. I get #Type! in my record field.

Well, you can use this:
? format(dateserial(2003,1,1),"ddd")
Wed
or even this:
? format(dateserial(2003,1,1),"dddd")
Wednesday
However, you suggest/state/hint/imply/note that your input month is a LONG TEXT month of January. (short would be Jan).
So, we need to take into account that fact.
(but, why oh why oh why oh why oh why was the DOB not just stored as a simple single datetime column? With such a column, then you are 100% free to break it apart into 3 columns for reporting etc., but always have one simple date column
However, you have what you have, probably not your fault.
So, then:
Dim strTestMonth As String
Dim intTestYear As Integer
Dim intTestDay As Integer
strTestMonth = "January"
intTestYear = 2003
intTestDay = 1
Dim strTestDate As String
Dim strDateFormat As String
strDateFormat = "mmmm/dd/yyyy"
strTestDate = strTestMonth & "/" & intTestDay & "/" & intTestYear
Dim dtDate As Date
dtDate = Format(strTestDate, strDateFormat)
' get day of week as number
Debug.Print Weekday(dtDate)
' get day of week as text
Debug.Print "Short day of week = " & Format(dtDate, "ddd")
Debug.Print "Long day of week " & Format(dtDate, "dddd")
Output:
4
Short day of week = Wed
Long day of week Wednesday
So, approach:
Convert the string into a internal date, and once done, then you are free to spit out the date in any format you want, including use of weekday function, or even format which can return a short day format (wed), or a longer date format (Wednesday).
It not clear if you need this "display" of the week day on the form, or in a report or whatever. So as always the VERY important issue becomes the when/where/how/what point in time you need this expression.
So, you could for example place this function in a standard code module: (not forms code module)
Public Function GetDayOfWeek(strMonth As String, _
intDay As Integer, _
intYear As Integer) As String
Dim strDateFormat As String
Dim dtDate As Date
strDateFormat = "mmmm/dd/yyyy"
dtDate = Format(strMonth & "/" & intDay & "/" & intYear, strDateFormat)
GetDayOfWeek = Format(dtDate, "dddd")
End Function
So, now when ever and "where" ever you need to display the weekday as "text", then you can do this for even a control on that form:
=(GetDayOfWeek([MonthField],[dayField], [YearField]))
So, place the above code in a standard code module (not forms code module), and then in code, or even as a expression on a control in a form, you can pass the 3 values, and it will return/display the day of week in long text format.

Use DateValue and a simple query:
Select
*,
DateValue(Str([year_birth]) & " " & [month_birth] & Str([day_birth])) As BirthDate,
WeekdayName(Weekday(DateValue(Str([year_birth]) & " " & [month_birth] & Str([day_birth])), 2), 2) As BirthWeekday
From
YourTable

Related

have a number like 000x-000yy that counts the number of invoices issued each month and year so that it resets after each month and year [duplicate]

I have autonumber field in MS Access.
Here, it's starting with 1, 2, 3,…
But I want to enumerate numbers starts, with
2017ICLAA001, 2017ICLAA002, 2017ICLAA003,…
How to do that?
Simply type "2017ICLAA"000 into the ID field's Format Property
Should be able to figure out what you want with this since "2017...." is not always going to be the same and if you change it then it will jack up your database.
Example of Year-Number output: 17-0001
When the year changes the number auto resets to 1, because it checks the date then the number value which is incremental from 1 to 9,999 each year. You can delete records and it won't affect numbering since it always checks for the largest integer based on the current year, which is defined by your computers time/clock.
Must have the following columns: [AutonumberID] [DateCreated] [ColumnForYear-Number]
You should set the "[DateCreated]" column's "Default Value" in the Table's DesignView to "=Date()" (without quotes) so a date is added automatically when creating a record.
Add the following to your form's [Event Procedure] BEFOREINSERT otherwise if you update content in the record later (BeforeUpdate) it WILL change the record number everytime a change is made. You've been warned!
Do not use the date of a "[Last Modified]" type of column otherwise you will regret it in the future if you change/update anything in the record when the year changes and edits are made (think about it). Ensure you have a dedicated "[DateCreated]" column that doesn't change after inserting/adding the record no matter what year you decide to make any changes.
Here is the code:
Option Compare Database
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim vLast As Variant
Dim iNext As Integer
vLast = DMax("[ColumnForYear-Number]", "[Table]", "[ColumnForYear-Number] LIKE '" & _
Format([txtDateCreated], "yy\*\'"))
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 4)) + 1
End If
Me![ColumnForYear-Number] = Format([txtDateCreated], "yy") & "-" & Format(iNext, "0000")
End Sub
To get more than 9,999 records in one year change the number 4 in Val(Right(vLast, 4)) to a larger integer, then change the zeros in Format(iNext, "0000") to reflect the number of placeholders. The number 4 and there are four zeros. The same thing applies to the year, just change anywhere there is "yy" to "yyyy" for a four digit year. When making changes ensure the data type for the table's field/column can accept the total characters to be calculated or it will chop off any excess characters. Default is usually 255 characters for text however if your's says 8 characters are allowed for the [ColumnForYear-Number] and you are trying to add 9 or more then you will get frustrated troubleshooting a simple problem. Just FYI.
"[txtDateCreated]" is where the actual date entry exists and not the same as "[DateCreated]" which is the column name, unless you named your label that under the "Other" tab in Property Sheet. In other words columns are [columnname] and the textbox area where values are added/changed/viewed in FORMS should be labeled [txtcolumnname] (minus the brackets of course).
Additional options that are already configured into the format you request are listed in the next response (see below).
Since I had some more time on my hands I decided to answer your question more directly with a couple of options. My assumptions are: (1) You want the year 2017 to change automatically and (2) a prefix you define ICLAA followed by (3) an incremental number 001 that resets with each new year and (4) this is for a form with entry boxes (hence [txt...]).
Table Columns Required:
[AutoNumber] <=Not used here, it's just to show it still exists
[Column4UniqueValue] set the data type to Short Text and ensure your columns field size is set to 12 or more otherwise it will not work and will kick an error.
[DateCreated] set to Date/Time with format as General Date default value set =Date(), set Show Date Picker to Never for good measure, and set Locked value to Yes so user cannot change\override the value in the form. Note: this column [DateCreated] is not required if you decide to go with option two (2) listed below.
After you created the columns above in your table go to your form and add the new fields onto the form, click inside the newly added text field box and set its Other name as txt.... , then go into VBA Code Builder [Alt+F11] and add the code from either option one or option two.
Option One (with DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format([txtAreaOfDateCreated], "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format([txtAreaOfDateCreated], "yyyy") & Prefix & Format(iNext, "000")
End Sub
Option Two (without DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format(Date, "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format(Date, "yyyy") & Prefix & Format(iNext, "000")
End Sub
Your end results will look exactly like this 2017ICLAA001 and auto increment each year starting from one. Test it by creating a few records then change your computer's date/time clock to a later or earlier year and add another record. It should change with the year and when the year changes it will auto increment to the next highest value for that year. You can test this by toggling the computer year back and forth just to watch the values remain consistent when you add new records.

VBA SystemTime - 30 days

I am working on a code from a previous developer. This code has SystemTime set up.
Is there a way to get today date and minus 30 days in this format?
Code Below:
Public Function GetIsoTimestampTest() As String
Dim st As SYSTEMTIME
'Get the local date and time
GetSystemTime st
'Format the result
GetIsoTimestampTest = _
Format$(st.wYear, "0000") & "-" & _
Format$(st.wMonth, "00") & "-" & _
Format$(st.wDay, "00") & "T" & _
Format$(st.wHour, "00") & ":" & _
Format$(st.wMinute, "00") & ":" & _
Format$(st.wSecond, "00") & "Z"
End Function
Build a native date & time, add -30 days, format as a string:
utcInIsoFormat = Format$(DateAdd("d", -30, _
DateSerial(st.wYear, st.wMonth, st.wDay) _
+ TimeSerial(st.wHour, st.wMinute, st.wSecond)), "yyyy-mm-ddThh:nn:ssZ")
SYSTEMTIME appears to be a custom type defined elsewhere in your code. It's not a standard type available in Access VBA. So to use it effectively, you need to find the definition. Also GetSystemTime is also likely a custom function exclusive to your code. Here's a sample definition of a similar type, although it may not be exactly what's implemented in your system: http://custom-designed-databases.com/wordpress/2011/get-milliseconds-or-seconds-from-system-time-with-vba/
That said, System Time would refer to the Windows system time. You also have a native ability in VBA to get time using the Now() function. (https://msdn.microsoft.com/en-us/library/office/gg278671.aspx) This returns a variable with type Date, which is equivalent to a number where the integer represents days and the decimal represents time of day. An example to get 30 days prior to today would be:
Dim lastMonth as Date
Dim formattedDate as String
lastMonth = Now() - 30
formattedDate = Format(lastMonth, "yyyy-mm-ddThh:nn:ssZ")
DateSerial happily accepts a negative day count. Thus:
Public Function IsoDateMinus30() As Date
Dim st As SYSTEMTIME
Dim Result As Date
' Get the local date and time
GetSystemTime st
Result = DateSerial(st.wYear, st.wMonth, st.wDay - 30)
' To include time:
'
' Result = _
' DateSerial(st.wYear, st.wMonth, st.wDay - 30) + _
' TimeSerial(st.wHour, st.wMinute, st.wSecond)
IsoDateMinus30 = Result
End Function

How to set custom ID field?

I have autonumber field in MS Access.
Here, it's starting with 1, 2, 3,…
But I want to enumerate numbers starts, with
2017ICLAA001, 2017ICLAA002, 2017ICLAA003,…
How to do that?
Simply type "2017ICLAA"000 into the ID field's Format Property
Should be able to figure out what you want with this since "2017...." is not always going to be the same and if you change it then it will jack up your database.
Example of Year-Number output: 17-0001
When the year changes the number auto resets to 1, because it checks the date then the number value which is incremental from 1 to 9,999 each year. You can delete records and it won't affect numbering since it always checks for the largest integer based on the current year, which is defined by your computers time/clock.
Must have the following columns: [AutonumberID] [DateCreated] [ColumnForYear-Number]
You should set the "[DateCreated]" column's "Default Value" in the Table's DesignView to "=Date()" (without quotes) so a date is added automatically when creating a record.
Add the following to your form's [Event Procedure] BEFOREINSERT otherwise if you update content in the record later (BeforeUpdate) it WILL change the record number everytime a change is made. You've been warned!
Do not use the date of a "[Last Modified]" type of column otherwise you will regret it in the future if you change/update anything in the record when the year changes and edits are made (think about it). Ensure you have a dedicated "[DateCreated]" column that doesn't change after inserting/adding the record no matter what year you decide to make any changes.
Here is the code:
Option Compare Database
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim vLast As Variant
Dim iNext As Integer
vLast = DMax("[ColumnForYear-Number]", "[Table]", "[ColumnForYear-Number] LIKE '" & _
Format([txtDateCreated], "yy\*\'"))
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 4)) + 1
End If
Me![ColumnForYear-Number] = Format([txtDateCreated], "yy") & "-" & Format(iNext, "0000")
End Sub
To get more than 9,999 records in one year change the number 4 in Val(Right(vLast, 4)) to a larger integer, then change the zeros in Format(iNext, "0000") to reflect the number of placeholders. The number 4 and there are four zeros. The same thing applies to the year, just change anywhere there is "yy" to "yyyy" for a four digit year. When making changes ensure the data type for the table's field/column can accept the total characters to be calculated or it will chop off any excess characters. Default is usually 255 characters for text however if your's says 8 characters are allowed for the [ColumnForYear-Number] and you are trying to add 9 or more then you will get frustrated troubleshooting a simple problem. Just FYI.
"[txtDateCreated]" is where the actual date entry exists and not the same as "[DateCreated]" which is the column name, unless you named your label that under the "Other" tab in Property Sheet. In other words columns are [columnname] and the textbox area where values are added/changed/viewed in FORMS should be labeled [txtcolumnname] (minus the brackets of course).
Additional options that are already configured into the format you request are listed in the next response (see below).
Since I had some more time on my hands I decided to answer your question more directly with a couple of options. My assumptions are: (1) You want the year 2017 to change automatically and (2) a prefix you define ICLAA followed by (3) an incremental number 001 that resets with each new year and (4) this is for a form with entry boxes (hence [txt...]).
Table Columns Required:
[AutoNumber] <=Not used here, it's just to show it still exists
[Column4UniqueValue] set the data type to Short Text and ensure your columns field size is set to 12 or more otherwise it will not work and will kick an error.
[DateCreated] set to Date/Time with format as General Date default value set =Date(), set Show Date Picker to Never for good measure, and set Locked value to Yes so user cannot change\override the value in the form. Note: this column [DateCreated] is not required if you decide to go with option two (2) listed below.
After you created the columns above in your table go to your form and add the new fields onto the form, click inside the newly added text field box and set its Other name as txt.... , then go into VBA Code Builder [Alt+F11] and add the code from either option one or option two.
Option One (with DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format([txtAreaOfDateCreated], "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format([txtAreaOfDateCreated], "yyyy") & Prefix & Format(iNext, "000")
End Sub
Option Two (without DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format(Date, "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format(Date, "yyyy") & Prefix & Format(iNext, "000")
End Sub
Your end results will look exactly like this 2017ICLAA001 and auto increment each year starting from one. Test it by creating a few records then change your computer's date/time clock to a later or earlier year and add another record. It should change with the year and when the year changes it will auto increment to the next highest value for that year. You can test this by toggling the computer year back and forth just to watch the values remain consistent when you add new records.

DSum with date criteria

I need to count the number of shifts worked by people over the last twelve months. I want to use DateSerial. My code works if I input an actual date, not DateSerial. I tested my code by changing DateSerial to return a date other than twelve months ago but my code always gives the figure for the sum of all data - going back more than twelve months. So it ignores MyDt. Where am I going wrong?
Public Function Shifts() As Integer
Dim MyDt As Date
MyDt = DateSerial(Year(Date), Month(Date) - 12, 1) - 1
Shifts = DSum("Shifts", "tblWorkNew", "GP = " & GPLookup & "And Month > #31/10/2012#") 'This works for any date.
Shifts = DSum("Shifts", "tblWorkNew", "GP = " & GPLookup & "And Month > " & MyDt) 'This only gives all data, i.e. ignores MyDt
End Function
MyDt is Date/Time, but you include it as a string in your DSum criteria argument. So transform the value to a string which the db engine recognizes as the date you intend.
Shifts = DSum("Shifts", "tblWorkNew", _
"GP = " & GPLookup & _
" And [Month] > " & Format(MyDt, "\#yyyy-mm-dd\#"))
I added a space before And because it looked like there was one missing. I assumed Month is the name of a field in your tblWorkNew table, so enclosed it in square brackets to inform the db engine you don't want the Month() function instead.

CDate type mismatch error

I'm trying to convert a text field into a date using CDate() in a recordset but keep getting a type mismatch error. The input text format is MMDDYYYY. Does CDate not recognize this format? Do I need a separate function? Any ideas?
Text Date -> Converted Date
--------- --------------
04122012 -> 04/12/2012
Dim db As DAO.Database
Dim rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tbl_dates", Type:=dbOpenDynaset)
Do Until rst.EOF
rst.Edit
rst![Converted Date]=CDate(rst![Text Date])
rst.Update
rst.MoveNext
Loop
Set rst = Nothing
Set db = Nothing
CDate() won't accept your date string without some type of delimiter between the month, day, and year parts. This attempt fails with a type mismatch error.
? CDate("04122012")
If it's helpful, you can use the IsDate() function to check whether your date strings are in a format CDate() will accept.
? IsDate("04122012")
False
? IsDate("04-12-2012")
True
? IsDate("04/12/2012")
True
? CDate("04-12-2012")
4/12/2012
bar = "04122012" : Debug.Print CDate(Left(bar,2) & "-" & _
Mid(bar,3,2) & "-" & Right(bar,4))
4/12/2012
Edit: If there is a mismatch between your system's locale setting and the format of your date strings, you can transform those date strings to yyyy-mm-dd format to avoid problems with CDate().
bar = "04122012" : Debug.Print CDate(Right(bar,4) & "-" & _
Left(bar,2) & "-" & Mid(bar,3,2))
4/12/2012
The help for CDate says:
CDate recognizes date formats according to the locale setting of your system. The correct order of day, month, and year may not be determined if it is provided in a format other than one of the recognized date settings.
To avoid potential confusion due to locale settings, you might use DateSerial instead of CDate, as in expression like this (assuming Text Date always has 8 characters in MMDDYYYY format):
DateSerial(Right(rst![Text Date], 4), Left(rst![Text Date], 2), Mid(rst![Text Date], 3, 2))